xserver: Branch 'xwayland' - 681 commits

Kristian Høgsberg krh at kemper.freedesktop.org
Fri Mar 7 14:08:54 PST 2014


Rebased ref, commits from common ancestor:
commit 5863ec4883e5960ac13e5681534da869063305df
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Sep 18 22:08:16 2009 -0400

    Add xwayland module
    
    Squashed and rebased from the xwayland-1.12 branch.  Contributions from
    
      Christopher James Halse Rogers <christopher.halse.rogers at canonical.com>
      Corentin Chary <corentin.chary at gmail.com>
      Daniel Stone <daniel at fooishbar.org>
      Kristian Høgsberg <krh at bitplanet.net>
      Robert Bragg <robert at linux.intel.com>
      Scott Moreau <oreaus at gmail.com>
      Tiago Vignatti <tiago.vignatti at intel.com>
      Giovanni Campagna <gcampagn at redhat.com>
      Jonas Ã…dahl <jadahl at gmail.com>
      Ray Strode <rstrode at redhat.com>
      Trevor McCort <tjmccort at gmail.com>
      Rui Matos <tiagomatos at gmail.com>

diff --git a/configure.ac b/configure.ac
index 74819bf..6d412f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
 AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
 AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
+AC_ARG_ENABLE(wayland,      AS_HELP_STRING([--disable-wayland], [Build Wayland extension (default: auto)]), [WAYLAND=$enableval], [WAYLAND=auto])
 
 dnl DDXes.
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
@@ -1019,6 +1020,18 @@ fi
 if test "x$MITSHM" = xauto; then
 	MITSHM="$ac_cv_sysv_ipc"
 fi
+
+WAYLAND_MODULES="wayland-client libdrm"
+if test "x$WAYLAND" = xauto; then
+        PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES, [WAYLAND=yes], [WAYLAND=no])
+fi
+if test "x$WAYLAND" = xyes; then
+        PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES)
+	AC_DEFINE(XORG_WAYLAND, 1, [Support wayland mode])
+	WAYLAND_SCANNER_RULES(['$(top_srcdir)/hw/xfree86/xwayland'])
+fi
+AM_CONDITIONAL(WAYLAND, [test "x$WAYLAND" = xyes])
+
 AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
 if test "x$MITSHM" = xyes; then
 	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
@@ -1248,6 +1261,7 @@ if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "
 		PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
 	fi
 fi
+AM_CONDITIONAL(DRM, test "x$DRM" = xyes)
 
 if test "x$DRI2" = xyes; then
 	save_CFLAGS=$CFLAGS
@@ -2485,6 +2499,7 @@ hw/xfree86/dixmods/Makefile
 hw/xfree86/doc/Makefile
 hw/xfree86/dri/Makefile
 hw/xfree86/dri2/Makefile
+hw/xfree86/xwayland/Makefile
 hw/xfree86/exa/Makefile
 hw/xfree86/exa/man/Makefile
 hw/xfree86/fbdevhw/Makefile
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 73e1b4c..9c82ffd 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -14,10 +14,15 @@ DRI3_BUILDDIR = $(top_builddir)/dri3
 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la
 endif
 
+
 if GLAMOR_EGL
 GLAMOR_EGL_SUBDIR = glamor_egl
 endif
 
+if WAYLAND
+WAYLAND_SUBDIR = xwayland
+endif
+
 if XF86UTILS
 XF86UTILS_SUBDIR = utils
 endif
@@ -36,13 +41,13 @@ endif
 
 SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \
 	  ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \
-	  $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
+	  $(DRI2_SUBDIR) $(WAYLAND_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
 	  fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \
 	  $(GLAMOR_EGL_SUBDIR)
 
 DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
                parser ramdac shadowfb vbe vgahw \
-               loader dixmods dri dri2 exa modes \
+               loader dixmods dri dri2 exa modes xwayland \
 	       utils doc man
 
 bin_PROGRAMS = Xorg
diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 4eb86de..47ef684 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -274,11 +274,17 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
 
 #if !defined(sun)
     /* Fallback to platform default frame buffer driver */
-    if (i < (nmatches - 1)) {
+    if (i < (nmatches - 2)) {
+#ifdef XORG_WAYLAND
+        if (xorgWayland) {
+            matches[i++] = xnfstrdup("wlglamor");
+            matches[i++] = xnfstrdup("wayland");
+        } else
+#endif
 #if !defined(__linux__) && defined(__sparc__)
-        matches[i++] = xnfstrdup("wsfb");
+            matches[i++] = xnfstrdup("wsfb");
 #else
-        matches[i++] = xnfstrdup("fbdev");
+            matches[i++] = xnfstrdup("fbdev");
 #endif
     }
 #endif                          /* !sun */
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 542d5ab..7eb8b1b 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -118,7 +118,8 @@ static ModuleDefault ModuleDefaults[] = {
     {.name = "fb",.toLoad = TRUE,.load_opt = NULL},
     {.name = "shadow",.toLoad = TRUE,.load_opt = NULL},
 #endif
-    {.name = NULL,.toLoad = FALSE,.load_opt = NULL}
+    {.name = "xwayland",.toLoad = FALSE,.load_opt=NULL},
+    {.name = NULL,.toLoad = FALSE,.load_opt=NULL}
 };
 
 /* Forward declarations */
@@ -260,6 +261,17 @@ xf86ModulelistFromConfig(void ***optlist)
         return NULL;
     }
 
+    /*
+     * Set the xwayland module to autoload if requested.
+     */
+    if (xorgWayland) {
+        for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+            if (strcmp(ModuleDefaults[i].name, "xwayland") == 0) {
+                ModuleDefaults[i].toLoad = TRUE;
+            }
+        }
+    }
+
     if (xf86configptr->conf_modules) {
         /* Walk the disable list and let people know what we've parsed to
          * not be loaded 
@@ -507,9 +519,13 @@ xf86InputDriverlistFromConfig(void)
 static void
 fixup_video_driver_list(const char **drivers)
 {
-    static const char *fallback[4] = { "fbdev", "vesa", "wsfb", NULL };
+    static const char *fallback_hw[4] = { "fbdev", "vesa", "wsfb", NULL };
     const char **end, **drv;
     const char *x;
+#ifdef XORG_WAYLAND
+    static const char *fallback_wl[2] = { "wayland", NULL };
+#endif
+    static const char **fallbacks;
     int i;
 
     /* walk to the end of the list */
@@ -520,9 +536,15 @@ fixup_video_driver_list(const char **drivers)
      * for each of the fallback drivers, if we find it in the list,
      * swap it with the last available non-fallback driver.
      */
-    for (i = 0; fallback[i]; i++) {
+#ifdef XORG_WAYLAND
+    if (xorgWayland)
+        fallbacks = fallback_wl;
+    else
+#endif
+        fallbacks = fallback_hw;
+    for (i = 0; fallbacks[i]; i++) {
         for (drv = drivers; drv != end; drv++) {
-            if (strstr(*drv, fallback[i])) {
+            if (strstr(*drv, fallbacks[i])) {
                 x = *drv;
                 *drv = *end;
                 *end = x;
@@ -859,6 +881,13 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
     xf86Msg(from, "%sutomatically adding GPU devices\n",
             xf86Info.autoAddGPU ? "A" : "Not a");
+
+    /* FIXME: Do that at the right place (before xf86Msg). */
+    if (xorgWayland) {
+            xf86Info.autoAddDevices = FALSE;
+            xf86Info.autoEnableDevices = FALSE;
+    }
+
     /*
      * Set things up based on the config file information.  Some of these
      * settings may be overridden later when the command line options are
@@ -949,9 +978,10 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
 #endif
 
-    /* if we're not hotplugging, force some input devices to exist */
-    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices &&
-                                   xf86Info.autoEnableDevices);
+    if (xorgWayland) /* Don't force input devices */
+	xf86Info.forceInputDevices = FALSE;
+    else /* if we're not hotplugging, force some input devices to exist */
+	xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
 
     /* when forcing input devices, we use kbd. otherwise evdev, so use the
      * evdev rules set. */
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 7df7a80..b41d2cc 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -204,3 +204,5 @@ Bool xf86VidModeAllowNonLocal = FALSE;
 #endif
 RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
 Bool xorgHWAccess = FALSE;
+Bool xorgWayland = FALSE;
+Bool xorgRootless = FALSE;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index ff4d38f..919d35f 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -550,6 +550,25 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             /* Non-seat0 X servers should not open console */
             if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0())
                 xorgHWOpenConsole = TRUE;
+
+	    if (xorgWayland) {
+                if (flags != HW_WAYLAND) {
+                    xf86DeleteDriver(i);
+                    continue;
+                }
+
+                want_hw_access = FALSE;
+                xorgHWOpenConsole = FALSE;
+	    }
+        }
+
+        for (i = 0; i < xf86NumDrivers; i++) {
+                if (xf86DriverList[i] == NULL) {
+                        for (j = i; j < xf86NumDrivers; j++) {
+                            xf86DriverList[j] = xf86DriverList[j + 1];
+                        }
+                        xf86NumDrivers--;
+                }
         }
 
         if (xorgHWOpenConsole)
@@ -963,6 +982,9 @@ InitInput(int argc, char **argv)
 
     mieqInit();
 
+    if (xorgWayland)
+	return;
+
     /* Initialize all configured input devices */
     for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
         (*pInfo)->options =
@@ -1463,6 +1485,16 @@ ddxProcessArgument(int argc, char **argv, int i)
         return 1;
     }
 
+    if (!strcmp(argv[i], "-wayland")) {
+        xorgWayland = TRUE;
+        return 1;
+    }
+
+    if (!strcmp(argv[i], "-rootless")) {
+        xorgRootless = TRUE;
+        return 1;
+    }
+
     /* OS-specific processing */
     return xf86ProcessArgument(argc, argv, i);
 }
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 6e374eb..f843765 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -91,6 +91,8 @@ extern _X_EXPORT int xf86NumScreens;
 extern _X_EXPORT const char *xf86VisualNames[];
 extern _X_EXPORT int xf86Verbose;       /* verbosity level */
 extern _X_EXPORT int xf86LogVerbose;    /* log file verbosity level */
+extern _X_EXPORT Bool xorgWayland;
+extern _X_EXPORT Bool xorgRootless;
 
 extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
 
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index b164b7f..676f9d8 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -288,6 +288,7 @@ typedef struct {
 #define HW_MMIO 2
 #define HW_SKIP_CONSOLE 4
 #define NEED_IO_ENABLED(x) (x & HW_IO)
+#define HW_WAYLAND 8
 
 typedef CARD32 xorgHWFlags;
 
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index c70f72e..3d40138 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1332,13 +1332,16 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen,
 }
 
 static int
-DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic)
+DRI2AuthMagic (ClientPtr client, ScreenPtr pScreen, uint32_t magic)
 {
     DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
     if (ds == NULL)
         return -EINVAL;
 
-    return (*ds->LegacyAuthMagic) (ds->fd, magic);
+    if (ds->LegacyAuthMagic2)
+        return (*ds->LegacyAuthMagic2) (pScreen, magic);
+    else
+        return (*ds->LegacyAuthMagic) (ds->fd, magic);
 }
 
 Bool
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 38b4f58..ed67d01 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -207,7 +207,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client,
 /**
  * Version of the DRI2InfoRec structure defined in this header
  */
-#define DRI2INFOREC_VERSION 9
+#define DRI2INFOREC_VERSION 10
 
 typedef struct {
     unsigned int version;       /**< Version of this struct */
diff --git a/hw/xfree86/xwayland/.gitignore b/hw/xfree86/xwayland/.gitignore
new file mode 100644
index 0000000..abedfee
--- /dev/null
+++ b/hw/xfree86/xwayland/.gitignore
@@ -0,0 +1,4 @@
+drm-client-protocol.h
+drm-protocol.c
+xserver-client-protocol.h
+xserver-protocol.c
diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am
new file mode 100644
index 0000000..22ab154
--- /dev/null
+++ b/hw/xfree86/xwayland/Makefile.am
@@ -0,0 +1,46 @@
+AM_CPPFLAGS =					\
+	$(XORG_INCS)				\
+	-I$(srcdir)/../ddc			\
+	-I$(srcdir)/../ramdac			\
+	-I$(srcdir)/../i2c			\
+	-I$(srcdir)/../parser			\
+	-I$(srcdir)/../modes
+
+libxwayland_la_LTLIBRARIES = libxwayland.la
+AM_CFLAGS = \
+	-DHAVE_XORG_CONFIG_H \
+	@DIX_CFLAGS@ @XORG_CFLAGS@ @XWAYLAND_CFLAGS@ \
+	-I$(top_srcdir)/hw/xfree86/common \
+	-I$(top_srcdir)/hw/xfree86/os-support/bus
+
+libxwayland_la_LDFLAGS = -module -avoid-version @XWAYLAND_LIBS@
+libxwayland_ladir = $(moduledir)/extensions
+libxwayland_la_SOURCES =			\
+	xwayland.c				\
+	xwayland-input.c			\
+	xwayland-output.c			\
+	xwayland-cursor.c			\
+	xwayland-window.c			\
+	xwayland-private.h			\
+	drm-client-protocol.h			\
+	drm-protocol.c				\
+	xserver-client-protocol.h		\
+	xserver-protocol.c
+
+if DRM
+AM_CFLAGS += @LIBDRM_CFLAGS@
+libxwayland_la_LDFLAGS += @LIBDRM_LIBS@
+libxwayland_la_SOURCES += xwayland-drm.c
+endif
+
+sdk_HEADERS = xwayland.h
+
+BUILT_SOURCES =					\
+	drm-client-protocol.h			\
+	drm-protocol.c				\
+	xserver-client-protocol.h		\
+	xserver-protocol.c
+
+CLEANFILES = $(BUILT_SOURCES)
+
+ at wayland_scanner_rules@
diff --git a/hw/xfree86/xwayland/drm.xml b/hw/xfree86/xwayland/drm.xml
new file mode 100644
index 0000000..89fd8f0
--- /dev/null
+++ b/hw/xfree86/xwayland/drm.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="drm">
+
+  <copyright>
+    Copyright © 2008-2011 Kristian Høgsberg
+    Copyright © 2010-2011 Intel Corporation
+
+    Permission to use, copy, modify, distribute, and sell this
+    software and its documentation for any purpose is hereby granted
+    without fee, provided that\n 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
+    the copyright holders not be used in advertising or publicity
+    pertaining to distribution of the software without specific,
+    written prior permission.  The copyright holders make no
+    representations about the suitability of this software for any
+    purpose.  It is provided "as is" without express or implied
+    warranty.
+
+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+  </copyright>
+
+  <!-- drm support. This object is created by the server and published
+       using the display's global event. -->
+  <interface name="wl_drm" version="1">
+    <enum name="error">
+      <entry name="authenticate_fail" value="0"/>
+      <entry name="invalid_format" value="1"/>
+      <entry name="invalid_name" value="2"/>
+    </enum>
+
+    <enum name="format">
+      <!-- The drm format codes match the #defines in drm_fourcc.h.
+           The formats actually supported by the compositor will be
+           reported by the format event. -->
+      <entry name="c8" value="0x20203843"/>
+      <entry name="rgb332" value="0x38424752"/>
+      <entry name="bgr233" value="0x38524742"/>
+      <entry name="xrgb4444" value="0x32315258"/>
+      <entry name="xbgr4444" value="0x32314258"/>
+      <entry name="rgbx4444" value="0x32315852"/>
+      <entry name="bgrx4444" value="0x32315842"/>
+      <entry name="argb4444" value="0x32315241"/>
+      <entry name="abgr4444" value="0x32314241"/>
+      <entry name="rgba4444" value="0x32314152"/>
+      <entry name="bgra4444" value="0x32314142"/>
+      <entry name="xrgb1555" value="0x35315258"/>
+      <entry name="xbgr1555" value="0x35314258"/>
+      <entry name="rgbx5551" value="0x35315852"/>
+      <entry name="bgrx5551" value="0x35315842"/>
+      <entry name="argb1555" value="0x35315241"/>
+      <entry name="abgr1555" value="0x35314241"/>
+      <entry name="rgba5551" value="0x35314152"/>
+      <entry name="bgra5551" value="0x35314142"/>
+      <entry name="rgb565" value="0x36314752"/>
+      <entry name="bgr565" value="0x36314742"/>
+      <entry name="rgb888" value="0x34324752"/>
+      <entry name="bgr888" value="0x34324742"/>
+      <entry name="xrgb8888" value="0x34325258"/>
+      <entry name="xbgr8888" value="0x34324258"/>
+      <entry name="rgbx8888" value="0x34325852"/>
+      <entry name="bgrx8888" value="0x34325842"/>
+      <entry name="argb8888" value="0x34325241"/>
+      <entry name="abgr8888" value="0x34324241"/>
+      <entry name="rgba8888" value="0x34324152"/>
+      <entry name="bgra8888" value="0x34324142"/>
+      <entry name="xrgb2101010" value="0x30335258"/>
+      <entry name="xbgr2101010" value="0x30334258"/>
+      <entry name="rgbx1010102" value="0x30335852"/>
+      <entry name="bgrx1010102" value="0x30335842"/>
+      <entry name="argb2101010" value="0x30335241"/>
+      <entry name="abgr2101010" value="0x30334241"/>
+      <entry name="rgba1010102" value="0x30334152"/>
+      <entry name="bgra1010102" value="0x30334142"/>
+      <entry name="yuyv" value="0x56595559"/>
+      <entry name="yvyu" value="0x55595659"/>
+      <entry name="uyvy" value="0x59565955"/>
+      <entry name="vyuy" value="0x59555956"/>
+      <entry name="ayuv" value="0x56555941"/>
+      <entry name="nv12" value="0x3231564e"/>
+      <entry name="nv21" value="0x3132564e"/>
+      <entry name="nv16" value="0x3631564e"/>
+      <entry name="nv61" value="0x3136564e"/>
+      <entry name="yuv410" value="0x39565559"/>
+      <entry name="yvu410" value="0x39555659"/>
+      <entry name="yuv411" value="0x31315559"/>
+      <entry name="yvu411" value="0x31315659"/>
+      <entry name="yuv420" value="0x32315559"/>
+      <entry name="yvu420" value="0x32315659"/>
+      <entry name="yuv422" value="0x36315559"/>
+      <entry name="yvu422" value="0x36315659"/>
+      <entry name="yuv444" value="0x34325559"/>
+      <entry name="yvu444" value="0x34325659"/>
+    </enum>
+
+    <!-- Call this request with the magic received from drmGetMagic().
+         It will be passed on to the drmAuthMagic() or
+         DRIAuthConnection() call.  This authentication must be
+         completed before create_buffer could be used. -->
+    <request name="authenticate">
+      <arg name="id" type="uint"/>
+    </request>
+
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_buffer">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="stride" type="uint"/>
+      <arg name="format" type="uint"/>
+    </request>
+
+    <!-- Notification of the path of the drm device which is used by
+         the server.  The client should use this device for creating
+         local buffers.  Only buffers created from this device should
+         be be passed to the server using this drm object's
+         create_buffer request. -->
+    <event name="device">
+      <arg name="name" type="string"/>
+    </event>
+
+    <event name="format">
+      <arg name="format" type="uint"/>
+    </event>
+
+    <!-- Raised if the authenticate request succeeded -->
+    <event name="authenticated"/>
+  </interface>
+
+</protocol>
diff --git a/hw/xfree86/xwayland/xserver.xml b/hw/xfree86/xwayland/xserver.xml
new file mode 100644
index 0000000..9e25f5c
--- /dev/null
+++ b/hw/xfree86/xwayland/xserver.xml
@@ -0,0 +1,18 @@
+<protocol name="xserver">
+
+  <interface name="xserver" version="1">
+    <request name="set_window_id">
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="id" type="uint"/>
+    </request>
+
+    <event name="client">
+      <arg name="fd" type="fd"/>
+    </event>
+
+    <event name="listen_socket">
+      <arg name="fd" type="fd"/>
+    </event>
+  </interface>
+
+</protocol>
diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
new file mode 100644
index 0000000..2b3cb5e
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-cursor.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <cursorstr.h>
+#include <xf86Crtc.h>
+#include <mipointrst.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+expand_source_and_mask(CursorPtr cursor, void *data)
+{
+    CARD32 *argb, *p, d, fg, bg;
+    CursorBitsPtr bits = cursor->bits;
+    int size;
+    int x, y, stride, i, bit;
+
+    size = bits->width * bits->height * 4;
+    argb = malloc(size);
+    if (argb == NULL)
+	return;
+
+    p = argb;
+    fg = ((cursor->foreRed & 0xff00) << 8) |
+	(cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8);
+    bg = ((cursor->backRed & 0xff00) << 8) |
+	(cursor->backGreen & 0xff00) | (cursor->backGreen >> 8);
+    stride = (bits->width / 8 + 3) & ~3;
+    for (y = 0; y < bits->height; y++)
+	for (x = 0; x < bits->width; x++) {
+	    i = y * stride + x / 8;
+	    bit = 1 << (x & 7);
+	    if (bits->source[i] & bit)
+		d = fg;
+	    else
+		d = bg;
+	    if (bits->mask[i] & bit)
+		d |= 0xff000000;
+	    else
+		d = 0x00000000;
+
+	    *p++ = d;
+	}
+
+    memcpy(data, argb, size);
+    free(argb);
+}
+
+static Bool
+xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
+{
+    struct xwl_screen *xwl_screen;
+    int size;
+    char filename[] = "/tmp/wayland-shm-XXXXXX";
+    int fd;
+    struct wl_shm_pool *pool;
+    struct wl_buffer *buffer;
+    void *data;
+
+    xwl_screen = xwl_screen_get(screen);
+    size = cursor->bits->width * cursor->bits->height * 4;
+
+    fd = mkstemp(filename);
+    if (fd < 0) {
+	ErrorF("open %s failed: %s", filename, strerror(errno));
+	return FALSE;
+    }
+    if (ftruncate(fd, size) < 0) {
+	ErrorF("ftruncate failed: %s", strerror(errno));
+	close(fd);
+	return FALSE;
+    }
+
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    unlink(filename);
+
+    if (data == MAP_FAILED) {
+	ErrorF("mmap failed: %s", strerror(errno));
+	close(fd);
+	return FALSE;
+    }
+
+    if (cursor->bits->argb)
+	memcpy(data, cursor->bits->argb, size);
+    else
+	expand_source_and_mask(cursor, data);
+    munmap(data, size);
+
+    pool = wl_shm_create_pool(xwl_screen->shm, fd, size);
+    close(fd);
+    buffer = wl_shm_pool_create_buffer(pool, 0,
+				  cursor->bits->width, cursor->bits->height,
+				  cursor->bits->width * 4,
+				  WL_SHM_FORMAT_ARGB8888);
+    wl_shm_pool_destroy(pool);
+
+    dixSetPrivate(&cursor->devPrivates,
+                  &xwl_screen->cursor_private_key, buffer);
+
+    return TRUE;
+}
+
+static Bool
+xwl_unrealize_cursor(DeviceIntPtr device,
+			ScreenPtr screen, CursorPtr cursor)
+{
+    struct wl_buffer *buffer;
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+    buffer = dixGetPrivate(&cursor->devPrivates,
+                           &xwl_screen->cursor_private_key);
+    wl_buffer_destroy(buffer);
+
+    return TRUE;
+}
+
+void
+xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
+{
+    struct wl_buffer *buffer;
+
+    if (!xwl_seat->wl_pointer)
+        return;
+
+    if (!xwl_seat->x_cursor) {
+        wl_pointer_set_cursor(xwl_seat->wl_pointer,
+                              xwl_seat->pointer_enter_serial,
+                              NULL, 0, 0);
+        return;
+    }
+
+    buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates,
+                           &xwl_seat->xwl_screen->cursor_private_key);
+
+    wl_pointer_set_cursor(xwl_seat->wl_pointer,
+			  xwl_seat->pointer_enter_serial,
+			  xwl_seat->cursor,
+			  xwl_seat->x_cursor->bits->xhot,
+			  xwl_seat->x_cursor->bits->yhot);
+    wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
+    wl_surface_damage(xwl_seat->cursor, 0, 0,
+		      xwl_seat->x_cursor->bits->width,
+		      xwl_seat->x_cursor->bits->height);
+    wl_surface_commit(xwl_seat->cursor);
+}
+
+static void
+xwl_set_cursor(DeviceIntPtr device,
+	       ScreenPtr screen, CursorPtr cursor, int x, int y)
+{
+    struct xwl_screen *xwl_screen;
+    struct xwl_seat *xwl_seat;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    if (!xwl_screen || xorg_list_is_empty(&xwl_screen->seat_list))
+	return;
+
+    xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list,
+		                     struct xwl_seat, link);
+
+    xwl_seat->x_cursor = cursor;
+    xwl_seat_set_cursor(xwl_seat);
+}
+
+static void
+xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
+{
+}
+
+static Bool
+xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    return xwl_screen->sprite_funcs->DeviceCursorInitialize(device,
+							       screen);
+}
+
+static void
+xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen);
+}
+
+static miPointerSpriteFuncRec xwl_pointer_sprite_funcs =
+{
+    xwl_realize_cursor,
+    xwl_unrealize_cursor,
+    xwl_set_cursor,
+    xwl_move_cursor,
+    xwl_device_cursor_initialize,
+    xwl_device_cursor_cleanup
+};
+
+int
+xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    miPointerScreenPtr pointer_priv;
+
+    if (!dixRegisterPrivateKey(&xwl_screen->cursor_private_key,
+                               PRIVATE_CURSOR, 0))
+	return BadAlloc;
+
+    pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey);
+    xwl_screen->sprite_funcs = pointer_priv->spriteFuncs;
+    pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs;
+
+    return Success;
+}
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
new file mode 100644
index 0000000..5250857
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <xf86drm.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+#include <drm-client-protocol.h>
+
+#include <xf86Xinput.h>
+#include <xf86Crtc.h>
+#include <xf86str.h>
+#include <windowstr.h>
+#include <input.h>
+#include <inputstr.h>
+#include <exevents.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "../dri2/dri2.h"
+
+struct xwl_auth_req {
+    struct xorg_list link;
+
+    ClientPtr client;
+    struct xwl_screen *xwl_screen;
+    uint32_t magic;
+};
+
+static void
+drm_handle_device (void *data, struct wl_drm *drm, const char *device)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    xwl_screen->device_name = strdup (device);
+}
+
+static void
+drm_handle_format(void *data, struct wl_drm *wl_drm, uint32_t format)
+{
+}
+
+static void
+drm_handle_authenticated (void *data, struct wl_drm *drm)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_auth_req *req;
+
+    xwl_screen->authenticated = 1;
+
+    /* it does one authentication transaction at a time, so if there's an
+     * element in the list, we call DRI2SendAuthReply for that client, remove
+     * the head and free the struct. If there are still elements in the list,
+     * it means that we have one or more clients waiting to be authenticated
+     * and we send out a wl_drm authenticate request for the first client in
+     * the list */
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
+	return;
+
+    req = xorg_list_first_entry(&xwl_screen->authenticate_client_list,
+	                        struct xwl_auth_req, link);
+    DRI2SendAuthReply(req->client, TRUE);
+    AttendClient(req->client);
+    xorg_list_del(&req->link);
+    free(req);
+
+    xorg_list_for_each_entry(req, &xwl_screen->authenticate_client_list,
+	                     link) {
+	wl_drm_authenticate (xwl_screen->drm, req->magic);
+	return;
+    }
+}
+
+static const struct wl_drm_listener xwl_drm_listener =
+{
+    drm_handle_device,
+    drm_handle_format,
+    drm_handle_authenticated
+};
+
+static void
+drm_handler(void *data, struct wl_registry *registry, uint32_t id,
+	    const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_drm") == 0) {
+	xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
+                                           &wl_drm_interface, 1);
+	wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* Nothing to do here, wl_drm should not be removed */
+}
+
+static const struct wl_registry_listener drm_listener = {
+    drm_handler,
+    global_remove
+};
+
+int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
+{
+    uint32_t magic;
+
+    xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener,
+                             xwl_screen);
+
+    /* Ensure drm_handler has seen all the interfaces */
+    wl_display_roundtrip(xwl_screen->display);
+    /* Ensure the xwl_drm_listener has seen the drm device, if any */
+    wl_display_roundtrip(xwl_screen->display);
+
+    ErrorF("wayland_drm_screen_init, device name %s\n",
+	   xwl_screen->device_name);
+
+    xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR);
+    if (xwl_screen->drm_fd < 0) {
+	ErrorF("failed to open the drm fd\n");
+	return BadAccess;
+    }
+
+    if (drmGetMagic(xwl_screen->drm_fd, &magic)) {
+	ErrorF("failed to get drm magic");
+	return BadAccess;
+    }
+
+    wl_drm_authenticate(xwl_screen->drm, magic);
+
+    wl_display_roundtrip(xwl_screen->display);
+
+    ErrorF("opened drm fd: %d\n", xwl_screen->drm_fd);
+
+    if (!xwl_screen->authenticated) {
+	ErrorF("Failed to auth drm fd\n");
+	return BadAccess;
+    }
+
+    return Success;
+}
+
+Bool xwl_drm_initialised(struct xwl_screen *xwl_screen)
+{
+    return xwl_screen->authenticated;
+}
+
+int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
+{
+    return xwl_screen->drm_fd;
+}
+
+int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+			    uint32_t magic)
+{
+    struct xwl_auth_req *req;
+
+    if (!xwl_screen->drm)
+	return BadAccess;
+
+    req = malloc (sizeof *req);
+    if (req == NULL)
+	return BadAlloc;
+
+    req->client = client;
+    req->xwl_screen = xwl_screen;
+    req->magic = magic;
+
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
+	wl_drm_authenticate (xwl_screen->drm, magic);
+
+    xorg_list_append(&req->link, &xwl_screen->authenticate_client_list);
+
+    IgnoreClient(req->client);
+    xwl_screen->authenticated = 0;
+
+    return Success;
+}
+
+
+int
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, uint32_t name)
+{
+    VisualID visual;
+    WindowPtr window = xwl_window->window;
+    ScreenPtr screen = window->drawable.pScreen;
+    uint32_t format;
+    int i;
+
+    visual = wVisual(window);
+    for (i = 0; i < screen->numVisuals; i++)
+	if (screen->visuals[i].vid == visual)
+	    break;
+
+    switch (screen->visuals[i].nplanes) {
+    case 32:
+	format = WL_DRM_FORMAT_ARGB8888;
+        break;
+    case 24:
+    default:
+	format = WL_DRM_FORMAT_XRGB8888;
+        break;
+    case 16:
+        format = WL_DRM_FORMAT_RGB565;
+        break;
+    }
+
+    xwl_window->buffer =
+      wl_drm_create_buffer(xwl_window->xwl_screen->drm,
+			   name,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height,
+			   pixmap->devKind,
+			   format);
+
+    return xwl_window->buffer ? Success : BadDrawable;
+}
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
new file mode 100644
index 0000000..6db047e
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+#include <X11/extensions/compositeproto.h>
+#include <xserver-properties.h>
+
+#include <compositeext.h>
+#include <selection.h>
+#include <extinit.h>
+#include <exevents.h>
+#include <input.h>
+#include <inpututils.h>
+#include <inputstr.h>
+#include <exevents.h>
+#include <xkbsrv.h>
+#include <xf86Xinput.h>
+#include <xf86Crtc.h>
+#include <xf86str.h>
+#include <windowstr.h>
+#include <xf86Priv.h>
+#include <mipointrst.h>
+#include <sys/mman.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+	/* Nothing to do, dix handles all settings */
+}
+
+static int
+xwl_pointer_proc(DeviceIntPtr device, int what)
+{
+#define NBUTTONS 10
+#define NAXES 2
+    BYTE map[NBUTTONS + 1];
+    int i = 0;
+    Atom btn_labels[NBUTTONS] = {0};
+    Atom axes_labels[NAXES] = {0};
+
+    switch (what) {
+    case DEVICE_INIT:
+	device->public.on = FALSE;
+
+        for (i = 1; i <= NBUTTONS; i++)
+            map[i] = i;
+
+        btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+        btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+        btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+        btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+        btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+        btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+        btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+        /* don't know about the rest */
+
+        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+
+        if (!InitValuatorClassDeviceStruct(device, 2, btn_labels,
+                                           GetMotionHistorySize(), Absolute))
+            return BadValue;
+
+        /* Valuators */
+        InitValuatorAxisStruct(device, 0, axes_labels[0],
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
+        InitValuatorAxisStruct(device, 1, axes_labels[1],
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
+
+        if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
+            return BadValue;
+
+        if (!InitButtonClassDeviceStruct(device, 3, btn_labels, map))
+            return BadValue;
+
+        return Success;
+
+    case DEVICE_ON:
+	device->public.on = TRUE;
+        return Success;
+
+    case DEVICE_OFF:
+    case DEVICE_CLOSE:
+	device->public.on = FALSE;
+        return Success;
+    }
+
+    return BadMatch;
+
+#undef NBUTTONS
+#undef NAXES
+}
+
+static void
+xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
+{
+    /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in
+     * ctrl->leds - needs private protocol. */
+}
+
+static int
+xwl_keyboard_proc(DeviceIntPtr device, int what)
+{
+    InputInfoPtr pInfo = device->public.devicePrivate;
+    struct xwl_seat *xwl_seat = pInfo->private;
+    int len;
+
+    switch (what) {
+    case DEVICE_INIT:
+	device->public.on = FALSE;
+        if (xwl_seat->keymap)
+            len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size);
+        else
+            len = 0;
+        if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap,
+						len,
+						NULL, xwl_keyboard_control))
+            return BadValue;
+
+        return Success;
+    case DEVICE_ON:
+	device->public.on = TRUE;
+        return Success;
+
+    case DEVICE_OFF:
+    case DEVICE_CLOSE:
+	device->public.on = FALSE;
+        return Success;
+    }
+
+    return BadMatch;
+}
+
+static void
+xwl_keyboard_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+}
+
+static int
+xwl_keyboard_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    pInfo->type_name = "xwayland-keyboard";
+    pInfo->device_control = xwl_keyboard_proc;
+    pInfo->read_input = NULL;
+    pInfo->control_proc = NULL;
+    pInfo->switch_mode = NULL;
+    pInfo->fd = -1;
+
+    return Success;
+}
+
+_X_EXPORT InputDriverRec xwl_keyboard_driver = {
+    1,
+    "xwayland-keyboard",
+    NULL,
+    xwl_keyboard_init,
+    xwl_keyboard_uninit,
+    NULL,
+};
+
+static void
+xwl_pointer_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+}
+
+static int
+xwl_pointer_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    pInfo->type_name = "xwayland-pointer";
+    pInfo->device_control = xwl_pointer_proc;
+    pInfo->read_input = NULL;
+    pInfo->control_proc = NULL;
+    pInfo->switch_mode = NULL;
+    pInfo->fd = -1;
+
+    return Success;
+}
+
+_X_EXPORT InputDriverRec xwl_pointer_driver = {
+    1,
+    "xwayland-pointer",
+    NULL,
+    xwl_pointer_init,
+    xwl_pointer_uninit,
+    NULL,
+};
+
+void
+xwl_input_teardown(void *p)
+{
+}
+
+void *
+xwl_input_setup(void *module, void *opts, int *errmaj, int *errmin)
+{
+    xf86AddInputDriver(&xwl_keyboard_driver, module, 0);
+    xf86AddInputDriver(&xwl_pointer_driver, module, 0);
+
+    return module;
+}
+
+static DeviceIntPtr
+device_added(struct xwl_seat *xwl_seat, const char *driver)
+{
+    DeviceIntPtr dev = NULL;
+    InputInfoPtr pInfo;
+    int rc;
+
+    pInfo = xf86AllocateInput();
+    if (!pInfo)
+        return NULL;
+
+    pInfo->driver = xstrdup(driver);
+
+    if (asprintf(&pInfo->name, "%s:%d", pInfo->driver, xwl_seat->id) == -1) {
+	free(pInfo);
+	return NULL;
+    }
+
+    pInfo->private = xwl_seat;
+
+    rc = xf86NewInputDevice(pInfo, &dev, 1);
+    if (rc != Success) {
+	free(pInfo);
+	return NULL;
+    }
+
+    LogMessage(X_INFO, "config/xwayland: Adding input device %s\n",
+	       pInfo->name);
+
+    return dev;
+}
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+		     uint32_t serial, struct wl_surface *surface,
+		     wl_fixed_t sx_w, wl_fixed_t sy_w)
+
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev = xwl_seat->pointer;
+    int i;
+    int sx = wl_fixed_to_int(sx_w);
+    int sy = wl_fixed_to_int(sy_w);
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
+
+    xwl_seat->xwl_screen->serial = serial;
+    xwl_seat->pointer_enter_serial = serial;
+
+    xwl_seat->focus_window = wl_surface_get_user_data(surface);
+
+    (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE);
+
+    SetDeviceRedirectWindow(xwl_seat->pointer, xwl_seat->focus_window->window);
+
+    /* Ideally, X clients shouldn't see these button releases.  When
+     * the pointer leaves a window with buttons down, it means that
+     * the wayland compositor has grabbed the pointer.  The button
+     * release event is consumed by whatever grab in the compositor
+     * and won't be sent to clients (the X server is a client).
+     * However, we need to reset X's idea of which buttons are up and
+     * down, and they're all up (by definition) when the pointer
+     * enters a window.  We should figure out a way to swallow these
+     * events, perhaps using an X grab whenever the pointer is not in
+     * any X window, but for now just send the events. */
+    for (i = 0; i < dev->button->numButtons; i++)
+	if (BitIsOn(dev->button->down, i))
+		xf86PostButtonEvent(dev, TRUE, i, 0, 0, 0);
+
+    (*pScreen->DisplayCursor)(dev, pScreen, dev->spriteInfo->sprite->current);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+		     uint32_t serial, struct wl_surface *surface)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev = xwl_seat->pointer;
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    xwl_seat->focus_window = NULL;
+    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
+    (*pScreen->DisplayCursor)(dev, pScreen, NullCursor);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+		      uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+    struct xwl_seat *xwl_seat = data;
+    int32_t dx, dy;
+    int sx = wl_fixed_to_int(sx_w);
+    int sy = wl_fixed_to_int(sy_w);
+    ValuatorMask mask;
+
+    if (!xwl_seat->focus_window)
+	return ;
+
+    dx = xwl_seat->focus_window->window->drawable.x;
+    dy = xwl_seat->focus_window->window->drawable.y;
+
+    valuator_mask_zero(&mask);
+    valuator_mask_set(&mask, 0, dx + sx);
+    valuator_mask_set(&mask, 1, dy + sy);
+
+    QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
+		       POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
+		      uint32_t time, uint32_t button, uint32_t state)
+{
+    struct xwl_seat *xwl_seat = data;
+    int index;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    switch (button) {
+    case BTN_MIDDLE:
+	index = 2;
+	break;
+    case BTN_RIGHT:
+	index = 3;
+	break;
+    default:
+	index = button - BTN_LEFT + 1;
+	break;
+    }
+
+    xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, state, 0, 0);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+		    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+    struct xwl_seat *xwl_seat = data;
+    int index, count;
+    int i, val;
+    const int divisor = 10;
+
+    if (time - xwl_seat->scroll_time > 2000) {
+	xwl_seat->vertical_scroll = 0;
+	xwl_seat->horizontal_scroll = 0;
+    }
+    xwl_seat->scroll_time = time;
+
+    /* FIXME: Need to do proper smooth scrolling here! */
+    switch (axis) {
+    case WL_POINTER_AXIS_VERTICAL_SCROLL:
+	xwl_seat->vertical_scroll += value / divisor;
+	val = wl_fixed_to_int(xwl_seat->vertical_scroll);
+	xwl_seat->vertical_scroll -= wl_fixed_from_int(val);
+
+	if (val <= -1)
+            index = 4;
+	else if (val >= 1)
+            index = 5;
+	else
+            return;
+	break;
+    case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+	xwl_seat->horizontal_scroll += value / divisor;
+	val = wl_fixed_to_int(xwl_seat->horizontal_scroll);
+	xwl_seat->horizontal_scroll -= wl_fixed_from_int(val);
+
+	if (val <= -1)
+            index = 6;
+	else if (val >= 1)
+            index = 7;
+	else
+            return;
+	break;
+    default:
+	return;
+    }
+
+    count = abs(val);
+    for (i = 0; i < count; i++) {
+	xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, 1, 0, 0);
+	xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, 0, 0, 0);
+    }
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+	pointer_handle_enter,
+	pointer_handle_leave,
+	pointer_handle_motion,
+	pointer_handle_button,
+	pointer_handle_axis,
+};
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
+		    uint32_t time, uint32_t key, uint32_t state)
+{
+    struct xwl_seat *xwl_seat = data;
+    uint32_t *k, *end;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    end = xwl_seat->keys.data + xwl_seat->keys.size;
+    for (k = xwl_seat->keys.data; k < end; k++) {
+	if (*k == key)
+	    *k = *--end;
+    }
+    xwl_seat->keys.size = (void *) end - xwl_seat->keys.data;
+    if (state) {
+	k = wl_array_add(&xwl_seat->keys, sizeof *k);
+	*k = key;
+    }
+
+    xf86PostKeyboardEvent(xwl_seat->keyboard, key + 8, state);
+}
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+		       uint32_t format, int fd, uint32_t size)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr master;
+    XkbDescPtr xkb;
+    XkbChangesRec changes = { 0 };
+
+    if (xwl_seat->keymap)
+        munmap(xwl_seat->keymap, xwl_seat->keymap_size);
+
+    xwl_seat->keymap_size = size;
+    xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+    if (xwl_seat->keymap == MAP_FAILED) {
+        xwl_seat->keymap_size = 0;
+        xwl_seat->keymap = NULL;
+        goto out;
+    }
+
+    if (!xwl_seat->keyboard)
+        goto out;
+
+    xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap,
+                                     strnlen(xwl_seat->keymap, xwl_seat->keymap_size));
+    if (!xkb)
+        goto out;
+
+    XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes);
+    /* Keep the current controls */
+    XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc);
+
+    XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb);
+
+    master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
+    if (master && master->lastSlave == xwl_seat->keyboard)
+        XkbDeviceApplyKeymap(master, xkb);
+
+    XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE);
+
+ out:
+    close(fd);
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+		      uint32_t serial,
+		      struct wl_surface *surface, struct wl_array *keys)
+{
+    struct xwl_seat *xwl_seat = data;
+    uint32_t *k;
+
+    xwl_seat->xwl_screen->serial = serial;
+    xwl_seat->keyboard_focus = surface;
+
+    wl_array_copy(&xwl_seat->keys, keys);
+    wl_array_for_each(k, &xwl_seat->keys)
+	xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 1);
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+		      uint32_t serial, struct wl_surface *surface)
+{
+    struct xwl_seat *xwl_seat = data;
+    uint32_t *k;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    wl_array_for_each(k, &xwl_seat->keys)
+	xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 0);
+
+    xwl_seat->keyboard_focus = NULL;
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+			  uint32_t serial, uint32_t mods_depressed,
+			  uint32_t mods_latched, uint32_t mods_locked,
+			  uint32_t group)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev;
+    XkbStateRec old_state, *new_state;
+    xkbStateNotify sn;
+    CARD16 changed;
+
+    /* We don't need any of this while we have keyboard focus since
+       the regular key event processing already takes care of setting
+       our internal state correctly. */
+    if (xwl_seat->keyboard_focus)
+        return;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        if (dev != xwl_seat->keyboard && dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
+            continue;
+
+        old_state = dev->key->xkbInfo->state;
+        new_state = &dev->key->xkbInfo->state;
+
+        new_state->locked_group = group & XkbAllGroupsMask;
+        new_state->locked_mods = mods_locked & XkbAllModifiersMask;
+        XkbLatchModifiers(dev, XkbAllModifiersMask, mods_latched & XkbAllModifiersMask);
+
+        XkbComputeDerivedState(dev->key->xkbInfo);
+
+        changed = XkbStateChangedFlags(&old_state, new_state);
+        if (!changed)
+            continue;
+
+        sn.keycode = 0;
+        sn.eventType = 0;
+        sn.requestMajor = XkbReqCode;
+        sn.requestMinor = X_kbLatchLockState; /* close enough */
+        sn.changed = changed;
+        XkbSendStateNotify(dev, &sn);
+    }
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+	keyboard_handle_keymap,
+	keyboard_handle_enter,
+	keyboard_handle_leave,
+	keyboard_handle_key,
+	keyboard_handle_modifiers,
+};
+
+static void
+add_devices(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct xwl_seat *xwl_seat = data;
+
+    wl_callback_destroy(callback);
+
+    if (xwl_seat->wl_pointer)
+	xwl_seat->pointer = device_added(xwl_seat, "xwayland-pointer");
+    if (xwl_seat->wl_keyboard)
+	xwl_seat->keyboard = device_added(xwl_seat, "xwayland-keyboard");
+}
+
+static const struct wl_callback_listener add_devices_listener = {
+	add_devices
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+			 enum wl_seat_capability caps)
+{
+	struct xwl_seat *xwl_seat = data;
+	struct wl_callback *callback;
+
+	if (caps & WL_SEAT_CAPABILITY_POINTER) {
+	    xwl_seat->wl_pointer = wl_seat_get_pointer(seat);
+	    wl_pointer_add_listener(xwl_seat->wl_pointer,
+				    &pointer_listener, xwl_seat);
+            xwl_seat_set_cursor(xwl_seat);
+	}
+
+	if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+	    xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat);
+	    wl_keyboard_add_listener(xwl_seat->wl_keyboard,
+				     &keyboard_listener, xwl_seat);
+
+	}
+        /* FIXME: Touch ... */
+
+	/* Add devices after we've received keymaps. */
+	if (caps) {
+	    callback = wl_display_sync(xwl_seat->xwl_screen->display);
+	    wl_callback_add_listener(callback,
+				     &add_devices_listener, xwl_seat);
+	}
+}
+
+static const struct wl_seat_listener seat_listener = {
+	seat_handle_capabilities,
+};
+
+static void
+create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
+{
+    struct xwl_seat *xwl_seat;
+
+    xwl_seat = calloc(sizeof *xwl_seat, 1);
+    if (xwl_seat == NULL) {
+	ErrorF("create_input ENOMEM");
+	return ;
+    }
+
+    xwl_seat->xwl_screen = xwl_screen;
+    xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
+
+    xwl_seat->seat =
+	wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
+    xwl_seat->id = id;
+
+    xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
+    wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
+    wl_array_init(&xwl_seat->keys);
+}
+
+static void
+input_handler(void *data, struct wl_registry *registry, uint32_t id,
+	      const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_seat") == 0) {
+        create_input_device(xwl_screen, id);
+    } else if (strcmp(interface, "xserver") == 0) {
+        xwl_screen->xorg_server =
+            wl_registry_bind(registry, id, &xserver_interface, 1);
+        xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
+                             xwl_screen);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* FIXME */
+}
+
+static const struct wl_registry_listener input_listener = {
+    input_handler,
+    global_remove,
+};
+
+void
+xwl_input_init(struct xwl_screen *xwl_screen)
+{
+    xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
+                             xwl_screen);
+}
diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
new file mode 100644
index 0000000..a45e213
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-output.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <cursorstr.h>
+#include <xf86Crtc.h>
+#include <mipointrst.h>
+#include <randrstr.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+}
+
+static Bool
+crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		    Rotation rotation, int x, int y)
+{
+	return TRUE;
+}
+
+static void
+crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+crtc_show_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static PixmapPtr
+crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+	return NULL;
+}
+
+static void *
+crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+	return NULL;
+}
+
+static void
+crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+}
+
+static void
+crtc_destroy(xf86CrtcPtr crtc)
+{
+    /* Nothing to do here, we only destroy CRTCs when instructed to do
+       so by wl_output changes
+    */
+}
+
+static const xf86CrtcFuncsRec crtc_funcs = {
+    .dpms                = crtc_dpms,
+    .set_mode_major      = crtc_set_mode_major,
+    .set_cursor_colors   = crtc_set_cursor_colors,
+    .set_cursor_position = crtc_set_cursor_position,
+    .show_cursor         = crtc_show_cursor,
+    .hide_cursor         = crtc_hide_cursor,
+    .load_cursor_argb    = crtc_load_cursor_argb,
+    .shadow_create       = crtc_shadow_create,
+    .shadow_allocate     = crtc_shadow_allocate,
+    .shadow_destroy      = crtc_shadow_destroy,
+    .destroy		 = crtc_destroy,
+};
+
+static void
+output_dpms(xf86OutputPtr output, int mode)
+{
+	return;
+}
+
+static xf86OutputStatus
+output_detect(xf86OutputPtr output)
+{
+	return XF86OutputStatusConnected;
+}
+
+static Bool
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+output_get_modes(xf86OutputPtr xf86output)
+{
+    struct xwl_output *output = xf86output->driver_private;
+    struct monitor_ranges *ranges;
+    DisplayModePtr modes;
+
+    modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE);
+    output->xf86monitor.det_mon[0].type = DS_RANGES;
+    ranges = &output->xf86monitor.det_mon[0].section.ranges;
+    ranges->min_h = modes->HSync - 10;
+    ranges->max_h = modes->HSync + 10;
+    ranges->min_v = modes->VRefresh - 10;
+    ranges->max_v = modes->VRefresh + 10;
+    ranges->max_clock = modes->Clock + 100;
+    output->xf86monitor.det_mon[1].type = DT;
+    output->xf86monitor.det_mon[2].type = DT;
+    output->xf86monitor.det_mon[3].type = DT;
+    output->xf86monitor.no_sections = 0;
+
+    xf86output->MonInfo = &output->xf86monitor;
+
+    return modes;
+}
+
+static void
+output_destroy(xf86OutputPtr xf86output)
+{
+    struct xwl_output *output = xf86output->driver_private;
+
+    free(output);
+}
+
+static const xf86OutputFuncsRec output_funcs = {
+    .dpms	= output_dpms,
+    .detect	= output_detect,
+    .mode_valid	= output_mode_valid,
+    .get_modes	= output_get_modes,
+    .destroy	= output_destroy
+};
+
+struct xwl_output *
+xwl_output_create(struct xwl_screen *xwl_screen)
+{
+    struct xwl_output *xwl_output;
+    xf86OutputPtr xf86output;
+    xf86CrtcPtr xf86crtc;
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(xwl_screen->scrninfo);
+    int crtcId, outputId;
+    static int nameId;
+    char *name;
+
+    xwl_output = calloc(sizeof *xwl_output, 1);
+    if (xwl_output == NULL) {
+	ErrorF("create_output ENOMEM");
+	return NULL;
+    }
+
+    nameId++;
+    if (asprintf(&name, "XWAYLAND-%d", nameId) < 0) {
+        ErrorF("create_output ENOMEM");
+        free(xwl_output);
+        return NULL;
+    }
+
+    xwl_output->xwl_screen = xwl_screen;
+
+    xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs);
+    xf86crtc->enabled = TRUE;
+    xf86crtc->driver_private = xwl_output;
+
+    for (crtcId = 0; crtcId < xf86_config->num_crtc; crtcId++) {
+        if (xf86_config->crtc[crtcId] == xf86crtc)
+            break;
+    }
+
+    xf86output = xf86OutputCreate(xwl_screen->scrninfo,
+				  &output_funcs, name);
+    xf86output->driver_private = xwl_output;
+    xf86output->possible_crtcs = 1 << crtcId;
+
+    for (outputId = 0; outputId < xf86_config->num_output; outputId++) {
+        if (xf86_config->output[outputId] == xf86output)
+            break;
+    }
+
+    xf86output->possible_clones = 1 << outputId;
+
+    xwl_output->xf86output = xf86output;
+    xwl_output->xf86crtc = xf86crtc;
+    xwl_output->xf86output->crtc = xf86crtc;
+
+    free(name);
+
+    return xwl_output;
+}
+
+static Bool
+resize(ScrnInfoPtr scrn, int width, int height)
+{
+    if (scrn->virtualX == width && scrn->virtualY == height)
+	return TRUE;
+    /* We don't handle resize at all, we must match the compositor size */
+    return FALSE;
+}
+
+static const xf86CrtcConfigFuncsRec config_funcs = {
+    resize
+};
+
+static Rotation
+wl_transform_to_xrandr (enum wl_output_transform transform)
+{
+  switch (transform)
+    {
+    case WL_OUTPUT_TRANSFORM_NORMAL:
+      return RR_Rotate_0;
+    case WL_OUTPUT_TRANSFORM_90:
+      return RR_Rotate_90;
+    case WL_OUTPUT_TRANSFORM_180:
+      return RR_Rotate_180;
+    case WL_OUTPUT_TRANSFORM_270:
+      return RR_Rotate_270;
+    case WL_OUTPUT_TRANSFORM_FLIPPED:
+      return RR_Reflect_X | RR_Rotate_0;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+      return RR_Reflect_X | RR_Rotate_90;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+      return RR_Reflect_X | RR_Rotate_180;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+      return RR_Reflect_X | RR_Rotate_270;
+    }
+
+  return RR_Rotate_0;
+}
+
+static void
+display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
+			int physical_width, int physical_height, int subpixel,
+			const char *make, const char *model, int transform)
+{
+    struct xwl_output *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+
+    xwl_output->xf86output->mm_width = physical_width;
+    xwl_output->xf86output->mm_height = physical_height;
+
+    switch (subpixel) {
+    case WL_OUTPUT_SUBPIXEL_UNKNOWN:
+	xwl_output->xf86output->subpixel_order = SubPixelUnknown;
+	break;
+    case WL_OUTPUT_SUBPIXEL_NONE:
+	xwl_output->xf86output->subpixel_order = SubPixelNone;
+	break;
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalRGB;
+	break;
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalBGR;
+	break;
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalRGB;
+	break;
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalBGR;
+	break;
+    }
+
+    xwl_output->x = x;
+    xwl_output->y = y;
+    xwl_output->rotation = wl_transform_to_xrandr (transform);
+
+    xorg_list_append (&xwl_output->link, &xwl_screen->output_list);
+}
+
+static void
+display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+		    int width, int height, int refresh)
+{
+    struct xwl_output *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    ScreenPtr pScreen = xwl_screen->screen;
+    ScrnInfoPtr scrn = xwl_screen->scrninfo;
+    CARD16 width_mm, height_mm;
+    DisplayModePtr mode;
+    rrScrPrivPtr rp;
+
+    if (!(flags & WL_OUTPUT_MODE_CURRENT))
+	return;
+
+    xwl_output->width = width;
+    xwl_output->height = height;
+
+    if (xwl_output->x + xwl_output->width > scrn->virtualX ||
+	xwl_output->y + xwl_output->height > scrn->virtualY) {
+	/* Fake a RandR request to resize the screen. It will bounce
+	   back to our crtc_resize, which does nothing.
+	*/
+	/* Preupdate virtualX / virtualY, so that crtc_resize returns TRUE */
+	scrn->virtualX = xwl_output->x + xwl_output->width;
+	scrn->virtualY = xwl_output->y + xwl_output->height;
+
+	/* Ignore the compositor provided values for mm_width/mm_height,
+	   as it doesn't make sense to sum the values of different outputs.
+	   Just make the DPI 96 */
+	width_mm = (scrn->virtualX / 96.0) * 25.4 + 0.5;
+	height_mm = (scrn->virtualY / 96.0) * 25.4 + 0.5;
+
+	/* But! When the server starts, the RandR stuff is not initialized,
+	   so we can't call rrGetScrPriv. We updated virtualX/Y anyway, let's
+	   hope it's enough.
+	*/
+	if (xwl_screen->outputs_initialized) {
+	    rp = rrGetScrPriv(pScreen);
+	    if (rp->rrScreenSetSize)
+		rp->rrScreenSetSize(pScreen, scrn->virtualX, scrn->virtualY, width_mm, height_mm);
+	}
+    }
+
+    xwl_output->xf86crtc->enabled = TRUE;
+    mode = xf86CVTMode(width, height, (float) refresh / 1000, TRUE, FALSE);
+    xf86CrtcSetModeTransform(xwl_output->xf86crtc, mode, xwl_output->rotation,
+                             NULL, xwl_output->x, xwl_output->y);
+}
+
+static const struct wl_output_listener output_listener = {
+    display_handle_geometry,
+    display_handle_mode
+};
+
+static void
+global_handler(void *data, struct wl_registry *registry, uint32_t id,
+	       const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_output *xwl_output;
+
+    if (strcmp (interface, "wl_output") == 0) {
+	xwl_output = xwl_output_create(xwl_screen);
+	xwl_output->output = wl_registry_bind(registry, id,
+	                                      &wl_output_interface, 1);
+	xwl_output->name = id;
+	wl_output_add_listener(xwl_output->output,
+			       &output_listener, xwl_output);
+    }
+}
+
+void
+xwl_output_remove(struct xwl_output *xwl_output)
+{
+    xorg_list_del (&xwl_output->link);
+    xf86OutputDestroy (xwl_output->xf86output);
+    xf86CrtcDestroy (xwl_output->xf86crtc);
+
+    wl_output_destroy (xwl_output->output);
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_output *xwl_output, *tmp;
+
+    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
+	if (xwl_output->name == name) {
+	    xwl_output_remove(xwl_output);
+	    break;
+	}
+    }
+}
+
+static const struct wl_registry_listener global_listener = {
+    global_handler,
+    global_remove
+};
+
+void
+xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
+{
+    int ret;
+
+    xf86CrtcConfigInit(scrninfo, &config_funcs);
+
+    xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
+
+    xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
+                             xwl_screen);
+
+    while (xwl_screen->output_list.next == &xwl_screen->output_list) {
+        ret = wl_display_roundtrip(xwl_screen->display);
+        if (ret == -1)
+            FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+    }
+
+    xf86ProbeOutputModes(scrninfo, 0, 0);
+
+    xwl_screen->outputs_initialized = TRUE;
+
+    xf86SetScrnInfoModes(scrninfo);
+}
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
new file mode 100644
index 0000000..bc39630
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2010 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _XWAYLAND_PRIVATE_H_
+#define _XWAYLAND_PRIVATE_H_
+
+struct xwl_window {
+    struct xwl_screen		*xwl_screen;
+    struct wl_surface		*surface;
+    struct wl_buffer		*buffer;
+    WindowPtr			 window;
+    DamagePtr			 damage;
+    struct xorg_list		 link;
+    struct xorg_list		 link_damage;
+};
+
+struct xwl_output;
+
+struct xwl_screen {
+    struct xwl_driver		*driver;
+    ScreenPtr			 screen;
+    ScrnInfoPtr			 scrninfo;
+    int				 drm_fd;
+    int				 wayland_fd;
+    struct wl_display		*display;
+    struct wl_registry          *registry;
+    struct wl_registry          *drm_registry;
+    struct wl_registry          *input_registry;
+    struct wl_registry          *output_registry;
+    struct wl_compositor	*compositor;
+    struct wl_drm		*drm;
+    struct wl_shm		*shm;
+    struct xserver		*xorg_server;
+    uint32_t			 mask;
+    uint32_t			 flags;
+    char			*device_name;
+    uint32_t			 authenticated;
+    struct xorg_list		 output_list;
+    struct xorg_list		 seat_list;
+    struct xorg_list		 damage_window_list;
+    struct xorg_list		 window_list;
+    struct xorg_list		 authenticate_client_list;
+    uint32_t			 serial;
+    Bool                         outputs_initialized;
+
+    DevPrivateKeyRec             cursor_private_key;
+
+    CreateWindowProcPtr		 CreateWindow;
+    DestroyWindowProcPtr	 DestroyWindow;
+    RealizeWindowProcPtr	 RealizeWindow;
+    UnrealizeWindowProcPtr	 UnrealizeWindow;
+    SetWindowPixmapProcPtr	 SetWindowPixmap;
+    MoveWindowProcPtr		 MoveWindow;
+    miPointerSpriteFuncPtr	 sprite_funcs;
+};
+
+struct xwl_output {
+    struct xorg_list             link;
+    struct wl_output		*output;
+    struct xwl_screen		*xwl_screen;
+    int32_t			 x, y, width, height;
+    xf86Monitor			 xf86monitor;
+    xf86OutputPtr		 xf86output;
+    xf86CrtcPtr			 xf86crtc;
+    int32_t                      name;
+    Rotation                     rotation;
+};
+
+
+#define MODIFIER_META 0x01
+
+struct xwl_seat {
+    DeviceIntPtr		 pointer;
+    DeviceIntPtr		 keyboard;
+    struct xwl_screen		*xwl_screen;
+    struct wl_seat		*seat;
+    struct wl_pointer		*wl_pointer;
+    struct wl_keyboard		*wl_keyboard;
+    struct wl_array		 keys;
+    struct wl_surface		*cursor;
+    struct xwl_window		*focus_window;
+    uint32_t			 id;
+    uint32_t			 pointer_enter_serial;
+    struct xorg_list		 link;
+    CursorPtr                    x_cursor;
+
+    wl_fixed_t			 horizontal_scroll;
+    wl_fixed_t			 vertical_scroll;
+    uint32_t			 scroll_time;
+
+    size_t			 keymap_size;
+    char			*keymap;
+    struct wl_surface           *keyboard_focus;
+};
+
+
+struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+
+void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo);
+
+int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen);
+int xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen);
+
+struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen);
+
+void xwl_input_teardown(void *p);
+void *xwl_input_setup(void *module, void *opts, int *errmaj, int *errmin);
+void xwl_input_init(struct xwl_screen *screen);
+
+Bool xwl_drm_initialised(struct xwl_screen *screen);
+
+void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
+
+void xwl_output_remove(struct xwl_output *output);
+
+extern const struct xserver_listener xwl_server_listener;
+
+#endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c
new file mode 100644
index 0000000..a2a8206
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <xf86Crtc.h>
+#include <selection.h>
+#include <exevents.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static DevPrivateKeyRec xwl_window_private_key;
+
+static void
+free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
+{
+    PixmapPtr pixmap = data;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+
+    (*screen->DestroyPixmap)(pixmap);
+    wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener free_pixmap_listener = {
+	free_pixmap,
+};
+
+static void
+xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
+{
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    struct wl_callback *callback;
+
+    /* We can safely destroy the buffer because we only use one buffer
+     * per surface in xwayland model */
+    if (xwl_window->buffer)
+        wl_buffer_destroy(xwl_window->buffer);
+
+    xwl_screen->driver->create_window_buffer(xwl_window, pixmap);
+
+    if (!xwl_window->buffer) {
+        ErrorF("failed to create buffer\n");
+	return;
+    }
+
+    wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0);
+    wl_surface_damage(xwl_window->surface, 0, 0,
+		      pixmap->drawable.width,
+		      pixmap->drawable.height);
+
+    callback = wl_display_sync(xwl_screen->display);
+    wl_callback_add_listener(callback, &free_pixmap_listener, pixmap);
+    pixmap->refcnt++;
+}
+
+static void
+damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
+{
+    struct xwl_window *xwl_window = data;
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
+}
+
+static void
+damage_destroy(DamagePtr pDamage, void *data)
+{
+}
+
+static Bool
+xwl_realize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+    Bool ret;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->RealizeWindow = xwl_screen->RealizeWindow;
+    ret = (*screen->RealizeWindow)(window);
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
+    screen->RealizeWindow = xwl_realize_window;
+
+    if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) {
+	if (window->redirectDraw != RedirectDrawManual)
+	    return ret;
+    } else {
+	if (window->parent)
+	    return ret;
+    }
+
+    xwl_window = calloc(sizeof *xwl_window, 1);
+    xwl_window->xwl_screen = xwl_screen;
+    xwl_window->window = window;
+    xwl_window->surface =
+	wl_compositor_create_surface(xwl_screen->compositor);
+    if (xwl_window->surface == NULL) {
+	ErrorF("wl_display_create_surface failed\n");
+	return FALSE;
+    }
+
+    if (xwl_screen->xorg_server)
+	xserver_set_window_id(xwl_screen->xorg_server,
+			      xwl_window->surface, window->drawable.id);
+
+    wl_surface_set_user_data(xwl_window->surface, xwl_window);
+    xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window));
+
+    dixSetPrivate(&window->devPrivates,
+		  &xwl_window_private_key, xwl_window);
+
+    xwl_window->damage =
+	DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
+		     FALSE, screen, xwl_window);
+    DamageRegister(&window->drawable, xwl_window->damage);
+    DamageSetReportAfterOp(xwl_window->damage, TRUE);
+
+    xorg_list_add(&xwl_window->link, &xwl_screen->window_list);
+    xorg_list_init(&xwl_window->link_damage);
+
+    return ret;
+}
+
+static Bool
+xwl_unrealize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+    struct xwl_seat *xwl_seat;
+    Bool ret;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    xorg_list_for_each_entry(xwl_seat,
+			     &xwl_screen->seat_list, link) {
+	if (!xwl_seat->focus_window)
+	    continue ;
+	if (xwl_seat->focus_window->window == window) {
+	    xwl_seat->focus_window = NULL;
+	    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
+	}
+    }
+
+    screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
+    ret = (*screen->UnrealizeWindow)(window);
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
+    screen->UnrealizeWindow = xwl_unrealize_window;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (!xwl_window)
+	return ret;
+
+    if (xwl_window->buffer)
+	wl_buffer_destroy(xwl_window->buffer);
+    wl_surface_destroy(xwl_window->surface);
+    xorg_list_del(&xwl_window->link);
+    if (RegionNotEmpty(DamageRegion(xwl_window->damage)))
+	xorg_list_del(&xwl_window->link_damage);
+    DamageUnregister(xwl_window->damage);
+    DamageDestroy(xwl_window->damage);
+    free(xwl_window);
+    dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
+
+    return ret;
+}
+
+static void
+xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
+    (*screen->SetWindowPixmap)(window, pixmap);
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (xwl_window)
+	xwl_window_attach(xwl_window, pixmap);
+}
+
+static void
+xwl_move_window(WindowPtr window, int x, int y,
+		   WindowPtr sibling, VTKind kind)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->MoveWindow = xwl_screen->MoveWindow;
+    (*screen->MoveWindow)(window, x, y, sibling, kind);
+    xwl_screen->MoveWindow = screen->MoveWindow;
+    screen->MoveWindow = xwl_move_window;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (xwl_window == NULL)
+	return;
+}
+
+int
+xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
+	return BadAlloc;
+
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
+    screen->RealizeWindow = xwl_realize_window;
+
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
+    screen->UnrealizeWindow = xwl_unrealize_window;
+
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    xwl_screen->MoveWindow = screen->MoveWindow;
+    screen->MoveWindow = xwl_move_window;
+
+    return Success;
+}
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
new file mode 100644
index 0000000..293fbf7
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+
+#include <extinit.h>
+
+#include <xf86Xinput.h>
+#include <xf86Crtc.h>
+#include <xf86Priv.h>
+#include <os.h>
+#include <selection.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+/*
+ * TODO:
+ *  - lose X kb focus when wayland surface loses it
+ *  - active grabs, grab owner crack
+ */
+
+static DevPrivateKeyRec xwl_screen_private_key;
+
+static void
+xserver_client(void *data, struct xserver *xserver, int fd)
+{
+    AddClientOnOpenFD(fd);
+}
+
+static void
+xserver_listen_socket(void *data, struct xserver *xserver, int fd)
+{
+    ListenOnOpenFD(fd, TRUE);
+}
+
+const struct xserver_listener xwl_server_listener = {
+    xserver_client,
+    xserver_listen_socket
+};
+
+static void
+xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    ErrorF("xwl_input_delayed_init\n");
+
+    wl_callback_destroy(callback);
+    xwl_input_init(xwl_screen);
+}
+
+static const struct wl_callback_listener delayed_init_listner = {
+	xwl_input_delayed_init
+};
+
+static void
+registry_global(void *data, struct wl_registry *registry, uint32_t id,
+	        const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_compositor") == 0) {
+	xwl_screen->compositor =
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+    } else if (strcmp(interface, "wl_shm") == 0) {
+        xwl_screen->shm =
+            wl_registry_bind(registry, id, &wl_shm_interface, 1);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* Nothing to do here, wl_compositor and wl_shm should not be removed */
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_global,
+    global_remove
+};
+
+static void
+wakeup_handler(void *data, int err, void *read_mask)
+{
+    struct xwl_screen *xwl_screen = data;
+    int ret;
+
+    if (err < 0)
+        return;
+
+    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
+        return;
+
+    ret = wl_display_dispatch(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+}
+
+static void
+block_handler(void *data, struct timeval **tv, void *read_mask)
+{
+    struct xwl_screen *xwl_screen = data;
+    int ret;
+
+    ret = wl_display_dispatch_pending(xwl_screen->display);
+    if (ret == -1)
+	FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+
+    ret = wl_display_flush(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
+}
+
+int
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    struct wl_callback *callback;
+
+    xwl_screen->screen = screen;
+
+    if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
+	return BadAlloc;
+
+    dixSetPrivate(&screen->devPrivates,
+		  &xwl_screen_private_key, xwl_screen);
+
+    xwl_screen_init_window(xwl_screen, screen);
+
+    xwl_screen_init_cursor(xwl_screen, screen);
+
+    AddGeneralSocket(xwl_screen->wayland_fd);
+    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
+
+    callback = wl_display_sync(xwl_screen->display);
+    wl_callback_add_listener(callback, &delayed_init_listner, xwl_screen);
+
+    return Success;
+}
+
+struct xwl_screen *
+xwl_screen_get(ScreenPtr screen)
+{
+    return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
+}
+
+struct xwl_screen *
+xwl_screen_create(void)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = calloc(sizeof *xwl_screen, 1);
+    if (xwl_screen == NULL) {
+	ErrorF("calloc failed\n");
+	return NULL;
+    }
+
+    xwl_screen->display = wl_display_connect(NULL);
+    if (xwl_screen->display == NULL) {
+	ErrorF("wl_display_create failed\n");
+	return NULL;
+    }
+
+    return xwl_screen;
+}
+
+Bool
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
+		    uint32_t flags, struct xwl_driver *driver)
+{
+    int ret;
+
+    noScreenSaverExtension = TRUE;
+
+    xorg_list_init(&xwl_screen->output_list);
+    xorg_list_init(&xwl_screen->seat_list);
+    xorg_list_init(&xwl_screen->damage_window_list);
+    xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->authenticate_client_list);
+    xwl_screen->scrninfo = scrninfo;
+    xwl_screen->driver = driver;
+    xwl_screen->flags = flags;
+    xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
+
+    if (xorgRootless)
+	xwl_screen->flags |= XWL_FLAGS_ROOTLESS;
+
+    /* Set up listener so we'll catch all events. */
+    xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->registry, &registry_listener,
+                             xwl_screen);
+    ret = wl_display_roundtrip(xwl_screen->display);
+    if (ret == -1) {
+        xf86DrvMsg(scrninfo->scrnIndex, X_ERROR,
+                   "failed to dispatch Wayland events: %s\n", strerror(errno));
+        return FALSE;
+    }
+
+#ifdef WITH_LIBDRM
+    if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen))
+	if (xwl_drm_pre_init(xwl_screen) != Success)
+            return FALSE;
+#endif
+
+    xwayland_screen_preinit_output(xwl_screen, scrninfo);
+
+    return TRUE;
+}
+
+int
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, int fd)
+{
+    struct wl_shm_pool *pool;
+    WindowPtr window = xwl_window->window;
+    ScreenPtr screen = window->drawable.pScreen;
+    VisualID visual = wVisual(window);
+    uint32_t format;
+    int size, stride, bpp, i;
+
+    for (i = 0; i < screen->numVisuals; i++)
+        if (screen->visuals[i].vid == visual)
+            break;
+
+    switch (screen->visuals[i].nplanes) {
+    case 32:
+        format = WL_SHM_FORMAT_ARGB8888;
+        bpp = 4;
+        break;
+    case 24:
+    default:
+        format = WL_SHM_FORMAT_XRGB8888;
+        bpp = 4;
+        break;
+#ifdef WL_SHM_FORMAT_RGB565
+    case 16:
+        /* XXX: Check run-time protocol version too */
+        format = WL_SHM_FORMAT_RGB565;
+        bpp = 2;
+        break;
+#endif
+    }
+
+    stride = pixmap->drawable.width * bpp;
+    size = stride * pixmap->drawable.height;
+
+    pool = wl_shm_create_pool(xwl_window->xwl_screen->shm, fd, size);
+    xwl_window->buffer =  wl_shm_pool_create_buffer(pool, 0,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height,
+			   stride, format);
+    wl_shm_pool_destroy(pool);
+
+    return xwl_window->buffer ? Success : BadDrawable;
+}
+
+void xwl_screen_close(struct xwl_screen *xwl_screen)
+{
+    struct xwl_seat *xwl_seat, *itmp;
+    struct xwl_window *xwl_window, *wtmp;
+
+    if (xwl_screen->registry)
+        wl_registry_destroy(xwl_screen->registry);
+    xwl_screen->registry = NULL;
+
+    xorg_list_for_each_entry_safe(xwl_seat, itmp,
+				  &xwl_screen->seat_list, link) {
+	wl_seat_destroy(xwl_seat->seat);
+	free(xwl_seat);
+    }
+    xorg_list_for_each_entry_safe(xwl_window, wtmp,
+				  &xwl_screen->window_list, link) {
+	wl_buffer_destroy(xwl_window->buffer);
+	wl_surface_destroy(xwl_window->surface);
+	free(xwl_window);
+    }
+
+    xorg_list_init(&xwl_screen->seat_list);
+    xorg_list_init(&xwl_screen->damage_window_list);
+    xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->authenticate_client_list);
+
+    wl_display_roundtrip(xwl_screen->display);
+}
+
+void xwl_screen_destroy(struct xwl_screen *xwl_screen)
+{
+    struct xwl_output *xwl_output, *tmp;
+
+    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
+	xwl_output_remove(xwl_output);
+	break;
+    }
+
+    free(xwl_screen);
+}
+
+/* DDX driver must call this after submitting the rendering */
+void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
+{
+    struct xwl_window *xwl_window;
+    RegionPtr region;
+    BoxPtr box;
+    int count, i;
+
+    xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
+			     link_damage) {
+	region = DamageRegion(xwl_window->damage);
+	count = RegionNumRects(region);
+	for (i = 0; i < count; i++) {
+	    box = &RegionRects(region)[i];
+	    wl_surface_damage(xwl_window->surface,
+			      box->x1, box->y1,
+			      box->x2 - box->x1,
+			      box->y2 - box->y1);
+	}
+	wl_surface_attach(xwl_window->surface,
+			  xwl_window->buffer,
+			  0, 0);
+	wl_surface_commit(xwl_window->surface);
+	DamageEmpty(xwl_window->damage);
+    }
+
+    xorg_list_init(&xwl_screen->damage_window_list);
+}
+
+static void *
+xwl_setup(void *module, void *opts, int *errmaj, int *errmin)
+{
+    return xwl_input_setup(module, opts, errmaj, errmin);
+}
+
+static void
+xwl_teardown(void *p)
+{
+    xwl_input_teardown(p);
+}
+
+static XF86ModuleVersionInfo xwl_version_info = {
+    "xwayland",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_EXTENSION,
+    ABI_EXTENSION_VERSION,
+    MOD_CLASS_NONE,
+    { 0, 0, 0, 0 }
+};
+
+_X_EXPORT const XF86ModuleData xwaylandModuleData = {
+    &xwl_version_info,
+    &xwl_setup,
+    &xwl_teardown
+};
+
+int
+xwl_version(void)
+{
+    return xwl_version_info.minorversion;
+}
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
new file mode 100644
index 0000000..f268366
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _XWAYLAND_H_
+#define _XWAYLAND_H_
+
+#define XWL_VERSION 2
+
+struct xwl_window;
+struct xwl_screen;
+
+struct xwl_driver {
+    int version;
+    int use_drm;
+    int (*create_window_buffer)(struct xwl_window *xwl_window,
+                                PixmapPtr pixmap);
+};
+
+#define XWL_FLAGS_ROOTLESS 0x01
+
+extern _X_EXPORT int
+xwl_version(void);
+
+extern _X_EXPORT struct xwl_screen *
+xwl_screen_create(void);
+
+extern _X_EXPORT Bool
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
+		    uint32_t flags, struct xwl_driver *driver);
+
+extern _X_EXPORT int
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen);
+
+extern _X_EXPORT int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT int
+xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_close(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_destroy(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_post_damage(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT int
+xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+		     uint32_t magic);
+
+extern _X_EXPORT int
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, uint32_t name);
+
+extern _X_EXPORT int
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, int fd);
+
+#endif /* _XWAYLAND_H_ */
diff --git a/include/input.h b/include/input.h
index 36463f2..afbb370 100644
--- a/include/input.h
+++ b/include/input.h
@@ -508,7 +508,7 @@ extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr slave, DeviceIntPtr master);
 
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
-extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
+extern _X_EXPORT DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
 
 extern _X_EXPORT int AllocDevicePair(ClientPtr client,
                                      const char *name,
diff --git a/include/os.h b/include/os.h
index 3b4e8f3..5be3bcc 100644
--- a/include/os.h
+++ b/include/os.h
@@ -166,10 +166,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ );
 
 extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ );
 
-#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+
 extern _X_EXPORT void AddClientOnOpenFD(int /* fd */ );
-#endif
 
 extern _X_EXPORT CARD32 GetTimeInMillis(void);
 extern _X_EXPORT CARD64 GetTimeInMicros(void);
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index 487d7ad..b5b0ed4 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -145,4 +145,7 @@
 /* Support APM/ACPI power management in the server */
 #undef XF86PM
 
+/* Building Xorg server. */
+#undef XORG_WAYLAND
+
 #endif /* _XORG_CONFIG_H_ */
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index 8bf9d38..b4180f4 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -227,4 +227,7 @@
 /* Ask fontsproto to make font path element names const */
 #define FONT_PATH_ELEMENT_NAME_CONST    1
 
+/* Building Xorg server. */
+#undef XORG_WAYLAND
+
 #endif /* _XORG_SERVER_H_ */
diff --git a/os/connection.c b/os/connection.c
index b0e999e..848e723 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -64,7 +64,6 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#include <xorg-server.h>
 #ifdef WIN32
 #include <X11/Xwinsock.h>
 #endif
@@ -1259,7 +1258,6 @@ MakeClientGrabPervious(ClientPtr client)
     }
 }
 
-#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 /* Add a fd (from launchd) to our listeners */
 void
 ListenOnOpenFD(int fd, int noxauth)
@@ -1334,5 +1332,3 @@ AddClientOnOpenFD(int fd)
         return;
     }
 }
-
-#endif
commit 7a47f77cf942dadb67db13aa8bde9311d9eacd2e
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Mon Oct 21 14:41:53 2013 +0200

    xkb: Factor out a function to copy a keymap's controls unto another

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 5d8e409..49e236d 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -837,6 +837,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
                                 int /* press */ ,
                                 int /* button */ );
 
+extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
+                                      XkbDescPtr /* src */ );
+
 #include "xkbfile.h"
 #include "xkbrules.h"
 
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 6196a17..dc570f0 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
     if (rep.loaded) {
         XkbDescPtr old_xkb;
         xkbNewKeyboardNotify nkn;
-        int i, nG, nTG;
 
         old_xkb = xkb;
         xkb = new;
         dev->key->xkbInfo->desc = xkb;
         new = old_xkb;          /* so it'll get freed automatically */
 
-        *xkb->ctrls = *old_xkb->ctrls;
-        for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
-            nG = XkbKeyNumGroups(xkb, i);
-            if (nG >= XkbNumKbdGroups) {
-                nTG = XkbNumKbdGroups;
-                break;
-            }
-            if (nG > nTG) {
-                nTG = nG;
-            }
-        }
-        xkb->ctrls->num_groups = nTG;
+        XkbCopyControls(xkb, old_xkb);
 
         nkn.deviceID = nkn.oldDeviceID = dev->id;
         nkn.minKeyCode = new->min_key_code;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 1f8a839..6cf6e79 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
         xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
     }
 }
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+    int i, nG, nTG;
+
+    if (!dst || !src)
+        return;
+
+    *dst->ctrls = *src->ctrls;
+
+    for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
+        nG = XkbKeyNumGroups(dst, i);
+        if (nG >= XkbNumKbdGroups) {
+            nTG = XkbNumKbdGroups;
+            break;
+        }
+        if (nG > nTG) {
+            nTG = nG;
+        }
+    }
+    dst->ctrls->num_groups = nTG;
+}
commit e07b8fdb7d89495008093d29423caf466e9b263f
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Tue Oct 22 16:50:29 2013 +0200

    xkb: Repurpose XkbCopyDeviceKeymap to apply a given keymap to a device
    
    This will also make it useful for cases when we have a new keymap to
    apply to a device but don't have a source device.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index bf4c226..37f4a60 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
     mk->sourceid = device->id;
 
-    if (!XkbCopyDeviceKeymap(master, device))
+    if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
         FatalError("Couldn't pivot keymap from device to core!\n");
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 253612e..5d8e409 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -820,8 +820,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
 extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
                           XkbDescPtr /* src */ );
 
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
-                                          DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+                                           XkbDescPtr /* src */ );
 
 extern void XkbFilterEvents(ClientPtr /* pClient */ ,
                             int /* nEvents */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 31bb8d3..6196a17 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5991,7 +5991,7 @@ ProcXkbGetKbdByName(ClientPtr client)
                 continue;
 
             if (tmpd != dev)
-                XkbCopyDeviceKeymap(tmpd, dev);
+                XkbDeviceApplyKeymap(tmpd, xkb);
 
             if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
                 old_sli = tmpd->kbdfeed->xkb_sli;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c6af60..1f8a839 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 }
 
 Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 {
     xkbNewKeyboardNotify nkn;
     Bool ret;
 
-    if (!dst->key || !src->key)
+    if (!dst->key || !desc)
         return FALSE;
 
     memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
     nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
     nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
     nkn.deviceID = dst->id;
-    nkn.oldDeviceID = dst->id;  /* maybe src->id? */
-    nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
-    nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+    nkn.oldDeviceID = dst->id;
+    nkn.minKeyCode = desc->min_key_code;
+    nkn.maxKeyCode = desc->max_key_code;
     nkn.requestMajor = XkbReqCode;
     nkn.requestMinor = X_kbSetMap;      /* Near enough's good enough. */
     nkn.changed = XkbNKN_KeycodesMask;
-    if (src->key->xkbInfo->desc->geom)
+    if (desc->geom)
         nkn.changed |= XkbNKN_GeometryMask;
 
-    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
     if (ret)
         XkbSendNewKeyboardNotify(dst, &nkn);
 
commit d0319cce7cd5237d02b6fb338e056cea5996eda5
Author: Tiago Vignatti <tiago.vignatti at intel.com>
Date:   Wed Aug 21 21:23:09 2013 -0700

    dri2: Introduce a third version of the AuthMagic function
    
    This most recent version takes a client pointer to allow xwayland to
    asynchronously authenticate a client.

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 729a323..c70f72e 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -121,8 +121,9 @@ typedef struct _DRI2Screen {
     DRI2ScheduleSwapProcPtr ScheduleSwap;
     DRI2GetMSCProcPtr GetMSC;
     DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
-    DRI2AuthMagic2ProcPtr AuthMagic;
     DRI2AuthMagicProcPtr LegacyAuthMagic;
+    DRI2AuthMagic2ProcPtr LegacyAuthMagic2;
+    DRI2AuthMagic3ProcPtr AuthMagic;
     DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
     DRI2SwapLimitValidateProcPtr SwapLimitValidate;
     DRI2GetParamProcPtr GetParam;
@@ -1352,7 +1353,7 @@ DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
         return FALSE;
 
     primescreen = GetScreenPrime(pScreen, dri2_client->prime_id);
-    if ((*ds->AuthMagic)(primescreen, magic))
+    if ((*ds->AuthMagic)(client, primescreen, magic))
         return FALSE;
     return TRUE;
 }
@@ -1457,8 +1458,11 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
         cur_minor = 1;
     }
 
+    if (info->version >= 10) {
+        ds->AuthMagic = info->AuthMagic3;
+    }
     if (info->version >= 8) {
-        ds->AuthMagic = info->AuthMagic2;
+        ds->LegacyAuthMagic2 = info->AuthMagic2;
     }
     if (info->version >= 5) {
         ds->LegacyAuthMagic = info->AuthMagic;
@@ -1497,7 +1501,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
          * If the driver doesn't provide an AuthMagic function
          * it relies on the old method (using libdrm) or fails
          */
-        if (!ds->LegacyAuthMagic)
+        if (!ds->LegacyAuthMagic2 && !ds->LegacyAuthMagic)
 #ifdef WITH_LIBDRM
             ds->LegacyAuthMagic = drmAuthMagic;
 #else
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 1e7afdd..38b4f58 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -65,6 +65,8 @@ typedef void (*DRI2CopyRegionProcPtr) (DrawablePtr pDraw,
 typedef void (*DRI2WaitProcPtr) (WindowPtr pWin, unsigned int sequence);
 typedef int (*DRI2AuthMagicProcPtr) (int fd, uint32_t magic);
 typedef int (*DRI2AuthMagic2ProcPtr) (ScreenPtr pScreen, uint32_t magic);
+typedef int (*DRI2AuthMagic3ProcPtr) (ClientPtr client,
+                                      ScreenPtr pScreen, uint32_t magic);
 
 /**
  * Schedule a buffer swap
@@ -252,6 +254,9 @@ typedef struct {
     DRI2CreateBuffer2ProcPtr CreateBuffer2;
     DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
     DRI2CopyRegion2ProcPtr CopyRegion2;
+
+    /* added in version 10 */
+    DRI2AuthMagic3ProcPtr AuthMagic3;
 } DRI2InfoRec, *DRI2InfoPtr;
 
 extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info);
@@ -268,6 +273,8 @@ extern _X_EXPORT Bool DRI2Connect(ClientPtr client, ScreenPtr pScreen,
 
 extern _X_EXPORT Bool DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic);
 
+extern _X_EXPORT void DRI2SendAuthReply(ClientPtr client, Bool status);
+
 extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
                                         DrawablePtr pDraw,
                                         XID id,
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index ffd66fa..b858213 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -136,11 +136,23 @@ ProcDRI2Connect(ClientPtr client)
     return Success;
 }
 
+void
+DRI2SendAuthReply(ClientPtr client, Bool status)
+{
+    xDRI2AuthenticateReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .authenticated = status
+    };
+
+    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+}
+
 static int
 ProcDRI2Authenticate(ClientPtr client)
 {
     REQUEST(xDRI2AuthenticateReq);
-    xDRI2AuthenticateReply rep;
     DrawablePtr pDraw;
     int status;
 
@@ -149,13 +161,12 @@ ProcDRI2Authenticate(ClientPtr client)
                        &pDraw, &status))
         return status;
 
-    rep = (xDRI2AuthenticateReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic)
-    };
-    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+    status = DRI2Authenticate(client, pDraw->pScreen, stuff->magic);
+
+    /* if non-blocking authentication is in progress, then don't send a reply
+     * now but later in the implementation (e.g. drm_handle_authenticated) */
+    if (client->ignoreCount == 0)
+        DRI2SendAuthReply(client, status);
 
     return Success;
 }
commit 602a857c7a2f1c64893af941ab49601a518c25fb
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Sep 18 22:09:03 2009 -0400

    Add redirect window for input device feature

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e9f670e..bf4c226 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -2044,6 +2044,19 @@ DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
 }
 
+void
+SetDeviceRedirectWindow(DeviceIntPtr dev, WindowPtr window)
+{
+    SpritePtr pSprite = dev->spriteInfo->sprite;
+    DeviceIntPtr mouse;
+
+    mouse = IsMaster(dev) ? dev : GetMaster(dev, MASTER_POINTER);
+
+    pSprite->redirectWindow = window;
+
+    CheckMotion(NULL, mouse);
+}
+
 int
 InitProximityClassDeviceStruct(DeviceIntPtr dev)
 {
diff --git a/dix/events.c b/dix/events.c
index f05dada..7c7afa8 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2880,7 +2880,16 @@ XYToWindow(SpritePtr pSprite, int x, int y)
     BoxRec box;
 
     pSprite->spriteTraceGood = 1;       /* root window still there */
-    pWin = RootWindow(pSprite)->firstChild;
+    if (pSprite->redirectWindow == PointerRootWin) {
+        return RootWindow(pSprite);
+    }
+    else if (pSprite->redirectWindow) {
+        pWin = pSprite->redirectWindow;
+        pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+        pWin = pWin->firstChild;
+    }
+    else
+        pWin = RootWindow(pSprite)->firstChild;
     while (pWin) {
         if ((pWin->mapped) &&
             (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
diff --git a/include/exevents.h b/include/exevents.h
index 321fc42..ba93be3 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -162,6 +162,10 @@ extern void
  ProcessOtherEvent(InternalEvent * /* ev */ ,
                    DeviceIntPtr /* other */ );
 
+extern _X_EXPORT void
+  SetDeviceRedirectWindow(DeviceIntPtr /* dev */ ,
+                        WindowPtr /* window */ );
+
 extern int
  CheckGrabValues(ClientPtr /* client */ ,
                  GrabParameters * /* param */ );
diff --git a/include/inputstr.h b/include/inputstr.h
index f6cfb04..35dd469 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -246,6 +246,8 @@ typedef struct _SpriteRec {
     ScreenPtr pEnqueueScreen;
     ScreenPtr pDequeueScreen;
 
+    WindowPtr redirectWindow;
+
 } SpriteRec;
 
 typedef struct _KeyClassRec {
commit b0f11ed1f20e34531c32ef3cd7ddd936b3b91c6d
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Jul 21 09:55:46 2011 -0700

    Export xf86NewInputDevice and xf86AllocateInput

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f6f2b90..67fedc8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -811,7 +811,7 @@ xf86InputDevicePostInit(DeviceIntPtr dev)
  *
  * @return Success or an error code
  */
-_X_INTERNAL int
+int
 xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
 {
     InputDriverPtr drv = NULL;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index b6d1251..32dbcf6 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -172,10 +172,9 @@ extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
 extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev);
-
-/* not exported */
-int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
-InputInfoPtr xf86AllocateInput(void);
+extern _X_EXPORT int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev,
+                                        BOOL is_auto);
+extern _X_EXPORT InputInfoPtr xf86AllocateInput(void);
 
 /* xf86Helper.c */
 extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, void *module,
commit b1e6e75fbfaa80a1faf42516b8eb43efbb29cf7e
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Jun 21 21:28:31 2011 -0400

    os: Add a function to create a client for an fd

diff --git a/include/opaque.h b/include/opaque.h
index 73d40c3..7ec1d85 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -74,5 +74,6 @@ extern _X_EXPORT Bool whiteRoot;
 extern _X_EXPORT Bool bgNoneRoot;
 
 extern _X_EXPORT Bool CoreDump;
+extern _X_EXPORT Bool NoListenAll;
 
 #endif                          /* OPAQUE_H */
diff --git a/include/os.h b/include/os.h
index e5f86d6..3b4e8f3 100644
--- a/include/os.h
+++ b/include/os.h
@@ -166,8 +166,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ );
 
 extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ );
 
-#ifdef XQUARTZ
-extern void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+#if defined(XQUARTZ) || defined(XORG_WAYLAND)
+extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+extern _X_EXPORT void AddClientOnOpenFD(int /* fd */ );
 #endif
 
 extern _X_EXPORT CARD32 GetTimeInMillis(void);
diff --git a/os/connection.c b/os/connection.c
index ddf4f0a..b0e999e 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -64,6 +64,7 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
+#include <xorg-server.h>
 #ifdef WIN32
 #include <X11/Xwinsock.h>
 #endif
@@ -138,6 +139,7 @@ fd_set OutputPending;           /* clients with reply/event data ready to go */
 int MaxClients = 0;
 Bool NewOutputPending;          /* not yet attempted to write some new output */
 Bool AnyClientsWriteBlocked;    /* true if some client blocked on write */
+Bool NoListenAll;               /* Don't establish any listening sockets */
 
 static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
 Bool RunFromSigStopParent;      /* send SIGSTOP to our own process; Upstart (or
@@ -406,7 +408,10 @@ CreateWellKnownSockets(void)
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line, or to NULL when the -displayfd
      * option is used. */
-    if (display) {
+    if (NoListenAll) {
+        ListenTransCount = 0;
+    }
+    else if (display) {
         if (TryCreateSocket(atoi(display), &partial) &&
             ListenTransCount >= 1)
             if (!PartialNetwork && partial)
@@ -440,9 +445,10 @@ CreateWellKnownSockets(void)
             DefineSelf (fd);
     }
 
-    if (!XFD_ANYSET(&WellKnownConnections))
+    if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll)
         FatalError
             ("Cannot establish any listening sockets - Make sure an X server isn't already running");
+
 #if !defined(WIN32)
     OsSignal(SIGPIPE, SIG_IGN);
     OsSignal(SIGHUP, AutoResetServer);
@@ -1253,7 +1259,7 @@ MakeClientGrabPervious(ClientPtr client)
     }
 }
 
-#ifdef XQUARTZ
+#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 /* Add a fd (from launchd) to our listeners */
 void
 ListenOnOpenFD(int fd, int noxauth)
@@ -1309,4 +1315,24 @@ ListenOnOpenFD(int fd, int noxauth)
 #endif
 }
 
+/* based on TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) */
+void
+AddClientOnOpenFD(int fd)
+{
+    XtransConnInfo ciptr;
+    CARD32 connect_time;
+
+    ciptr = _XSERVTransReopenCOTSServer(5, fd, "@anonymous");
+
+    _XSERVTransSetOption(ciptr, TRANS_NONBLOCKING, 1);
+    ciptr->flags |= TRANS_NOXAUTH;
+
+    connect_time = GetTimeInMillis();
+
+    if (!AllocNewConnection(ciptr, fd, connect_time)) {
+        fprintf(stderr, "failed to create client for wayland server\n");
+        return;
+    }
+}
+
 #endif
diff --git a/os/utils.c b/os/utils.c
index 497779b..8b6ca4b 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -832,7 +832,11 @@ ProcessCommandLine(int argc, char *argv[])
 #endif
         else if (strcmp(argv[i], "-nolisten") == 0) {
             if (++i < argc) {
-                if (_XSERVTransNoListen(argv[i]))
+                if (strcmp(argv[i], "all") == 0) {
+                    NoListenAll = TRUE;
+                    nolock = TRUE;
+                }
+                else if (_XSERVTransNoListen(argv[i]))
                     ErrorF("Failed to disable listen for %s transport",
                            argv[i]);
             }
commit 0f5dd143807bf55f5c88089d637d9c35d3548e51
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 17:45:08 2013 -0400

    xkb: Add XkbCompileKeymapFromString()
    
    This new function compiles a keymap from an in-memory string.  We use it
    to add a new keyooard device init function,
    InitKeyboardDeviceStructFromString(), which inits a keyboard device with
    a keymap specified as a string instead of a rmlvo set.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/include/input.h b/include/input.h
index 93c4510..36463f2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
                                                KbdCtrlProcPtr /*controlProc */
                                                );
 
+extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+							 const char *keymap,
+							 int keymap_length,
+							 BellProcPtr bell_func,
+							 KbdCtrlProcPtr ctrl_func);
+
 extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
                                CARD8 * /* map */ ,
                                int /* len */ ,
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index e799799..253612e 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -869,4 +869,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
                                              XkbRMLVOSet *      /* rmlvo */
     );
 
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
+						       const char *keymap,
+						       int keymap_length);
+
 #endif                          /* _XKBSRV_H_ */
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index d266b36..d4281a0 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -262,6 +262,35 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
     return file;
 }
 
+static unsigned
+LoadXKM(unsigned want, unsigned need, XkbCompContextPtr ctx, XkbDescPtr *xkbRtrn)
+{
+    FILE *file;
+    char fileName[PATH_MAX];
+    unsigned missing;
+
+    file = XkbDDXOpenConfigFile(ctx->keymap, fileName, PATH_MAX);
+    if (file == NULL) {
+        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
+                   fileName);
+        return 0;
+    }
+    missing = XkmReadFile(file, need, want, xkbRtrn);
+    if (*xkbRtrn == NULL) {
+        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
+        fclose(file);
+        (void) unlink(fileName);
+        return 0;
+    }
+    else {
+        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
+               (*xkbRtrn)->defined);
+    }
+    fclose(file);
+    (void) unlink(fileName);
+    return (need | want) & (~missing);
+}
+
 unsigned
 XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbComponentNamesPtr names,
@@ -270,9 +299,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
 {
     XkbDescPtr xkb;
-    FILE *file;
-    char fileName[PATH_MAX];
-    unsigned missing;
     XkbCompContextRec ctx;
 
     *xkbRtrn = NULL;
@@ -292,26 +318,30 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
         LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    file = XkbDDXOpenConfigFile(ctx.keymap, fileName, PATH_MAX);
-    if (file == NULL) {
-        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
-                   fileName);
-        return 0;
-    }
-    missing = XkmReadFile(file, need, want, xkbRtrn);
-    if (*xkbRtrn == NULL) {
-        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
-        fclose(file);
-        (void) unlink(fileName);
+
+    return LoadXKM(want, need, &ctx, xkbRtrn);
+}
+
+static unsigned
+XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
+			   const char *keymap, int keymap_length,
+			   unsigned want,
+			   unsigned need,
+			   XkbDescPtr *xkbRtrn)
+{
+    XkbCompContextRec ctx;
+
+    *xkbRtrn = NULL;
+
+    if (StartXkbComp(&ctx))
+	fwrite(keymap, keymap_length, 1, ctx.out);
+
+    if (!FinishXkbComp(&ctx)) {
+        LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    else {
-        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
-               (*xkbRtrn)->defined);
-    }
-    fclose(file);
-    (void) unlink(fileName);
-    return (need | want) & (~missing);
+
+    return LoadXKM(want, need, &ctx, xkbRtrn);
 }
 
 Bool
@@ -407,6 +437,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
     return xkb;
 }
 
+static XkbDescPtr
+KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
+{
+    XkbRMLVOSet dflts;
+
+    if (xkb)
+	return xkb;
+
+    /* we didn't get what we really needed. And that will likely leave
+     * us with a keyboard that doesn't work. Use the defaults instead */
+    LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
+	       "keymap instead.\n");
+
+    XkbGetRulesDflts(&dflts);
+
+    xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+
+    XkbFreeRMLVOSet(&dflts, FALSE);
+
+    return xkb;
+}
+
+
 XkbDescPtr
 XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 {
@@ -424,20 +477,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 
     xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
 
-    if (!xkb) {
-        XkbRMLVOSet dflts;
+    return KeymapOrDefaults(dev, xkb);
+}
 
-        /* we didn't get what we really needed. And that will likely leave
-         * us with a keyboard that doesn't work. Use the defaults instead */
-        LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
-                   "keymap instead.\n");
+XkbDescPtr
+XkbCompileKeymapFromString(DeviceIntPtr dev,
+			   const char *keymap, int keymap_length)
+{
+    XkbDescPtr xkb;
+    unsigned int need, provided;
 
-        XkbGetRulesDflts(&dflts);
+    if (!dev || !keymap) {
+        LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
+        return NULL;
+    }
 
-        xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+    /* These are the components we really really need */
+    need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
+        XkmKeyNamesMask | XkmVirtualModsMask;
 
-        XkbFreeRMLVOSet(&dflts, FALSE);
+    provided =
+	XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
+				   XkmAllIndicesMask, need, &xkb);
+    if ((need & provided) != need) {
+	if (xkb) {
+	    XkbFreeKeyboard(xkb, 0, TRUE);
+	    xkb = NULL;
+	}
     }
 
-    return xkb;
+    return KeymapOrDefaults(dev, xkb);
 }
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 33420b6..766ca7b 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
     return Success;
 }
 
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
-                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+				 const char *keymap, int keymap_length,
+				 BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
 {
     int i;
     unsigned int check;
@@ -522,7 +523,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     BUG_RETURN_VAL(dev->key != NULL, FALSE);
     BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
 
-    if (!rmlvo) {
+    if (!rmlvo && !keymap) {
         rmlvo = &rmlvo_dflts;
         XkbGetRulesDflts(rmlvo);
     }
@@ -550,19 +551,26 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     }
     dev->key->xkbInfo = xkbi;
 
-    if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+    if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
         XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
         xkb_cached_map = NULL;
     }
 
     if (xkb_cached_map)
         LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
-    else {
+    else if (rmlvo) {
         xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
         if (!xkb_cached_map) {
             ErrorF("XKB: Failed to compile keymap\n");
             goto unwind_info;
         }
+    } else {
+	xkb_cached_map = XkbCompileKeymapFromString(dev,
+						    keymap, keymap_length);
+        if (!xkb_cached_map) {
+            ErrorF("XKB: Failed to compile keymap from string\n");
+            goto unwind_info;
+        }
     }
 
     xkb = XkbAllocKeyboard();
@@ -627,8 +635,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
 
     dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
 
-    XkbSetRulesDflts(rmlvo);
-    XkbSetRulesUsed(rmlvo);
+    if (rmlvo) {
+	XkbSetRulesDflts(rmlvo);
+	XkbSetRulesUsed(rmlvo);
+    }
     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
 
     return TRUE;
@@ -647,6 +657,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     return FALSE;
 }
 
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, rmlvo,
+					    NULL, 0, bell_func, ctrl_func);
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+				   const char *keymap, int keymap_length,
+				   BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, NULL,
+					    keymap, keymap_length,
+					    bell_func, ctrl_func);
+}
+
 /***====================================================================***/
 
         /*
commit af623f52043b9bed6f9ba3158fa8fd18913b2cec
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 17:11:03 2013 -0400

    xkb: Split out code to start and finish xkbcomp
    
    Using the context struct from previous commit, we can now split out
    code to start xkbcomp and to finish and clean up after it.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index cf9faa4..d266b36 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -99,10 +99,7 @@ typedef struct XkbCompContext {
 } XkbCompContextRec, *XkbCompContextPtr;
 
 static Bool
-XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
-                           XkbComponentNamesPtr names,
-                           unsigned want,
-                           unsigned need, XkbCompContextPtr ctx)
+StartXkbComp(XkbCompContextPtr ctx)
 {
     char xkm_output_dir[PATH_MAX];
 
@@ -168,14 +165,15 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     ctx->out = fopen(ctx->tmpname, "w");
 #endif
 
+    return ctx->out != NULL;
+}
+
+static Bool
+FinishXkbComp(XkbCompContextPtr ctx)
+{
+    if (!ctx->buf)
+	return FALSE;
     if (ctx->out != NULL) {
-#ifdef DEBUG
-        if (xkbDebugFlags) {
-            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
-            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
-        }
-#endif
-        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
 #ifndef WIN32
         if (Pclose(ctx->out) == 0)
 #else
@@ -209,6 +207,25 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     return FALSE;
 }
 
+static Bool
+XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
+                           XkbComponentNamesPtr names,
+                           unsigned want,
+                           unsigned need, XkbCompContextPtr ctx)
+{
+    if (StartXkbComp(ctx)) {
+#ifdef DEBUG
+        if (xkbDebugFlags) {
+            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
+            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
+        }
+#endif
+        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
+    }
+
+    return FinishXkbComp(ctx);
+}
+
 static FILE *
 XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 {
commit 30d3ba350d5f8723679d62b402130fd11267bb47
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 16:54:55 2013 -0400

    xkb: Add struct XkbCompContext
    
    This commit adds a struct that contains most of the context for starting,
    running and cleaning up after xkbcomp.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index f458e3b..cf9faa4 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -90,14 +90,21 @@ OutputDirectory(char *outdir, size_t size)
     }
 }
 
+typedef struct XkbCompContext {
+    char keymap[PATH_MAX];
+    FILE *out;
+    char *buf;
+    char tmpname[PATH_MAX];
+    const char *xkmfile;
+} XkbCompContextRec, *XkbCompContextPtr;
+
 static Bool
 XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
                            XkbComponentNamesPtr names,
                            unsigned want,
-                           unsigned need, char *nameRtrn, int nameRtrnLen)
+                           unsigned need, XkbCompContextPtr ctx)
 {
-    FILE *out;
-    char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
+    char xkm_output_dir[PATH_MAX];
 
     const char *emptystring = "";
     char *xkbbasedirflag = NULL;
@@ -105,22 +112,19 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     const char *xkbbindirsep = emptystring;
 
 #ifdef WIN32
-    /* WIN32 has no popen. The input must be stored in a file which is
-       used as input for xkbcomp. xkbcomp does not read from stdin. */
-    char tmpname[PATH_MAX];
-    const char *xkmfile = tmpname;
+    ctx->xkmfile = ctx->tmpname;
 #else
-    const char *xkmfile = "-";
+    ctx->xkmfile = "-";
 #endif
 
-    snprintf(keymap, sizeof(keymap), "server-%s", display);
+    snprintf(ctx->keymap, sizeof(ctx->keymap), "server-%s", display);
 
     OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
 
 #ifdef WIN32
-    strcpy(tmpname, Win32TempDir());
-    strcat(tmpname, "\\xkb_XXXXXX");
-    (void) mktemp(tmpname);
+    strcpy(ctx->tmpname, Win32TempDir());
+    strcat(ctx->tmpname, "\\xkb_XXXXXX");
+    (void) mktemp(ctx->tmpname);
 #endif
 
     if (XkbBaseDirectory != NULL) {
@@ -139,73 +143,69 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
         }
     }
 
-    if (asprintf(&buf,
+    if (asprintf(&ctx->buf,
                  "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
                  "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
                  xkbbindir, xkbbindirsep,
                  ((xkbDebugFlags < 2) ? 1 :
                   ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)),
-                 xkbbasedirflag ? xkbbasedirflag : "", xkmfile,
+                 xkbbasedirflag ? xkbbasedirflag : "", ctx->xkmfile,
                  PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
-                 xkm_output_dir, keymap) == -1)
-        buf = NULL;
+                 xkm_output_dir, ctx->keymap) == -1)
+        ctx->buf = NULL;
 
     free(xkbbasedirflag);
 
-    if (!buf) {
+    if (!ctx->buf) {
         LogMessage(X_ERROR,
                    "XKB: Could not invoke xkbcomp: not enough memory\n");
         return FALSE;
     }
 
 #ifndef WIN32
-    out = Popen(buf, "w");
+    ctx->out = Popen(ctx->buf, "w");
 #else
-    out = fopen(tmpname, "w");
+    ctx->out = fopen(ctx->tmpname, "w");
 #endif
 
-    if (out != NULL) {
+    if (ctx->out != NULL) {
 #ifdef DEBUG
         if (xkbDebugFlags) {
             ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
             XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
         }
 #endif
-        XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
+        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
 #ifndef WIN32
-        if (Pclose(out) == 0)
+        if (Pclose(ctx->out) == 0)
 #else
-        if (fclose(out) == 0 && System(buf) >= 0)
+        if (fclose(ctx->out) == 0 && System(ctx->buf) >= 0)
 #endif
         {
             if (xkbDebugFlags)
-                DebugF("[xkb] xkb executes: %s\n", buf);
-            if (nameRtrn) {
-                strlcpy(nameRtrn, keymap, nameRtrnLen);
-            }
-            free(buf);
+                DebugF("[xkb] xkb executes: %s\n", ctx->buf);
+            free(ctx->buf);
 #ifdef WIN32
-            unlink(tmpname);
+            unlink(ctx->tmpname);
 #endif
             return TRUE;
         }
         else
-            LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
+            LogMessage(X_ERROR, "Error compiling keymap (%s)\n", ctx->keymap);
 #ifdef WIN32
         /* remove the temporary file */
-        unlink(tmpname);
+        unlink(ctx->tmpname);
 #endif
     }
     else {
 #ifndef WIN32
         LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n");
 #else
-        LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
+        LogMessage(X_ERROR, "Could not open file %s\n", ctx->tmpname);
 #endif
     }
-    if (nameRtrn)
-        nameRtrn[0] = '\0';
-    free(buf);
+    ctx->keymap[0] = '\0';
+    free(ctx->buf);
     return FALSE;
 }
 
@@ -256,6 +256,7 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
     FILE *file;
     char fileName[PATH_MAX];
     unsigned missing;
+    XkbCompContextRec ctx;
 
     *xkbRtrn = NULL;
     if ((keybd == NULL) || (keybd->key == NULL) ||
@@ -270,12 +271,11 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                    keybd->name ? keybd->name : "(unnamed keyboard)");
         return 0;
     }
-    else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need,
-                                         nameRtrn, nameRtrnLen)) {
+    else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need, &ctx)) {
         LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
+    file = XkbDDXOpenConfigFile(ctx.keymap, fileName, PATH_MAX);
     if (file == NULL) {
         LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
                    fileName);
commit 093f0ba88a383fab7e6f2ae73958e454bc027ea0
Author: Robert Bragg <robert at linux.intel.com>
Date:   Thu Jan 12 18:16:08 2012 +0000

    dbe: Cleanup in CloseScreen hook not ext CloseDown
    
    Instead of registering an extension CloseDownProc when adding the dbe
    extension this patch hooks into pScreen->CloseScreen so that the chain
    of pScreen->DestroyWindow hooks remains valid until all windows have
    been destroyed. Previously it was possible for DbeResetProc to be called
    before the root window had been destroyed and the unwrapping of
    pScreen->DestroyWindow would clobber the chain of callbacks.
    
    This is needed for xwayland to be able to know when the root window is
    destroyed so it can unredirect root sub-windows.

diff --git a/dbe/dbe.c b/dbe/dbe.c
index 8896720..96f9f91 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -1230,7 +1230,7 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
 
 /******************************************************************************
  *
- * DBE DIX Procedure: DbeResetProc
+ * DBE DIX Procedure: DbeCloseScreen
  *
  * Description:
  *
@@ -1239,25 +1239,20 @@ DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
  *     other tasks related to shutting down the extension.
  *
  *****************************************************************************/
-static void
-DbeResetProc(ExtensionEntry * extEntry)
+static Bool
+DbeCloseScreen(ScreenPtr pScreen)
 {
-    int i;
-    ScreenPtr pScreen;
-    DbeScreenPrivPtr pDbeScreenPriv;
-
-    for (i = 0; i < screenInfo.numScreens; i++) {
-        pScreen = screenInfo.screens[i];
-        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+    DbeScreenPrivPtr pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 
-        if (pDbeScreenPriv) {
-            /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
-            pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
-            pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
-            free(pDbeScreenPriv);
-        }
+    if (pDbeScreenPriv) {
+        /* Unwrap CloseScreen, which was wrapped in DbeExtensionInit(). */
+        pScreen->CloseScreen = pDbeScreenPriv->CloseScreen;
+        pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
+        free(pDbeScreenPriv);
     }
-}                               /* DbeResetProc() */
+
+    return (*pScreen->CloseScreen) (pScreen);
+}                               /* DbeCloseScreen */
 
 /******************************************************************************
  *
@@ -1427,6 +1422,9 @@ DbeExtensionInit(void)
 
                 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
                 pScreen->DestroyWindow = DbeDestroyWindow;
+
+                pDbeScreenPriv->CloseScreen = pScreen->CloseScreen;
+                pScreen->CloseScreen = DbeCloseScreen;
             }
             else {
                 /* DDX initialization failed.  Stub the screen. */
@@ -1454,7 +1452,7 @@ DbeExtensionInit(void)
     /* Now add the extension. */
     extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
                             DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
-                            DbeResetProc, StandardMinorOpcode);
+                            NULL, StandardMinorOpcode);
 
     dbeErrorBase = extEntry->errorBase;
     SetResourceTypeErrorValue(dbeWindowPrivResType,
diff --git a/dbe/dbestruct.h b/dbe/dbestruct.h
index 2002066..7733d0e 100644
--- a/dbe/dbestruct.h
+++ b/dbe/dbestruct.h
@@ -176,6 +176,7 @@ typedef struct _DbeScreenPrivRec {
      */
     PositionWindowProcPtr PositionWindow;
     DestroyWindowProcPtr DestroyWindow;
+    CloseScreenProcPtr CloseScreen;
 
     /* Per-screen DIX routines */
     Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ ,
commit da08316605b26830b4d8f8fb2d9e69471cdc80ab
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 31 00:07:42 2013 -0800

    glamor: Add support for DRI3.
    
    The render-nodes case is untested.
    
    v2: Add a flag for wayland to suppress the native DRI3 support.
        Wayland isn't running as a master itself, so it can't do the auth
        on its own and has to ask the compositor to do it for us.  Dropped
        XXX about randr provider -- the conclusion from discussion with
        keithp was that if the driver's dri3_open for a provider on a
        different screen, that's a core dri3 bug.
    v3: Don't put quite so much under GLAMOR_NO_DRI3, and add a comment
        explaining what this is about.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 041004e..e12f497 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -67,10 +67,12 @@ typedef enum glamor_pixmap_type {
 #define GLAMOR_USE_SCREEN		(1 << 1)
 #define GLAMOR_USE_PICTURE_SCREEN 	(1 << 2)
 #define GLAMOR_USE_EGL_SCREEN		(1 << 3)
+#define GLAMOR_NO_DRI3			(1 << 4)
 #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
 				 | GLAMOR_USE_SCREEN 			\
                                  | GLAMOR_USE_PICTURE_SCREEN		\
-				 | GLAMOR_USE_EGL_SCREEN)
+				 | GLAMOR_USE_EGL_SCREEN                \
+                                 | GLAMOR_NO_DRI3)
 
 /* @glamor_init: Initialize glamor internal data structure.
  *
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 56d8913..05e6bd0 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -50,6 +50,7 @@
 
 #include "glamor.h"
 #include "glamor_priv.h"
+#include "dri3.h"
 
 static const char glamor_name[] = "glamor";
 
@@ -68,6 +69,7 @@ struct glamor_egl_screen_private {
     EGLDisplay display;
     EGLContext context;
     EGLint major, minor;
+    char *device_path;
 
     CreateScreenResourcesProcPtr CreateScreenResources;
     CloseScreenProcPtr CloseScreen;
@@ -627,10 +629,67 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
     return FALSE;
 }
 
+static int
+glamor_dri3_open(ScreenPtr screen,
+                 RRProviderPtr provider,
+                 int *fdp)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    int fd;
+    drm_magic_t magic;
+
+    fd = open(glamor_egl->device_path, O_RDWR|O_CLOEXEC);
+    if (fd < 0)
+        return BadAlloc;
+
+    /* Before FD passing in the X protocol with DRI3 (and increased
+     * security of rendering with per-process address spaces on the
+     * GPU), the kernel had to come up with a way to have the server
+     * decide which clients got to access the GPU, which was done by
+     * each client getting a unique (magic) number from the kernel,
+     * passing it to the server, and the server then telling the
+     * kernel which clients were authenticated for using the device.
+     *
+     * Now that we have FD passing, the server can just set up the
+     * authentication on its own and hand the prepared FD off to the
+     * client.
+     */
+    if (drmGetMagic(fd, &magic) < 0) {
+        if (errno == EACCES) {
+            /* Assume that we're on a render node, and the fd is
+             * already as authenticated as it should be.
+             */
+            *fdp = fd;
+            return Success;
+        } else {
+            close(fd);
+            return BadMatch;
+        }
+    }
+
+    if (drmAuthMagic(glamor_egl->fd, magic) < 0) {
+        close(fd);
+        return BadMatch;
+    }
+
+    *fdp = fd;
+    return Success;
+}
+
+static dri3_screen_info_rec glamor_dri3_info = {
+    .version = 0,
+    .open = glamor_dri3_open,
+    .pixmap_from_fd = glamor_pixmap_from_fd,
+    .fd_from_pixmap = glamor_fd_from_pixmap,
+};
+
 void
 glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     struct glamor_egl_screen_private *glamor_egl =
         glamor_egl_get_screen_private(scrn);
 
@@ -642,6 +701,30 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 
     glamor_ctx->get_context = glamor_egl_get_context;
     glamor_ctx->put_context = glamor_egl_put_context;
+
+    if (glamor_egl->dri3_capable) {
+        /* Tell the core that we have the interfaces for import/export
+         * of pixmaps.
+         */
+        glamor_enable_dri3(screen);
+
+        /* If the driver wants to do its own auth dance (e.g. Xwayland
+         * on pre-3.15 kernels that don't have render nodes and thus
+         * has the wayland compositor as a master), then it needs us
+         * to stay out of the way and let it init DRI3 on its own.
+         */
+        if (!(glamor_priv->flags & GLAMOR_NO_DRI3)) {
+            /* To do DRI3 device FD generation, we need to open a new fd
+             * to the same device we were handed in originally.
+             */
+            glamor_egl->device_path = drmGetDeviceNameFromFd(glamor_egl->fd);
+
+            if (!dri3_screen_init(screen, &glamor_dri3_info)) {
+                xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                           "Failed to initialize DRI3.\n");
+            }
+        }
+    }
 }
 
 static void
@@ -658,6 +741,8 @@ glamor_egl_free_screen(ScrnInfoPtr scrn)
         if (glamor_egl->gbm)
             gbm_device_destroy(glamor_egl->gbm);
 #endif
+        free(glamor_egl->device_path);
+
         scrn->FreeScreen = glamor_egl->saved_free_screen;
         free(glamor_egl);
         scrn->FreeScreen(scrn);
diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
index bb1b511..85e1c0c 100644
--- a/hw/xfree86/glamor_egl/Makefile.am
+++ b/hw/xfree86/glamor_egl/Makefile.am
@@ -36,5 +36,8 @@ libglamoregl_la_LIBADD = \
 	$(top_builddir)/glamor/libglamor.la \
 	$()
 
-AM_CPPFLAGS = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS) \
+	-I$(top_srcdir)/dri3 \
+	$()
+
 AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
commit fb4a1e6ef6f80a7670e92cab2bc490d4afd80a9b
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Dec 30 18:49:46 2013 -0800

    glamor: Rename the DRI-related pixmap functions.
    
    There was confusion over whether they should have egl in the name, and
    they had DRI3 in the name even though they're useful to have without
    DRI3.
    
    v2: Just rename glamor_name_from_pixmap for now -- I'd accidentally
        conflict-resolved in adding new parameters from a later commit.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 85fd560..fa753bb 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -567,16 +567,16 @@ glamor_enable_dri3(ScreenPtr screen)
 }
 
 Bool
-glamor_is_dri3_support_enabled(ScreenPtr screen)
+glamor_supports_pixmap_import_export(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
     return glamor_priv->dri3_enabled;
 }
 
-int
-glamor_dri3_fd_from_pixmap(ScreenPtr screen,
-                           PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+_X_EXPORT int
+glamor_fd_from_pixmap(ScreenPtr screen,
+                      PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
 {
     glamor_pixmap_private *pixmap_priv;
     glamor_screen_private *glamor_priv =
@@ -600,7 +600,7 @@ glamor_dri3_fd_from_pixmap(ScreenPtr screen,
 }
 
 int
-glamor_dri3_name_from_pixmap(PixmapPtr pixmap)
+glamor_name_from_pixmap(PixmapPtr pixmap)
 {
     glamor_pixmap_private *pixmap_priv;
     glamor_screen_private *glamor_priv =
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 89e7d80..041004e 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -173,21 +173,23 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
                                                       unsigned int, Bool,
                                                       CARD16 *, CARD32 *);
 
-/* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled.
+/* @glamor_supports_pixmap_import_export: Returns whether
+ * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and
+ * glamor_pixmap_from_fd() are supported.
  *
  * @screen: Current screen pointer.
  *
- * To have DRI3 support enabled, glamor and glamor_egl need to be initialized,
- * and glamor_egl_init_textured_pixmap need to be called. glamor also
- * has to be compiled with gbm support.
- * The EGL layer need to have the following extensions working:
+ * To have DRI3 support enabled, glamor and glamor_egl need to be
+ * initialized. glamor also has to be compiled with gbm support.
+ *
+ * The EGL layer needs to have the following extensions working:
+ *
  * .EGL_KHR_gl_texture_2D_image
  * .EGL_EXT_image_dma_buf_import
- * If DRI3 support is not enabled, the following helpers will return an error.
  * */
-extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen);
 
-/* @glamor_dri3_fd_from_pixmap: DRI3 helper to get a dma-buf fd from a pixmap.
+/* @glamor_fd_from_pixmap: Get a dma-buf fd from a pixmap.
  *
  * @screen: Current screen pointer.
  * @pixmap: The pixmap from which we want the fd.
@@ -198,22 +200,25 @@ extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen);
  * content.
  * Returns the fd on success, -1 on error.
  * */
-extern _X_EXPORT int glamor_dri3_fd_from_pixmap(ScreenPtr screen,
-                                                PixmapPtr pixmap,
-                                                CARD16 *stride, CARD32 *size);
+extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
+                                           PixmapPtr pixmap,
+                                           CARD16 *stride, CARD32 *size);
 
-/* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap.
+/**
+ * @glamor_name_from_pixmap: Gets a gem name from a pixmap.
  *
  * @pixmap: The pixmap from which we want the gem name.
  *
- * the pixmap and the buffer associated by the gem name will share the same
- * content. This function can be used by the DDX to support DRI2, but needs
- * glamor DRI3 support to be activated.
+ * the pixmap and the buffer associated by the gem name will share the
+ * same content. This function can be used by the DDX to support DRI2,
+ * and needs the same set of buffer export GL extensions as DRI3
+ * support.
+ *
  * Returns the name on success, -1 on error.
  * */
-extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap);
+extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap);
 
-/* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd.
+/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd.
  *
  * @screen: Current screen pointer.
  * @fd: The dma-buf fd to import.
@@ -225,13 +230,13 @@ extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap);
  *
  * Returns a valid pixmap if the import succeeded, else NULL.
  * */
-extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
-                                                          int fd,
-                                                          CARD16 width,
-                                                          CARD16 height,
-                                                          CARD16 stride,
-                                                          CARD8 depth,
-                                                          CARD8 bpp);
+extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen,
+                                                 int fd,
+                                                 CARD16 width,
+                                                 CARD16 height,
+                                                 CARD16 stride,
+                                                 CARD8 depth,
+                                                 CARD8 bpp);
 
 #ifdef GLAMOR_FOR_XORG
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 9dcba71..56d8913 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -453,12 +453,12 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 #endif
 }
 
-PixmapPtr
-glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
-                               int fd,
-                               CARD16 width,
-                               CARD16 height,
-                               CARD16 stride, CARD8 depth, CARD8 bpp)
+_X_EXPORT PixmapPtr
+glamor_pixmap_from_fd(ScreenPtr screen,
+                      int fd,
+                      CARD16 width,
+                      CARD16 height,
+                      CARD16 stride, CARD8 depth, CARD8 bpp)
 {
 #ifdef GLAMOR_HAS_GBM
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
commit 2d20f75b60276508424997d9fa8c5b97d8f1d92b
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 22:19:07 2013 -0800

    xorg: Connect up the glamor XV code, xorg DDX-only for now.
    
    Porting this code to be non-xorg-dependent is going to take
    significant hacking, so just dump it in the glamoregl module for the
    moment, so I can hack on it while regression testing.
    
    v2: Fix compiler warnings by adding #include dix-config.h at the top,
        don't try to auto-init (I'll try to fix the xv ABI later).
    v3: Fix last minute breakage of having reintroduced xf86ScrnToScreen
        (one of the compat macros).  Just use the drawable's pScreen instead.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 12a57c4..77492bc 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -37,7 +37,6 @@ libglamor_la_SOURCES = \
 	glamor_window.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
-	glamor_xv.c\
 	glamor_utils.h\
 	glamor.h
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 08ffd26..89e7d80 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -35,6 +35,9 @@
 #include <picturestr.h>
 #include <fb.h>
 #include <fbpict.h>
+#ifdef GLAMOR_FOR_XORG
+#include <xf86xv.h>
+#endif
 
 struct glamor_context;
 
@@ -434,7 +437,7 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC,
 extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
                                            int mode, int n, DDXPointPtr points);
 
-#if 0
+#ifdef GLAMOR_FOR_XORG
 extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen,
                                                     int num_texture_ports);
 #endif
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index fb5b855..d7e1836 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -41,7 +41,7 @@ static XF86ModuleVersionInfo VersRec = {
     MODINFOSTRING1,
     MODINFOSTRING2,
     XORG_VERSION_CURRENT,
-    0, 5, 1, /* version */
+    1, 0, 0, /* version */
     ABI_CLASS_ANSIC,            /* Only need the ansic layer */
     ABI_ANSIC_VERSION,
     MOD_CLASS_NONE,
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index dc39476..fb90457 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -32,10 +32,14 @@
  * Xv acceleration implementation
  */
 
-#include "glamor_priv.h"
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
 
-#ifdef GLAMOR_XV
 #include "xf86xv.h"
+#define GLAMOR_FOR_XORG
+#include "glamor_priv.h"
+
 #include <X11/extensions/Xv.h>
 #include "fourcc.h"
 /* Reference color space transform data */
@@ -430,7 +434,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
                     Bool sync,
                     RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
 {
-    ScreenPtr screen = xf86ScrnToScreen(pScrn);
+    ScreenPtr screen = pDrawable->pScreen;
     glamor_port_private *port_priv = (glamor_port_private *) data;
     INT32 x1, x2, y1, y2;
     int srcPitch, srcPitch2;
@@ -614,12 +618,3 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports)
     }
     return adapt;
 }
-#else
-#if 0
-XF86VideoAdaptorPtr
-glamor_xv_init(ScreenPtr screen, int num_texture_ports)
-{
-    return NULL;
-}
-#endif
-#endif
diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
index 827e033..bb1b511 100644
--- a/hw/xfree86/glamor_egl/Makefile.am
+++ b/hw/xfree86/glamor_egl/Makefile.am
@@ -24,6 +24,7 @@ module_LTLIBRARIES = libglamoregl.la
 libglamoregl_la_SOURCES = \
 	$(top_srcdir)/glamor/glamor_egl.c \
 	$(top_srcdir)/glamor/glamor_eglmodule.c \
+	$(top_srcdir)/glamor/glamor_xv.c \
 	$()
 
 libglamoregl_la_LDFLAGS = \
commit 8d1cca30638f8a12c09efee27e9dedd90322b40e
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 16:44:15 2013 -0800

    xorg: Build a glamor_egl module.
    
    This is not exposing the API we want long term, but it should get
    existing DDX drivers up and running while we massage the API into
    shape.
    
    v2: Use LIBADD instead of LDFLAGS to fix deps on libglamor.la, and use
        version 0.5.1 (the point it was forked from the external repo).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index 5934950..74819bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -806,6 +806,8 @@ LIBAPPLEWM="applewm >= 1.4"
 LIBDMX="dmx >= 1.0.99.1"
 LIBDRI="dri >= 7.8.0"
 LIBDRM="libdrm >= 2.3.0"
+LIBEGL="egl"
+LIBGBM="gbm >= 9"
 LIBGL="gl >= 7.1.0"
 LIBXEXT="xext >= 1.0.99.4"
 LIBXFONT="xfont >= 1.4.2"
@@ -2070,7 +2072,15 @@ AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes])
 if test "x$GLAMOR" = xyes; then
 	AC_DEFINE(GLAMOR, 1, [Build glamor])
 	PKG_CHECK_MODULES([GLAMOR], [epoxy])
+
+	PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no])
+	if test "x$GBM" = xyes; then
+		AC_DEFINE(GLAMOR_HAS_GBM, 1,
+			  [Build glamor with GBM-based EGL support])
+	fi
+
 fi
+AM_CONDITIONAL([GLAMOR_EGL], [test "x$GBM" = xyes])
 
 dnl XWin DDX
 
@@ -2479,6 +2489,7 @@ hw/xfree86/exa/Makefile
 hw/xfree86/exa/man/Makefile
 hw/xfree86/fbdevhw/Makefile
 hw/xfree86/fbdevhw/man/Makefile
+hw/xfree86/glamor_egl/Makefile
 hw/xfree86/i2c/Makefile
 hw/xfree86/int10/Makefile
 hw/xfree86/loader/Makefile
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 5ddd602..fb5b855 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -30,6 +30,7 @@
 #include "dix-config.h"
 
 #include <xorg-server.h>
+#include <xf86.h>
 #define GLAMOR_FOR_XORG
 #include <xf86Module.h>
 #include "glamor.h"
@@ -40,7 +41,7 @@ static XF86ModuleVersionInfo VersRec = {
     MODINFOSTRING1,
     MODINFOSTRING2,
     XORG_VERSION_CURRENT,
-    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+    0, 5, 1, /* version */
     ABI_CLASS_ANSIC,            /* Only need the ansic layer */
     ABI_ANSIC_VERSION,
     MOD_CLASS_NONE,
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 9672904..73e1b4c 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -14,6 +14,10 @@ DRI3_BUILDDIR = $(top_builddir)/dri3
 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la
 endif
 
+if GLAMOR_EGL
+GLAMOR_EGL_SUBDIR = glamor_egl
+endif
+
 if XF86UTILS
 XF86UTILS_SUBDIR = utils
 endif
@@ -33,7 +37,8 @@ endif
 SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \
 	  ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \
 	  $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
-	  fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man
+	  fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \
+	  $(GLAMOR_EGL_SUBDIR)
 
 DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
                parser ramdac shadowfb vbe vgahw \
diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
new file mode 100644
index 0000000..827e033
--- /dev/null
+++ b/hw/xfree86/glamor_egl/Makefile.am
@@ -0,0 +1,39 @@
+# Copyright © 2013 Intel Corporation
+#
+# 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 (including the next
+# paragraph) 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.
+
+module_LTLIBRARIES = libglamoregl.la
+
+libglamoregl_la_SOURCES = \
+	$(top_srcdir)/glamor/glamor_egl.c \
+	$(top_srcdir)/glamor/glamor_eglmodule.c \
+	$()
+
+libglamoregl_la_LDFLAGS = \
+	-avoid-version \
+	$(GBM_LIBS) \
+	$()
+
+libglamoregl_la_LIBADD = \
+	$(top_builddir)/glamor/libglamor.la \
+	$()
+
+AM_CPPFLAGS = $(XORG_INCS)
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 7c77956..754e81e 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -481,4 +481,7 @@
 /* Build GLAMOR */
 #undef GLAMOR
 
+/* Build glamor's GBM-based EGL support */
+#undef GLAMOR_HAS_GBM
+
 #endif /* _DIX_CONFIG_H_ */
commit fa2e78788327c41bfd45b3de3c71bf9c26dcc85e
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 20 10:41:43 2013 -0800

    xephyr: Pass incoming XCB events to the Xlib event filter.
    
    This is the same thing that Qt ended up doing to get DRI2's event
    mangling to happen despite using an XCB event loop.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 75a6fcb..def50d8 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1223,6 +1223,9 @@ ephyrPoll(void)
             break;
         }
 
+        if (ephyr_glamor)
+            ephyr_glamor_process_event(xev);
+
         free(xev);
     }
 }
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index a937c1a..d56907f 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -29,12 +29,17 @@
 
 #include <stdlib.h>
 #include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
 #include <X11/Xlib-xcb.h>
 #include <xcb/xcb_aux.h>
 #include <pixman.h>
 #include <epoxy/glx.h>
 #include "ephyr_glamor_glx.h"
 #include "os.h"
+#include <X11/Xproto.h>
 
 /** @{
  *
@@ -218,6 +223,40 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
     glXSwapBuffers(dpy, glamor->glx_win);
 }
 
+/**
+ * Xlib-based handling of xcb events for glamor.
+ *
+ * We need to let the Xlib event filtering run on the event so that
+ * Mesa's dri2_glx.c userspace event mangling gets run, and we
+ * correctly get our invalidate events propagated into the driver.
+ */
+void
+ephyr_glamor_process_event(xcb_generic_event_t *xev)
+{
+
+    uint32_t response_type = xev->response_type & 0x7f;
+    /* Note the types on wire_to_event: there's an Xlib XEvent (with
+     * the broken types) that it returns, and a protocol xEvent that
+     * it inspects.
+     */
+    Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event);
+
+    XLockDisplay(dpy);
+    /* Set the event handler to NULL to get access to the current one. */
+    wire_to_event = XESetWireToEvent(dpy, response_type, NULL);
+    if (wire_to_event) {
+        XEvent processed_event;
+
+        /* OK they had an event handler.  Plug it back in, and call
+         * through to it.
+         */
+        XESetWireToEvent(dpy, response_type, wire_to_event);
+        xev->sequence = LastKnownRequestProcessed(dpy);
+        wire_to_event(dpy, &processed_event, (xEvent *)xev);
+    }
+    XUnlockDisplay(dpy);
+}
+
 struct ephyr_glamor *
 ephyr_glamor_glx_screen_init(xcb_window_t win)
 {
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.h b/hw/kdrive/ephyr/ephyr_glamor_glx.h
index 950beff..8995e1e 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.h
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.h
@@ -53,10 +53,21 @@ ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor);
 void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage);
-#else
+
+void
+ephyr_glamor_process_event(xcb_generic_event_t *xev);
+
+#else /* !GLAMOR */
+
 static inline void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage)
 {
 }
-#endif
+
+static inline void
+ephyr_glamor_process_event(xcb_generic_event_t *xev)
+{
+}
+
+#endif /* !GLAMOR */
commit 9fe052d90cca90fdf750d3a45b151be2ac7f0ebd
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 13:24:14 2013 -0800

    xephyr: Build support for rendering with glamor using a -glamor option.
    
    v2: Avoid making the Ximage for the screen that we'll never use, and
        drive the screen pixmap creation for glamor ourselves.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com> (v1)
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index 0fb2fc3..5934950 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2319,6 +2319,9 @@ if test "$KDRIVE" = yes; then
     if test "x$DRI" = xyes && test "x$GLX" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS libdrm xcb-glx xcb-xf86dri > 1.6"
     fi
+    if test "x$GLAMOR" = xyes; then
+        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS x11-xcb"
+    fi
 
     if test "x$XEPHYR" = xauto; then
         PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [XEPHYR="yes"], [XEPHYR="no"])
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7d8228c..85fd560 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -123,6 +123,17 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
     glamor_priv->back_pixmap = back_pixmap;
 }
 
+uint32_t
+glamor_get_pixmap_texture(PixmapPtr pixmap)
+{
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
+        return 0;
+
+    return pixmap_priv->base.fbo->tex;
+}
+
 PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                      unsigned int usage)
diff --git a/glamor/glamor.h b/glamor/glamor.h
index eec6872..08ffd26 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -124,6 +124,8 @@ extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
                                                PixmapPtr *back_pixmap);
 
+extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
+
 /* @glamor_glyphs_init: Initialize glyphs internal data structures.
  *
  * @pScreen: Current screen pointer.
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 6b790fd..040993c 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -27,12 +27,20 @@ AM_CPPFLAGS = 			\
 	@XEPHYR_INCS@		\
 	@XEPHYR_CFLAGS@		\
 	-I$(top_srcdir)		\
+	-I$(top_srcdir)/glamor	\
 	-I$(top_srcdir)/exa
 
 if XV
 XV_SRCS = ephyrvideo.c
 endif
 
+if GLAMOR
+GLAMOR_SRCS = \
+	ephyr_glamor_glx.c \
+	ephyr_glamor_glx.h \
+	()
+endif
+
 if DRI
 DRI_SRCS =			\
 	ephyrdriext.c		\
@@ -59,14 +67,24 @@ Xephyr_SOURCES = \
 	hostx.h \
 	$(XV_SRCS) \
 	$(DRI_SRCS) \
+	$(GLAMOR_SRCS) \
 	$()
 
+if GLAMOR
+AM_CPPFLAGS += $(XLIB_CFLAGS)
+XEPHYR_GLAMOR_LIB = \
+	$(top_builddir)/glamor/libglamor.la \
+	$(top_builddir)/glamor/libglamor_egl_stubs.la \
+	$()
+endif
+
 Xephyr_LDADD = 						\
 	$(top_builddir)/exa/libexa.la			\
+	$(XEPHYR_GLAMOR_LIB)				\
 	@KDRIVE_LIBS@					\
 	@XEPHYR_LIBS@
 
-Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@
+Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@ $(XEPHYR_GLAMOR_LIB)
 
 Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 9681273..75a6fcb 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -43,9 +43,15 @@
 #include "ephyrglxext.h"
 #endif                          /* XF86DRI */
 
+#ifdef GLAMOR
+#include "glamor.h"
+#endif
+#include "ephyr_glamor_glx.h"
+
 #include "xkbsrv.h"
 
 extern int KdTsPhyScreen;
+extern Bool ephyr_glamor;
 
 KdKeyboardInfo *ephyrKbd;
 KdPointerInfo *ephyrMouse;
@@ -326,15 +332,19 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen)
         int nbox;
         BoxPtr pbox;
 
-        nbox = RegionNumRects(pRegion);
-        pbox = RegionRects(pRegion);
-
-        while (nbox--) {
-            hostx_paint_rect(screen,
-                             pbox->x1, pbox->y1,
-                             pbox->x1, pbox->y1,
-                             pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
-            pbox++;
+        if (ephyr_glamor) {
+            ephyr_glamor_damage_redisplay(scrpriv->glamor, pRegion);
+        } else {
+            nbox = RegionNumRects(pRegion);
+            pbox = RegionRects(pRegion);
+
+            while (nbox--) {
+                hostx_paint_rect(screen,
+                                 pbox->x1, pbox->y1,
+                                 pbox->x1, pbox->y1,
+                                 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+                pbox++;
+            }
         }
         DamageEmpty(scrpriv->pDamage);
     }
@@ -662,6 +672,7 @@ ephyrInitScreen(ScreenPtr pScreen)
     return TRUE;
 }
 
+
 Bool
 ephyrFinishInitScreen(ScreenPtr pScreen)
 {
@@ -679,6 +690,12 @@ ephyrFinishInitScreen(ScreenPtr pScreen)
     return TRUE;
 }
 
+/**
+ * Called by kdrive after calling down the
+ * pScreen->CreateScreenResources() chain, this gives us a chance to
+ * make any pixmaps after the screen and all extensions have been
+ * initialized.
+ */
 Bool
 ephyrCreateResources(ScreenPtr pScreen)
 {
@@ -693,8 +710,13 @@ ephyrCreateResources(ScreenPtr pScreen)
         return KdShadowSet(pScreen,
                            scrpriv->randr,
                            ephyrShadowUpdate, ephyrWindowLinear);
-    else
+    else {
+#ifdef GLAMOR
+        if (ephyr_glamor)
+            ephyr_glamor_create_screen_resources(pScreen);
+#endif
         return ephyrSetInternalDamage(pScreen);
+    }
 }
 
 void
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 73fdb59..34ce460 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -80,6 +80,12 @@ typedef struct _ephyrScrPriv {
 
     KdScreenInfo *screen;
     int mynum;                  /* Screen number */
+
+    /**
+     * Per-screen Xlib-using state for glamor (private to
+     * ephyr_glamor_glx.c)
+     */
+    struct ephyr_glamor *glamor;
 } EphyrScrPriv;
 
 extern KdCardFuncs ephyrFuncs;
@@ -203,6 +209,14 @@ void
 void
  ephyrDrawFini(ScreenPtr pScreen);
 
+/* hostx.c glamor support */
+Bool ephyr_glamor_init(ScreenPtr pScreen);
+Bool ephyr_glamor_create_screen_resources(ScreenPtr pScreen);
+void ephyr_glamor_enable(ScreenPtr pScreen);
+void ephyr_glamor_disable(ScreenPtr pScreen);
+void ephyr_glamor_fini(ScreenPtr pScreen);
+void ephyr_glamor_host_paint_rect(ScreenPtr pScreen);
+
 /*ephyvideo.c*/
 
 Bool ephyrInitVideo(ScreenPtr pScreen);
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
new file mode 100644
index 0000000..a937c1a
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/** @file ephyr_glamor_glx.c
+ *
+ * Separate file for hiding Xlib and GLX-using parts of xephyr from
+ * the rest of the server-struct-aware build.
+ */
+
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcb_aux.h>
+#include <pixman.h>
+#include <epoxy/glx.h>
+#include "ephyr_glamor_glx.h"
+#include "os.h"
+
+/** @{
+ *
+ * global state for Xephyr with glamor.
+ *
+ * Xephyr can render with multiple windows, but all the windows have
+ * to be on the same X connection and all have to have the same
+ * visual.
+ */
+static Display *dpy;
+static XVisualInfo *visual_info;
+static GLXFBConfig fb_config;
+/** @} */
+
+/**
+ * Per-screen state for Xephyr with glamor.
+ */
+struct ephyr_glamor {
+    GLXContext ctx;
+    Window win;
+    GLXWindow glx_win;
+
+    GLuint tex;
+
+    GLuint texture_shader;
+    GLuint texture_shader_position_loc;
+    GLuint texture_shader_texcoord_loc;
+};
+
+static GLint
+ephyr_glamor_compile_glsl_prog(GLenum type, const char *source)
+{
+    GLint ok;
+    GLint prog;
+
+    prog = glCreateShader(type);
+    glShaderSource(prog, 1, (const GLchar **) &source, NULL);
+    glCompileShader(prog);
+    glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+    if (!ok) {
+        GLchar *info;
+        GLint size;
+
+        glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+        info = malloc(size);
+        if (info) {
+            glGetShaderInfoLog(prog, size, NULL, info);
+            ErrorF("Failed to compile %s: %s\n",
+                   type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
+            ErrorF("Program source:\n%s", source);
+            free(info);
+        }
+        else
+            ErrorF("Failed to get shader compilation info.\n");
+        FatalError("GLSL compile failure\n");
+    }
+
+    return prog;
+}
+
+static GLuint
+ephyr_glamor_build_glsl_prog(GLuint vs, GLuint fs)
+{
+    GLint ok;
+    GLuint prog;
+
+    prog = glCreateProgram();
+    glAttachShader(prog, vs);
+    glAttachShader(prog, fs);
+
+    glLinkProgram(prog);
+    glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+    if (!ok) {
+        GLchar *info;
+        GLint size;
+
+        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+        info = malloc(size);
+
+        glGetProgramInfoLog(prog, size, NULL, info);
+        ErrorF("Failed to link: %s\n", info);
+        FatalError("GLSL link failure\n");
+    }
+
+    return prog;
+}
+
+static void
+ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor)
+{
+    const char *vs_source =
+        "attribute vec2 texcoord;\n"
+        "attribute vec2 position;\n"
+        "varying vec2 t;\n"
+        "\n"
+        "void main()\n"
+        "{\n"
+        "    t = texcoord;\n"
+        "    gl_Position = vec4(position, 0, 1);\n"
+        "}\n";
+
+    const char *fs_source =
+        "varying vec2 t;\n"
+        "uniform sampler2D s; /* initially 0 */\n"
+        "\n"
+        "void main()\n"
+        "{\n"
+        "    gl_FragColor = texture2D(s, t);\n"
+        "}\n";
+
+    GLuint fs, vs, prog;
+
+    vs = ephyr_glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+    fs = ephyr_glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
+    prog = ephyr_glamor_build_glsl_prog(vs, fs);
+
+    glamor->texture_shader = prog;
+    glamor->texture_shader_position_loc = glGetAttribLocation(prog, "position");
+    assert(glamor->texture_shader_position_loc != -1);
+    glamor->texture_shader_texcoord_loc = glGetAttribLocation(prog, "texcoord");
+    assert(glamor->texture_shader_texcoord_loc != -1);
+}
+
+xcb_connection_t *
+ephyr_glamor_connect(void)
+{
+    dpy = XOpenDisplay(NULL);
+    if (!dpy)
+        return NULL;
+
+    XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
+
+    return XGetXCBConnection(dpy);
+}
+
+void
+ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex)
+{
+    glamor->tex = tex;
+}
+
+void
+ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
+                              struct pixman_region16 *damage)
+{
+    /* Redraw the whole screen, since glXSwapBuffers leaves the back
+     * buffer undefined.
+     */
+    static const float position[] = {
+        -1, -1,
+         1, -1,
+         1,  1,
+        -1,  1,
+    };
+    static const float texcoords[] = {
+        0, 1,
+        1, 1,
+        1, 0,
+        0, 0,
+    };
+
+    glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx);
+
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glUseProgram(glamor->texture_shader);
+
+    glVertexAttribPointer(glamor->texture_shader_position_loc,
+                          2, GL_FLOAT, FALSE, 0, position);
+    glVertexAttribPointer(glamor->texture_shader_texcoord_loc,
+                          2, GL_FLOAT, FALSE, 0, texcoords);
+    glEnableVertexAttribArray(glamor->texture_shader_position_loc);
+    glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, glamor->tex);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glDisableVertexAttribArray(glamor->texture_shader_position_loc);
+    glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc);
+
+    glXSwapBuffers(dpy, glamor->glx_win);
+}
+
+struct ephyr_glamor *
+ephyr_glamor_glx_screen_init(xcb_window_t win)
+{
+    GLXContext ctx;
+    struct ephyr_glamor *glamor;
+    GLXWindow glx_win;
+
+    glamor = calloc(1, sizeof(struct ephyr_glamor));
+    if (!glamor) {
+        FatalError("malloc");
+        return NULL;
+    }
+
+    glx_win = glXCreateWindow(dpy, fb_config, win, NULL);
+
+    ctx = glXCreateContext(dpy, visual_info, NULL, True);
+    if (ctx == NULL)
+        FatalError("glXCreateContext failed\n");
+
+    if (!glXMakeCurrent(dpy, glx_win, ctx))
+        FatalError("glXMakeCurrent failed\n");
+
+    glamor->ctx = ctx;
+    glamor->win = win;
+    glamor->glx_win = glx_win;
+    ephyr_glamor_setup_texturing_shader(glamor);
+
+    return glamor;
+}
+
+void
+ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor)
+{
+    glXMakeCurrent(dpy, None, NULL);
+    glXDestroyContext(dpy, glamor->ctx);
+    glXDestroyWindow(dpy, glamor->glx_win);
+
+    free(glamor);
+}
+
+xcb_visualtype_t *
+ephyr_glamor_get_visual(void)
+{
+    xcb_screen_t *xscreen =
+        xcb_aux_get_screen(XGetXCBConnection(dpy), DefaultScreen(dpy));
+    int attribs[] = {
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+        GLX_RED_SIZE, 1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE, 1,
+        GLX_DOUBLEBUFFER, 1,
+        None
+    };
+    int event_base = 0, error_base = 0, nelements;
+    GLXFBConfig *fbconfigs;
+
+    if (!glXQueryExtension (dpy, &error_base, &event_base))
+        FatalError("Couldn't find GLX extension\n");
+
+    fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &nelements);
+    if (!nelements)
+        FatalError("Couldn't choose an FBConfig\n");
+    fb_config = fbconfigs[0];
+    free(fbconfigs);
+
+    visual_info = glXGetVisualFromFBConfig(dpy, fb_config);
+    if (visual_info == NULL)
+        FatalError("Couldn't get RGB visual\n");
+
+    return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid);
+}
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.h b/hw/kdrive/ephyr/ephyr_glamor_glx.h
new file mode 100644
index 0000000..950beff
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/**
+ * ephyr_glamor_glx.h
+ *
+ * Prototypes exposed by ephyr_glamor_glx.c, without including any
+ * server headers.
+ */
+
+#include <xcb/xcb.h>
+#include "dix-config.h"
+
+struct ephyr_glamor;
+struct pixman_region16;
+
+xcb_connection_t *
+ephyr_glamor_connect(void);
+
+void
+ephyr_glamor_set_texture(struct ephyr_glamor *ephyr_glamor, uint32_t tex);
+
+xcb_visualtype_t *
+ephyr_glamor_get_visual(void);
+
+struct ephyr_glamor *
+ephyr_glamor_glx_screen_init(xcb_window_t win);
+
+void
+ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor);
+
+#ifdef GLAMOR
+void
+ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
+                              struct pixman_region16 *damage);
+#else
+static inline void
+ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
+                              struct pixman_region16 *damage)
+{
+}
+#endif
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 3230e70..807e717 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -35,6 +35,7 @@ extern Bool EphyrWantGrayScale;
 extern Bool EphyrWantResize;
 extern Bool kdHasPointer;
 extern Bool kdHasKbd;
+extern Bool ephyr_glamor;
 
 #ifdef GLXEXT
 extern Bool ephyrNoDRI;
@@ -138,6 +139,9 @@ ddxUseMsg(void)
     ErrorF("-fullscreen          Attempt to run Xephyr fullscreen\n");
     ErrorF("-grayscale           Simulate 8bit grayscale\n");
     ErrorF("-resizeable          Make Xephyr windows resizeable\n");
+#ifdef GLAMOR
+    ErrorF("-glamor              Enable 2D acceleration using glamor\n");
+#endif
     ErrorF
         ("-fakexa              Simulate acceleration using software rendering\n");
     ErrorF("-verbosity <level>   Set log verbosity level\n");
@@ -241,6 +245,16 @@ ddxProcessArgument(int argc, char **argv, int i)
         EphyrWantResize = 1;
         return 1;
     }
+#ifdef GLAMOR
+    else if (!strcmp (argv[i], "-glamor")) {
+        ephyr_glamor = TRUE;
+        ephyrFuncs.initAccel = ephyr_glamor_init;
+        ephyrFuncs.enableAccel = ephyr_glamor_enable;
+        ephyrFuncs.disableAccel = ephyr_glamor_disable;
+        ephyrFuncs.finiAccel = ephyr_glamor_fini;
+        return 1;
+    }
+#endif
     else if (!strcmp(argv[i], "-fakexa")) {
         ephyrFuncs.initAccel = ephyrDrawInit;
         ephyrFuncs.enableAccel = ephyrDrawEnable;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 44ad8e2..19c2ed2 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -36,6 +36,7 @@
 #include <string.h>             /* for memset */
 #include <errno.h>
 #include <time.h>
+#include <err.h>
 
 #include <sys/ipc.h>
 #include <sys/shm.h>
@@ -54,6 +55,11 @@
 #include <xcb/xf86dri.h>
 #include <xcb/glx.h>
 #endif /* XF86DRI */
+#ifdef GLAMOR
+#include <epoxy/gl.h>
+#include "glamor.h"
+#include "ephyr_glamor_glx.h"
+#endif
 #include "ephyrlog.h"
 #include "ephyr.h"
 
@@ -90,6 +96,7 @@ extern Bool EphyrWantResize;
 char *ephyrResName = NULL;
 int ephyrResNameFromCmd = 0;
 char *ephyrTitle = NULL;
+Bool ephyr_glamor = FALSE;
 
 static void
  hostx_set_fullscreen_hint(void);
@@ -302,7 +309,10 @@ hostx_init(void)
         | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
 
     EPHYR_DBG("mark");
-    HostX.conn = xcb_connect(NULL, &HostX.screen);
+    if (ephyr_glamor)
+        HostX.conn = ephyr_glamor_connect();
+    else
+        HostX.conn = xcb_connect(NULL, &HostX.screen);
     if (xcb_connection_has_error(HostX.conn)) {
         fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
         exit(1);
@@ -312,7 +322,11 @@ hostx_init(void)
     HostX.winroot = xscreen->root;
     HostX.gc = xcb_generate_id(HostX.conn);
     HostX.depth = xscreen->root_depth;
-    HostX.visual  = xcb_aux_find_visual_by_id(xscreen, xscreen->root_visual);
+    if (ephyr_glamor) {
+        HostX.visual = ephyr_glamor_get_visual();
+    } else {
+        HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
+    }
 
     xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL);
     cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE,
@@ -642,7 +656,7 @@ hostx_screen_init(KdScreenInfo *screen,
         }
     }
 
-    if (HostX.have_shm) {
+    if (!ephyr_glamor && HostX.have_shm) {
         scrpriv->ximg = xcb_image_create_native(HostX.conn,
                                                 width,
                                                 buffer_height,
@@ -677,7 +691,7 @@ hostx_screen_init(KdScreenInfo *screen,
         }
     }
 
-    if (!shm_success) {
+    if (!ephyr_glamor && !shm_success) {
         EPHYR_DBG("Creating image %dx%d for screen scrpriv=%p\n",
                   width, buffer_height, scrpriv);
         scrpriv->ximg = xcb_image_create_native(HostX.conn,
@@ -711,7 +725,11 @@ hostx_screen_init(KdScreenInfo *screen,
     scrpriv->win_width = width;
     scrpriv->win_height = height;
 
-    if (host_depth_matches_server(scrpriv)) {
+    if (ephyr_glamor) {
+        *bytes_per_line = 0;
+        *bits_per_pixel = 0;
+        return NULL;
+    } else if (host_depth_matches_server(scrpriv)) {
         *bytes_per_line = scrpriv->ximg->stride;
         *bits_per_pixel = scrpriv->ximg->bpp;
 
@@ -742,6 +760,21 @@ hostx_paint_rect(KdScreenInfo *screen,
 
     EPHYR_DBG("painting in screen %d\n", scrpriv->mynum);
 
+    if (ephyr_glamor) {
+        BoxRec box;
+        RegionRec region;
+
+        box.x1 = dx;
+        box.y1 = dy;
+        box.x2 = dx + width;
+        box.y2 = dy + height;
+
+        RegionInit(&region, &box, 1);
+        ephyr_glamor_damage_redisplay(scrpriv->glamor, &region);
+        RegionUninit(&region);
+        return;
+    }
+
     /*
      *  Copy the image data updated by the shadow layer
      *  on to the window
@@ -1170,3 +1203,86 @@ hostx_get_resource_id_peer(int a_local_resource_id, int *a_remote_resource_id)
 }
 
 #endif                          /* XF86DRI */
+
+#ifdef GLAMOR
+Bool
+ephyr_glamor_init(ScreenPtr screen)
+{
+    KdScreenPriv(screen);
+    KdScreenInfo *kd_screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = kd_screen->driver;
+
+    scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win);
+
+    glamor_init(screen,
+                GLAMOR_USE_SCREEN |
+                GLAMOR_USE_PICTURE_SCREEN |
+                GLAMOR_INVERTED_Y_AXIS);
+
+    return TRUE;
+}
+
+Bool
+ephyr_glamor_create_screen_resources(ScreenPtr pScreen)
+{
+    KdScreenPriv(pScreen);
+    KdScreenInfo *kd_screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = kd_screen->driver;
+    PixmapPtr screen_pixmap;
+    uint32_t tex;
+
+    if (!ephyr_glamor)
+        return TRUE;
+
+    if (!glamor_glyphs_init(pScreen))
+        return FALSE;
+
+    /* kdrive's fbSetupScreen() told mi to have
+     * miCreateScreenResources() (which is called before this) make a
+     * scratch pixmap wrapping ephyr-glamor's NULL
+     * KdScreenInfo->fb.framebuffer.
+     *
+     * We want a real (texture-based) screen pixmap at this point.
+     * This is what glamor will render into, and we'll then texture
+     * out of that into the host's window to present the results.
+     *
+     * Thus, delete the current screen pixmap, and put a fresh one in.
+     */
+    screen_pixmap = pScreen->GetScreenPixmap(pScreen);
+    pScreen->DestroyPixmap(screen_pixmap);
+
+    screen_pixmap = pScreen->CreatePixmap(pScreen,
+                                          pScreen->width,
+                                          pScreen->height,
+                                          pScreen->rootDepth, 0);
+    pScreen->SetScreenPixmap(screen_pixmap);
+
+    /* Tell the GLX code what to GL texture to read from. */
+    tex = glamor_get_pixmap_texture(screen_pixmap);
+    ephyr_glamor_set_texture(scrpriv->glamor, tex);
+
+    return TRUE;
+}
+
+void
+ephyr_glamor_enable(ScreenPtr screen)
+{
+}
+
+void
+ephyr_glamor_disable(ScreenPtr screen)
+{
+}
+
+void
+ephyr_glamor_fini(ScreenPtr screen)
+{
+    KdScreenPriv(screen);
+    KdScreenInfo *kd_screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = kd_screen->driver;
+
+    glamor_fini(screen);
+    ephyr_glamor_glx_screen_fini(scrpriv->glamor);
+    scrpriv->glamor = NULL;
+}
+#endif
commit b634e909895f6001e7d9543e1350b20c82c8c01c
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jun 27 23:56:23 2013 +0100

    hw/xwin: More closely follow ICCCM for setting input focus
    
    In multiwindow mode, more closely follow ICCCM section 4.1.7 when setting X
    input focus to a window when the native Windows window acquires input focus:
    
    - If InputHint is FALSE, don't use XSetInputFocus()
    - If the window supports the WM_TAKE_FOCUS protocol, send a WM_TAKE_FOCUS message
    
    This helps JDK 1.7 clients acquire the focus correctly.
    
    Also, factor out checking client support for a given WM_PROTOCOLS protocol as a
    separate function.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index c6da777..9f12521 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -111,6 +111,7 @@ typedef struct _WMInfo {
     WMMsgQueueRec wmMsgQueue;
     Atom atmWmProtos;
     Atom atmWmDelete;
+    Atom atmWmTakeFocus;
     Atom atmPrivMap;
     Bool fAllowOtherWM;
 } WMInfoRec, *WMInfoPtr;
@@ -453,6 +454,27 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
 }
 
 /*
+ * Does the client support the specified WM_PROTOCOLS protocol?
+ */
+
+static Bool
+IsWmProtocolAvailable(Display * pDisplay, Window iWindow, Atom atmProtocol)
+{
+  int i, n, found = 0;
+  Atom *protocols;
+
+  if (XGetWMProtocols(pDisplay, iWindow, &protocols, &n)) {
+    for (i = 0; i < n; ++i)
+      if (protocols[i] == atmProtocol)
+        ++found;
+
+    XFree(protocols);
+  }
+
+  return found > 0;
+}
+
+/*
  * Send a message to the X server from the WM thread
  */
 
@@ -805,21 +827,10 @@ winMultiWindowWMProc(void *pArg)
             ErrorF("\tWM_WM_KILL\n");
 #endif
             {
-                int i, n, found = 0;
-                Atom *protocols;
-
-                /* --- */
-                if (XGetWMProtocols(pWMInfo->pDisplay,
-                                    pNode->msg.iWindow, &protocols, &n)) {
-                    for (i = 0; i < n; ++i)
-                        if (protocols[i] == pWMInfo->atmWmDelete)
-                            ++found;
-
-                    XFree(protocols);
-                }
-
                 /* --- */
-                if (found)
+                if (IsWmProtocolAvailable(pWMInfo->pDisplay,
+                                          pNode->msg.iWindow,
+                                          pWMInfo->atmWmDelete))
                     SendXMessage(pWMInfo->pDisplay,
                                  pNode->msg.iWindow,
                                  pWMInfo->atmWmProtos, pWMInfo->atmWmDelete);
@@ -832,11 +843,39 @@ winMultiWindowWMProc(void *pArg)
 #if CYGMULTIWINDOW_DEBUG
             ErrorF("\tWM_WM_ACTIVATE\n");
 #endif
-
             /* Set the input focus */
-            XSetInputFocus(pWMInfo->pDisplay,
-                           pNode->msg.iWindow,
-                           RevertToPointerRoot, CurrentTime);
+
+            /*
+               ICCCM 4.1.7 is pretty opaque, but it appears that the rules are
+               actually quite simple:
+               -- the WM_HINTS input field determines whether the WM should call
+               XSetInputFocus()
+               -- independently, the WM_TAKE_FOCUS protocol determines whether
+               the WM should send a WM_TAKE_FOCUS ClientMessage.
+            */
+            {
+              Bool neverFocus = FALSE;
+              XWMHints *hints = XGetWMHints(pWMInfo->pDisplay, pNode->msg.iWindow);
+
+              if (hints) {
+                if (hints->flags & InputHint)
+                  neverFocus = !hints->input;
+                XFree(hints);
+              }
+
+              if (!neverFocus)
+                XSetInputFocus(pWMInfo->pDisplay,
+                               pNode->msg.iWindow,
+                               RevertToPointerRoot, CurrentTime);
+
+              if (IsWmProtocolAvailable(pWMInfo->pDisplay,
+                                        pNode->msg.iWindow,
+                                        pWMInfo->atmWmTakeFocus))
+                SendXMessage(pWMInfo->pDisplay,
+                             pNode->msg.iWindow,
+                             pWMInfo->atmWmProtos, pWMInfo->atmWmTakeFocus);
+
+            }
             break;
 
         case WM_WM_NAME_EVENT:
@@ -1404,6 +1443,8 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
                                        "WM_PROTOCOLS", False);
     pWMInfo->atmWmDelete = XInternAtom(pWMInfo->pDisplay,
                                        "WM_DELETE_WINDOW", False);
+    pWMInfo->atmWmTakeFocus = XInternAtom(pWMInfo->pDisplay,
+                                       "WM_TAKE_FOCUS", False);
 
     pWMInfo->atmPrivMap = XInternAtom(pWMInfo->pDisplay,
                                       WINDOWSWM_NATIVE_HWND, False);
commit 0fc84a2bb6970f6b05a19cd8b32a7f3f7fd148b3
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Feb 28 15:02:14 2014 +0000

    hw/xwin: Remove unnecessary casts from malloc/realloc/calloc calls
    
    Remove unnecessary casts from malloc/realloc/calloc calls. This is the style
    used for the majority of X server code.
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index f130651..6906114 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -1613,7 +1613,7 @@ glxWinCreateContext(__GLXscreen * screen,
         glxWinReleaseTexImage
     };
 
-    context = (__GLXWinContext *) calloc(1, sizeof(__GLXWinContext));
+    context = calloc(1, sizeof(__GLXWinContext));
 
     if (!context)
         return NULL;
diff --git a/hw/xwin/winallpriv.c b/hw/xwin/winallpriv.c
index cc3b3d1..629af92 100644
--- a/hw/xwin/winallpriv.c
+++ b/hw/xwin/winallpriv.c
@@ -58,7 +58,7 @@ winAllocatePrivates(ScreenPtr pScreen)
     }
 
     /* Allocate memory for the screen private structure */
-    pScreenPriv = (winPrivScreenPtr) malloc(sizeof(winPrivScreenRec));
+    pScreenPriv = malloc(sizeof(winPrivScreenRec));
     if (!pScreenPriv) {
         ErrorF("winAllocateScreenPrivates - malloc () failed\n");
         return FALSE;
@@ -150,7 +150,7 @@ winAllocateCmapPrivates(ColormapPtr pCmap)
     }
 
     /* Allocate memory for our private structure */
-    pCmapPriv = (winPrivCmapPtr) malloc(sizeof(winPrivCmapRec));
+    pCmapPriv = malloc(sizeof(winPrivCmapRec));
     if (!pCmapPriv) {
         ErrorF("winAllocateCmapPrivates - malloc () failed\n");
         return FALSE;
diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c
index 226c3f0..7d3c30e 100644
--- a/hw/xwin/winclipboardxevents.c
+++ b/hw/xwin/winclipboardxevents.c
@@ -248,7 +248,7 @@ winClipboardFlushXEvents(HWND hwnd,
                                                       (LPCWSTR) pszGlobalData,
                                                       -1, NULL, 0, NULL, NULL);
                 /* NOTE: iConvertDataLen includes space for null terminator */
-                pszConvertData = (char *) malloc(iConvertDataLen);
+                pszConvertData = malloc(iConvertDataLen);
                 WideCharToMultiByte(CP_UTF8,
                                     0,
                                     (LPCWSTR) pszGlobalData,
@@ -581,8 +581,7 @@ winClipboardFlushXEvents(HWND hwnd,
                                                   pszReturnData, -1, NULL, 0);
 
                 /* Allocate memory for the Unicode string */
-                pwszUnicodeStr
-                    = (wchar_t *) malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
+                pwszUnicodeStr = malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
                 if (!pwszUnicodeStr) {
                     ErrorF("winClipboardFlushXEvents - SelectionNotify "
                            "malloc failed for pwszUnicodeStr, aborting.\n");
diff --git a/hw/xwin/wincursor.c b/hw/xwin/wincursor.c
index a35336a..f3ac0f7 100644
--- a/hw/xwin/wincursor.c
+++ b/hw/xwin/wincursor.c
@@ -255,10 +255,8 @@ winLoadCursor(ScreenPtr pScreen, CursorPtr pCursor, int screen)
         bi.bV4BlueMask = 0x000000FF;
         bi.bV4AlphaMask = 0xFF000000;
 
-        lpBits =
-            (uint32_t *) calloc(pScreenPriv->cursor.sm_cx *
-                                pScreenPriv->cursor.sm_cy,
-                                sizeof(uint32_t));
+        lpBits = calloc(pScreenPriv->cursor.sm_cx * pScreenPriv->cursor.sm_cy,
+                        sizeof(uint32_t));
 
         if (lpBits) {
             int y;
@@ -302,9 +300,7 @@ winLoadCursor(ScreenPtr pScreen, CursorPtr pCursor, int screen)
         pbmiColors[2].rgbBlue = pCursor->foreBlue >> 8;
         pbmiColors[2].rgbReserved = 0;
 
-        lpBits =
-            (uint32_t *) calloc(pScreenPriv->cursor.sm_cx *
-                                pScreenPriv->cursor.sm_cy, sizeof(char));
+        lpBits = calloc(pScreenPriv->cursor.sm_cx * pScreenPriv->cursor.sm_cy, 1);
 
         pCur = (unsigned char *) lpBits;
         if (lpBits) {
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1dd8ba5..c6da777 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -405,7 +405,7 @@ Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
 
         for (i = 0; i < nNum; i++)
             iLen += strlen(ppList[i]);
-        pszReturnData = (char *) malloc(iLen + 1);
+        pszReturnData = malloc(iLen + 1);
         pszReturnData[0] = '\0';
         for (i = 0; i < nNum; i++)
             strcat(pszReturnData, ppList[i]);
@@ -413,7 +413,7 @@ Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
             XFreeStringList(ppList);
     }
     else {
-        pszReturnData = (char *) malloc(1);
+        pszReturnData = malloc(1);
         pszReturnData[0] = '\0';
     }
 
@@ -537,7 +537,7 @@ UpdateName(WMInfoPtr pWMInfo, Window iWindow)
             int iLen =
                 MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1, NULL, 0);
             wchar_t *pwszWideWindowName =
-                (wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1));
+                malloc(sizeof(wchar_t)*(iLen + 1));
             MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1,
                                 pwszWideWindowName, iLen);
 
@@ -1237,9 +1237,9 @@ winInitWM(void **ppWMInfo,
           pthread_mutex_t * ppmServerStarted,
           int dwScreen, HWND hwndScreen, BOOL allowOtherWM)
 {
-    WMProcArgPtr pArg = (WMProcArgPtr) malloc(sizeof(WMProcArgRec));
-    WMInfoPtr pWMInfo = (WMInfoPtr) malloc(sizeof(WMInfoRec));
-    XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc(sizeof(XMsgProcArgRec));
+    WMProcArgPtr pArg = malloc(sizeof(WMProcArgRec));
+    WMInfoPtr pWMInfo = malloc(sizeof(WMInfoRec));
+    XMsgProcArgPtr pXMsgArg = malloc(sizeof(XMsgProcArgRec));
 
     /* Bail if the input parameters are bad */
     if (pArg == NULL || pWMInfo == NULL || pXMsgArg == NULL) {
@@ -1432,7 +1432,7 @@ winSendMessageToWM(void *pWMInfo, winWMMessagePtr pMsg)
     ErrorF("winSendMessageToWM ()\n");
 #endif
 
-    pNode = (WMMsgNodePtr) malloc(sizeof(WMMsgNodeRec));
+    pNode = malloc(sizeof(WMMsgNodeRec));
     if (pNode != NULL) {
         memcpy(&pNode->msg, pMsg, sizeof(winWMMessageRec));
         PushMessage(&((WMInfoPtr) pWMInfo)->wmMsgQueue, pNode);
diff --git a/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c
index a2a5123..1859698 100644
--- a/hw/xwin/winnativegdi.c
+++ b/hw/xwin/winnativegdi.c
@@ -344,8 +344,7 @@ winCreateDIBNativeGDI(int iWidth, int iHeight, int iDepth,
     }
 
     /* Allocate bitmap info header */
-    pbmih = (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER)
-                                        + 256 * sizeof(RGBQUAD));
+    pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
     if (pbmih == NULL) {
         ErrorF("winCreateDIBNativeGDI - malloc () failed\n");
         return FALSE;
diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l
index 9af6103..fd13edc 100644
--- a/hw/xwin/winprefslex.l
+++ b/hw/xwin/winprefslex.l
@@ -45,7 +45,7 @@ extern void ErrorF (const char* /*f*/, ...);
 static char *makestr(char *str)
 {
   char *ptr;
-  ptr = (char*)malloc (strlen(str)+1);
+  ptr = malloc(strlen(str)+1);
   if (!ptr)
     {
       ErrorF ("winMultiWindowLex:makestr() out of memory\n");
diff --git a/hw/xwin/winprefsyacc.y b/hw/xwin/winprefsyacc.y
index 3b376b3..683fc44 100644
--- a/hw/xwin/winprefsyacc.y
+++ b/hw/xwin/winprefsyacc.y
@@ -311,10 +311,9 @@ static void
 AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param)
 {
   if (menu.menuItem==NULL)
-    menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM));
+    menu.menuItem = malloc(sizeof(MENUITEM));
   else
-    menu.menuItem = (MENUITEM*)
-      realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1));
+    menu.menuItem = realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1));
 
   strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX);
   menu.menuItem[menu.menuItems].text[MENU_MAX] = 0;
@@ -339,10 +338,9 @@ CloseMenu (void)
     }
   
   if (pref.menuItems)
-    pref.menu = (MENUPARSED*)
-      realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED));
+    pref.menu = realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED));
   else
-    pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED));
+    pref.menu = malloc (sizeof(MENUPARSED));
   
   memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED));
   pref.menuItems++;
@@ -365,10 +363,9 @@ static void
 AddIconLine (char *matchstr, char *iconfile)
 {
   if (pref.icon==NULL)
-    pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM));
+    pref.icon = malloc(sizeof(ICONITEM));
   else
-    pref.icon = (ICONITEM*)
-      realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1));
+    pref.icon = realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1));
 
   strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX);
   pref.icon[pref.iconItems].match[MENU_MAX] = 0;
@@ -401,10 +398,9 @@ static void
 AddStyleLine (char *matchstr, unsigned long style)
 {
   if (pref.style==NULL)
-    pref.style = (STYLEITEM*)malloc(sizeof(STYLEITEM));
+    pref.style = malloc(sizeof(STYLEITEM));
   else
-    pref.style = (STYLEITEM*)
-      realloc(pref.style, sizeof(STYLEITEM)*(pref.styleItems+1));
+    pref.style = realloc(pref.style, sizeof(STYLEITEM)*(pref.styleItems+1));
 
   strncpy(pref.style[pref.styleItems].match, matchstr, MENU_MAX);
   pref.style[pref.styleItems].match[MENU_MAX] = 0;
@@ -434,10 +430,9 @@ static void
 AddSysMenuLine (char *matchstr, char *menuname, int pos)
 {
   if (pref.sysMenu==NULL)
-    pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM));
+    pref.sysMenu = malloc(sizeof(SYSMENUITEM));
   else
-    pref.sysMenu = (SYSMENUITEM*)
-      realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1));
+    pref.sysMenu = realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1));
 
   strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX);
   pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0;
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index 2e3c64c..5c815eb 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -184,8 +184,7 @@ winQueryRGBBitsAndMasks(ScreenPtr pScreen)
     }
 
     /* Allocate a bitmap header and color table */
-    pbmih = (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER)
-                                        + 256 * sizeof(RGBQUAD));
+    pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
     if (pbmih == NULL) {
         ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
         return FALSE;
@@ -545,8 +544,7 @@ winInitScreenShadowGDI(ScreenPtr pScreen)
     pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen);
 
     /* Allocate bitmap info header */
-    pScreenPriv->pbmih = (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER)
-                                                     + 256 * sizeof(RGBQUAD));
+    pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
     if (pScreenPriv->pbmih == NULL) {
         ErrorF("winInitScreenShadowGDI - malloc () failed\n");
         return FALSE;
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 724976a..0b62696 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -184,8 +184,8 @@ InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv)
 
     /* Allocate bitmap info header */
     pRLWinPriv->pbmihShadow =
-        (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER)
-                                    + 256 * sizeof(RGBQUAD));
+        malloc(sizeof(BITMAPINFOHEADER)
+               + 256 * sizeof(RGBQUAD));
     if (pRLWinPriv->pbmihShadow == NULL) {
         ErrorF("InitWin32RootlessEngine - malloc () failed\n");
         return;
@@ -214,8 +214,7 @@ winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
              newX, newY, pFrame->width, pFrame->height);
 #endif
 
-    pRLWinPriv =
-        (win32RootlessWindowPtr) malloc(sizeof(win32RootlessWindowRec));
+    pRLWinPriv = malloc(sizeof(win32RootlessWindowRec));
     pRLWinPriv->pFrame = pFrame;
     pRLWinPriv->pfb = NULL;
     pRLWinPriv->hbmpShadow = NULL;
diff --git a/hw/xwin/winwindow.c b/hw/xwin/winwindow.c
index 759aa5e..8c1c28f 100644
--- a/hw/xwin/winwindow.c
+++ b/hw/xwin/winwindow.c
@@ -155,7 +155,7 @@ winCopyWindowNativeGDI(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     nbox = RegionNumRects(prgnDst);
 
     /* Allocate source points for each box */
-    if (!(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec))))
+    if (!(pptSrc = malloc(nbox * sizeof(DDXPointRec))))
         return;
 
     /* Set an iterator pointer */
diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c
index c3503db..2805ff7 100644
--- a/hw/xwin/winwindowswm.c
+++ b/hw/xwin/winwindowswm.c
@@ -162,7 +162,7 @@ ProcWindowsWMSelectInput(ClientPtr client)
         }
 
         /* build the entry */
-        pNewEvent = (WMEventPtr) malloc(sizeof(WMEventRec));
+        pNewEvent = malloc(sizeof(WMEventRec));
         if (!pNewEvent)
             return BadAlloc;
         pNewEvent->next = 0;
@@ -183,7 +183,7 @@ ProcWindowsWMSelectInput(ClientPtr client)
          * done through the resource database.
          */
         if (!pHead) {
-            pHead = (WMEventPtr *) malloc(sizeof(WMEventPtr));
+            pHead = malloc(sizeof(WMEventPtr));
             if (!pHead ||
                 !AddResource(eventResource, eventResourceType, (void *) pHead))
             {
commit 94f709cfce62e716f8d3adea388625850de71e78
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Feb 28 14:23:00 2014 +0000

    hw/xwin: Add missing FORCEEXIT token to XWin configuration file lexer
    
    Somehow this was left out of commmit f3fad371cce0f3836514ad5b29e59fa1ca0627a7
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l
index 15f7077..9af6103 100644
--- a/hw/xwin/winprefslex.l
+++ b/hw/xwin/winprefslex.l
@@ -90,6 +90,7 @@ ALWAYSONTOP             { return ALWAYSONTOP; }
 DEBUG                   { return DEBUGOUTPUT; }
 RELOAD                  { return RELOAD; }
 TRAYICON                { return TRAYICON; }
+FORCEEXIT		{ return FORCEEXIT; }
 SILENTEXIT		{ return SILENTEXIT; }
 "{"                     { return LB; }
 "}"                     { return RB; }
commit 6432d44020443bbda90bd46ffcb572b51be803a1
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Feb 28 14:21:46 2014 +0000

    hw/xwin: Silence bell when volume is zero
    
    Allow the bell to be turned off with X server option '-f 0', or by 'xset b off'.
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index b6b2086..3a75ab2 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -128,7 +128,7 @@ winKeybdBell(int iPercent, DeviceIntPtr pDeviceInt, void *pCtrl, int iClass)
      * sound on systems with a sound card or it will beep the PC speaker
      * on systems that do not have a sound card.
      */
-    MessageBeep(MB_OK);
+    if (iPercent > 0) MessageBeep(MB_OK);
 }
 
 /* Change some keyboard configuration parameters */
commit 7e37c4f727609d2d992ca46ffce56311c8d8225c
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Feb 28 14:21:06 2014 +0000

    hw/xwin: Fix typo in comment
    
    'i' before 'e' except after 'c'
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c
index 304e6df..157006d 100644
--- a/hw/xwin/winclipboardinit.c
+++ b/hw/xwin/winclipboardinit.c
@@ -77,7 +77,7 @@ winInitClipboard(void)
 }
 
 /*
- * Create the Windows window that we use to recieve Windows messages
+ * Create the Windows window that we use to receive Windows messages
  */
 
 HWND
commit d75195b62677f5b0f17bbe089b3aea5b295d5f2c
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Fri Feb 28 14:20:48 2014 +0000

    hw/xwin: Align parameter names in prototypes with definition
    
    A follow up to commits 2d9123fd, 451c5d91 and efe96a17, which changed the
    parameter name in the definition from index to i, to fix shadowing index() but
    didn't adjust the prototype declaration.
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 0adb227..80fc504 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -751,7 +751,7 @@ Bool
  winAllocatePrivates(ScreenPtr pScreen);
 
 Bool
- winInitCmapPrivates(ColormapPtr pCmap, int index);
+ winInitCmapPrivates(ColormapPtr pCmap, int i);
 
 Bool
  winAllocateCmapPrivates(ColormapPtr pCmap);
@@ -1056,12 +1056,12 @@ Bool
  winScreenInit(ScreenPtr pScreen, int argc, char **argv);
 
 Bool
- winFinishScreenInitFB(int index, ScreenPtr pScreen, int argc, char **argv);
+ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv);
 
 #if defined(XWIN_NATIVEGDI)
 Bool
 
-winFinishScreenInitNativeGDI(int index,
+winFinishScreenInitNativeGDI(int i,
                              ScreenPtr pScreen, int argc, char **argv);
 #endif
 
diff --git a/hw/xwin/winmonitors.h b/hw/xwin/winmonitors.h
index 8201e47..5fe3ecd 100644
--- a/hw/xwin/winmonitors.h
+++ b/hw/xwin/winmonitors.h
@@ -40,4 +40,4 @@ struct GetMonitorInfoData {
     HMONITOR monitorHandle;
 };
 
-Bool QueryMonitor(int index, struct GetMonitorInfoData *data);
+Bool QueryMonitor(int i, struct GetMonitorInfoData *data);
commit e53568e2c5004a434a16e3971fb2cd0823e6487b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Jan 1 16:43:38 2014 +0000

    hw/xwin: Just generate the WGL wrappers we need
    
    Just generate the WGL wrappers we need, rather than for everything in wgl.xml
    
    This avoids generating a lot of unused wrappers, and also avoids compilation
    requiring a wglext.h at least as new as wgl.xml
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py
index 683b9d9..cdbba63 100755
--- a/hw/xwin/glx/gen_gl_wrappers.py
+++ b/hw/xwin/glx/gen_gl_wrappers.py
@@ -43,35 +43,18 @@ thunkdefs=False
 staticwrappers=False
 nodebug=False
 
-#exclude base WGL API
-WinGDI={key: 1 for key in [
-     "wglCopyContext"
-    ,"wglCreateContext"
-    ,"wglCreateLayerContext"
-    ,"wglDeleteContext"
-    ,"wglGetCurrentContext"
-    ,"wglGetCurrentDC"
-    ,"wglGetProcAddress"
-    ,"wglMakeCurrent"
-    ,"wglShareLists"
-    ,"wglUseFontBitmapsA"
-    ,"wglUseFontBitmapsW"
-    ,"wglUseFontBitmaps"
-    ,"SwapBuffers"
-    ,"wglUseFontOutlinesA"
-    ,"wglUseFontOutlinesW"
-    ,"wglUseFontOutlines"
-    ,"wglDescribeLayerPlane"
-    ,"wglSetLayerPaletteEntries"
-    ,"wglGetLayerPaletteEntries"
-    ,"wglRealizeLayerPalette"
-    ,"wglSwapLayerBuffers"
-    ,"wglSwapMultipleBuffers"
-    ,"ChoosePixelFormat"
-    ,"DescribePixelFormat"
-    ,"GetEnhMetaFilePixelFormat"
-    ,"GetPixelFormat"
-    ,"SetPixelFormat"
+# list of WGL extension functions we use
+used_wgl_ext_fns = {key: 1 for key in [
+    "wglSwapIntervalEXT",
+    "wglGetExtensionsStringARB",
+    "wglDestroyPbufferARB",
+    "wglGetPbufferDCARB",
+    "wglReleasePbufferDCARB",
+    "wglCreatePbufferARB",
+    "wglMakeContextCurrentARB",
+    "wglChoosePixelFormatARB",
+    "wglGetPixelFormatAttribivARB",
+    "wglGetPixelFormatAttribivARB"
 ]}
 
 if __name__ == '__main__':
@@ -162,7 +145,7 @@ class PreResolveOutputGenerator(OutputGenerator):
     def genCmd(self, cmd, name):
         OutputGenerator.genCmd(self, cmd, name)
 
-        if name in WinGDI:
+        if prefix == 'wgl' and not name in used_wgl_ext_fns:
             return
 
         self.outFile.write('RESOLVE_DECL(PFN' + name.upper() + 'PROC);\n')
@@ -190,7 +173,7 @@ class WrapperOutputGenerator(OutputGenerator):
     def genCmd(self, cmd, name):
         OutputGenerator.genCmd(self, cmd, name)
 
-        if name in WinGDI:
+        if prefix == 'wgl' and not name in used_wgl_ext_fns:
             return
 
         proto=noneStr(cmd.elem.find('proto'))
commit dec5e9899bfee2a83f8a64f975790ecd2390256d
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Wed Apr 10 18:04:17 2013 +0100

    hw/xwin: Fix implicit-function-declaration warning in XwinExtensionInit() when compiled with XWIN_GLX_WINDOWS defined
    
    InitOutput.c: In function ‘XwinExtensionInit’:
    InitOutput.c:170:9: error: implicit declaration of function ‘glxWinPushNativeProvider’ [-Werror=implicit-function-declaration]
             glxWinPushNativeProvider();
             ^
    InitOutput.c:170:9: warning: nested extern declaration of ‘glxWinPushNativeProvider’ [-Wnested-externs]
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index b05ca27..9413350 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -58,8 +58,11 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
                                               HANDLE hToken,
                                               DWORD dwFlags, LPTSTR pszPath);
 #endif
-
 #include "glx_extinit.h"
+#ifdef XWIN_GLX_WINDOWS
+#include "glx/glwindows.h"
+#endif
+
 /*
  * References to external symbols
  */
commit caf1dec2a76fbbd21259fe4cc809e24a55ff79b4
Author: David Sodman <dsodman at chromium.org>
Date:   Mon Feb 10 09:07:33 2014 -0800

    V2: Add check for link from output to crtc before optimizing out a CrtcSet call
    
    The function RRCrtcSet call checks to see if the config being set is
    already configured, but, doesn't check that the selected outputs are
    connected to the crtc before skipping.  This means that the following
    sequence will omit the final CrtcSet call to the driver:
    
        CRTC c1 connect to output o
        CRTC c2 connect to output o
        CRTC c1 connect to output o
    
    This change adds the check to ensure that each of the calls are made to
    the driver.
    
    Signed-off-by: David Sodman <dsodman at chromium.org>
    Reviewed-by: Stéphane Marchesin <marcheu at chromium.org>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 6e181ba..6da698e 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -522,9 +522,19 @@ RRCrtcSet(RRCrtcPtr crtc,
     ScreenPtr pScreen = crtc->pScreen;
     Bool ret = FALSE;
     Bool recompute = TRUE;
+    Bool crtcChanged;
+    int  o;
 
     rrScrPriv(pScreen);
 
+    crtcChanged = FALSE;
+    for (o = 0; o < numOutputs; o++) {
+        if (outputs[o] && outputs[o]->crtc != crtc) {
+            crtcChanged = TRUE;
+            break;
+        }
+    }
+
     /* See if nothing changed */
     if (crtc->mode == mode &&
         crtc->x == x &&
@@ -532,7 +542,8 @@ RRCrtcSet(RRCrtcPtr crtc,
         crtc->rotation == rotation &&
         crtc->numOutputs == numOutputs &&
         !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
-        !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc)) {
+        !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
+        !crtcChanged) {
         recompute = FALSE;
         ret = TRUE;
     }
@@ -604,7 +615,6 @@ RRCrtcSet(RRCrtcPtr crtc,
 #endif
         }
         if (ret) {
-            int o;
 
             RRTellChanged(pScreen);
 
commit 249565a07d1d243e27440e2a5ecf4c95490903c6
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 23:13:51 2014 -0800

    Fix test/os to work on Solaris
    
    Due to bad decisions made decades ago at AT&T, on SVR4 OS'es the signal()
    function resets the signal handler before calling the signal handler
    (equivalent to sigaction flag SA_RESETHAND).  This is why the X server
    has a OsSignal() helper function in os/utils.c that uses the portable
    POSIX sigaction function to provide BSD/Linux semantics in a signal()
    style API, so we switch to use that in this test case, allowing it to
    pass on Solaris.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/os.c b/test/os.c
index 2d005a0..d85dcff 100644
--- a/test/os.c
+++ b/test/os.c
@@ -150,10 +150,10 @@ static void block_sigio_test_nested(void)
        tail guard must be hit.
      */
     void (*old_handler)(int);
-    old_handler = signal(SIGIO, sighandler);
+    old_handler = OsSignal(SIGIO, sighandler);
     expect_signal = 1;
     assert(raise(SIGIO) == 0);
-    assert(signal(SIGIO, old_handler) == sighandler);
+    assert(OsSignal(SIGIO, old_handler) == sighandler);
 #endif
 }
 
commit 0031f6b073c7a4cca553c1d3e185a63436a75cbe
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 23:13:50 2014 -0800

    Fix test/signal-logging to work on Solaris
    
    For some reason, Solaris libc sprintf() doesn't add "0x" to the %p output
    as glibc does, causing the test to fail for not matching the exact output.
    Since the 0x is desirable, we add it ourselves to the test string.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/signal-logging.c b/test/signal-logging.c
index d894373..88b37c1 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -346,7 +346,11 @@ static void logging_format(void)
     ptr = 1;
     do {
         char expected[30];
+#ifdef __sun /* Solaris doesn't autoadd "0x" to %p format */
+        sprintf(expected, "(EE) 0x%p\n", (void*)ptr);
+#else
         sprintf(expected, "(EE) %p\n", (void*)ptr);
+#endif
         LogMessageVerbSigSafe(X_ERROR, -1, "%p\n", (void*)ptr);
         read_log_msg(logmsg);
         assert(strcmp(logmsg, expected) == 0);
commit e67f2d7e0f9189beb2907fa06cff5ecc7f35f922
Author: Matthieu Herrb <matthieu.herrb at laas.fr>
Date:   Sun Feb 9 11:20:59 2014 +0100

    gcc 4.2.1 doesn't support #pragma GCC diagnostic ignored
    
    Signed-off-by: Matthieu Herrb <matthieu at herrb.eu>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/log.c b/os/log.c
index 8deb810..38193ee 100644
--- a/os/log.c
+++ b/os/log.c
@@ -195,7 +195,9 @@ LogInit(const char *fname, const char *backup)
     char *logFileName = NULL;
 
     if (fname && *fname) {
+#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 2
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
         if (asprintf(&logFileName, fname, display) == -1)
             FatalError("Cannot allocate space for the log file name\n");
 
@@ -206,7 +208,9 @@ LogInit(const char *fname, const char *backup)
                 char *suffix;
                 char *oldLog;
 
+#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 2
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
                 if ((asprintf(&suffix, backup, display) == -1) ||
                     (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1))
                     FatalError("Cannot allocate space for the log file name\n");
commit 1940508a4af33d44a7a8ef24bbdcd1e31e228dab
Merge: c85ea92 ddeca92
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Feb 24 16:27:52 2014 -0800

    Merge remote-tracking branch 'herrb/master'

commit c85ea92af145c98a4a3fc6cf7b9eac796a48cc2e
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Feb 24 09:51:39 2014 -0800

    Bump to 1.15.99.901
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 4859dae..0fb2fc3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.15.99.900, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2014-01-09"
-RELEASE_NAME="Golden Gaytime"
+AC_INIT([xorg-server], 1.15.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2014-02-24"
+RELEASE_NAME="Szechuan Hot Pot"
 AC_CONFIG_SRCDIR([Makefile.am])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
commit 0840a303c47b9b10ba8e24e62956da0f1675e963
Merge: 0f10cfd 3d71df4
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Feb 24 09:40:23 2014 -0800

    Merge remote-tracking branch 'anholt/glamor-pull-request'

commit 0f10cfd4b903d4db293ec47c8a9a0d8b33965803
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 20 13:18:05 2014 +1000

    Xi: check for invalid modifiers for XI2 passive grabs
    
    The other values are checked correctly, but if a modifier was outside the
    allowed range, it would go unnoticed and cause a out-of-bounds read error for
    any mask equal or larger than 256. The DetailRec where we store the grab masks
    is only sized to 8 * sizeof(Mask).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4ed58ee..e9f670e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -2183,7 +2183,8 @@ CheckGrabValues(ClientPtr client, GrabParameters *param)
         return BadValue;
     }
 
-    if (param->grabtype != XI2 && (param->modifiers != AnyModifier) &&
+    if (param->modifiers != AnyModifier &&
+        param->modifiers != XIAnyModifier &&
         (param->modifiers & ~AllModifiersMask)) {
         client->errorValue = param->modifiers;
         return BadValue;
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 8aba977..700622d 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -189,6 +189,10 @@ ProcXIPassiveGrabDevice(ClientPtr client)
         uint8_t status = Success;
 
         param.modifiers = *modifiers;
+        ret = CheckGrabValues(client, &param);
+        if (ret != Success)
+            goto out;
+
         switch (stuff->grab_type) {
         case XIGrabtypeButton:
             status = GrabButton(client, dev, mod_dev, stuff->detail,
commit ec6a44612565e0716bd5b2e2b80a8d381691feb6
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Wed Feb 19 13:48:06 2014 -0500

    test: remove source file from hashtabletest LDADD
    
    LDADD is for libraries and not for source code.
    
    Introduced in commit: 	ccb3e78124fb05defd0c9b438746b79d84dfc3ae
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/Makefile.am b/test/Makefile.am
index 2852bb3..f8aa659 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -36,7 +36,7 @@ fixes_LDADD=$(TEST_LDADD)
 xfree86_LDADD=$(TEST_LDADD)
 touch_LDADD=$(TEST_LDADD)
 signal_logging_LDADD=$(TEST_LDADD)
-hashtabletest_LDADD=$(TEST_LDADD) $(top_srcdir)/Xext/hashtable.c
+hashtabletest_LDADD=$(TEST_LDADD)
 os_LDADD=$(TEST_LDADD)
 
 libxservertest_la_LIBADD = $(XSERVER_LIBS)
commit 31b0be69e5eea3d1c82d6610bd37bbdb4dca779c
Author: Thierry Reding <treding at nvidia.com>
Date:   Wed Feb 19 17:16:48 2014 +0100

    test/input: Fix alignment assertion for doubles
    
    The code previously tried to compute the offset of a field in the
    valuator by subtracting the address of the valuator from the _value_ of
    the field (rather than the field's address). The correct way to do it
    would have been (note the &'s):
    
    	assert(((void *) &v->axisVal - (void *) v) % sizeof(double) == 0);
    	assert(((void *) &v->axes - (void *) v) % sizeof(double) == 0);
    
    That's essentially what the offsetof() macro does. Using offsetof() has
    the added benefit of not using void pointer arithmetic and therefore
    silencing a warning on some compilers.
    
    Signed-off-by: Thierry Reding <treding at nvidia.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/input.c b/test/input.c
index 5813e6d..9b5db89 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1390,8 +1390,8 @@ dix_valuator_alloc(void)
         assert(v->numAxes == num_axes);
 #if !defined(__i386__) && !defined(__m68k__) && !defined(__sh__)
         /* must be double-aligned on 64 bit */
-        assert(((void *) v->axisVal - (void *) v) % sizeof(double) == 0);
-        assert(((void *) v->axes - (void *) v) % sizeof(double) == 0);
+        assert(offsetof(struct _ValuatorClassRec, axisVal) % sizeof(double) == 0);
+        assert(offsetof(struct _ValuatorClassRec, axes) % sizeof(double) == 0);
 #endif
         num_axes++;
     }
commit 9368bdec1d37127e97411b684f0b1fce5ee97907
Author: Laércio de Sousa <lbsousajr at gmail.com>
Date:   Mon Feb 17 08:43:49 2014 +1000

    Get rid of config/non-seat0.conf.multi-seat
    
    This file is deprecated by commits c73c36b53 and 46cf2a6093.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/config/Makefile.am b/config/Makefile.am
index c6350be..0e20e8b 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -38,4 +38,4 @@ endif # !CONFIG_HAL
 
 endif # !CONFIG_UDEV
 
-EXTRA_DIST = x11-input.fdi 10-evdev.conf non-seat0.conf.multi-seat fdi2iclass.py 10-quirks.conf
+EXTRA_DIST = x11-input.fdi 10-evdev.conf fdi2iclass.py 10-quirks.conf
diff --git a/config/non-seat0.conf.multi-seat b/config/non-seat0.conf.multi-seat
deleted file mode 100644
index 34008ce..0000000
--- a/config/non-seat0.conf.multi-seat
+++ /dev/null
@@ -1,18 +0,0 @@
-# This is the default configuration for servers on seat-1 and above.
-#
-# Start the server with -config non-seat0.conf.multi-seat, or alternatively
-# rename the file to end in .conf and put it in the standard config
-# directory (though it will apply to _all_ seats!).
-#
-# * Disable VT switching with Ctrl-Alt-F1
-# * Force a grab on all input devices to detach them from the VT subsystem
-#   to avoid event leakage.
-
-Section "ServerFlags"
-        Option "DontVTSwitch" "on"
-EndSection
-
-Section "InputClass"
-        Identifier "Force input devices to seat"
-        Option "GrabDevice" "on"
-EndSection
commit 3d71df48e70884deccb293cf1fcffbdba8efd94b
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 14:21:05 2013 -0800

    glamor: Move the EGL DRI3 code to GLAMOR_HAS_GBM.
    
    There's nothing dependent on the presence of DRI3 code in the server
    for this, but it does rely on GBM.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 81e697b..9dcba71 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -190,7 +190,7 @@ glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
     EGLImageKHR image;
     GLuint texture;
 
-#ifdef GLAMOR_HAS_DRI3_SUPPORT
+#ifdef GLAMOR_HAS_GBM
     struct gbm_bo *bo;
     EGLNativePixmapType native_pixmap;
 
@@ -356,7 +356,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
     return ret;
 }
 
-#ifdef GLAMOR_HAS_DRI3_SUPPORT
+#ifdef GLAMOR_HAS_GBM
 int glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd);
 void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name);
 int
@@ -391,7 +391,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
                                  unsigned int tex,
                                  Bool want_name, CARD16 *stride, CARD32 *size)
 {
-#ifdef GLAMOR_HAS_DRI3_SUPPORT
+#ifdef GLAMOR_HAS_GBM
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_screen_private *glamor_priv =
         glamor_get_screen_private(screen);
@@ -460,7 +460,7 @@ glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
                                CARD16 height,
                                CARD16 stride, CARD8 depth, CARD8 bpp)
 {
-#ifdef GLAMOR_HAS_DRI3_SUPPORT
+#ifdef GLAMOR_HAS_GBM
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_egl_screen_private *glamor_egl;
     struct gbm_bo *bo;
@@ -735,7 +735,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
                                 KHR_surfaceless_opengl);
 #endif
 
-#ifdef GLAMOR_HAS_DRI3_SUPPORT
+#ifdef GLAMOR_HAS_GBM
     if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
         glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import"))
         glamor_egl->dri3_capable = TRUE;
commit 80cdbb20f9dcdfdf3e77ecf5cdd7dfb1a87d1a83
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 13:21:21 2013 -0800

    glamor: Fix linking of the gradient shaders on GLES2.
    
    GLES2 sensibly doesn't allow you to attach multiple shaders for the
    same stage to a single program.  This means we have to attach the
    whole thing in one glShaderSource call.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 9ecaf03..9f6f1b1 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -42,14 +42,13 @@
 
 #ifdef GLAMOR_GRADIENT_SHADER
 
-static GLint
-_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
-                                   int use_array)
+static const char *
+_glamor_create_getcolor_fs_source(ScreenPtr screen, int stops_count,
+                                  int use_array)
 {
     glamor_screen_private *glamor_priv;
 
     char *gradient_fs = NULL;
-    GLint fs_getcolor_prog;
 
 #define gradient_fs_getcolor\
 	    GLAMOR_DEFAULT_PRECISION\
@@ -181,17 +180,11 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
     if (use_array) {
         XNFasprintf(&gradient_fs,
                     gradient_fs_getcolor, stops_count, stops_count);
-        fs_getcolor_prog =
-            glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
-        free(gradient_fs);
+        return gradient_fs;
     }
     else {
-        fs_getcolor_prog =
-            glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
-                                     gradient_fs_getcolor_no_array);
+        return XNFstrdup(gradient_fs_getcolor_no_array);
     }
-
-    return fs_getcolor_prog;
 }
 
 static void
@@ -203,7 +196,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
 
     GLint gradient_prog = 0;
     char *gradient_fs = NULL;
-    GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+    GLint fs_prog, vs_prog;
 
     const char *gradient_vs =
         GLAMOR_DEFAULT_PRECISION
@@ -344,7 +337,10 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
 	    "    } else {\n"\
 	    "        gl_FragColor = get_color(stop_len);\n"\
 	    "    }\n"\
-	    "}\n"
+	    "}\n"\
+	    "\n"\
+            "%s\n" /* fs_getcolor_source */
+    const char *fs_getcolor_source;
 
     glamor_priv = glamor_get_screen_private(screen);
 
@@ -364,25 +360,24 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
 
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs);
 
+    fs_getcolor_source =
+        _glamor_create_getcolor_fs_source(screen, stops_count,
+                                          (stops_count > 0));
+
     XNFasprintf(&gradient_fs,
                 gradient_radial_fs_template,
                 PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL,
-                PIXMAN_REPEAT_REFLECT);
+                PIXMAN_REPEAT_REFLECT,
+                fs_getcolor_source);
 
-    fs_main_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
 
     free(gradient_fs);
 
-    fs_getcolor_prog =
-        _glamor_create_getcolor_fs_program(screen, stops_count,
-                                           (stops_count > 0));
-
     glAttachShader(gradient_prog, vs_prog);
-    glAttachShader(gradient_prog, fs_getcolor_prog);
-    glAttachShader(gradient_prog, fs_main_prog);
+    glAttachShader(gradient_prog, fs_prog);
     glDeleteShader(vs_prog);
-    glDeleteShader(fs_getcolor_prog);
-    glDeleteShader(fs_main_prog);
+    glDeleteShader(fs_prog);
 
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
@@ -416,7 +411,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
     int index = 0;
     GLint gradient_prog = 0;
     char *gradient_fs = NULL;
-    GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+    GLint fs_prog, vs_prog;
 
     const char *gradient_vs =
         GLAMOR_DEFAULT_PRECISION
@@ -559,7 +554,10 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
 	    "{\n"\
 	    "    float stop_len = get_stop_len();\n"\
 	    "    gl_FragColor = get_color(stop_len);\n"\
-	    "}\n"
+	    "}\n"\
+	    "\n"\
+            "%s" /* fs_getcolor_source */
+    const char *fs_getcolor_source;
 
     glamor_priv = glamor_get_screen_private(screen);
 
@@ -578,23 +576,21 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
 
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs);
 
+    fs_getcolor_source =
+        _glamor_create_getcolor_fs_source(screen, stops_count, stops_count > 0);
+
     XNFasprintf(&gradient_fs,
                 gradient_fs_template,
-                PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+                PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT,
+                fs_getcolor_source);
 
-    fs_main_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
     free(gradient_fs);
 
-    fs_getcolor_prog =
-        _glamor_create_getcolor_fs_program(screen, stops_count,
-                                           (stops_count > 0));
-
     glAttachShader(gradient_prog, vs_prog);
-    glAttachShader(gradient_prog, fs_getcolor_prog);
-    glAttachShader(gradient_prog, fs_main_prog);
+    glAttachShader(gradient_prog, fs_prog);
     glDeleteShader(vs_prog);
-    glDeleteShader(fs_getcolor_prog);
-    glDeleteShader(fs_main_prog);
+    glDeleteShader(fs_prog);
 
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
commit 76bd0f994959f30a37d41eaf06f43f23c3b23faf
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 13:09:25 2013 -0800

    glamor: Don't bother keeping references to shader stages for gradients.
    
    They never get reattached to any other program, so saving them to
    unreference later is a waste of code.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 9460199..9ecaf03 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -356,20 +356,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
     glamor_get_context(glamor_priv);
 
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
-        glDeleteShader(glamor_priv->radial_gradient_shaders
-                       [SHADER_GRADIENT_VS_PROG][2]);
-        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-        glDeleteShader(glamor_priv->radial_gradient_shaders
-                       [SHADER_GRADIENT_FS_MAIN_PROG][2]);
-        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
-            0;
-
-        glDeleteShader(glamor_priv->radial_gradient_shaders
-                       [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-        glamor_priv->
-            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
         glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
         glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
     }
@@ -394,6 +380,9 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
     glAttachShader(gradient_prog, vs_prog);
     glAttachShader(gradient_prog, fs_getcolor_prog);
     glAttachShader(gradient_prog, fs_main_prog);
+    glDeleteShader(vs_prog);
+    glDeleteShader(fs_getcolor_prog);
+    glDeleteShader(fs_main_prog);
 
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
@@ -414,13 +403,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
     }
 
     glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
-    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] =
-        vs_prog;
-    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] =
-        fs_main_prog;
-    glamor_priv->
-        radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
-        fs_getcolor_prog;
 
     glamor_put_context(glamor_priv);
 }
@@ -588,20 +570,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
 
     glamor_get_context(glamor_priv);
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
-        glDeleteShader(glamor_priv->linear_gradient_shaders
-                       [SHADER_GRADIENT_VS_PROG][2]);
-        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-        glDeleteShader(glamor_priv->linear_gradient_shaders
-                       [SHADER_GRADIENT_FS_MAIN_PROG][2]);
-        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
-            0;
-
-        glDeleteShader(glamor_priv->linear_gradient_shaders
-                       [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-        glamor_priv->
-            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
         glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
         glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
     }
@@ -624,6 +592,9 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
     glAttachShader(gradient_prog, vs_prog);
     glAttachShader(gradient_prog, fs_getcolor_prog);
     glAttachShader(gradient_prog, fs_main_prog);
+    glDeleteShader(vs_prog);
+    glDeleteShader(fs_getcolor_prog);
+    glDeleteShader(fs_main_prog);
 
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
@@ -644,13 +615,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
     }
 
     glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
-    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] =
-        vs_prog;
-    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] =
-        fs_main_prog;
-    glamor_priv->
-        linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
-        fs_getcolor_prog;
 
     glamor_put_context(glamor_priv);
 }
@@ -665,18 +629,7 @@ glamor_init_gradient_shader(ScreenPtr screen)
 
     for (i = 0; i < 3; i++) {
         glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
-        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] =
-            0;
-        glamor_priv->
-            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
-
         glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
-        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] =
-            0;
-        glamor_priv->
-            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
     }
     glamor_priv->linear_max_nstops = 0;
     glamor_priv->radial_max_nstops = 0;
@@ -699,39 +652,10 @@ glamor_fini_gradient_shader(ScreenPtr screen)
 
     for (i = 0; i < 3; i++) {
         /* Linear Gradient */
-        if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-            glDeleteShader(glamor_priv->linear_gradient_shaders
-                           [SHADER_GRADIENT_VS_PROG][i]);
-
-        if (glamor_priv->
-            linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-            glDeleteShader(glamor_priv->linear_gradient_shaders
-                           [SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-        if (glamor_priv->
-            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-            glDeleteShader(glamor_priv->linear_gradient_shaders
-                           [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
         if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
             glDeleteProgram(glamor_priv->gradient_prog
                             [SHADER_GRADIENT_LINEAR][i]);
 
-        /* Radial Gradient */
-        if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-            glDeleteShader(glamor_priv->radial_gradient_shaders
-                           [SHADER_GRADIENT_VS_PROG][i]);
-
-        if (glamor_priv->
-            radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-            glDeleteShader(glamor_priv->radial_gradient_shaders
-                           [SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-        if (glamor_priv->
-            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-            glDeleteShader(glamor_priv->radial_gradient_shaders
-                           [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
         if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
             glDeleteProgram(glamor_priv->gradient_prog
                             [SHADER_GRADIENT_RADIAL][i]);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index e28a021..fe4b423 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -141,13 +141,6 @@ enum gradient_shader {
     SHADER_GRADIENT_COUNT,
 };
 
-enum gradient_shader_prog {
-    SHADER_GRADIENT_VS_PROG,
-    SHADER_GRADIENT_FS_MAIN_PROG,
-    SHADER_GRADIENT_FS_GETCOLOR_PROG,
-    SHADER_GRADIENT_PROG_COUNT,
-};
-
 struct glamor_screen_private;
 struct glamor_pixmap_private;
 
@@ -251,9 +244,7 @@ typedef struct glamor_screen_private {
     /* glamor gradient, 0 for small nstops, 1 for
        large nstops and 2 for dynamic generate. */
     GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
-    GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
     int linear_max_nstops;
-    GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
     int radial_max_nstops;
 
     /* glamor trapezoid shader. */
commit 6e62cdf66d2f0baa4a26eff6f4917f73baf3b008
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 11:29:27 2013 -0800

    glamor: Fix typo in setting v_position's attrib location.
    
    Assuming it was the first attribute assigned by the GL, it would have
    ended up with location 0 anyway.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 4ea441e..9460199 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -395,7 +395,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
     glAttachShader(gradient_prog, fs_getcolor_prog);
     glAttachShader(gradient_prog, fs_main_prog);
 
-    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
+    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
     glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
 
     glamor_link_glsl_prog(gradient_prog);
commit f8d384fa8f0fa2a3ac04c4ad21fb04400490e8e6
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 02:13:27 2013 -0800

    glamor: Move shader precision stuff from build time to shader compile time.
    
    This is the last desktop-versus-ES2 build ifdef in core glamor.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 81b46b6..e28a021 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -37,11 +37,10 @@
 
 #include <epoxy/gl.h>
 
-#ifdef GLAMOR_GLES2
-#define GLAMOR_DEFAULT_PRECISION   "precision mediump float;\n"
-#else
-#define GLAMOR_DEFAULT_PRECISION
-#endif
+#define GLAMOR_DEFAULT_PRECISION  \
+    "#ifdef GL_ES\n"              \
+    "precision mediump float;\n"  \
+    "#endif\n"
 
 #ifdef RENDER
 #include "glyphstr.h"
commit 1adac62a7d9da099c779e65527ece611cf4d2f2c
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 02:10:53 2013 -0800

    glamor: Unifdef the picture-format-to-format-and-type functions.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 1dbeb04..77197b5 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -194,14 +194,13 @@ glamor_set_alu(ScreenPtr screen, unsigned char alu)
  *
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
-#ifndef GLAMOR_GLES2
 static int
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-                                           GLenum *tex_format,
-                                           GLenum *tex_type,
-                                           int *no_alpha,
-                                           int *revert,
-                                           int *swap_rb, int is_upload)
+glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
+                                              GLenum *tex_format,
+                                              GLenum *tex_type,
+                                              int *no_alpha,
+                                              int *revert,
+                                              int *swap_rb, int is_upload)
 {
     *no_alpha = 0;
     *revert = REVERT_NONE;
@@ -291,16 +290,15 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     return 0;
 }
 
-#else
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
 static int
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-                                           GLenum *tex_format,
-                                           GLenum *tex_type,
-                                           int *no_alpha,
-                                           int *revert,
-                                           int *swap_rb, int is_upload)
+glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format,
+                                                 GLenum *tex_format,
+                                                 GLenum *tex_type,
+                                                 int *no_alpha,
+                                                 int *revert,
+                                                 int *swap_rb, int is_upload)
 {
     int need_swap_rb = 0;
 
@@ -463,8 +461,6 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     return 0;
 }
 
-#endif
-
 static int
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
                                        GLenum *format,
@@ -474,6 +470,8 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
 {
     glamor_pixmap_private *pixmap_priv;
     PictFormatShort pict_format;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
@@ -481,11 +479,21 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
     else
         pict_format = format_for_depth(pixmap->drawable.depth);
 
-    return glamor_get_tex_format_type_from_pictformat(pict_format,
-                                                      format, type,
-                                                      no_alpha,
-                                                      revert,
-                                                      swap_rb, is_upload);
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        return glamor_get_tex_format_type_from_pictformat_gl(pict_format,
+                                                             format, type,
+                                                             no_alpha,
+                                                             revert,
+                                                             swap_rb,
+                                                             is_upload);
+    } else {
+        return glamor_get_tex_format_type_from_pictformat_gles2(pict_format,
+                                                                format, type,
+                                                                no_alpha,
+                                                                revert,
+                                                                swap_rb,
+                                                                is_upload);
+    }
 }
 
 static void *
commit 3747c260816a36352bb91ce06befcbffbbd747c7
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 16:12:15 2013 -0800

    glamor: Move glamor_get_tex_format_type_from_pictformat to a .c file.
    
    A pair of 150 lines of inlined switch statements in a header file is
    crazy.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 30aeebe..1dbeb04 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -185,6 +185,309 @@ glamor_set_alu(ScreenPtr screen, unsigned char alu)
     return TRUE;
 }
 
+/*
+ * Map picture's format to the correct gl texture format and type.
+ * no_alpha is used to indicate whehter we need to wire alpha to 1.
+ *
+ * Although opengl support A1/GL_BITMAP, we still don't use it
+ * here, it seems that mesa has bugs when uploading a A1 bitmap.
+ *
+ * Return 0 if find a matched texture type. Otherwise return -1.
+ **/
+#ifndef GLAMOR_GLES2
+static int
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+                                           GLenum *tex_format,
+                                           GLenum *tex_type,
+                                           int *no_alpha,
+                                           int *revert,
+                                           int *swap_rb, int is_upload)
+{
+    *no_alpha = 0;
+    *revert = REVERT_NONE;
+    *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+    switch (format) {
+    case PICT_a1:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        break;
+    case PICT_b8g8r8x8:
+        *no_alpha = 1;
+    case PICT_b8g8r8a8:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+        break;
+
+    case PICT_x8r8g8b8:
+        *no_alpha = 1;
+    case PICT_a8r8g8b8:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        break;
+    case PICT_x8b8g8r8:
+        *no_alpha = 1;
+    case PICT_a8b8g8r8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        break;
+    case PICT_x2r10g10b10:
+        *no_alpha = 1;
+    case PICT_a2r10g10b10:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        break;
+    case PICT_x2b10g10r10:
+        *no_alpha = 1;
+    case PICT_a2b10g10r10:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        break;
+
+    case PICT_r5g6b5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case PICT_b5g6r5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+        break;
+    case PICT_x1b5g5r5:
+        *no_alpha = 1;
+    case PICT_a1b5g5r5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        break;
+
+    case PICT_x1r5g5b5:
+        *no_alpha = 1;
+    case PICT_a1r5g5b5:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        break;
+    case PICT_a8:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        break;
+    case PICT_x4r4g4b4:
+        *no_alpha = 1;
+    case PICT_a4r4g4b4:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        break;
+
+    case PICT_x4b4g4r4:
+        *no_alpha = 1;
+    case PICT_a4b4g4r4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        break;
+
+    default:
+        LogMessageVerb(X_INFO, 0,
+                       "fail to get matched format for %x \n", format);
+        return -1;
+    }
+    return 0;
+}
+
+#else
+#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
+
+static int
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+                                           GLenum *tex_format,
+                                           GLenum *tex_type,
+                                           int *no_alpha,
+                                           int *revert,
+                                           int *swap_rb, int is_upload)
+{
+    int need_swap_rb = 0;
+
+    *no_alpha = 0;
+    *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+    switch (format) {
+    case PICT_b8g8r8x8:
+        *no_alpha = 1;
+    case PICT_b8g8r8a8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        need_swap_rb = 1;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        break;
+
+    case PICT_x8r8g8b8:
+        *no_alpha = 1;
+    case PICT_a8r8g8b8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_x8b8g8r8:
+        *no_alpha = 1;
+    case PICT_a8b8g8r8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        break;
+
+    case PICT_x2r10g10b10:
+        *no_alpha = 1;
+    case PICT_a2r10g10b10:
+        *tex_format = GL_RGBA;
+        /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
+         * we have to use GL_UNSIGNED_BYTE and do the conversion in
+         * shader latter.*/
+        *tex_type = GL_UNSIGNED_BYTE;
+        if (is_upload == 1) {
+            if (!IS_LITTLE_ENDIAN)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+        }
+        else {
+            if (!IS_LITTLE_ENDIAN) {
+                *revert = REVERT_DOWNLOADING_10_10_10_2;
+            }
+            else {
+                *revert = REVERT_DOWNLOADING_2_10_10_10;
+            }
+        }
+        need_swap_rb = 1;
+
+        break;
+
+    case PICT_x2b10g10r10:
+        *no_alpha = 1;
+    case PICT_a2b10g10r10:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        if (is_upload == 1) {
+            if (!IS_LITTLE_ENDIAN)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+        }
+        else {
+            if (!IS_LITTLE_ENDIAN) {
+                *revert = REVERT_DOWNLOADING_10_10_10_2;
+            }
+            else {
+                *revert = REVERT_DOWNLOADING_2_10_10_10;
+            }
+        }
+        break;
+
+    case PICT_r5g6b5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+        break;
+
+    case PICT_b5g6r5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
+        break;
+
+    case PICT_x1b5g5r5:
+        *no_alpha = 1;
+    case PICT_a1b5g5r5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+        if (IS_LITTLE_ENDIAN) {
+            *revert =
+                is_upload ? REVERT_UPLOADING_1_5_5_5 :
+                REVERT_DOWNLOADING_1_5_5_5;
+        }
+        else
+            *revert = REVERT_NONE;
+        break;
+
+    case PICT_x1r5g5b5:
+        *no_alpha = 1;
+    case PICT_a1r5g5b5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+        if (IS_LITTLE_ENDIAN) {
+            *revert =
+                is_upload ? REVERT_UPLOADING_1_5_5_5 :
+                REVERT_DOWNLOADING_1_5_5_5;
+        }
+        else
+            *revert = REVERT_NONE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_a1:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        break;
+
+    case PICT_a8:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = REVERT_NONE;
+        break;
+
+    case PICT_x4r4g4b4:
+        *no_alpha = 1;
+    case PICT_a4r4g4b4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_x4b4g4r4:
+        *no_alpha = 1;
+    case PICT_a4b4g4r4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        break;
+
+    default:
+        LogMessageVerb(X_INFO, 0,
+                       "fail to get matched format for %x \n", format);
+        return -1;
+    }
+
+    if (need_swap_rb)
+        *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
+    else
+        *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+    return 0;
+}
+
+#endif
+
+static int
+glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
+                                       GLenum *format,
+                                       GLenum *type,
+                                       int *no_alpha,
+                                       int *revert, int *swap_rb, int is_upload)
+{
+    glamor_pixmap_private *pixmap_priv;
+    PictFormatShort pict_format;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+        pict_format = pixmap_priv->base.picture->format;
+    else
+        pict_format = format_for_depth(pixmap->drawable.depth);
+
+    return glamor_get_tex_format_type_from_pictformat(pict_format,
+                                                      format, type,
+                                                      no_alpha,
+                                                      revert,
+                                                      swap_rb, is_upload);
+}
+
 static void *
 _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
                             int stride, int revert)
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 3de6133..9374c9d 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -914,286 +914,6 @@ format_for_pixmap(PixmapPtr pixmap)
 #define SWAP_UPLOADING	  	2
 #define SWAP_NONE_UPLOADING	3
 
-/*
- * Map picture's format to the correct gl texture format and type.
- * no_alpha is used to indicate whehter we need to wire alpha to 1.
- *
- * Although opengl support A1/GL_BITMAP, we still don't use it
- * here, it seems that mesa has bugs when uploading a A1 bitmap.
- *
- * Return 0 if find a matched texture type. Otherwise return -1.
- **/
-#ifndef GLAMOR_GLES2
-static inline int
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-                                           GLenum * tex_format,
-                                           GLenum * tex_type,
-                                           int *no_alpha,
-                                           int *revert,
-                                           int *swap_rb, int is_upload)
-{
-    *no_alpha = 0;
-    *revert = REVERT_NONE;
-    *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
-    switch (format) {
-    case PICT_a1:
-        *tex_format = GL_ALPHA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
-        break;
-    case PICT_b8g8r8x8:
-        *no_alpha = 1;
-    case PICT_b8g8r8a8:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8;
-        break;
-
-    case PICT_x8r8g8b8:
-        *no_alpha = 1;
-    case PICT_a8r8g8b8:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        break;
-    case PICT_x8b8g8r8:
-        *no_alpha = 1;
-    case PICT_a8b8g8r8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-        break;
-    case PICT_x2r10g10b10:
-        *no_alpha = 1;
-    case PICT_a2r10g10b10:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-        break;
-    case PICT_x2b10g10r10:
-        *no_alpha = 1;
-    case PICT_a2b10g10r10:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-        break;
-
-    case PICT_r5g6b5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        break;
-    case PICT_b5g6r5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
-        break;
-    case PICT_x1b5g5r5:
-        *no_alpha = 1;
-    case PICT_a1b5g5r5:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-        break;
-
-    case PICT_x1r5g5b5:
-        *no_alpha = 1;
-    case PICT_a1r5g5b5:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-        break;
-    case PICT_a8:
-        *tex_format = GL_ALPHA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        break;
-    case PICT_x4r4g4b4:
-        *no_alpha = 1;
-    case PICT_a4r4g4b4:
-        *tex_format = GL_BGRA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-        break;
-
-    case PICT_x4b4g4r4:
-        *no_alpha = 1;
-    case PICT_a4b4g4r4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-        break;
-
-    default:
-        LogMessageVerb(X_INFO, 0,
-                       "fail to get matched format for %x \n", format);
-        return -1;
-    }
-    return 0;
-}
-
-#else
-#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
-
-static inline int
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-                                           GLenum * tex_format,
-                                           GLenum * tex_type,
-                                           int *no_alpha,
-                                           int *revert,
-                                           int *swap_rb, int is_upload)
-{
-    int need_swap_rb = 0;
-
-    *no_alpha = 0;
-    *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
-    switch (format) {
-    case PICT_b8g8r8x8:
-        *no_alpha = 1;
-    case PICT_b8g8r8a8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        need_swap_rb = 1;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-        break;
-
-    case PICT_x8r8g8b8:
-        *no_alpha = 1;
-    case PICT_a8r8g8b8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        need_swap_rb = 1;
-        break;
-
-    case PICT_x8b8g8r8:
-        *no_alpha = 1;
-    case PICT_a8b8g8r8:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        break;
-
-    case PICT_x2r10g10b10:
-        *no_alpha = 1;
-    case PICT_a2r10g10b10:
-        *tex_format = GL_RGBA;
-        /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
-         * we have to use GL_UNSIGNED_BYTE and do the conversion in
-         * shader latter.*/
-        *tex_type = GL_UNSIGNED_BYTE;
-        if (is_upload == 1) {
-            if (!IS_LITTLE_ENDIAN)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-        }
-        else {
-            if (!IS_LITTLE_ENDIAN) {
-                *revert = REVERT_DOWNLOADING_10_10_10_2;
-            }
-            else {
-                *revert = REVERT_DOWNLOADING_2_10_10_10;
-            }
-        }
-        need_swap_rb = 1;
-
-        break;
-
-    case PICT_x2b10g10r10:
-        *no_alpha = 1;
-    case PICT_a2b10g10r10:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        if (is_upload == 1) {
-            if (!IS_LITTLE_ENDIAN)
-                *revert = REVERT_UPLOADING_10_10_10_2;
-            else
-                *revert = REVERT_UPLOADING_2_10_10_10;
-        }
-        else {
-            if (!IS_LITTLE_ENDIAN) {
-                *revert = REVERT_DOWNLOADING_10_10_10_2;
-            }
-            else {
-                *revert = REVERT_DOWNLOADING_2_10_10_10;
-            }
-        }
-        break;
-
-    case PICT_r5g6b5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
-        break;
-
-    case PICT_b5g6r5:
-        *tex_format = GL_RGB;
-        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-        need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
-        break;
-
-    case PICT_x1b5g5r5:
-        *no_alpha = 1;
-    case PICT_a1b5g5r5:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN) {
-            *revert =
-                is_upload ? REVERT_UPLOADING_1_5_5_5 :
-                REVERT_DOWNLOADING_1_5_5_5;
-        }
-        else
-            *revert = REVERT_NONE;
-        break;
-
-    case PICT_x1r5g5b5:
-        *no_alpha = 1;
-    case PICT_a1r5g5b5:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-        if (IS_LITTLE_ENDIAN) {
-            *revert =
-                is_upload ? REVERT_UPLOADING_1_5_5_5 :
-                REVERT_DOWNLOADING_1_5_5_5;
-        }
-        else
-            *revert = REVERT_NONE;
-        need_swap_rb = 1;
-        break;
-
-    case PICT_a1:
-        *tex_format = GL_ALPHA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
-        break;
-
-    case PICT_a8:
-        *tex_format = GL_ALPHA;
-        *tex_type = GL_UNSIGNED_BYTE;
-        *revert = REVERT_NONE;
-        break;
-
-    case PICT_x4r4g4b4:
-        *no_alpha = 1;
-    case PICT_a4r4g4b4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-        need_swap_rb = 1;
-        break;
-
-    case PICT_x4b4g4r4:
-        *no_alpha = 1;
-    case PICT_a4b4g4r4:
-        *tex_format = GL_RGBA;
-        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-        break;
-
-    default:
-        LogMessageVerb(X_INFO, 0,
-                       "fail to get matched format for %x \n", format);
-        return -1;
-    }
-
-    if (need_swap_rb)
-        *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
-    else
-        *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
-    return 0;
-}
-
-#endif
-
 inline static int
 cache_format(GLenum format)
 {
@@ -1209,29 +929,6 @@ cache_format(GLenum format)
     }
 }
 
-static inline int
-glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
-                                       GLenum * format,
-                                       GLenum * type,
-                                       int *no_alpha,
-                                       int *revert, int *swap_rb, int is_upload)
-{
-    glamor_pixmap_private *pixmap_priv;
-    PictFormatShort pict_format;
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-        pict_format = pixmap_priv->base.picture->format;
-    else
-        pict_format = format_for_depth(pixmap->drawable.depth);
-
-    return glamor_get_tex_format_type_from_pictformat(pict_format,
-                                                      format, type,
-                                                      no_alpha,
-                                                      revert,
-                                                      swap_rb, is_upload);
-}
-
 /* borrowed from uxa */
 static inline Bool
 glamor_get_rgba_from_pixel(CARD32 pixel,
commit 0e4f3414189b1820443b35248e4c9e03f0c2e34e
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 02:04:11 2013 -0800

    glamor: Unifdef the cache format indices.
    
    We only ask for GL_RGB on desktop GL as far as I can see, but now if
    GLES2 did happen to ask for GL_RGB it would return a cache index
    instead of -1.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a6cdf64..81b46b6 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -197,11 +197,7 @@ struct glamor_saved_procs {
     SetWindowPixmapProcPtr set_window_pixmap;
 };
 
-#ifdef GLAMOR_GLES2
 #define CACHE_FORMAT_COUNT 3
-#else
-#define CACHE_FORMAT_COUNT 2
-#endif
 
 #define CACHE_BUCKET_WCOUNT 4
 #define CACHE_BUCKET_HCOUNT 4
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d277468..3de6133 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1020,20 +1020,6 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     return 0;
 }
 
-/* Currently, we use RGBA to represent all formats. */
-inline static int
-cache_format(GLenum format)
-{
-    switch (format) {
-    case GL_ALPHA:
-        return 1;
-    case GL_RGBA:
-        return 0;
-    default:
-        return -1;
-    }
-}
-
 #else
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
@@ -1206,6 +1192,8 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     return 0;
 }
 
+#endif
+
 inline static int
 cache_format(GLenum format)
 {
@@ -1221,8 +1209,6 @@ cache_format(GLenum format)
     }
 }
 
-#endif
-
 static inline int
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
                                        GLenum * format,
commit d63283860a7c04a12838dead0dfd6d04fb73a093
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 01:23:15 2013 -0800

    glamor: Pass pixmaps around to unifdef glamor_iformat_for_depth().
    
    v2: Just pass in the PicturePtr to glamor_pict_format_is_compatible()
        (suggestion by keithp)
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index baee4dd..7d8228c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -95,7 +95,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
         glamor_destroy_fbo(fbo);
     }
 
-    gl_iformat_for_depth(pixmap->drawable.depth, &format);
+    format = gl_iformat_for_pixmap(pixmap);
     fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
                                      pixmap->drawable.height, format, tex, 0);
 
@@ -162,7 +162,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     pixmap_priv->base.pixmap = pixmap;
     pixmap_priv->base.glamor_priv = glamor_priv;
 
-    gl_iformat_for_depth(depth, &format);
+    format = gl_iformat_for_pixmap(pixmap);
 
     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index f51a7e4..8bbe2e9 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -93,8 +93,7 @@ glamor_create_picture(PicturePtr picture)
              * we have to mark this pixmap as a separated texture, and don't
              * fallback to DDX layer. */
             if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-                && !glamor_pict_format_is_compatible(picture->format,
-                                                     pixmap->drawable.depth))
+                && !glamor_pict_format_is_compatible(picture))
                 glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
         }
     }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 5442c90..30aeebe 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -403,7 +403,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     if (*tex == 0) {
         glGenTextures(1, tex);
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-            gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+            iformat = gl_iformat_for_pixmap(pixmap);
         else
             iformat = format;
         non_sub = 1;
@@ -603,7 +603,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
         return 0;
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-        gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+        iformat = gl_iformat_for_pixmap(pixmap);
     else
         iformat = format;
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index eafd2bc..d277468 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -869,19 +869,17 @@ format_for_depth(int depth)
     }
 }
 
-static inline void
-gl_iformat_for_depth(int depth, GLenum * format)
+static inline GLenum
+gl_iformat_for_pixmap(PixmapPtr pixmap)
 {
-    switch (depth) {
-#ifndef GLAMOR_GLES2
-    case 1:
-    case 8:
-        *format = GL_ALPHA;
-        break;
-#endif
-    default:
-        *format = GL_RGBA;
-        break;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
+        (pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8)) {
+        return GL_ALPHA;
+    } else {
+        return GL_RGBA;
     }
 }
 
@@ -1319,16 +1317,18 @@ glamor_get_rgba_from_pixel(CARD32 pixel,
 }
 
 inline static Bool
-glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth)
+glamor_pict_format_is_compatible(PicturePtr picture)
 {
     GLenum iformat;
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 
-    gl_iformat_for_depth(depth, &iformat);
+    iformat = gl_iformat_for_pixmap(pixmap);
     switch (iformat) {
     case GL_RGBA:
-        return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8);
+        return (picture->format == PICT_a8r8g8b8 ||
+                picture->format == PICT_x8r8g8b8);
     case GL_ALPHA:
-        return (pict_format == PICT_a8);
+        return (picture->format == PICT_a8);
     default:
         return FALSE;
     }
commit f3f4fc7a65589a200a086ea7b1527f91941bc19b
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 01:17:10 2013 -0800

    glamor: Add a screen argument to drop an ifdef from glamor_set_alu().
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 8cc7cad..d6bcacd 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -338,6 +338,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
                     Bool upsidedown, Pixel bitplane,
                     void *closure, Bool fallback)
 {
+    ScreenPtr screen = dst->pScreen;
     PixmapPtr dst_pixmap, src_pixmap;
     glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
     glamor_screen_private *glamor_priv;
@@ -354,7 +355,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
     src_pixmap = glamor_get_drawable_pixmap(src);
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
-    glamor_priv = glamor_get_screen_private(dst->pScreen);
+    glamor_priv = glamor_get_screen_private(screen);
 
     DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
            box[0].x1, box[0].y1,
@@ -368,7 +369,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
         if (!glamor_set_planemask(dst_pixmap, gc->planemask))
             goto fall_back;
         glamor_get_context(glamor_priv);
-        if (!glamor_set_alu(gc->alu)) {
+        if (!glamor_set_alu(screen, gc->alu)) {
             glamor_put_context(glamor_priv);
             goto fail;
         }
@@ -546,7 +547,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 
  fail:
     glamor_get_context(glamor_priv);
-    glamor_set_alu(GXcopy);
+    glamor_set_alu(screen, GXcopy);
     glamor_put_context(glamor_priv);
 
     if (ok)
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index d1c16ad..dda55ea 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -330,7 +330,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     }
 
     glamor_get_context(glamor_priv);
-    if (!glamor_set_alu(alu)) {
+    if (!glamor_set_alu(screen, alu)) {
         if (alu == GXclear)
             fg_pixel = 0;
         else {
@@ -345,7 +345,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     box.y2 = y + height;
     glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
 
-    glamor_set_alu(GXcopy);
+    glamor_set_alu(screen, GXcopy);
     glamor_put_context(glamor_priv);
 
     return TRUE;
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 41d5f5a..5442c90 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -115,9 +115,17 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 }
 
 Bool
-glamor_set_alu(unsigned char alu)
+glamor_set_alu(ScreenPtr screen, unsigned char alu)
 {
-#ifndef GLAMOR_GLES2
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+        if (alu != GXcopy)
+            return FALSE;
+        else
+            return TRUE;
+    }
+
     if (alu == GXcopy) {
         glDisable(GL_COLOR_LOGIC_OP);
         return TRUE;
@@ -173,10 +181,7 @@ glamor_set_alu(unsigned char alu)
         glamor_fallback("unsupported alu %x\n", alu);
         return FALSE;
     }
-#else
-    if (alu != GXcopy)
-        return FALSE;
-#endif
+
     return TRUE;
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 53af353..a6cdf64 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -599,7 +599,7 @@ glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
                                                   int no_alpha, int revert,
                                                   int swap_rb);
 
-Bool glamor_set_alu(unsigned char alu);
+Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 9abb95d..7288af3 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -196,7 +196,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     }
 
     glamor_get_context(glamor_priv);
-    if (!glamor_set_alu(alu)) {
+    if (!glamor_set_alu(screen, alu)) {
         glamor_fallback("unsupported alu %x\n", alu);
         glamor_put_context(glamor_priv);
         goto fail;
@@ -291,7 +291,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     else
         _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
 
-    glamor_set_alu(GXcopy);
+    glamor_set_alu(screen, GXcopy);
     glamor_put_context(glamor_priv);
     return TRUE;
  fail:
commit 9553020b7184ed7a7ef3f02d60556d519ea3e769
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 25 11:39:13 2013 -0800

    glamor: Drop a bunch of GLES2 ifdefs.
    
    Now that we're using epoxy, we can write code using both desktop and
    ES symbols and decide what to use at runtime.
    
    v2: Fix a spelling mistake (latter), since the lines were moved
        anyway (noticed by Rémi Cardona).  Fix condition invert in
        glamor_set_composite_texture (caught by Michel Dänzer).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com> (v1)
    Reviewed-by: Adam Jackson <ajax at redhat.com> (v1)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 4c962ac..baee4dd 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -301,26 +301,29 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         goto fail;;
     }
 
+    if (epoxy_is_desktop_gl())
+        glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+    else
+        glamor_priv->gl_flavor = GLAMOR_GL_ES2;
+
     gl_version = glamor_gl_get_version();
 
-#ifndef GLAMOR_GLES2
-    if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
-        ErrorF("Require OpenGL version 1.3 or latter.\n");
-        goto fail;
-    }
-#else
-    if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
-        ErrorF("Require Open GLES2.0 or latter.\n");
-        goto fail;
-    }
-#endif
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
+            ErrorF("Require OpenGL version 1.3 or later.\n");
+            goto fail;
+        }
+    } else {
+        if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
+            ErrorF("Require Open GLES2.0 or later.\n");
+            goto fail;
+        }
 
-#ifdef GLAMOR_GLES2
-    if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
-        ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
-        goto fail;
+        if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
+            ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
+            goto fail;
+        }
     }
-#endif
 
     glamor_priv->has_pack_invert =
         glamor_gl_has_extension("GL_MESA_pack_invert");
@@ -333,11 +336,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_set_debug_level(&glamor_debug_level);
 
-#ifdef GLAMOR_GLES2
-    glamor_priv->gl_flavor = GLAMOR_GL_ES2;
-#else
-    glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
-#endif
     /* If we are using egl screen, call egl screen init to
      * register correct close screen function. */
     if (flags & GLAMOR_USE_EGL_SCREEN) {
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 498a06e..8cc7cad 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -31,7 +31,6 @@
  *
  * GC CopyArea implementation
  */
-#ifndef GLAMOR_GLES2
 static Bool
 glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
                             DrawablePtr dst,
@@ -117,7 +116,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     glamor_priv->state = BLIT_STATE;
     return TRUE;
 }
-#endif
 
 static Bool
 glamor_copy_n_to_n_textured(DrawablePtr src,
@@ -170,10 +168,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
-#ifndef GLAMOR_GLES2
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
-#endif
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+    }
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
@@ -266,15 +264,14 @@ __glamor_copy_n_to_n(DrawablePtr src,
            box[0].x1, box[0].y1,
            box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
            dx, dy, src_pixmap, dst_pixmap);
-#ifndef GLAMOR_GLES2
-    if (!overlaped &&
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
+        !overlaped &&
         (glamor_priv->state != RENDER_STATE
          || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
         && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
         ret = TRUE;
         goto done;
     }
-#endif
     glamor_calculate_boxes_bound(&bound, box, nbox);
 
     /*  Overlaped indicate the src and dst are the same pixmap. */
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index c9bd519..d1c16ad 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -240,13 +240,15 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
         }
         if (box_cnt == 1)
             glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
-        else
-#ifndef GLAMOR_GLES2
-            glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
-                                GL_UNSIGNED_SHORT, NULL);
-#else
-            glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
-#endif
+        else {
+            if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+                glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
+                                    GL_UNSIGNED_SHORT, NULL);
+            } else {
+                glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT,
+                               NULL);
+            }
+        }
         nbox -= box_cnt;
         box += box_cnt;
     }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ecc4606..093a215 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -535,14 +535,16 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
     repeat_type = picture->repeatType;
     switch (picture->repeatType) {
     case RepeatNone:
-#ifndef GLAMOR_GLES2
-        /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
-#else
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#endif
+        if (glamor_priv->gl_flavor != GLAMOR_GL_ES2) {
+            /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                            GL_CLAMP_TO_BORDER);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                            GL_CLAMP_TO_BORDER);
+        } else {
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        }
         break;
     case RepeatNormal:
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -807,14 +809,14 @@ glamor_flush_composite_rects(ScreenPtr screen)
     if (!glamor_priv->render_nr_verts)
         return;
 
-#ifndef GLAMOR_GLES2
-    glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
-                        (glamor_priv->render_nr_verts * 3) / 2,
-                        GL_UNSIGNED_SHORT, NULL);
-#else
-    glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
-                   GL_UNSIGNED_SHORT, NULL);
-#endif
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
+                            (glamor_priv->render_nr_verts * 3) / 2,
+                            GL_UNSIGNED_SHORT, NULL);
+    } else {
+        glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
+                       GL_UNSIGNED_SHORT, NULL);
+    }
     glamor_put_context(glamor_priv);
 }
 
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index e64c19d..7bc925a 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1554,16 +1554,16 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
                          glamor_priv->vb, GL_DYNAMIC_DRAW);
         }
 
-#ifndef GLAMOR_GLES2
-        glDrawRangeElements(GL_TRIANGLES, 0,
-                            glamor_priv->render_nr_verts,
-                            (glamor_priv->render_nr_verts * 3) / 2,
-                            GL_UNSIGNED_SHORT, NULL);
-#else
-        glDrawElements(GL_TRIANGLES,
-                       (glamor_priv->render_nr_verts * 3) / 2,
-                       GL_UNSIGNED_SHORT, NULL);
-#endif
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+            glDrawRangeElements(GL_TRIANGLES, 0,
+                                glamor_priv->render_nr_verts,
+                                (glamor_priv->render_nr_verts * 3) / 2,
+                                GL_UNSIGNED_SHORT, NULL);
+        } else {
+            glDrawElements(GL_TRIANGLES,
+                           (glamor_priv->render_nr_verts * 3) / 2,
+                           GL_UNSIGNED_SHORT, NULL);
+        }
     }
 
     glBindBuffer(GL_ARRAY_BUFFER, 0);
commit c3c8a5f36034b6a2ce48d1d42e3de5af36406c38
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 25 11:36:35 2013 -0800

    glamor: yInverted is a boolean value, so use the Bool type.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 5947d7f..4c962ac 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -280,10 +280,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         return FALSE;
 
     if (flags & GLAMOR_INVERTED_Y_AXIS) {
-        glamor_priv->yInverted = 1;
+        glamor_priv->yInverted = TRUE;
     }
     else
-        glamor_priv->yInverted = 0;
+        glamor_priv->yInverted = FALSE;
 
     if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
         LogMessage(X_WARNING,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f2bc002..53af353 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -215,7 +215,7 @@ struct glamor_saved_procs {
 #define RENDER_IDEL_MAX 32
 
 typedef struct glamor_screen_private {
-    int yInverted;
+    Bool yInverted;
     unsigned int tick;
     enum glamor_gl_flavor gl_flavor;
     int has_pack_invert;
commit 12cbfeed81d3ae73e10ee8a2b6619fb4f403b8f6
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Dec 23 18:00:46 2013 -0800

    glamor: Drop fixed function transformation matrix setup.
    
    gl_ModelViewProjection and friends aren't used in our shaders, so this
    setup didn't do anything.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 9fe2b2e..41d5f5a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -69,12 +69,6 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
     glamor_get_context(fbo->glamor_priv);
 
     glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
-#ifndef GLAMOR_GLES2
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-#endif
     glViewport(x0, y0, width, height);
 
     glamor_put_context(fbo->glamor_priv);
commit 62965d278c347ff323f2262d767978794e32f841
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Dec 23 17:50:46 2013 -0800

    glamor: Drop useless glEnable/glDisable(GL_TEXTURE_2D) calls.
    
    Those calls are only for enabling texture handling in the fixed
    function pipeline, while everything we do is with shaders.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 7279d34..498a06e 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -171,7 +171,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
 #ifndef GLAMOR_GLES2
-    glEnable(GL_TEXTURE_2D);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 #endif
@@ -208,9 +207,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#ifndef GLAMOR_GLES2
-    glDisable(GL_TEXTURE_2D);
-#endif
     glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
     glamor_put_context(glamor_priv);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 4012755..9fe2b2e 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -538,18 +538,12 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-#ifndef GLAMOR_GLES2
-    glEnable(GL_TEXTURE_2D);
-#endif
     glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
     glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
     glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-#ifndef GLAMOR_GLES2
-    glDisable(GL_TEXTURE_2D);
-#endif
     glUseProgram(0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 60ccd67..702e89f 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -170,7 +170,6 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
-    glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -220,7 +219,6 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     glDeleteTextures(1, &tex);
-    glDisable(GL_TEXTURE_2D);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     return;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 34530f3..ecc4606 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -572,9 +572,6 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         break;
     }
-#ifndef GLAMOR_GLES2
-    glEnable(GL_TEXTURE_2D);
-#endif
 
     /*
      *  GLES2 doesn't support RepeatNone. We need to fix it anyway.
@@ -1409,12 +1406,6 @@ glamor_composite_with_shader(CARD8 op,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
     glDisable(GL_BLEND);
-#ifndef GLAMOR_GLES2
-    glActiveTexture(GL_TEXTURE0);
-    glDisable(GL_TEXTURE_2D);
-    glActiveTexture(GL_TEXTURE1);
-    glDisable(GL_TEXTURE_2D);
-#endif
     DEBUGF("finish rendering.\n");
     glUseProgram(0);
     glamor_priv->state = RENDER_STATE;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 5b58e80..9abb95d 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -135,9 +135,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-#ifndef GLAMOR_GLES2
-    glEnable(GL_TEXTURE_2D);
-#endif
     glamor_set_repeat_normalize_tcoords
         (src_pixmap_priv, RepeatNormal,
          src_xscale, src_yscale,
@@ -158,9 +155,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#ifndef GLAMOR_GLES2
-    glDisable(GL_TEXTURE_2D);
-#endif
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glUseProgram(0);
     glamor_put_context(glamor_priv);
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 6ef0c1d..e64c19d 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -976,12 +976,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
     glDisable(GL_BLEND);
-#ifndef GLAMOR_GLES2
-    glActiveTexture(GL_TEXTURE0);
-    glDisable(GL_TEXTURE_2D);
-    glActiveTexture(GL_TEXTURE1);
-    glDisable(GL_TEXTURE_2D);
-#endif
     glUseProgram(0);
     glamor_put_context(glamor_priv);
 
commit 4afe15d8bfd575c010ed1868697a7922a37ab378
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 15:27:52 2013 -0800

    glamor: Put in a pluggable context switcher for GLX versus EGL.
    
    The GLX side just gets the context from the current state.  That's
    also something I want to do for EGL, so that the making a context is
    separate from initializing glamor, but I think I need the modesetting
    driver in the server before I think about hacking on that more.
    
    The previous code was rather incestuous, along with pulling in xf86
    dependencies to our dix code.  The new code just initializes itself
    from the current state.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 17cae97..12a57c4 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -6,6 +6,7 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
+	glamor_context.h \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
 	glamor_core.c \
@@ -13,6 +14,7 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_glx.c \
 	glamor_glyphs.c \
 	glamor_polyfillrect.c \
 	glamor_polylines.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 410ebd2..5947d7f 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -340,8 +340,12 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #endif
     /* If we are using egl screen, call egl screen init to
      * register correct close screen function. */
-    if (flags & GLAMOR_USE_EGL_SCREEN)
-        glamor_egl_screen_init(screen);
+    if (flags & GLAMOR_USE_EGL_SCREEN) {
+        glamor_egl_screen_init(screen, &glamor_priv->ctx);
+    } else {
+        if (!glamor_glx_screen_init(&glamor_priv->ctx))
+            goto fail;
+    }
 
     glamor_priv->saved_procs.close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_close_screen;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 05f565b..eec6872 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -36,6 +36,8 @@
 #include <fb.h>
 #include <fbpict.h>
 
+struct glamor_context;
+
 /*
  * glamor_pixmap_type : glamor pixmap's type.
  * @MEMORY: pixmap is in memory.
@@ -142,11 +144,6 @@ extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
                                                 int depth, unsigned int usage);
 
-extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
-
-extern _X_EXPORT void glamor_egl_make_current(ScreenPtr screen);
-extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
-
 /* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
  *
  * @front: front pixmap.
diff --git a/glamor/glamor_context.h b/glamor/glamor_context.h
new file mode 100644
index 0000000..8781afc
--- /dev/null
+++ b/glamor/glamor_context.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/**
+ * @file glamor_context.h
+ *
+ * This is the struct of state required for context switching in
+ * glamor.  It has to use types that don't require including either
+ * server headers or Xlib headers, since it will be included by both
+ * the server and the GLX (xlib) code.
+ */
+
+struct glamor_context {
+    /** Either an EGLDisplay or an Xlib Display */
+    void *display;
+
+    /** Either a GLXContext or an EGLContext. */
+    void *ctx;
+
+    /** The EGLSurface we should MakeCurrent to */
+    void *drawable;
+
+    /** The GLXDrawable we should MakeCurrent to */
+    uint32_t drawable_xid;
+
+    /**
+     * Count of how deep in glamor_get_context() we are, to reduce
+     * MakeCurrent calls.
+     */
+    int get_count;
+
+    void (*get_context)(struct glamor_context *glamor_ctx);
+    void (*put_context)(struct glamor_context *glamor_ctx);
+};
+
+Bool glamor_glx_screen_init(struct glamor_context *glamor_ctx);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 906598a..81e697b 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -49,6 +49,7 @@
 #include <epoxy/egl.h>
 
 #include "glamor.h"
+#include "glamor_priv.h"
 
 static const char glamor_name[] = "glamor";
 
@@ -87,6 +88,7 @@ struct glamor_egl_screen_private {
 
 int xf86GlamorEGLPrivateIndex = -1;
 
+
 static struct glamor_egl_screen_private *
 glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 {
@@ -94,38 +96,30 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
         scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
 
-_X_EXPORT void
-glamor_egl_make_current(ScreenPtr screen)
+static void
+glamor_egl_get_context(struct glamor_context *glamor_ctx)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_egl_screen_private *glamor_egl =
-        glamor_egl_get_screen_private(scrn);
-
-    if (glamor_egl->gl_context_depth++)
+    if (glamor_ctx->get_count++)
         return;
 
-    if (glamor_egl->context != eglGetCurrentContext()) {
-        eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+    if (glamor_ctx->ctx != eglGetCurrentContext()) {
+        eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        if (!eglMakeCurrent(glamor_egl->display,
+        if (!eglMakeCurrent(glamor_ctx->display,
                             EGL_NO_SURFACE, EGL_NO_SURFACE,
-                            glamor_egl->context)) {
+                            glamor_ctx->ctx)) {
             FatalError("Failed to make EGL context current\n");
         }
     }
 }
 
-_X_EXPORT void
-glamor_egl_restore_context(ScreenPtr screen)
+static void
+glamor_egl_put_context(struct glamor_context *glamor_ctx)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_egl_screen_private *glamor_egl =
-        glamor_egl_get_screen_private(scrn);
-
-    if (--glamor_egl->gl_context_depth)
+    if (--glamor_ctx->get_count)
         return;
 
-    eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+    eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
                    EGL_NO_SURFACE, EGL_NO_CONTEXT);
 }
 
@@ -284,6 +278,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(screen);
     struct glamor_egl_screen_private *glamor_egl;
     EGLImageKHR image;
     GLuint texture;
@@ -292,7 +288,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_egl_make_current(screen);
+    glamor_get_context(glamor_priv);
     if (glamor_egl->has_gem) {
         if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
             xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -322,7 +318,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
     ret = TRUE;
 
  done:
-    glamor_egl_restore_context(screen);
+    glamor_put_context(glamor_priv);
     return ret;
 }
 
@@ -331,6 +327,8 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(screen);
     struct glamor_egl_screen_private *glamor_egl;
     EGLImageKHR image;
     GLuint texture;
@@ -338,7 +336,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_egl_make_current(screen);
+    glamor_get_context(glamor_priv);
 
     image = eglCreateImageKHR(glamor_egl->display,
                               glamor_egl->context,
@@ -354,7 +352,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
     ret = TRUE;
 
  done:
-    glamor_egl_restore_context(screen);
+    glamor_put_context(glamor_priv);
     return ret;
 }
 
@@ -395,6 +393,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 {
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(screen);
     struct glamor_egl_screen_private *glamor_egl;
     EGLImageKHR image;
     struct gbm_bo *bo;
@@ -408,7 +408,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_egl_make_current(screen);
+    glamor_get_context(glamor_priv);
 
     image = dixLookupPrivate(&pixmap->devPrivates,
                              glamor_egl_pixmap_private_key);
@@ -446,7 +446,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     gbm_bo_destroy(bo);
  failure:
-    glamor_egl_restore_context(screen);
+    glamor_put_context(glamor_priv);
     return fd;
 #else
     return -1;
@@ -628,7 +628,7 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
 }
 
 void
-glamor_egl_screen_init(ScreenPtr screen)
+glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     struct glamor_egl_screen_private *glamor_egl =
@@ -636,6 +636,12 @@ glamor_egl_screen_init(ScreenPtr screen)
 
     glamor_egl->saved_close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_egl_close_screen;
+
+    glamor_ctx->ctx = glamor_egl->context;
+    glamor_ctx->display = glamor_egl->display;
+
+    glamor_ctx->get_context = glamor_egl_get_context;
+    glamor_ctx->put_context = glamor_egl_put_context;
 }
 
 static void
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index 1449d08..4fd9e80 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -29,7 +29,7 @@
 #include "glamor_priv.h"
 
 void
-glamor_egl_screen_init(ScreenPtr screen)
+glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
 {
 }
 
@@ -38,16 +38,6 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 {
 }
 
-void
-glamor_egl_make_current(ScreenPtr screen)
-{
-}
-
-void
-glamor_egl_restore_context(ScreenPtr screen)
-{
-}
-
 int
 glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
                                  PixmapPtr pixmap,
diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c
new file mode 100644
index 0000000..311bf75
--- /dev/null
+++ b/glamor/glamor_glx.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <epoxy/glx.h>
+#include "glamor_context.h"
+
+/**
+ * @file glamor_glx.c
+ *
+ * GLX context management for glamor.
+ *
+ * This has to be kept separate from the server sources because of
+ * Xlib's conflicting definition of CARD32 and similar typedefs.
+ */
+
+static void
+glamor_glx_get_context(struct glamor_context *glamor_ctx)
+{
+    GLXContext old_ctx;
+
+    if (glamor_ctx->get_count++)
+        return;
+
+    old_ctx = glXGetCurrentContext();
+    if (old_ctx == glamor_ctx->ctx)
+        return;
+
+    glXMakeCurrent(glamor_ctx->display, glamor_ctx->drawable_xid,
+                   glamor_ctx->ctx);
+}
+
+
+static void
+glamor_glx_put_context(struct glamor_context *glamor_ctx)
+{
+    if (--glamor_ctx->get_count)
+        return;
+
+    /* We actually reset the context, so that indirect GLX's EGL usage
+     * won't get confused by ours.
+     */
+    glXMakeCurrent(glamor_ctx->display, None, NULL);
+}
+
+Bool
+glamor_glx_screen_init(struct glamor_context *glamor_ctx)
+{
+    glamor_ctx->ctx = glXGetCurrentContext();
+    if (!glamor_ctx->ctx)
+        return False;
+
+    glamor_ctx->display = glXGetCurrentDisplay();
+    if (!glamor_ctx->display)
+        return False;
+
+    glamor_ctx->drawable_xid = glXGetCurrentDrawable();
+
+    glamor_ctx->get_context = glamor_glx_get_context;
+    glamor_ctx->put_context = glamor_glx_put_context;
+
+    return True;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8477091..f2bc002 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -48,6 +48,7 @@
 #endif
 
 #include "glamor_debug.h"
+#include "glamor_context.h"
 
 #include <list.h>
 
@@ -281,6 +282,8 @@ typedef struct glamor_screen_private {
 
     /* xv */
     GLint xv_prog;
+
+    struct glamor_context ctx;
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -927,6 +930,9 @@ void glamor_composite_rectangles(CARD8 op,
                                  xRenderColor *color,
                                  int num_rects, xRectangle *rects);
 
+extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
+                                             struct glamor_context *glamor_ctx);
+
 /* glamor_xv */
 typedef struct {
     uint32_t transform_index;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b82517a..eafd2bc 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1817,29 +1817,15 @@ __fls(unsigned long x)
 #endif
 
 static inline void
-glamor_make_current(ScreenPtr screen)
-{
-    glamor_egl_make_current(screen);
-}
-
-static inline void
-glamor_restore_current(ScreenPtr screen)
-{
-    glamor_egl_restore_context(screen);
-}
-
-static inline void
 glamor_get_context(glamor_screen_private * glamor_priv)
 {
-    if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
-        glamor_make_current(glamor_priv->screen);
+    glamor_priv->ctx.get_context(&glamor_priv->ctx);
 }
 
 static inline void
 glamor_put_context(glamor_screen_private * glamor_priv)
 {
-    if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
-        glamor_restore_current(glamor_priv->screen);
+    glamor_priv->ctx.put_context(&glamor_priv->ctx);
 }
 
 #endif
commit 781c692cf970642865f0e537f4905c43192f9935
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 13:10:24 2013 -0800

    glamor: Rename glamor_get/put_dispatch to glamor_get/put_context.
    
    It used to be the thing that returned your dispatch table and happeend
    to set up the context, but now it just sets up the context.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 74ae150..410ebd2 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -219,11 +219,11 @@ glamor_block_handler(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_priv->tick++;
     glFlush();
     glamor_fbo_expire(glamor_priv);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     if (glamor_priv->state == RENDER_STATE
         && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
         glamor_priv->state = IDLE_STATE;
@@ -236,9 +236,9 @@ _glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
     glamor_screen_private *glamor_priv = data;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glFlush();
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 6eb0d98..7279d34 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -71,7 +71,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
     pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->fb);
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@@ -113,7 +113,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
                               GL_COLOR_BUFFER_BIT, GL_NEAREST);
         }
     }
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     glamor_priv->state = BLIT_STATE;
     return TRUE;
 }
@@ -157,7 +157,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -213,7 +213,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 #endif
     glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
     return TRUE;
@@ -374,12 +374,12 @@ _glamor_copy_n_to_n(DrawablePtr src,
     if (gc) {
         if (!glamor_set_planemask(dst_pixmap, gc->planemask))
             goto fall_back;
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         if (!glamor_set_alu(gc->alu)) {
-            glamor_put_dispatch(glamor_priv);
+            glamor_put_context(glamor_priv);
             goto fail;
         }
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
     }
 
     if (!src_pixmap_priv) {
@@ -552,9 +552,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
     }
 
  fail:
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_set_alu(GXcopy);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     if (ok)
         return TRUE;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index fe49cb3..5883809 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -215,7 +215,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     char *source;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_priv->finish_access_prog[0] = glCreateProgram();
     glamor_priv->finish_access_prog[1] = glCreateProgram();
 
@@ -274,7 +274,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     glUniform1i(sampler_uniform_location, 0);
     glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -283,10 +283,10 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glDeleteProgram(glamor_priv->finish_access_prog[0]);
     glDeleteProgram(glamor_priv->finish_access_prog[1]);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -307,11 +307,11 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
     if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
         assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
 
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
         glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
 
         pixmap_priv->base.fbo->pbo_valid = FALSE;
         pixmap_priv->base.fbo->pbo = 0;
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index bb7af2c..281cf83 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -129,7 +129,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
-    glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_context(fbo->glamor_priv);
 
     if (fbo->fb)
         glDeleteFramebuffers(1, &fbo->fb);
@@ -137,7 +137,7 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
         glDeleteTextures(1, &fbo->tex);
     if (fbo->pbo)
         glDeleteBuffers(1, &fbo->pbo);
-    glamor_put_dispatch(fbo->glamor_priv);
+    glamor_put_context(fbo->glamor_priv);
 
     free(fbo);
 }
@@ -180,7 +180,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
     int status;
 
-    glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_context(fbo->glamor_priv);
 
     if (fbo->fb == 0)
         glGenFramebuffers(1, &fbo->fb);
@@ -219,7 +219,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
         FatalError("destination is framebuffer incomplete: %s [%x]\n",
                    str, status);
     }
-    glamor_put_dispatch(fbo->glamor_priv);
+    glamor_put_context(fbo->glamor_priv);
 }
 
 glamor_pixmap_fbo *
@@ -241,9 +241,9 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->glamor_priv = glamor_priv;
 
     if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         glGenBuffers(1, &fbo->pbo);
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
         goto done;
     }
 
@@ -341,14 +341,14 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
                                                        w, h);
     }
     if (!tex) {
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         glGenTextures(1, &tex);
         glBindTexture(GL_TEXTURE_2D, tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                      format, GL_UNSIGNED_BYTE, NULL);
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
     }
     return tex;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index e98fc5b..c9bd519 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -153,7 +153,7 @@ glamor_init_solid_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_priv->solid_prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
@@ -166,7 +166,7 @@ glamor_init_solid_shader(ScreenPtr screen)
 
     glamor_priv->solid_color_uniform_location =
         glGetUniformLocation(glamor_priv->solid_prog, "color");
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -175,9 +175,9 @@ glamor_fini_solid_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glDeleteProgram(glamor_priv->solid_prog);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -193,7 +193,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glUseProgram(glamor_priv->solid_prog);
 
     glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
@@ -256,7 +256,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
 }
@@ -327,13 +327,13 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
         return FALSE;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (!glamor_set_alu(alu)) {
         if (alu == GXclear)
             fg_pixel = 0;
         else {
             glamor_fallback("unsupported alu %x\n", alu);
-            glamor_put_dispatch(glamor_priv);
+            glamor_put_context(glamor_priv);
             return FALSE;
         }
     }
@@ -344,7 +344,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
 
     glamor_set_alu(GXcopy);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     return TRUE;
 }
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index c118f34..caafa43 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -1278,9 +1278,9 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
                  * thus we have to composite from the cache picture
                  * to the cache picture, we need a flush here to make
                  * sure latter we get the corret glyphs data.*/
-                glamor_get_dispatch(glamor_priv);
+                glamor_get_context(glamor_priv);
                 glFlush();
-                glamor_put_dispatch(glamor_priv);
+                glamor_put_context(glamor_priv);
             }
         }
         else {
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 08df996..4ea441e 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -176,7 +176,7 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
         "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     if (use_array) {
         XNFasprintf(&gradient_fs,
@@ -353,7 +353,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
         glDeleteShader(glamor_priv->radial_gradient_shaders
@@ -422,7 +422,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
         fs_getcolor_prog;
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -586,7 +586,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
         glDeleteShader(glamor_priv->linear_gradient_shaders
                        [SHADER_GRADIENT_VS_PROG][2]);
@@ -652,7 +652,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
         linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
         fs_getcolor_prog;
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -695,7 +695,7 @@ glamor_fini_gradient_shader(ScreenPtr screen)
     int i = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     for (i = 0; i < 3; i++) {
         /* Linear Gradient */
@@ -737,7 +737,7 @@ glamor_fini_gradient_shader(ScreenPtr screen)
                             [SHADER_GRADIENT_RADIAL][i]);
     }
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -868,7 +868,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
            tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
            tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                           GL_FALSE, 0, vertices);
@@ -878,7 +878,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     return 1;
 }
@@ -1021,7 +1021,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     GLint r2_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1258,7 +1258,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glUseProgram(0);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return dst_picture;
 
  GRADIENT_FAIL:
@@ -1279,7 +1279,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return NULL;
 }
 
@@ -1343,7 +1343,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     GLint pt_distance_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1611,7 +1611,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glUseProgram(0);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return dst_picture;
 
  GRADIENT_FAIL:
@@ -1632,7 +1632,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return NULL;
 }
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 7f152fc..4012755 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -66,7 +66,7 @@ void
 glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
                                   int width, int height)
 {
-    glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_context(fbo->glamor_priv);
 
     glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 #ifndef GLAMOR_GLES2
@@ -77,7 +77,7 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
 #endif
     glViewport(x0, y0, width, height);
 
-    glamor_put_dispatch(fbo->glamor_priv);
+    glamor_put_context(fbo->glamor_priv);
 }
 
 void
@@ -400,7 +400,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     int non_sub = 0;
     unsigned int iformat = 0;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (*tex == 0) {
         glGenTextures(1, tex);
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -425,7 +425,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 
     if (bits == NULL)
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -522,7 +522,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                  x + w, y + h,
                                  glamor_priv->yInverted, vertices);
     /* Slow path, we need to flip y or wire alpha to 1. */
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                           GL_FALSE, 2 * sizeof(float), vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -556,7 +556,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     glDeleteTextures(1, &tex);
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     if (need_free_bits)
         free(bits);
@@ -838,7 +838,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     if (temp_fbo == NULL)
         return NULL;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     temp_xscale = 1.0 / w;
     temp_yscale = 1.0 / h;
 
@@ -876,7 +876,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return temp_fbo;
 }
 
@@ -956,7 +956,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         fbo_y_off = 0;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
 
     if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
@@ -987,7 +987,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         unsigned int temp_pbo;
         int yy;
 
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         glGenBuffers(1, &temp_pbo);
         glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
         glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ);
@@ -1002,7 +1002,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
     }
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     if (need_post_conversion) {
         /* As OpenGL desktop version never enters here.
@@ -1176,10 +1176,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
         data = malloc(stride * pixmap->drawable.height);
     }
     else {
-        glamor_get_dispatch(glamor_priv);
+        glamor_get_context(glamor_priv);
         if (pixmap_priv->base.fbo->pbo == 0)
             glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
         pbo = pixmap_priv->base.fbo->pbo;
     }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 760af83..34530f3 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -316,7 +316,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     GLint source_sampler_uniform_location, mask_sampler_uniform_location;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     vs = glamor_create_composite_vs(key);
     if (vs == 0)
         goto out;
@@ -365,7 +365,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     }
 
  out:
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static glamor_composite_shader *
@@ -407,7 +407,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
     int eb_size;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glGenBuffers(1, &glamor_priv->vbo);
     glGenBuffers(1, &glamor_priv->ebo);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
@@ -448,7 +448,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
         glamor_priv->vb = (char *) vb;
     }
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -459,7 +459,7 @@ glamor_fini_composite_shaders(ScreenPtr screen)
     int i, j, k;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glDeleteBuffers(1, &glamor_priv->vbo);
     glDeleteBuffers(1, &glamor_priv->ebo);
 
@@ -473,7 +473,7 @@ glamor_fini_composite_shaders(ScreenPtr screen)
     if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb)
         free(glamor_priv->vb);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -529,7 +529,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
     float wh[4];
     int repeat_type;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glActiveTexture(GL_TEXTURE0 + unit);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
     repeat_type = picture->repeatType;
@@ -598,7 +598,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
             repeat_type -= RepeatFix;
     }
     glUniform1i(repeat_location, repeat_type);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -717,7 +717,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
         if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
@@ -764,7 +764,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
                                          4 : 2) * sizeof(float)));
         glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
     }
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -797,7 +797,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
         glUnmapBuffer(GL_ARRAY_BUFFER);
     else {
@@ -818,7 +818,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
     glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
                    GL_UNSIGNED_SHORT, NULL);
 #endif
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 int pict_format_combine_tab[][3] = {
@@ -1194,7 +1194,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
 
     glamor_priv = dest_priv->base.glamor_priv;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glUseProgram(shader->prog);
 
     if (key->source == SHADER_SOURCE_SOLID) {
@@ -1229,7 +1229,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
         glBlendFunc(op_info->source_blend, op_info->dest_blend);
     }
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -1286,7 +1286,7 @@ glamor_composite_with_shader(CARD8 op,
     glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
     glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
     glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
@@ -1421,7 +1421,7 @@ glamor_composite_with_shader(CARD8 op,
     glamor_priv->render_idle_cnt = 0;
     if (saved_source_format)
         source->format = saved_source_format;
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     ret = TRUE;
     return ret;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 8ceb549..5b58e80 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -62,7 +62,7 @@ glamor_init_tile_shader(ScreenPtr screen)
     GLint sampler_uniform_location;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_priv->tile_prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
@@ -83,7 +83,7 @@ glamor_init_tile_shader(ScreenPtr screen)
     glamor_priv->tile_wh =
         glGetUniformLocation(glamor_priv->tile_prog, "wh");
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -92,9 +92,9 @@ glamor_fini_tile_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glDeleteProgram(glamor_priv->tile_prog);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -124,7 +124,7 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
     pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glUseProgram(glamor_priv->tile_prog);
 
     glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
@@ -163,7 +163,7 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 #endif
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
@@ -201,10 +201,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         goto fail;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (!glamor_set_alu(alu)) {
         glamor_fallback("unsupported alu %x\n", alu);
-        glamor_put_dispatch(glamor_priv);
+        glamor_put_context(glamor_priv);
         goto fail;
     }
 
@@ -298,7 +298,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
 
     glamor_set_alu(GXcopy);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return TRUE;
  fail:
     return FALSE;
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index b398213..6ef0c1d 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -205,7 +205,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
         glUnmapBuffer(GL_ARRAY_BUFFER);
     else {
@@ -219,7 +219,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
         return;
 
     glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -602,7 +602,7 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -669,7 +669,7 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
                                               stride * sizeof(float)));
     glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -811,7 +811,7 @@ _glamor_trapezoids_with_shader(CARD8 op,
         goto TRAPEZOID_OUT;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     box = REGION_RECTS(&region);
     nbox = REGION_NUM_RECTS(&region);
@@ -983,7 +983,7 @@ _glamor_trapezoids_with_shader(CARD8 op,
     glDisable(GL_TEXTURE_2D);
 #endif
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 
  TRAPEZOID_OUT:
     if (box) {
@@ -1336,7 +1336,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glamor_priv->trapezoid_prog = glCreateProgram();
 
@@ -1361,7 +1361,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 
     glUseProgram(0);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -1370,9 +1370,9 @@ glamor_fini_trapezoid_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glDeleteProgram(glamor_priv->trapezoid_prog);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -1413,7 +1413,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
         return FALSE;
     }
 
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
@@ -1582,7 +1582,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
     glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
     glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     return TRUE;
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d427360..b82517a 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1829,14 +1829,14 @@ glamor_restore_current(ScreenPtr screen)
 }
 
 static inline void
-glamor_get_dispatch(glamor_screen_private * glamor_priv)
+glamor_get_context(glamor_screen_private * glamor_priv)
 {
     if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
         glamor_make_current(glamor_priv->screen);
 }
 
 static inline void
-glamor_put_dispatch(glamor_screen_private * glamor_priv)
+glamor_put_context(glamor_screen_private * glamor_priv)
 {
     if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
         glamor_restore_current(glamor_priv->screen);
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 89787a4..dc39476 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -93,7 +93,7 @@ glamor_init_xv_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glamor_priv->xv_prog = glCreateProgram();
 
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs);
@@ -107,7 +107,7 @@ glamor_init_xv_shader(ScreenPtr screen)
                          GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glamor_link_glsl_prog(glamor_priv->xv_prog);
 
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 void
@@ -116,10 +116,10 @@ glamor_fini_xv_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
 
     glDeleteProgram(glamor_priv->xv_prog);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
 }
 
 #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
@@ -324,7 +324,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
                                   &src_yscale[i]);
         }
     }
-    glamor_get_dispatch(glamor_priv);
+    glamor_get_context(glamor_priv);
     glUseProgram(glamor_priv->xv_prog);
 
     uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
@@ -413,7 +413,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glUseProgram(0);
-    glamor_put_dispatch(glamor_priv);
+    glamor_put_context(glamor_priv);
     DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
 }
 
commit 0373b3f4f7c7aec633468b37f9236a2734dbcc74
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 12:18:20 2013 -0800

    glamor: Convert to using libepoxy.
    
    Libepoxy hides all the GL versus GLES2 dispatch handling for us, with
    higher performance.
    
    v2: Squash in the later patch to drop the later of two repeated
        glamor_get_dispatch()es instead (caught by keithp)
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 21a6591..4859dae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2069,7 +2069,7 @@ dnl glamor
 AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes])
 if test "x$GLAMOR" = xyes; then
 	AC_DEFINE(GLAMOR, 1, [Build glamor])
-	PKG_CHECK_MODULES([GLAMOR], [egl gl])
+	PKG_CHECK_MODULES([GLAMOR], [epoxy])
 fi
 
 dnl XWin DDX
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 3fe2530..17cae97 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -10,11 +10,9 @@ libglamor_la_SOURCES = \
 	glamor_copywindow.c \
 	glamor_core.c \
 	glamor_debug.h \
-	glamor_gl_dispatch.h \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
-	glamor_glext.h \
 	glamor_glyphs.c \
 	glamor_polyfillrect.c \
 	glamor_polylines.c \
@@ -35,7 +33,6 @@ libglamor_la_SOURCES = \
 	glamor_largepixmap.c\
 	glamor_picture.c\
 	glamor_window.c\
-	glamor_gl_dispatch.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
 	glamor_xv.c\
diff --git a/glamor/glamor.c b/glamor/glamor.c
index feb110a..74ae150 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -218,11 +218,10 @@ void
 glamor_block_handler(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     glamor_priv->tick++;
-    dispatch->glFlush();
+    glFlush();
     glamor_fbo_expire(glamor_priv);
     glamor_put_dispatch(glamor_priv);
     if (glamor_priv->state == RENDER_STATE
@@ -236,9 +235,9 @@ static void
 _glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
     glamor_screen_private *glamor_priv = data;
-    glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
 
-    dispatch->glFlush();
+    glamor_get_dispatch(glamor_priv);
+    glFlush();
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -316,8 +315,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     }
 #endif
 
-    glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version);
-
 #ifdef GLAMOR_GLES2
     if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
         ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
@@ -329,8 +326,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         glamor_gl_has_extension("GL_MESA_pack_invert");
     glamor_priv->has_fbo_blit =
         glamor_gl_has_extension("GL_EXT_framebuffer_blit");
-    glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
-                                         &glamor_priv->max_fbo_size);
+    glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
 #ifdef MAX_FBO_SIZE
     glamor_priv->max_fbo_size = MAX_FBO_SIZE;
 #endif
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 2735ba0..6eb0d98 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -42,7 +42,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
     int fbo_x_off, fbo_y_off;
     int src_fbo_x_off, src_fbo_y_off;
@@ -72,9 +71,8 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
     pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
-                                src_pixmap_priv->base.fbo->fb);
+    glamor_get_dispatch(glamor_priv);
+    glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->fb);
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     dst_x_off += fbo_x_off;
@@ -84,23 +82,15 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 
     for (i = 0; i < nbox; i++) {
         if (glamor_priv->yInverted) {
-            dispatch->glBlitFramebuffer((box[i].x1 + dx +
-                                         src_x_off),
-                                        (box[i].y1 +
-                                         src_y_off),
-                                        (box[i].x2 + dx +
-                                         src_x_off),
-                                        (box[i].y2 +
-                                         src_y_off),
-                                        (box[i].x1 +
-                                         dst_x_off),
-                                        (box[i].y1 +
-                                         dst_y_off),
-                                        (box[i].x2 +
-                                         dst_x_off),
-                                        (box[i].y2 +
-                                         dst_y_off),
-                                        GL_COLOR_BUFFER_BIT, GL_NEAREST);
+            glBlitFramebuffer(box[i].x1 + dx + src_x_off,
+                              box[i].y1 + src_y_off,
+                              box[i].x2 + dx + src_x_off,
+                              box[i].y2 + src_y_off,
+                              box[i].x1 + dst_x_off,
+                              box[i].y1 + dst_y_off,
+                              box[i].x2 + dst_x_off,
+                              box[i].y2 + dst_y_off,
+                              GL_COLOR_BUFFER_BIT, GL_NEAREST);
         }
         else {
             int flip_dst_y1 =
@@ -112,19 +102,15 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
             int flip_src_y2 =
                 src_pixmap->drawable.height - (box[i].y1 + src_y_off);
 
-            dispatch->glBlitFramebuffer(box[i].x1 + dx +
-                                        src_x_off,
-                                        flip_src_y1,
-                                        box[i].x2 + dx +
-                                        src_x_off,
-                                        flip_src_y2,
-                                        box[i].x1 +
-                                        dst_x_off,
-                                        flip_dst_y1,
-                                        box[i].x2 +
-                                        dst_x_off,
-                                        flip_dst_y2,
-                                        GL_COLOR_BUFFER_BIT, GL_NEAREST);
+            glBlitFramebuffer(box[i].x1 + dx + src_x_off,
+                              flip_src_y1,
+                              box[i].x2 + dx + src_x_off,
+                              flip_src_y2,
+                              box[i].x1 + dst_x_off,
+                              flip_dst_y1,
+                              box[i].x2 + dst_x_off,
+                              flip_dst_y2,
+                              GL_COLOR_BUFFER_BIT, GL_NEAREST);
         }
     }
     glamor_put_dispatch(glamor_priv);
@@ -140,7 +126,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 {
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(dst->pScreen);
-    glamor_gl_dispatch *dispatch;
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int i;
@@ -172,37 +157,33 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, 2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     dx += src_x_off;
     dy += src_y_off;
 
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
 #ifndef GLAMOR_GLES2
-    dispatch->glEnable(GL_TEXTURE_2D);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+    glEnable(GL_TEXTURE_2D);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 #endif
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-                                    GL_FLOAT, GL_FALSE,
-                                    2 * sizeof(float), texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-    dispatch->glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE);
-    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
-                          SWAP_NONE_UPLOADING);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(glamor_priv->finish_access_prog[0]);
+    glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE);
+    glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING);
 
     for (i = 0; i < nbox; i++) {
 
@@ -222,15 +203,15 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
                                      box[i].x2 + dx,
                                      box[i].y2 + dy,
                                      glamor_priv->yInverted, texcoords);
-        dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-    dispatch->glDisable(GL_TEXTURE_2D);
+    glDisable(GL_TEXTURE_2D);
 #endif
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
     glamor_put_dispatch(glamor_priv);
     glamor_priv->state = RENDER_STATE;
@@ -367,7 +348,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
     PixmapPtr dst_pixmap, src_pixmap;
     glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     BoxPtr extent;
     RegionRec region;
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
@@ -394,8 +374,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
     if (gc) {
         if (!glamor_set_planemask(dst_pixmap, gc->planemask))
             goto fall_back;
-        dispatch = glamor_get_dispatch(glamor_priv);
-        if (!glamor_set_alu(dispatch, gc->alu)) {
+        glamor_get_dispatch(glamor_priv);
+        if (!glamor_set_alu(gc->alu)) {
             glamor_put_dispatch(glamor_priv);
             goto fail;
         }
@@ -572,8 +552,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
     }
 
  fail:
-    dispatch = glamor_get_dispatch(glamor_priv);
-    glamor_set_alu(dispatch, GXcopy);
+    glamor_get_dispatch(glamor_priv);
+    glamor_set_alu(GXcopy);
     glamor_put_dispatch(glamor_priv);
 
     if (ok)
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4eac856..fe49cb3 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -51,24 +51,23 @@ glamor_get_drawable_location(const DrawablePtr drawable)
 }
 
 GLint
-glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
-                         const char *source)
+glamor_compile_glsl_prog(GLenum type, const char *source)
 {
     GLint ok;
     GLint prog;
 
-    prog = dispatch->glCreateShader(type);
-    dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL);
-    dispatch->glCompileShader(prog);
-    dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+    prog = glCreateShader(type);
+    glShaderSource(prog, 1, (const GLchar **) &source, NULL);
+    glCompileShader(prog);
+    glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
     if (!ok) {
         GLchar *info;
         GLint size;
 
-        dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+        glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
         info = malloc(size);
         if (info) {
-            dispatch->glGetShaderInfoLog(prog, size, NULL, info);
+            glGetShaderInfoLog(prog, size, NULL, info);
             ErrorF("Failed to compile %s: %s\n",
                    type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
             ErrorF("Program source:\n%s", source);
@@ -83,20 +82,20 @@ glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
 }
 
 void
-glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog)
+glamor_link_glsl_prog(GLint prog)
 {
     GLint ok;
 
-    dispatch->glLinkProgram(prog);
-    dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+    glLinkProgram(prog);
+    glGetProgramiv(prog, GL_LINK_STATUS, &ok);
     if (!ok) {
         GLchar *info;
         GLint size;
 
-        dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
         info = malloc(size);
 
-        dispatch->glGetProgramInfoLog(prog, size, NULL, info);
+        glGetProgramInfoLog(prog, size, NULL, info);
         ErrorF("Failed to link: %s\n", info);
         FatalError("GLSL link failure\n");
     }
@@ -143,7 +142,6 @@ void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     const char *vs_source =
         "attribute vec4 v_position;\n"
         "attribute vec4 v_texcoord0;\n"
@@ -217,72 +215,65 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     char *source;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
-    glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
+    glamor_get_dispatch(glamor_priv);
+    glamor_priv->finish_access_prog[0] = glCreateProgram();
+    glamor_priv->finish_access_prog[1] = glCreateProgram();
 
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
 
     XNFasprintf(&source, "%s%s", common_source, fs_source);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
     free(source);
 
-    dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-    dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
 
-    avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
 
     XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
-    set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+    set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
                                               source);
     free(source);
 
-    dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-    dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
-                             set_alpha_prog);
+    glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
 
-    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
-                                   GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
-                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]);
+    glBindAttribLocation(glamor_priv->finish_access_prog[0],
+                         GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(glamor_priv->finish_access_prog[0],
+                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
 
-    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
-                                   GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
-                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]);
+    glBindAttribLocation(glamor_priv->finish_access_prog[1],
+                         GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(glamor_priv->finish_access_prog[1],
+                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
 
     glamor_priv->finish_access_revert[0] =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
-                                       "revert");
+        glGetUniformLocation(glamor_priv->finish_access_prog[0], "revert");
 
     glamor_priv->finish_access_swap_rb[0] =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
-                                       "swap_rb");
+        glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
     sampler_uniform_location =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
-                                       "sampler");
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-    dispatch->glUniform1i(sampler_uniform_location, 0);
-    dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0);
-    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
-    dispatch->glUseProgram(0);
+        glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[0]);
+    glUniform1i(sampler_uniform_location, 0);
+    glUniform1i(glamor_priv->finish_access_revert[0], 0);
+    glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
+    glUseProgram(0);
 
     glamor_priv->finish_access_revert[1] =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
-                                       "revert");
+        glGetUniformLocation(glamor_priv->finish_access_prog[1], "revert");
     glamor_priv->finish_access_swap_rb[1] =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
-                                       "swap_rb");
+        glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
     sampler_uniform_location =
-        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
-                                       "sampler");
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
-    dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0);
-    dispatch->glUniform1i(sampler_uniform_location, 0);
-    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
-    dispatch->glUseProgram(0);
+        glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[1]);
+    glUniform1i(glamor_priv->finish_access_revert[1], 0);
+    glUniform1i(sampler_uniform_location, 0);
+    glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -290,12 +281,11 @@ void
 glamor_fini_finish_access_shaders(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
-    dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
+    glamor_get_dispatch(glamor_priv);
+    glDeleteProgram(glamor_priv->finish_access_prog[0]);
+    glDeleteProgram(glamor_priv->finish_access_prog[1]);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -315,14 +305,12 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
     }
 
     if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
-        glamor_gl_dispatch *dispatch;
-
         assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
 
-        dispatch = glamor_get_dispatch(glamor_priv);
-        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-        dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
+        glamor_get_dispatch(glamor_priv);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+        glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
         glamor_put_dispatch(glamor_priv);
 
         pixmap_priv->base.fbo->pbo_valid = FALSE;
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 2f97a83..906598a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -37,8 +37,6 @@
 #include <errno.h>
 #include <xf86.h>
 #include <xf86drm.h>
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
 #define EGL_DISPLAY_NO_X_MESA
 
 #ifdef GLAMOR_HAS_GBM
@@ -46,19 +44,11 @@
 #include <drm_fourcc.h>
 #endif
 
-#if GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include <GL/gl.h>
-#endif
-
 #define MESA_EGL_NO_X11_HEADERS
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#include <epoxy/gl.h>
+#include <epoxy/egl.h>
 
 #include "glamor.h"
-#include "glamor_gl_dispatch.h"
 
 static const char glamor_name[] = "glamor";
 
@@ -91,10 +81,6 @@ struct glamor_egl_screen_private {
     int gl_context_depth;
     int dri3_capable;
 
-    PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
-    PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
-    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
-    struct glamor_gl_dispatch *dispatch;
     CloseScreenProcPtr saved_close_screen;
     xf86FreeScreenProc *saved_free_screen;
 };
@@ -164,11 +150,11 @@ _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
     attribs[5] = stride;
     if (depth != 32 && depth != 24)
         return EGL_NO_IMAGE_KHR;
-    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-                                             glamor_egl->context,
-                                             EGL_DRM_BUFFER_MESA,
-                                             (void *) (uintptr_t) name,
-                                             attribs);
+    image = eglCreateImageKHR(glamor_egl->display,
+                              glamor_egl->context,
+                              EGL_DRM_BUFFER_MESA,
+                              (void *) (uintptr_t) name,
+                              attribs);
     if (image == EGL_NO_IMAGE_KHR)
         return EGL_NO_IMAGE_KHR;
 
@@ -192,15 +178,13 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
                                  *glamor_egl,
                                  EGLImageKHR image, GLuint * texture)
 {
-    glamor_egl->dispatch->glGenTextures(1, texture);
-    glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture);
-    glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                          GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                          GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-    (glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D, image);
-    glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0);
+    glGenTextures(1, texture);
+    glBindTexture(GL_TEXTURE_2D, *texture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+    glBindTexture(GL_TEXTURE_2D, 0);
     return TRUE;
 }
 
@@ -228,15 +212,15 @@ glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
      * compile with dri3 support enabled */
     native_pixmap = bo;
 
-    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-                                             EGL_NO_CONTEXT,
-                                             EGL_NATIVE_PIXMAP_KHR,
-                                             native_pixmap, NULL);
+    image = eglCreateImageKHR(glamor_egl->display,
+                              EGL_NO_CONTEXT,
+                              EGL_NATIVE_PIXMAP_KHR,
+                              native_pixmap, NULL);
     gbm_bo_destroy(bo);
     if (image == EGL_NO_IMAGE_KHR)
         return 0;
     glamor_create_texture_from_image(glamor_egl, image, &texture);
-    glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+    eglDestroyImageKHR(glamor_egl->display, image);
 
     return texture;
 #else
@@ -356,9 +340,9 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 
     glamor_egl_make_current(screen);
 
-    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-                                             glamor_egl->context,
-                                             EGL_NATIVE_PIXMAP_KHR, bo, NULL);
+    image = eglCreateImageKHR(glamor_egl->display,
+                              glamor_egl->context,
+                              EGL_NATIVE_PIXMAP_KHR, bo, NULL);
     if (image == EGL_NO_IMAGE_KHR) {
         glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
         goto done;
@@ -430,11 +414,11 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
                              glamor_egl_pixmap_private_key);
 
     if (image == EGL_NO_IMAGE_KHR || image == NULL) {
-        image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-                                                 glamor_egl->context,
-                                                 EGL_GL_TEXTURE_2D_KHR,
-                                                 (EGLClientBuffer) (uintptr_t)
-                                                 tex, attribs);
+        image = eglCreateImageKHR(glamor_egl->display,
+                                  glamor_egl->context,
+                                  EGL_GL_TEXTURE_2D_KHR,
+                                  (EGLClientBuffer) (uintptr_t)
+                                  tex, attribs);
         if (image == EGL_NO_IMAGE_KHR)
             goto failure;
 
@@ -506,10 +490,10 @@ glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
     attribs[3] = height;
     attribs[7] = fd;
     attribs[11] = stride;
-    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-                                             EGL_NO_CONTEXT,
-                                             EGL_LINUX_DMA_BUF_EXT,
-                                             NULL, attribs);
+    image = eglCreateImageKHR(glamor_egl->display,
+                              EGL_NO_CONTEXT,
+                              EGL_LINUX_DMA_BUF_EXT,
+                              NULL, attribs);
 
     if (image == EGL_NO_IMAGE_KHR)
         return NULL;
@@ -518,7 +502,7 @@ glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
      * usage of the image. Use gbm_bo to bypass the limitations. */
 
     bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
-    glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+    eglDestroyImageKHR(glamor_egl->display, image);
 
     if (!bo)
         return NULL;
@@ -555,7 +539,7 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
          * a texture. we must call glFlush to make sure the
          * operation on that texture has been done.*/
         glamor_block_handler(pixmap->drawable.pScreen);
-        glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+        eglDestroyImageKHR(glamor_egl->display, image);
         dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
                       NULL);
     }
@@ -605,8 +589,7 @@ glamor_egl_close_screen(ScreenPtr screen)
     glamor_egl = glamor_egl_get_screen_private(scrn);
     screen_pixmap = screen->GetScreenPixmap(screen);
 
-    glamor_egl->egl_destroy_image_khr(glamor_egl->display,
-                                      glamor_egl->front_image);
+    eglDestroyImageKHR(glamor_egl->display,glamor_egl->front_image);
     dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key,
                   NULL);
     glamor_egl->front_image = NULL;
@@ -614,7 +597,7 @@ glamor_egl_close_screen(ScreenPtr screen)
         back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
                                       glamor_egl_pixmap_private_key);
         if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
-            glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
+            eglDestroyImageKHR(glamor_egl->display, back_image);
             dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
                           glamor_egl_pixmap_private_key, NULL);
         }
@@ -751,21 +734,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
         glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import"))
         glamor_egl->dri3_capable = TRUE;
 #endif
-    glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
-        eglGetProcAddress("eglCreateImageKHR");
-
-    glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC)
-        eglGetProcAddress("eglDestroyImageKHR");
-
-    glamor_egl->egl_image_target_texture2d_oes =
-        (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
-        eglGetProcAddress("glEGLImageTargetTexture2DOES");
-
-    if (!glamor_egl->egl_create_image_khr
-        || !glamor_egl->egl_image_target_texture2d_oes) {
-        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n");
-        return FALSE;
-    }
 
     glamor_egl->context = eglCreateContext(glamor_egl->display,
                                            NULL, EGL_NO_CONTEXT,
@@ -809,17 +777,3 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen)
         glamor_enable_dri3(screen);
     return TRUE;
 }
-
-Bool
-glamor_gl_dispatch_init(ScreenPtr screen,
-                        struct glamor_gl_dispatch *dispatch, int gl_version)
-{
-    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    struct glamor_egl_screen_private *glamor_egl =
-        glamor_egl_get_screen_private(scrn);
-    if (!glamor_gl_dispatch_init_impl
-        (dispatch, gl_version, (get_proc_address_t) eglGetProcAddress))
-        return FALSE;
-    glamor_egl->dispatch = dispatch;
-    return TRUE;
-}
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d94e530..bb7af2c 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -129,14 +129,14 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
-    glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_dispatch(fbo->glamor_priv);
 
     if (fbo->fb)
-        dispatch->glDeleteFramebuffers(1, &fbo->fb);
+        glDeleteFramebuffers(1, &fbo->fb);
     if (fbo->tex)
-        dispatch->glDeleteTextures(1, &fbo->tex);
+        glDeleteTextures(1, &fbo->tex);
     if (fbo->pbo)
-        dispatch->glDeleteBuffers(1, &fbo->pbo);
+        glDeleteBuffers(1, &fbo->pbo);
     glamor_put_dispatch(fbo->glamor_priv);
 
     free(fbo);
@@ -178,19 +178,17 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 static void
 glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
-    glamor_gl_dispatch *dispatch;
     int status;
 
-    dispatch = glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_dispatch(fbo->glamor_priv);
 
     if (fbo->fb == 0)
-        dispatch->glGenFramebuffers(1, &fbo->fb);
+        glGenFramebuffers(1, &fbo->fb);
     assert(fbo->tex != 0);
-    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
-    dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
-                                     GL_COLOR_ATTACHMENT0,
-                                     GL_TEXTURE_2D, fbo->tex, 0);
-    status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                           GL_TEXTURE_2D, fbo->tex, 0);
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
     if (status != GL_FRAMEBUFFER_COMPLETE) {
         const char *str;
 
@@ -243,10 +241,8 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->glamor_priv = glamor_priv;
 
     if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
-        glamor_gl_dispatch *dispatch;
-
-        dispatch = glamor_get_dispatch(glamor_priv);
-        dispatch->glGenBuffers(1, &fbo->pbo);
+        glamor_get_dispatch(glamor_priv);
+        glGenBuffers(1, &fbo->pbo);
         glamor_put_dispatch(glamor_priv);
         goto done;
     }
@@ -334,7 +330,6 @@ static int
 _glamor_create_tex(glamor_screen_private *glamor_priv,
                    int w, int h, GLenum format)
 {
-    glamor_gl_dispatch *dispatch;
     unsigned int tex = 0;
 
     /* With dri3, we want to allocate ARGB8888 pixmaps only.
@@ -346,15 +341,13 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
                                                        w, h);
     }
     if (!tex) {
-        dispatch = glamor_get_dispatch(glamor_priv);
-        dispatch->glGenTextures(1, &tex);
-        dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-                                  GL_NEAREST);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-                                  GL_NEAREST);
-        dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-                               format, GL_UNSIGNED_BYTE, NULL);
+        glamor_get_dispatch(glamor_priv);
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, tex);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+                     format, GL_UNSIGNED_BYTE, NULL);
         glamor_put_dispatch(glamor_priv);
     }
     return tex;
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index d59e620..e98fc5b 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -137,7 +137,6 @@ void
 glamor_init_solid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     const char *solid_vs =
         "attribute vec4 v_position;"
         "void main()\n"
@@ -154,19 +153,19 @@ glamor_init_solid_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    glamor_priv->solid_prog = dispatch->glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs);
-    dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
+    glamor_get_dispatch(glamor_priv);
+    glamor_priv->solid_prog = glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
+    glAttachShader(glamor_priv->solid_prog, vs_prog);
+    glAttachShader(glamor_priv->solid_prog, fs_prog);
 
-    dispatch->glBindAttribLocation(glamor_priv->solid_prog,
-                                   GLAMOR_VERTEX_POS, "v_position");
-    glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
+    glBindAttribLocation(glamor_priv->solid_prog,
+                         GLAMOR_VERTEX_POS, "v_position");
+    glamor_link_glsl_prog(glamor_priv->solid_prog);
 
     glamor_priv->solid_color_uniform_location =
-        dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color");
+        glGetUniformLocation(glamor_priv->solid_prog, "color");
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -174,11 +173,10 @@ void
 glamor_fini_solid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glDeleteProgram(glamor_priv->solid_prog);
+    glamor_get_dispatch(glamor_priv);
+    glDeleteProgram(glamor_priv->solid_prog);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -188,7 +186,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_gl_dispatch *dispatch;
     GLfloat xscale, yscale;
     float vertices[32];
     float *pvertices = vertices;
@@ -196,10 +193,10 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glUseProgram(glamor_priv->solid_prog);
+    glamor_get_dispatch(glamor_priv);
+    glUseProgram(glamor_priv->solid_prog);
 
-    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
+    glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
 
     pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
 
@@ -221,11 +218,11 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
     }
 
     if (_X_UNLIKELY(nbox > 1))
-        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), pvertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, 2 * sizeof(float), pvertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     while (nbox) {
         int box_cnt, i;
@@ -242,16 +239,13 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
             valid_vertices += 4 * 2;
         }
         if (box_cnt == 1)
-            dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
+            glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
         else
 #ifndef GLAMOR_GLES2
-            dispatch->glDrawRangeElements(GL_TRIANGLES,
-                                          0,
-                                          box_cnt * 4,
-                                          box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
+            glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
+                                GL_UNSIGNED_SHORT, NULL);
 #else
-            dispatch->glDrawElements(GL_TRIANGLES,
-                                     box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
+            glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
 #endif
         nbox -= box_cnt;
         box += box_cnt;
@@ -260,8 +254,8 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
     if (pvertices != vertices)
         free(pvertices);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
@@ -321,7 +315,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private *pixmap_priv;
-    glamor_gl_dispatch *dispatch;
     BoxRec box;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -334,8 +327,8 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
         return FALSE;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    if (!glamor_set_alu(dispatch, alu)) {
+    glamor_get_dispatch(glamor_priv);
+    if (!glamor_set_alu(alu)) {
         if (alu == GXclear)
             fg_pixel = 0;
         else {
@@ -350,7 +343,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     box.y2 = y + height;
     glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
 
-    glamor_set_alu(dispatch, GXcopy);
+    glamor_set_alu(GXcopy);
     glamor_put_dispatch(glamor_priv);
 
     return TRUE;
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
deleted file mode 100644
index 0bdda9c..0000000
--- a/glamor/glamor_gl_dispatch.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- * Copyright © 1998 Keith Packard
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Zhigang Gong <zhigang.gong at gmail.com>
- *
- */
-
-#include "glamor_priv.h"
-#include <dlfcn.h>
-
-#define INIT_FUNC(dst,func_name,get)			\
-  dst->func_name = get(#func_name);			\
-  if (dst->func_name == NULL) {				\
-    dst->func_name = (void *)dlsym(NULL, #func_name);	\
-    if (dst->func_name == NULL) {			\
-      ErrorF("Failed to get function %s\n", #func_name);\
-      goto fail;					\
-    }							\
-  }							\
-
-_X_EXPORT Bool
-glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-                             int gl_version,
-                             void *(*get_proc_address) (const char *))
-{
-#ifndef GLAMOR_GLES2
-    INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
-    INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
-    INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
-    INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
-    INIT_FUNC(dispatch, glLogicOp, get_proc_address);
-    INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
-    INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
-    INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
-    INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
-    INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address);
-#endif
-    INIT_FUNC(dispatch, glViewport, get_proc_address);
-    INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
-    INIT_FUNC(dispatch, glDrawElements, get_proc_address);
-    INIT_FUNC(dispatch, glReadPixels, get_proc_address);
-    INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
-    INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
-    INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
-    INIT_FUNC(dispatch, glGenTextures, get_proc_address);
-    INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
-    INIT_FUNC(dispatch, glBindTexture, get_proc_address);
-    INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
-    INIT_FUNC(dispatch, glFlush, get_proc_address);
-    INIT_FUNC(dispatch, glFinish, get_proc_address);
-    INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
-    INIT_FUNC(dispatch, glGetString, get_proc_address);
-    INIT_FUNC(dispatch, glScissor, get_proc_address);
-    INIT_FUNC(dispatch, glEnable, get_proc_address);
-    INIT_FUNC(dispatch, glDisable, get_proc_address);
-    INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
-    INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
-    INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
-    INIT_FUNC(dispatch, glBufferData, get_proc_address);
-    INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
-    INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
-    INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
-    INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
-    INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
-    INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
-    INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
-    INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
-    INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
-    INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
-    INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
-    INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
-    INIT_FUNC(dispatch, glShaderSource, get_proc_address);
-
-    INIT_FUNC(dispatch, glUseProgram, get_proc_address);
-    INIT_FUNC(dispatch, glUniform1i, get_proc_address);
-    INIT_FUNC(dispatch, glUniform1f, get_proc_address);
-    INIT_FUNC(dispatch, glUniform4f, get_proc_address);
-    INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
-    INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
-    INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
-    INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address);
-    INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
-    INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
-    INIT_FUNC(dispatch, glCreateShader, get_proc_address);
-    INIT_FUNC(dispatch, glCompileShader, get_proc_address);
-    INIT_FUNC(dispatch, glAttachShader, get_proc_address);
-    INIT_FUNC(dispatch, glDeleteShader, get_proc_address);
-    INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
-    INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
-    INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
-    INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
-    INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
-
-    return TRUE;
- fail:
-    return FALSE;
-}
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
deleted file mode 100644
index 63790b4..0000000
--- a/glamor/glamor_gl_dispatch.h
+++ /dev/null
@@ -1,128 +0,0 @@
-typedef struct glamor_gl_dispatch {
-    /* Transformation functions */
-    void (*glMatrixMode) (GLenum mode);
-    void (*glLoadIdentity) (void);
-    void (*glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
-    /* Drawing functions */
-    void (*glRasterPos2i) (GLint x, GLint y);
-
-    /* Vertex Array */
-    void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
-
-    /* Elements Array */
-    void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type,
-                            const GLvoid * indices);
-    void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end,
-                                 GLsizei count, GLenum type,
-                                 const GLvoid * indices);
-
-    /* Raster functions */
-    void (*glReadPixels) (GLint x, GLint y,
-                          GLsizei width, GLsizei height,
-                          GLenum format, GLenum type, GLvoid * pixels);
-
-    void (*glDrawPixels) (GLsizei width, GLsizei height,
-                          GLenum format, GLenum type, const GLvoid * pixels);
-    void (*glPixelStorei) (GLenum pname, GLint param);
-    /* Texture Mapping */
-
-    void (*glTexParameteri) (GLenum target, GLenum pname, GLint param);
-    void (*glTexImage2D) (GLenum target, GLint level,
-                          GLint internalFormat,
-                          GLsizei width, GLsizei height,
-                          GLint border, GLenum format, GLenum type,
-                          const GLvoid * pixels);
-    /* 1.1 */
-    void (*glGenTextures) (GLsizei n, GLuint * textures);
-    void (*glDeleteTextures) (GLsizei n, const GLuint * textures);
-    void (*glBindTexture) (GLenum target, GLuint texture);
-    void (*glTexSubImage2D) (GLenum target, GLint level,
-                             GLint xoffset, GLint yoffset,
-                             GLsizei width, GLsizei height,
-                             GLenum format, GLenum type, const GLvoid * pixels);
-    /* MISC */
-    void (*glFlush) (void);
-    void (*glFinish) (void);
-    void (*glGetIntegerv) (GLenum pname, GLint * params);
-    const GLubyte *(*glGetString) (GLenum name);
-    void (*glScissor) (GLint x, GLint y, GLsizei width, GLsizei height);
-    void (*glEnable) (GLenum cap);
-    void (*glDisable) (GLenum cap);
-    void (*glBlendFunc) (GLenum sfactor, GLenum dfactor);
-    void (*glLogicOp) (GLenum opcode);
-
-    /* 1.3 */
-    void (*glActiveTexture) (GLenum texture);
-
-    /* GL Extentions */
-    void (*glGenBuffers) (GLsizei n, GLuint * buffers);
-    void (*glBufferData) (GLenum target, GLsizeiptr size,
-                          const GLvoid * data, GLenum usage);
-    GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
-    GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset,
-                                 GLsizeiptr length, GLbitfield access);
-     GLboolean(*glUnmapBuffer) (GLenum target);
-    void (*glBindBuffer) (GLenum target, GLuint buffer);
-    void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
-
-    void (*glFramebufferTexture2D) (GLenum target, GLenum attachment,
-                                    GLenum textarget, GLuint texture,
-                                    GLint level);
-    void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
-    void (*glDeleteFramebuffers) (GLsizei n, const GLuint * framebuffers);
-    void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers);
-     GLenum(*glCheckFramebufferStatus) (GLenum target);
-    void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1,
-                               GLint srcY1, GLint dstX0, GLint dstY0,
-                               GLint dstX1, GLint dstY1,
-                               GLbitfield mask, GLenum filter);
-
-    void (*glVertexAttribPointer) (GLuint index, GLint size,
-                                   GLenum type, GLboolean normalized,
-                                   GLsizei stride, const GLvoid * pointer);
-    void (*glDisableVertexAttribArray) (GLuint index);
-    void (*glEnableVertexAttribArray) (GLuint index);
-    void (*glBindAttribLocation) (GLuint program, GLuint index,
-                                  const GLchar * name);
-
-    void (*glLinkProgram) (GLuint program);
-    void (*glShaderSource) (GLuint shader, GLsizei count,
-                            const GLchar * *string, const GLint * length);
-    void (*glUseProgram) (GLuint program);
-    void (*glUniform1i) (GLint location, GLint v0);
-    void (*glUniform1f) (GLint location, GLfloat v0);
-    void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
-                         GLfloat v2, GLfloat v3);
-    void (*glUniform1fv) (GLint location, GLsizei count, const GLfloat * value);
-    void (*glUniform2fv) (GLint location, GLsizei count, const GLfloat * value);
-    void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat * value);
-    void (*glUniformMatrix3fv) (GLint location, GLsizei count,
-                                GLboolean transpose, const GLfloat * value);
-     GLuint(*glCreateProgram) (void);
-     GLuint(*glDeleteProgram) (GLuint);
-     GLuint(*glCreateShader) (GLenum type);
-    void (*glCompileShader) (GLuint shader);
-    void (*glAttachShader) (GLuint program, GLuint shader);
-    void (*glDeleteShader) (GLuint shader);
-    void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint * params);
-    void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
-                                GLsizei * length, GLchar * infoLog);
-    void (*glGetProgramiv) (GLuint program, GLenum pname, GLint * params);
-    void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize,
-                                 GLsizei * length, GLchar * infoLog);
-     GLint(*glGetUniformLocation) (GLuint program, const GLchar * name);
-
-} glamor_gl_dispatch;
-
-typedef void *(*get_proc_address_t) (const char *);
-
-_X_EXPORT Bool
-
-glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-                             int gl_version,
-                             get_proc_address_t get_proc_address);
-
-_X_EXPORT Bool
-
-glamor_gl_dispatch_init(ScreenPtr screen,
-                        struct glamor_gl_dispatch *dispatch, int gl_version);
diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h
deleted file mode 100644
index 2a220c3..0000000
--- a/glamor/glamor_glext.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright © 2001 Keith Packard
- * Copyright © 2008 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Zhigang Gong <zhigang.gong at linux.intel.com>
- *
- */
-
-#ifdef GLAMOR_GLES2
-
-#define GL_BGRA                                 GL_BGRA_EXT
-#define GL_COLOR_INDEX                          0x1900
-#define GL_BITMAP                               0x1A00
-#define GL_UNSIGNED_INT_8_8_8_8                 0x8035
-#define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367
-#define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368
-#define GL_UNSIGNED_INT_10_10_10_2              0x8036
-#define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
-
-#define GL_PIXEL_PACK_BUFFER              0x88EB
-#define GL_PIXEL_UNPACK_BUFFER            0x88EC
-#define GL_CLAMP_TO_BORDER                0x812D
-
-#define GL_READ_WRITE                     0x88BA
-#define GL_READ_ONLY                      0x88B8
-#define GL_WRITE_ONLY                     0x88B9
-#define GL_STREAM_DRAW                    0x88E0
-#define GL_STREAM_READ                    0x88E1
-#define GL_PACK_ROW_LENGTH                      0x0D02
-#define GL_UNPACK_ROW_LENGTH                    0x0CF2
-
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
-
-#define GL_PACK_INVERT_MESA               0x8758
-#define GL_MAP_UNSYNCHRONIZED_BIT         0x0020
-#define GL_MAP_READ_BIT                   0x0001
-#define GL_MAP_WRITE_BIT                  0x0002
-
-#endif
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 3586b33..c118f34 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -1274,14 +1274,12 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
             if (buffer->source == NULL)
                 buffer->source = source;
             if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
-                glamor_gl_dispatch *dispatch;
-
                 /* mode 1 means we are using global mask cache,
                  * thus we have to composite from the cache picture
                  * to the cache picture, we need a flush here to make
                  * sure latter we get the corret glyphs data.*/
-                dispatch = glamor_get_dispatch(glamor_priv);
-                dispatch->glFlush();
+                glamor_get_dispatch(glamor_priv);
+                glFlush();
                 glamor_put_dispatch(glamor_priv);
             }
         }
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index df2ccb8..08df996 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -47,7 +47,6 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
                                    int use_array)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     char *gradient_fs = NULL;
     GLint fs_getcolor_prog;
@@ -177,18 +176,18 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
         "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     if (use_array) {
         XNFasprintf(&gradient_fs,
                     gradient_fs_getcolor, stops_count, stops_count);
         fs_getcolor_prog =
-            glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, gradient_fs);
+            glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
         free(gradient_fs);
     }
     else {
         fs_getcolor_prog =
-            glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+            glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
                                      gradient_fs_getcolor_no_array);
     }
 
@@ -200,7 +199,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
                                        int dyn_gen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     int index;
 
     GLint gradient_prog = 0;
@@ -355,42 +353,37 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
-        dispatch->glDeleteShader(glamor_priv->
-                                 radial_gradient_shaders
-                                 [SHADER_GRADIENT_VS_PROG][2]);
+        glDeleteShader(glamor_priv->radial_gradient_shaders
+                       [SHADER_GRADIENT_VS_PROG][2]);
         glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
 
-        dispatch->glDeleteShader(glamor_priv->
-                                 radial_gradient_shaders
-                                 [SHADER_GRADIENT_FS_MAIN_PROG][2]);
+        glDeleteShader(glamor_priv->radial_gradient_shaders
+                       [SHADER_GRADIENT_FS_MAIN_PROG][2]);
         glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
             0;
 
-        dispatch->glDeleteShader(glamor_priv->
-                                 radial_gradient_shaders
-                                 [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+        glDeleteShader(glamor_priv->radial_gradient_shaders
+                       [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
         glamor_priv->
             radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
 
-        dispatch->glDeleteProgram(glamor_priv->
-                                  gradient_prog[SHADER_GRADIENT_RADIAL][2]);
+        glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
         glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
     }
 
-    gradient_prog = dispatch->glCreateProgram();
+    gradient_prog = glCreateProgram();
 
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs);
 
     XNFasprintf(&gradient_fs,
                 gradient_radial_fs_template,
                 PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL,
                 PIXMAN_REPEAT_REFLECT);
 
-    fs_main_prog = glamor_compile_glsl_prog(dispatch,
-                                            GL_FRAGMENT_SHADER, gradient_fs);
+    fs_main_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
 
     free(gradient_fs);
 
@@ -398,18 +391,16 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         _glamor_create_getcolor_fs_program(screen, stops_count,
                                            (stops_count > 0));
 
-    dispatch->glAttachShader(gradient_prog, vs_prog);
-    dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-    dispatch->glAttachShader(gradient_prog, fs_main_prog);
+    glAttachShader(gradient_prog, vs_prog);
+    glAttachShader(gradient_prog, fs_getcolor_prog);
+    glAttachShader(gradient_prog, fs_main_prog);
 
-    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS,
-                                   "v_positionsition");
-    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE,
-                                   "v_texcoord");
+    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
+    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
 
-    glamor_link_glsl_prog(dispatch, gradient_prog);
+    glamor_link_glsl_prog(gradient_prog);
 
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
 
     if (dyn_gen) {
         index = 2;
@@ -439,7 +430,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
                                        int dyn_gen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     int index = 0;
     GLint gradient_prog = 0;
@@ -596,58 +586,51 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
-        dispatch->glDeleteShader(glamor_priv->
-                                 linear_gradient_shaders
-                                 [SHADER_GRADIENT_VS_PROG][2]);
+        glDeleteShader(glamor_priv->linear_gradient_shaders
+                       [SHADER_GRADIENT_VS_PROG][2]);
         glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
 
-        dispatch->glDeleteShader(glamor_priv->
-                                 linear_gradient_shaders
-                                 [SHADER_GRADIENT_FS_MAIN_PROG][2]);
+        glDeleteShader(glamor_priv->linear_gradient_shaders
+                       [SHADER_GRADIENT_FS_MAIN_PROG][2]);
         glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
             0;
 
-        dispatch->glDeleteShader(glamor_priv->
-                                 linear_gradient_shaders
-                                 [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+        glDeleteShader(glamor_priv->linear_gradient_shaders
+                       [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
         glamor_priv->
             linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
 
-        dispatch->glDeleteProgram(glamor_priv->
-                                  gradient_prog[SHADER_GRADIENT_LINEAR][2]);
+        glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
         glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
     }
 
-    gradient_prog = dispatch->glCreateProgram();
+    gradient_prog = glCreateProgram();
 
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, gradient_vs);
 
     XNFasprintf(&gradient_fs,
                 gradient_fs_template,
                 PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
 
-    fs_main_prog = glamor_compile_glsl_prog(dispatch,
-                                            GL_FRAGMENT_SHADER, gradient_fs);
+    fs_main_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, gradient_fs);
     free(gradient_fs);
 
     fs_getcolor_prog =
         _glamor_create_getcolor_fs_program(screen, stops_count,
                                            (stops_count > 0));
 
-    dispatch->glAttachShader(gradient_prog, vs_prog);
-    dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-    dispatch->glAttachShader(gradient_prog, fs_main_prog);
+    glAttachShader(gradient_prog, vs_prog);
+    glAttachShader(gradient_prog, fs_getcolor_prog);
+    glAttachShader(gradient_prog, fs_main_prog);
 
-    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS,
-                                   "v_position");
-    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE,
-                                   "v_texcoord");
+    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
 
-    glamor_link_glsl_prog(dispatch, gradient_prog);
+    glamor_link_glsl_prog(gradient_prog);
 
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
 
     if (dyn_gen) {
         index = 2;
@@ -709,56 +692,49 @@ void
 glamor_fini_gradient_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     int i = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     for (i = 0; i < 3; i++) {
         /* Linear Gradient */
         if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     linear_gradient_shaders
-                                     [SHADER_GRADIENT_VS_PROG][i]);
+            glDeleteShader(glamor_priv->linear_gradient_shaders
+                           [SHADER_GRADIENT_VS_PROG][i]);
 
         if (glamor_priv->
             linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     linear_gradient_shaders
-                                     [SHADER_GRADIENT_FS_MAIN_PROG][i]);
+            glDeleteShader(glamor_priv->linear_gradient_shaders
+                           [SHADER_GRADIENT_FS_MAIN_PROG][i]);
 
         if (glamor_priv->
             linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     linear_gradient_shaders
-                                     [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+            glDeleteShader(glamor_priv->linear_gradient_shaders
+                           [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
 
         if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
-            dispatch->glDeleteProgram(glamor_priv->
-                                      gradient_prog[SHADER_GRADIENT_LINEAR][i]);
+            glDeleteProgram(glamor_priv->gradient_prog
+                            [SHADER_GRADIENT_LINEAR][i]);
 
         /* Radial Gradient */
         if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     radial_gradient_shaders
-                                     [SHADER_GRADIENT_VS_PROG][i]);
+            glDeleteShader(glamor_priv->radial_gradient_shaders
+                           [SHADER_GRADIENT_VS_PROG][i]);
 
         if (glamor_priv->
             radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     radial_gradient_shaders
-                                     [SHADER_GRADIENT_FS_MAIN_PROG][i]);
+            glDeleteShader(glamor_priv->radial_gradient_shaders
+                           [SHADER_GRADIENT_FS_MAIN_PROG][i]);
 
         if (glamor_priv->
             radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-            dispatch->glDeleteShader(glamor_priv->
-                                     radial_gradient_shaders
-                                     [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+            glDeleteShader(glamor_priv->radial_gradient_shaders
+                           [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
 
         if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
-            dispatch->glDeleteProgram(glamor_priv->
-                                      gradient_prog[SHADER_GRADIENT_RADIAL][i]);
+            glDeleteProgram(glamor_priv->gradient_prog
+                            [SHADER_GRADIENT_RADIAL][i]);
     }
 
     glamor_put_dispatch(glamor_priv);
@@ -835,7 +811,6 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 {
     glamor_pixmap_private *pixmap_priv;
     PixmapPtr pixmap = NULL;
-    glamor_gl_dispatch *dispatch = NULL;
 
     pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
     pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -893,15 +868,15 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
            tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
            tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 0, vertices);
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                                    GL_FALSE, 0, tex_vertices);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, 0, vertices);
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                          GL_FALSE, 0, tex_vertices);
 
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glamor_put_dispatch(glamor_priv);
 
@@ -996,7 +971,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
                                         PictFormatShort format)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     PicturePtr dst_picture = NULL;
     PixmapPtr pixmap = NULL;
     GLint gradient_prog = 0;
@@ -1047,7 +1021,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     GLint r2_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1088,77 +1062,74 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     }
 
     /* Bind all the uniform vars . */
-    transform_mat_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
-    repeat_type_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-    n_stop_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "n_stop");
-    A_value_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "A_value");
-    repeat_type_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-    c1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c1");
-    r1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r1");
-    c2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c2");
-    r2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r2");
+    transform_mat_uniform_location = glGetUniformLocation(gradient_prog,
+                                                          "transform_mat");
+    repeat_type_uniform_location = glGetUniformLocation(gradient_prog,
+                                                        "repeat_type");
+    n_stop_uniform_location = glGetUniformLocation(gradient_prog, "n_stop");
+    A_value_uniform_location = glGetUniformLocation(gradient_prog, "A_value");
+    repeat_type_uniform_location =glGetUniformLocation(gradient_prog,
+                                                       "repeat_type");
+    c1_uniform_location = glGetUniformLocation(gradient_prog, "c1");
+    r1_uniform_location = glGetUniformLocation(gradient_prog, "r1");
+    c2_uniform_location = glGetUniformLocation(gradient_prog, "c2");
+    r2_uniform_location = glGetUniformLocation(gradient_prog, "r2");
 
     if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
         stop0_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop0");
+            glGetUniformLocation(gradient_prog, "stop0");
         stop1_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop1");
+            glGetUniformLocation(gradient_prog, "stop1");
         stop2_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop2");
+            glGetUniformLocation(gradient_prog, "stop2");
         stop3_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop3");
+            glGetUniformLocation(gradient_prog, "stop3");
         stop4_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop4");
+            glGetUniformLocation(gradient_prog, "stop4");
         stop5_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop5");
+            glGetUniformLocation(gradient_prog, "stop5");
         stop6_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop6");
+            glGetUniformLocation(gradient_prog, "stop6");
         stop7_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop7");
+            glGetUniformLocation(gradient_prog, "stop7");
 
         stop_color0_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+            glGetUniformLocation(gradient_prog, "stop_color0");
         stop_color1_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+            glGetUniformLocation(gradient_prog, "stop_color1");
         stop_color2_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+            glGetUniformLocation(gradient_prog, "stop_color2");
         stop_color3_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+            glGetUniformLocation(gradient_prog, "stop_color3");
         stop_color4_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+            glGetUniformLocation(gradient_prog, "stop_color4");
         stop_color5_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+            glGetUniformLocation(gradient_prog, "stop_color5");
         stop_color6_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+            glGetUniformLocation(gradient_prog, "stop_color6");
         stop_color7_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+            glGetUniformLocation(gradient_prog, "stop_color7");
     }
     else {
         stops_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stops");
+            glGetUniformLocation(gradient_prog, "stops");
         stop_colors_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+            glGetUniformLocation(gradient_prog, "stop_colors");
     }
 
-    dispatch->glUseProgram(gradient_prog);
+    glUseProgram(gradient_prog);
 
-    dispatch->glUniform1i(repeat_type_uniform_location,
-                          src_picture->repeatType);
+    glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
 
     if (src_picture->transform) {
         _glamor_gradient_convert_trans_matrix(src_picture->transform,
                                               transform_mat, width, height, 0);
-        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-                                     1, 1, &transform_mat[0][0]);
+        glUniformMatrix3fv(transform_mat_uniform_location,
+                           1, 1, &transform_mat[0][0]);
     }
     else {
-        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-                                     1, 1, &identity_mat[0][0]);
+        glUniformMatrix3fv(transform_mat_uniform_location,
+                           1, 1, &identity_mat[0][0]);
     }
 
     if (!_glamor_gradient_set_pixmap_destination
@@ -1193,54 +1164,53 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
         int j = 0;
 
-        dispatch->glUniform4f(stop_color0_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color0_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color1_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color1_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color2_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color2_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color3_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color3_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color4_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color4_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color5_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color5_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color6_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color6_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color7_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color7_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
 
         j = 0;
-        dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-        dispatch->glUniform1i(n_stop_uniform_location, count);
+        glUniform1f(stop0_uniform_location, n_stops[j++]);
+        glUniform1f(stop1_uniform_location, n_stops[j++]);
+        glUniform1f(stop2_uniform_location, n_stops[j++]);
+        glUniform1f(stop3_uniform_location, n_stops[j++]);
+        glUniform1f(stop4_uniform_location, n_stops[j++]);
+        glUniform1f(stop5_uniform_location, n_stops[j++]);
+        glUniform1f(stop6_uniform_location, n_stops[j++]);
+        glUniform1f(stop7_uniform_location, n_stops[j++]);
+        glUniform1i(n_stop_uniform_location, count);
     }
     else {
-        dispatch->glUniform4fv(stop_colors_uniform_location, count,
-                               stop_colors);
-        dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-        dispatch->glUniform1i(n_stop_uniform_location, count);
+        glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+        glUniform1fv(stops_uniform_location, count, n_stops);
+        glUniform1i(n_stop_uniform_location, count);
     }
 
     c1x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
@@ -1255,25 +1225,25 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
     glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted,
                              cxy);
-    dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
-    dispatch->glUniform1f(r1_uniform_location, r1);
+    glUniform2fv(c1_uniform_location, 1, cxy);
+    glUniform1f(r1_uniform_location, r1);
 
     glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted,
                              cxy);
-    dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
-    dispatch->glUniform1f(r2_uniform_location, r2);
+    glUniform2fv(c2_uniform_location, 1, cxy);
+    glUniform1f(r2_uniform_location, r2);
 
     A_value =
         (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 -
                                                                  r1) * (r2 -
                                                                         r1);
-    dispatch->glUniform1f(A_value_uniform_location, A_value);
+    glUniform1f(A_value_uniform_location, A_value);
 
     DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
            c1x, c1y, r1, c2x, c2y, r2, A_value);
 
     /* Now rendering. */
-    dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
     /* Do the clear logic. */
     if (stops_count > RADIAL_SMALL_STOPS) {
@@ -1281,12 +1251,12 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
         free(stop_colors);
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
 
     glamor_put_dispatch(glamor_priv);
     return dst_picture;
@@ -1303,12 +1273,12 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
             free(stop_colors);
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     return NULL;
 }
@@ -1321,7 +1291,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
                                         PictFormatShort format)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     PicturePtr dst_picture = NULL;
     PixmapPtr pixmap = NULL;
     GLint gradient_prog = 0;
@@ -1374,7 +1343,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     GLint pt_distance_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1417,79 +1386,78 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
     /* Bind all the uniform vars . */
     n_stop_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+        glGetUniformLocation(gradient_prog, "n_stop");
     pt_slope_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
+        glGetUniformLocation(gradient_prog, "pt_slope");
     repeat_type_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+        glGetUniformLocation(gradient_prog, "repeat_type");
     hor_ver_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
+        glGetUniformLocation(gradient_prog, "hor_ver");
     transform_mat_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+        glGetUniformLocation(gradient_prog, "transform_mat");
     cos_val_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "cos_val");
+        glGetUniformLocation(gradient_prog, "cos_val");
     p1_distance_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
+        glGetUniformLocation(gradient_prog, "p1_distance");
     pt_distance_uniform_location =
-        dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
+        glGetUniformLocation(gradient_prog, "pt_distance");
 
     if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
         stop0_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop0");
+            glGetUniformLocation(gradient_prog, "stop0");
         stop1_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop1");
+            glGetUniformLocation(gradient_prog, "stop1");
         stop2_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop2");
+            glGetUniformLocation(gradient_prog, "stop2");
         stop3_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop3");
+            glGetUniformLocation(gradient_prog, "stop3");
         stop4_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop4");
+            glGetUniformLocation(gradient_prog, "stop4");
         stop5_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop5");
+            glGetUniformLocation(gradient_prog, "stop5");
         stop6_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop6");
+            glGetUniformLocation(gradient_prog, "stop6");
         stop7_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop7");
+            glGetUniformLocation(gradient_prog, "stop7");
 
         stop_color0_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+            glGetUniformLocation(gradient_prog, "stop_color0");
         stop_color1_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+            glGetUniformLocation(gradient_prog, "stop_color1");
         stop_color2_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+            glGetUniformLocation(gradient_prog, "stop_color2");
         stop_color3_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+            glGetUniformLocation(gradient_prog, "stop_color3");
         stop_color4_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+            glGetUniformLocation(gradient_prog, "stop_color4");
         stop_color5_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+            glGetUniformLocation(gradient_prog, "stop_color5");
         stop_color6_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+            glGetUniformLocation(gradient_prog, "stop_color6");
         stop_color7_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+            glGetUniformLocation(gradient_prog, "stop_color7");
     }
     else {
         stops_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stops");
+            glGetUniformLocation(gradient_prog, "stops");
         stop_colors_uniform_location =
-            dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+            glGetUniformLocation(gradient_prog, "stop_colors");
     }
 
-    dispatch->glUseProgram(gradient_prog);
+    glUseProgram(gradient_prog);
 
-    dispatch->glUniform1i(repeat_type_uniform_location,
-                          src_picture->repeatType);
+    glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
 
     /* set the transform matrix. */
     if (src_picture->transform) {
         _glamor_gradient_convert_trans_matrix(src_picture->transform,
                                               transform_mat, width, height, 1);
-        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-                                     1, 1, &transform_mat[0][0]);
+        glUniformMatrix3fv(transform_mat_uniform_location,
+                           1, 1, &transform_mat[0][0]);
     }
     else {
-        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-                                     1, 1, &identity_mat[0][0]);
+        glUniformMatrix3fv(transform_mat_uniform_location,
+                           1, 1, &identity_mat[0][0]);
     }
 
     if (!_glamor_gradient_set_pixmap_destination
@@ -1547,66 +1515,65 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
         int j = 0;
 
-        dispatch->glUniform4f(stop_color0_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color0_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color1_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color1_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color2_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color2_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color3_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color3_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color4_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color4_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color5_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color5_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color6_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color6_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
         j++;
-        dispatch->glUniform4f(stop_color7_uniform_location,
-                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
-                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        glUniform4f(stop_color7_uniform_location,
+                    stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                    stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
 
         j = 0;
-        dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-        dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-
-        dispatch->glUniform1i(n_stop_uniform_location, count);
+        glUniform1f(stop0_uniform_location, n_stops[j++]);
+        glUniform1f(stop1_uniform_location, n_stops[j++]);
+        glUniform1f(stop2_uniform_location, n_stops[j++]);
+        glUniform1f(stop3_uniform_location, n_stops[j++]);
+        glUniform1f(stop4_uniform_location, n_stops[j++]);
+        glUniform1f(stop5_uniform_location, n_stops[j++]);
+        glUniform1f(stop6_uniform_location, n_stops[j++]);
+        glUniform1f(stop7_uniform_location, n_stops[j++]);
+
+        glUniform1i(n_stop_uniform_location, count);
     }
     else {
-        dispatch->glUniform4fv(stop_colors_uniform_location, count,
-                               stop_colors);
-        dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-        dispatch->glUniform1i(n_stop_uniform_location, count);
+        glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+        glUniform1fv(stops_uniform_location, count, n_stops);
+        glUniform1i(n_stop_uniform_location, count);
     }
 
     if (src_picture->pSourcePict->linear.p2.y == src_picture->pSourcePict->linear.p1.y) {       // The horizontal case.
-        dispatch->glUniform1i(hor_ver_uniform_location, 1);
+        glUniform1i(hor_ver_uniform_location, 1);
         DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n",
                pt1[1], pt2[1]);
 
         p1_distance = pt1[0];
         pt_distance = (pt2[0] - p1_distance);
-        dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-        dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+        glUniform1f(p1_distance_uniform_location, p1_distance);
+        glUniform1f(pt_distance_uniform_location, pt_distance);
     }
     else {
         /* The slope need to compute here. In shader, the viewport set will change
@@ -1616,20 +1583,20 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
             (float) (src_picture->pSourcePict->linear.p2.y
                      - src_picture->pSourcePict->linear.p1.y);
         slope = slope * yscale / xscale;
-        dispatch->glUniform1f(pt_slope_uniform_location, slope);
-        dispatch->glUniform1i(hor_ver_uniform_location, 0);
+        glUniform1f(pt_slope_uniform_location, slope);
+        glUniform1i(hor_ver_uniform_location, 0);
 
         cos_val = sqrt(1.0 / (slope * slope + 1.0));
-        dispatch->glUniform1f(cos_val_uniform_location, cos_val);
+        glUniform1f(cos_val_uniform_location, cos_val);
 
         p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
         pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
-        dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-        dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+        glUniform1f(p1_distance_uniform_location, p1_distance);
+        glUniform1f(pt_distance_uniform_location, pt_distance);
     }
 
     /* Now rendering. */
-    dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
     /* Do the clear logic. */
     if (stops_count > LINEAR_SMALL_STOPS) {
@@ -1637,12 +1604,12 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
         free(stop_colors);
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
 
     glamor_put_dispatch(glamor_priv);
     return dst_picture;
@@ -1659,12 +1626,12 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
             free(stop_colors);
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     return NULL;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f7de59c..7f152fc 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -66,16 +66,16 @@ void
 glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
                                   int width, int height)
 {
-    glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+    glamor_get_dispatch(fbo->glamor_priv);
 
-    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 #ifndef GLAMOR_GLES2
-    dispatch->glMatrixMode(GL_PROJECTION);
-    dispatch->glLoadIdentity();
-    dispatch->glMatrixMode(GL_MODELVIEW);
-    dispatch->glLoadIdentity();
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
 #endif
-    dispatch->glViewport(x0, y0, width, height);
+    glViewport(x0, y0, width, height);
 
     glamor_put_dispatch(fbo->glamor_priv);
 }
@@ -121,59 +121,59 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 }
 
 Bool
-glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
+glamor_set_alu(unsigned char alu)
 {
 #ifndef GLAMOR_GLES2
     if (alu == GXcopy) {
-        dispatch->glDisable(GL_COLOR_LOGIC_OP);
+        glDisable(GL_COLOR_LOGIC_OP);
         return TRUE;
     }
-    dispatch->glEnable(GL_COLOR_LOGIC_OP);
+    glEnable(GL_COLOR_LOGIC_OP);
     switch (alu) {
     case GXclear:
-        dispatch->glLogicOp(GL_CLEAR);
+        glLogicOp(GL_CLEAR);
         break;
     case GXand:
-        dispatch->glLogicOp(GL_AND);
+        glLogicOp(GL_AND);
         break;
     case GXandReverse:
-        dispatch->glLogicOp(GL_AND_REVERSE);
+        glLogicOp(GL_AND_REVERSE);
         break;
     case GXandInverted:
-        dispatch->glLogicOp(GL_AND_INVERTED);
+        glLogicOp(GL_AND_INVERTED);
         break;
     case GXnoop:
-        dispatch->glLogicOp(GL_NOOP);
+        glLogicOp(GL_NOOP);
         break;
     case GXxor:
-        dispatch->glLogicOp(GL_XOR);
+        glLogicOp(GL_XOR);
         break;
     case GXor:
-        dispatch->glLogicOp(GL_OR);
+        glLogicOp(GL_OR);
         break;
     case GXnor:
-        dispatch->glLogicOp(GL_NOR);
+        glLogicOp(GL_NOR);
         break;
     case GXequiv:
-        dispatch->glLogicOp(GL_EQUIV);
+        glLogicOp(GL_EQUIV);
         break;
     case GXinvert:
-        dispatch->glLogicOp(GL_INVERT);
+        glLogicOp(GL_INVERT);
         break;
     case GXorReverse:
-        dispatch->glLogicOp(GL_OR_REVERSE);
+        glLogicOp(GL_OR_REVERSE);
         break;
     case GXcopyInverted:
-        dispatch->glLogicOp(GL_COPY_INVERTED);
+        glLogicOp(GL_COPY_INVERTED);
         break;
     case GXorInverted:
-        dispatch->glLogicOp(GL_OR_INVERTED);
+        glLogicOp(GL_OR_INVERTED);
         break;
     case GXnand:
-        dispatch->glLogicOp(GL_NAND);
+        glLogicOp(GL_NAND);
         break;
     case GXset:
-        dispatch->glLogicOp(GL_SET);
+        glLogicOp(GL_SET);
         break;
     default:
         glamor_fallback("unsupported alu %x\n", alu);
@@ -397,13 +397,12 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 {
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_gl_dispatch *dispatch;
     int non_sub = 0;
     unsigned int iformat = 0;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     if (*tex == 0) {
-        dispatch->glGenTextures(1, tex);
+        glGenTextures(1, tex);
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
             gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
         else
@@ -412,22 +411,20 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
         assert(x == 0 && y == 0);
     }
 
-    dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glBindTexture(GL_TEXTURE_2D, *tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
     if (bits == NULL)
-        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
+        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
     if (non_sub)
-        dispatch->glTexImage2D(GL_TEXTURE_2D,
-                               0, iformat, w, h, 0, format, type, bits);
+        glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
     else
-        dispatch->glTexSubImage2D(GL_TEXTURE_2D,
-                                  0, x, y, w, h, format, type, bits);
+        glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
 
     if (bits == NULL)
-        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -440,7 +437,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_gl_dispatch *dispatch;
     static float vertices[8];
 
     static float texcoords[8] = { 0, 1,
@@ -526,40 +522,39 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                  x + w, y + h,
                                  glamor_priv->yInverted, vertices);
     /* Slow path, we need to flip y or wire alpha to 1. */
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), ptexcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glamor_get_dispatch(glamor_priv);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, 2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                          GL_FALSE, 2 * sizeof(float), ptexcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     __glamor_upload_pixmap_to_texture(pixmap, &tex,
                                       format, type, 0, 0, w, h, bits, pbo);
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, tex);
 
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 #ifndef GLAMOR_GLES2
-    dispatch->glEnable(GL_TEXTURE_2D);
+    glEnable(GL_TEXTURE_2D);
 #endif
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
-    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-                          swap_rb);
+    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+    glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
 
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 #ifndef GLAMOR_GLES2
-    dispatch->glDisable(GL_TEXTURE_2D);
+    glDisable(GL_TEXTURE_2D);
 #endif
-    dispatch->glUseProgram(0);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDeleteTextures(1, &tex);
-    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDeleteTextures(1, &tex);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
     glamor_put_dispatch(glamor_priv);
 
@@ -831,7 +826,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     glamor_screen_private *glamor_priv;
     ScreenPtr screen;
     glamor_pixmap_fbo *temp_fbo;
-    glamor_gl_dispatch *dispatch;
     float temp_xscale, temp_yscale, source_xscale, source_yscale;
     static float vertices[8];
     static float texcoords[8];
@@ -844,7 +838,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     if (temp_fbo == NULL)
         return NULL;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     temp_xscale = 1.0 / w;
     temp_yscale = 1.0 / h;
 
@@ -852,9 +846,9 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
                                  temp_xscale, temp_yscale, 0, 0, w, h,
                                  glamor_priv->yInverted, vertices);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
     glamor_set_normalize_tcoords(source_priv, source_xscale,
@@ -863,26 +857,25 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
                                  x + w, y + h,
                                  glamor_priv->yInverted, texcoords);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
     glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
-    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-                          swap_rb);
+    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+    glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
 
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     return temp_fbo;
 }
@@ -905,7 +898,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
     void *data, *read;
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_gl_dispatch *dispatch;
     glamor_pixmap_fbo *temp_fbo = NULL;
     int need_post_conversion = 0;
     int need_free_data = 0;
@@ -964,56 +956,52 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         fbo_y_off = 0;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+    glamor_get_dispatch(glamor_priv);
+    glPixelStorei(GL_PACK_ALIGNMENT, 4);
 
     if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
 
         if (!glamor_priv->yInverted) {
             assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-            dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
+            glPixelStorei(GL_PACK_INVERT_MESA, 1);
         }
 
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
             assert(pbo > 0);
-            dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
-            dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-                                   stride * h, NULL, gl_usage);
+            glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
+            glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage);
         }
 
-        dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type,
-                               data);
+        glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
 
         if (!glamor_priv->yInverted) {
             assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-            dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
+            glPixelStorei(GL_PACK_INVERT_MESA, 0);
         }
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
-            bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
-            dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+            bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
+            glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
         }
     }
     else {
         unsigned int temp_pbo;
         int yy;
 
-        dispatch = glamor_get_dispatch(glamor_priv);
-        dispatch->glGenBuffers(1, &temp_pbo);
-        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
-        dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-                               stride * h, NULL, GL_STREAM_READ);
-        dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
-                               format, type, 0);
-        read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
+        glamor_get_dispatch(glamor_priv);
+        glGenBuffers(1, &temp_pbo);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
+        glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ);
+        glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, 0);
+        read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
         for (yy = 0; yy < pixmap->drawable.height; yy++)
             memcpy((char *) data + yy * stride,
                    (char *) read + (h - yy - 1) * stride, stride);
-        dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
-        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-        dispatch->glDeleteBuffers(1, &temp_pbo);
+        glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+        glDeleteBuffers(1, &temp_pbo);
     }
 
-    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glamor_put_dispatch(glamor_priv);
 
     if (need_post_conversion) {
@@ -1168,7 +1156,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     void *data = NULL, *dst;
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_gl_dispatch *dispatch;
     int pbo = 0;
 
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -1189,9 +1176,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
         data = malloc(stride * pixmap->drawable.height);
     }
     else {
-        dispatch = glamor_get_dispatch(glamor_priv);
+        glamor_get_dispatch(glamor_priv);
         if (pixmap_priv->base.fbo->pbo == 0)
-            dispatch->glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
+            glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
         glamor_put_dispatch(glamor_priv);
         pbo = pixmap_priv->base.fbo->pbo;
     }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index dc38730..8477091 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -35,15 +35,11 @@
 #endif
 #include "glamor.h"
 
-#ifdef GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#include <epoxy/gl.h>
 
+#ifdef GLAMOR_GLES2
 #define GLAMOR_DEFAULT_PRECISION   "precision mediump float;\n"
-#include "glamor_glext.h"
 #else
-#include <GL/gl.h>
-#include <GL/glext.h>
 #define GLAMOR_DEFAULT_PRECISION
 #endif
 
@@ -178,8 +174,6 @@ typedef struct {
     uint16_t evict;
 } glamor_glyph_cache_t;
 
-#include "glamor_gl_dispatch.h"
-
 struct glamor_saved_procs {
     CloseScreenProcPtr close_screen;
     CreateGCProcPtr create_gc;
@@ -220,7 +214,6 @@ struct glamor_saved_procs {
 #define RENDER_IDEL_MAX 32
 
 typedef struct glamor_screen_private {
-    struct glamor_gl_dispatch _dispatch;
     int yInverted;
     unsigned int tick;
     enum glamor_gl_flavor gl_flavor;
@@ -583,9 +576,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
                     unsigned char alu, unsigned long planemask,
                     unsigned long fg_pixel, unsigned long bg_pixel,
                     int stipple_x, int stipple_y);
-GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type,
-                               const char *source);
-void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog);
+GLint glamor_compile_glsl_prog(GLenum type, const char *source);
+void glamor_link_glsl_prog(GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
                                     unsigned long fg_pixel, GLfloat *color);
 
@@ -604,7 +596,7 @@ glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
                                                   int no_alpha, int revert,
                                                   int swap_rb);
 
-Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu);
+Bool glamor_set_alu(unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 6b25bec..60ccd67 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -67,27 +67,26 @@ glamor_init_putimage_shaders(ScreenPtr screen)
     if (!GLEW_ARB_fragment_shader)
         return;
 
-    prog = dispatch->glCreateProgram();
+    prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
-    dispatch->glAttachShader(prog, vs_prog);
-    dispatch->glAttachShader(prog, fs_prog);
+    glAttachShader(prog, vs_prog);
+    glAttachShader(prog, fs_prog);
     glamor_link_glsl_prog(prog);
 
-    dispatch->glUseProgram(prog);
-    sampler_uniform_location =
-        dispatch->glGetUniformLocation(prog, "bitmap_sampler");
-    dispatch->glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(prog);
+    sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler");
+    glUniform1i(sampler_uniform_location, 0);
 
     glamor_priv->put_image_xybitmap_fg_uniform_location =
-        dispatch->glGetUniformLocation(prog, "fg");
+        glGetUniformLocation(prog, "fg");
     glamor_priv->put_image_xybitmap_bg_uniform_location =
-        dispatch->glGetUniformLocation(prog, "bg");
+        glGetUniformLocation(prog, "bg");
     glamor_get_transform_uniform_locations(prog,
                                            &glamor_priv->
                                            put_image_xybitmap_transform);
     glamor_priv->put_image_xybitmap_prog = prog;
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
 #endif
 }
 
@@ -162,40 +161,38 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     if (!glamor_set_planemask(pixmap, gc->planemask))
         goto fail;
 
-    dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
+    glUseProgram(glamor_priv->put_image_xybitmap_prog);
 
     glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
-    dispatch->glUniform4fv
-        (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
+    glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
     glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
-    dispatch->glUniform4fv
-        (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
-
-    dispatch->glGenTextures(1, &tex);
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glEnable(GL_TEXTURE_2D);
-    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
-                           w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
-    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
+
+    glGenTextures(1, &tex);
+    glActiveTexture(GL_TEXTURE0);
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+                 w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
 
     /* Now that we've set up our bitmap texture and the shader, shove
      * the destination rectangle through the cliprects and run the
      * shader on the resulting fragments.
      */
-    dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
-    dispatch->glEnableClientState(GL_VERTEX_ARRAY);
-    dispatch->glClientActiveTexture(GL_TEXTURE0);
-    dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
-    dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glVertexPointer(2, GL_FLOAT, 0, dest_coords);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-    dispatch->glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_SCISSOR_TEST);
     clip = fbGetCompositeClip(gc);
     for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) {
         int x1 = x;
@@ -214,19 +211,18 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
         if (x1 >= x2 || y1 >= y2)
             continue;
 
-        dispatch->glScissor(box->x1,
-                            y_flip(pixmap, box->y1),
-                            box->x2 - box->x1, box->y2 - box->y1);
-        dispatch->glDrawArrays(GL_QUADS, 0, 4);
+        glScissor(box->x1, y_flip(pixmap, box->y1),
+                  box->x2 - box->x1, box->y2 - box->y1);
+        glDrawArrays(GL_QUADS, 0, 4);
     }
 
-    dispatch->glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_SCISSOR_TEST);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
-    dispatch->glDeleteTextures(1, &tex);
-    dispatch->glDisable(GL_TEXTURE_2D);
-    dispatch->glDisableClientState(GL_VERTEX_ARRAY);
-    dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDeleteTextures(1, &tex);
+    glDisable(GL_TEXTURE_2D);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     return;
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 4a3a97c..760af83 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -62,8 +62,7 @@ static struct blendinfo composite_op_info[] = {
 
 #define RepeatFix			10
 static GLuint
-glamor_create_composite_fs(glamor_gl_dispatch *dispatch,
-                           struct shader_key *key)
+glamor_create_composite_fs(struct shader_key *key)
 {
     const char *repeat_define =
         "#define RepeatNone               	      0\n"
@@ -266,15 +265,14 @@ glamor_create_composite_fs(glamor_gl_dispatch *dispatch,
     XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture,
                 rel_sampler, source_fetch, mask_fetch, in);
 
-    prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
+    prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
     free(source);
 
     return prog;
 }
 
 static GLuint
-glamor_create_composite_vs(glamor_gl_dispatch *dispatch,
-                           struct shader_key *key)
+glamor_create_composite_vs(struct shader_key *key)
 {
     const char *main_opening =
         "attribute vec4 v_position;\n"
@@ -304,7 +302,7 @@ glamor_create_composite_vs(glamor_gl_dispatch *dispatch,
                 main_opening,
                 source_coords_setup, mask_coords_setup, main_closing);
 
-    prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
+    prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source);
     free(source);
 
     return prog;
@@ -317,55 +315,52 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     GLuint vs, fs, prog;
     GLint source_sampler_uniform_location, mask_sampler_uniform_location;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    vs = glamor_create_composite_vs(dispatch, key);
+    glamor_get_dispatch(glamor_priv);
+    vs = glamor_create_composite_vs(key);
     if (vs == 0)
         goto out;
-    fs = glamor_create_composite_fs(dispatch, key);
+    fs = glamor_create_composite_fs(key);
     if (fs == 0)
         goto out;
 
-    prog = dispatch->glCreateProgram();
-    dispatch->glAttachShader(prog, vs);
-    dispatch->glAttachShader(prog, fs);
+    prog = glCreateProgram();
+    glAttachShader(prog, vs);
+    glAttachShader(prog, fs);
 
-    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
+    glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
 
-    glamor_link_glsl_prog(dispatch, prog);
+    glamor_link_glsl_prog(prog);
 
     shader->prog = prog;
 
-    dispatch->glUseProgram(prog);
+    glUseProgram(prog);
 
     if (key->source == SHADER_SOURCE_SOLID) {
-        shader->source_uniform_location =
-            dispatch->glGetUniformLocation(prog, "source");
+        shader->source_uniform_location = glGetUniformLocation(prog, "source");
     }
     else {
         source_sampler_uniform_location =
-            dispatch->glGetUniformLocation(prog, "source_sampler");
-        dispatch->glUniform1i(source_sampler_uniform_location, 0);
-        shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
+            glGetUniformLocation(prog, "source_sampler");
+        glUniform1i(source_sampler_uniform_location, 0);
+        shader->source_wh = glGetUniformLocation(prog, "source_wh");
         shader->source_repeat_mode =
-            dispatch->glGetUniformLocation(prog, "source_repeat_mode");
+            glGetUniformLocation(prog, "source_repeat_mode");
     }
 
     if (key->mask != SHADER_MASK_NONE) {
         if (key->mask == SHADER_MASK_SOLID) {
-            shader->mask_uniform_location =
-                dispatch->glGetUniformLocation(prog, "mask");
+            shader->mask_uniform_location = glGetUniformLocation(prog, "mask");
         }
         else {
             mask_sampler_uniform_location =
-                dispatch->glGetUniformLocation(prog, "mask_sampler");
-            dispatch->glUniform1i(mask_sampler_uniform_location, 1);
-            shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
+                glGetUniformLocation(prog, "mask_sampler");
+            glUniform1i(mask_sampler_uniform_location, 1);
+            shader->mask_wh = glGetUniformLocation(prog, "mask_wh");
             shader->mask_repeat_mode =
-                dispatch->glGetUniformLocation(prog, "mask_repeat_mode");
+                glGetUniformLocation(prog, "mask_repeat_mode");
         }
     }
 
@@ -407,23 +402,21 @@ void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     unsigned short *eb;
     float *vb = NULL;
     int eb_size;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glGenBuffers(1, &glamor_priv->vbo);
-    dispatch->glGenBuffers(1, &glamor_priv->ebo);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+    glamor_get_dispatch(glamor_priv);
+    glGenBuffers(1, &glamor_priv->vbo);
+    glGenBuffers(1, &glamor_priv->ebo);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
     eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-        dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-                               eb_size, NULL, GL_STATIC_DRAW);
-        eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, NULL, GL_STATIC_DRAW);
+        eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
     }
     else {
         vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
@@ -438,19 +431,18 @@ glamor_init_composite_shaders(ScreenPtr screen)
     glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-        dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+        glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     }
     else {
-        dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-                               eb_size, eb, GL_STATIC_DRAW);
-        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
+        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-        dispatch->glBufferData(GL_ARRAY_BUFFER,
-                               GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) *
-                               2, NULL, GL_DYNAMIC_DRAW);
-        dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+        glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        glBufferData(GL_ARRAY_BUFFER,
+                     GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) *
+                     2, NULL, GL_DYNAMIC_DRAW);
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
 
         free(eb);
         glamor_priv->vb = (char *) vb;
@@ -463,21 +455,20 @@ void
 glamor_fini_composite_shaders(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     glamor_composite_shader *shader;
     int i, j, k;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
-    dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
+    glamor_get_dispatch(glamor_priv);
+    glDeleteBuffers(1, &glamor_priv->vbo);
+    glDeleteBuffers(1, &glamor_priv->ebo);
 
     for (i = 0; i < SHADER_SOURCE_COUNT; i++)
         for (j = 0; j < SHADER_MASK_COUNT; j++)
             for (k = 0; k < SHADER_IN_COUNT; k++) {
                 shader = &glamor_priv->composite_shader[i][j][k];
                 if (shader->prog)
-                    dispatch->glDeleteProgram(shader->prog);
+                    glDeleteProgram(shader->prog);
             }
     if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb)
         free(glamor_priv->vb);
@@ -535,44 +526,35 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
                              glamor_pixmap_private *pixmap_priv,
                              GLuint wh_location, GLuint repeat_location)
 {
-    glamor_gl_dispatch *dispatch;
     float wh[4];
     int repeat_type;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glActiveTexture(GL_TEXTURE0 + unit);
-    dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
+    glamor_get_dispatch(glamor_priv);
+    glActiveTexture(GL_TEXTURE0 + unit);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
     repeat_type = picture->repeatType;
     switch (picture->repeatType) {
     case RepeatNone:
 #ifndef GLAMOR_GLES2
         /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-                                  GL_CLAMP_TO_BORDER);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-                                  GL_CLAMP_TO_BORDER);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 #else
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-                                  GL_CLAMP_TO_EDGE);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-                                  GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 #endif
         break;
     case RepeatNormal:
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
         break;
     case RepeatPad:
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-                                  GL_CLAMP_TO_EDGE);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-                                  GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         break;
     case RepeatReflect:
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-                                  GL_MIRRORED_REPEAT);
-        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-                                  GL_MIRRORED_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
         break;
     }
 
@@ -580,22 +562,18 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
     default:
     case PictFilterFast:
     case PictFilterNearest:
-        dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                  GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                  GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         break;
     case PictFilterGood:
     case PictFilterBest:
     case PictFilterBilinear:
-        dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                  GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        dispatch->glTexParameteri(GL_TEXTURE_2D,
-                                  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         break;
     }
 #ifndef GLAMOR_GLES2
-    dispatch->glEnable(GL_TEXTURE_2D);
+    glEnable(GL_TEXTURE_2D);
 #endif
 
     /*
@@ -615,19 +593,18 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
         if ((wh[0] != 1.0 || wh[1] != 1.0)
             || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
                 && repeat_type == RepeatFix))
-            dispatch->glUniform4fv(wh_location, 1, wh);
+            glUniform4fv(wh_location, 1, wh);
         else
             repeat_type -= RepeatFix;
     }
-    dispatch->glUniform1i(repeat_location, repeat_type);
+    glUniform1i(repeat_location, repeat_type);
     glamor_put_dispatch(glamor_priv);
 }
 
 static void
-glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color,
-                           GLint uniform_location)
+glamor_set_composite_solid(float *color, GLint uniform_location)
 {
-    dispatch->glUniform4fv(uniform_location, 1, color);
+    glUniform4fv(uniform_location, 1, color);
 }
 
 static int
@@ -729,7 +706,6 @@ void
 glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
     int vert_size;
 
     glamor_priv->render_nr_verts = 0;
@@ -741,63 +717,52 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+    glamor_get_dispatch(glamor_priv);
+    glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
         if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
             glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
                 glamor_priv->vb_stride;
             glamor_priv->vbo_offset = 0;
-            dispatch->glBufferData(GL_ARRAY_BUFFER,
-                                   glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+            glBufferData(GL_ARRAY_BUFFER,
+                         glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
         }
 
-        glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
-                                                     glamor_priv->vbo_offset,
-                                                     vert_size,
-                                                     GL_MAP_WRITE_BIT |
-                                                     GL_MAP_UNSYNCHRONIZED_BIT);
+        glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
+                                           glamor_priv->vbo_offset,
+                                           vert_size,
+                                           GL_MAP_WRITE_BIT |
+                                           GL_MAP_UNSYNCHRONIZED_BIT);
         assert(glamor_priv->vb != NULL);
         glamor_priv->vb -= glamor_priv->vbo_offset;
     }
     else
         glamor_priv->vbo_offset = 0;
 
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, glamor_priv->vb_stride,
-                                    (void *) ((long)
-                                              glamor_priv->vbo_offset));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          glamor_priv->vb_stride,
+                          (void *) ((long)
+                                    glamor_priv->vbo_offset));
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     if (glamor_priv->has_source_coords) {
-        dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-                                        GL_FLOAT, GL_FALSE,
-                                        glamor_priv->vb_stride, (void *) ((long)
-                                                                          glamor_priv->
-                                                                          vbo_offset
-                                                                          +
-                                                                          2 *
-                                                                          sizeof
-                                                                          (float)));
-        dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+        glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                              GL_FLOAT, GL_FALSE,
+                              glamor_priv->vb_stride,
+                              (void *) ((long) glamor_priv->vbo_offset +
+                                        2 * sizeof(float)));
+        glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     }
 
     if (glamor_priv->has_mask_coords) {
-        dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2,
-                                        GL_FLOAT, GL_FALSE,
-                                        glamor_priv->vb_stride, (void *) ((long)
-                                                                          glamor_priv->
-                                                                          vbo_offset
-                                                                          +
-                                                                          (glamor_priv->
-                                                                           has_source_coords
-                                                                           ? 4 :
-                                                                           2) *
-                                                                          sizeof
-                                                                          (float)));
-        dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
+        glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE,
+                              glamor_priv->vb_stride,
+                              (void *) ((long) glamor_priv->vbo_offset +
+                                        (glamor_priv->has_source_coords ?
+                                         4 : 2) * sizeof(float)));
+        glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
     }
     glamor_put_dispatch(glamor_priv);
 }
@@ -831,30 +796,27 @@ static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-        dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+        glUnmapBuffer(GL_ARRAY_BUFFER);
     else {
 
-        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-        dispatch->glBufferData(GL_ARRAY_BUFFER,
-                               glamor_priv->vbo_offset,
-                               glamor_priv->vb, GL_DYNAMIC_DRAW);
+        glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+                     glamor_priv->vb, GL_DYNAMIC_DRAW);
     }
 
     if (!glamor_priv->render_nr_verts)
         return;
 
 #ifndef GLAMOR_GLES2
-    dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
-                                  (glamor_priv->render_nr_verts * 3) / 2,
-                                  GL_UNSIGNED_SHORT, NULL);
+    glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
+                        (glamor_priv->render_nr_verts * 3) / 2,
+                        GL_UNSIGNED_SHORT, NULL);
 #else
-    dispatch->glDrawElements(GL_TRIANGLES,
-                             (glamor_priv->render_nr_verts * 3) / 2,
-                             GL_UNSIGNED_SHORT, NULL);
+    glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
+                   GL_UNSIGNED_SHORT, NULL);
 #endif
     glamor_put_dispatch(glamor_priv);
 }
@@ -1228,17 +1190,15 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
                                   glamor_composite_shader *shader,
                                   struct blendinfo *op_info)
 {
-    glamor_gl_dispatch *dispatch;
     glamor_screen_private *glamor_priv;
 
     glamor_priv = dest_priv->base.glamor_priv;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glUseProgram(shader->prog);
+    glamor_get_dispatch(glamor_priv);
+    glUseProgram(shader->prog);
 
     if (key->source == SHADER_SOURCE_SOLID) {
-        glamor_set_composite_solid(dispatch,
-                                   shader->source_solid_color,
+        glamor_set_composite_solid(shader->source_solid_color,
                                    shader->source_uniform_location);
     }
     else {
@@ -1250,8 +1210,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
 
     if (key->mask != SHADER_MASK_NONE) {
         if (key->mask == SHADER_MASK_SOLID) {
-            glamor_set_composite_solid(dispatch,
-                                       shader->mask_solid_color,
+            glamor_set_composite_solid(shader->mask_solid_color,
                                        shader->mask_uniform_location);
         }
         else {
@@ -1263,11 +1222,11 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
     }
 
     if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) {
-        dispatch->glDisable(GL_BLEND);
+        glDisable(GL_BLEND);
     }
     else {
-        dispatch->glEnable(GL_BLEND);
-        dispatch->glBlendFunc(op_info->source_blend, op_info->dest_blend);
+        glEnable(GL_BLEND);
+        glBlendFunc(op_info->source_blend, op_info->dest_blend);
     }
 
     glamor_put_dispatch(glamor_priv);
@@ -1289,7 +1248,6 @@ glamor_composite_with_shader(CARD8 op,
     PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
     PixmapPtr source_pixmap = NULL;
     PixmapPtr mask_pixmap = NULL;
-    glamor_gl_dispatch *dispatch = NULL;
     GLfloat dst_xscale, dst_yscale;
     GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
     struct shader_key key, key_ca;
@@ -1328,7 +1286,7 @@ glamor_composite_with_shader(CARD8 op,
     glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
     glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
     glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
@@ -1445,20 +1403,20 @@ glamor_composite_with_shader(CARD8 op,
         }
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-    dispatch->glDisable(GL_BLEND);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glDisable(GL_TEXTURE_2D);
-    dispatch->glActiveTexture(GL_TEXTURE1);
-    dispatch->glDisable(GL_TEXTURE_2D);
+    glActiveTexture(GL_TEXTURE0);
+    glDisable(GL_TEXTURE_2D);
+    glActiveTexture(GL_TEXTURE1);
+    glDisable(GL_TEXTURE_2D);
 #endif
     DEBUGF("finish rendering.\n");
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
     if (saved_source_format)
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 9c8e521..8ceb549 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -37,7 +37,6 @@ void
 glamor_init_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     const char *tile_vs =
         "attribute vec4 v_position;\n"
         "attribute vec4 v_texcoord0;\n"
@@ -63,27 +62,27 @@ glamor_init_tile_shader(ScreenPtr screen)
     GLint sampler_uniform_location;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    glamor_priv->tile_prog = dispatch->glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs);
-    dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
-
-    dispatch->glBindAttribLocation(glamor_priv->tile_prog,
-                                   GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(glamor_priv->tile_prog,
-                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
+    glamor_get_dispatch(glamor_priv);
+    glamor_priv->tile_prog = glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
+    glAttachShader(glamor_priv->tile_prog, vs_prog);
+    glAttachShader(glamor_priv->tile_prog, fs_prog);
+
+    glBindAttribLocation(glamor_priv->tile_prog,
+                         GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(glamor_priv->tile_prog,
+                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(glamor_priv->tile_prog);
 
     sampler_uniform_location =
-        dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler");
-    dispatch->glUseProgram(glamor_priv->tile_prog);
-    dispatch->glUniform1i(sampler_uniform_location, 0);
+        glGetUniformLocation(glamor_priv->tile_prog, "sampler");
+    glUseProgram(glamor_priv->tile_prog);
+    glUniform1i(sampler_uniform_location, 0);
 
     glamor_priv->tile_wh =
-        dispatch->glGetUniformLocation(glamor_priv->tile_prog, "wh");
-    dispatch->glUseProgram(0);
+        glGetUniformLocation(glamor_priv->tile_prog, "wh");
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -91,11 +90,10 @@ void
 glamor_fini_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glDeleteProgram(glamor_priv->tile_prog);
+    glamor_get_dispatch(glamor_priv);
+    glDeleteProgram(glamor_priv->tile_prog);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -105,7 +103,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
     int x1 = x;
     int x2 = x + width;
     int y1 = y;
@@ -127,19 +124,19 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
     pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glUseProgram(glamor_priv->tile_prog);
+    glamor_get_dispatch(glamor_priv);
+    glUseProgram(glamor_priv->tile_prog);
 
     glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
-    dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glUniform2fv(glamor_priv->tile_wh, 1, wh);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 #ifndef GLAMOR_GLES2
-    dispatch->glEnable(GL_TEXTURE_2D);
+    glEnable(GL_TEXTURE_2D);
 #endif
     glamor_set_repeat_normalize_tcoords
         (src_pixmap_priv, RepeatNormal,
@@ -147,26 +144,25 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
          tile_x1, tile_y1,
          tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-                                    GL_FLOAT, GL_FALSE,
-                                    2 * sizeof(float), source_texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), source_texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
                                  x1, y1,
                                  x2, y2, glamor_priv->yInverted, vertices);
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-    dispatch->glDisable(GL_TEXTURE_2D);
+    glDisable(GL_TEXTURE_2D);
 #endif
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
 
     glamor_priv->state = RENDER_STATE;
@@ -182,7 +178,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private *dst_pixmap_priv;
     glamor_pixmap_private *src_pixmap_priv;
-    glamor_gl_dispatch *dispatch;
 
     dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
     src_pixmap_priv = glamor_get_pixmap_private(tile);
@@ -206,8 +201,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         goto fail;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-    if (!glamor_set_alu(dispatch, alu)) {
+    glamor_get_dispatch(glamor_priv);
+    if (!glamor_set_alu(alu)) {
         glamor_fallback("unsupported alu %x\n", alu);
         glamor_put_dispatch(glamor_priv);
         goto fail;
@@ -302,7 +297,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     else
         _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
 
-    glamor_set_alu(dispatch, GXcopy);
+    glamor_set_alu(GXcopy);
     glamor_put_dispatch(glamor_priv);
     return TRUE;
  fail:
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index cd99a47..b398213 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -204,23 +204,21 @@ static void
 glamor_flush_composite_triangles(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-        dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+        glUnmapBuffer(GL_ARRAY_BUFFER);
     else {
 
-        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-        dispatch->glBufferData(GL_ARRAY_BUFFER,
-                               glamor_priv->vbo_offset,
-                               glamor_priv->vb, GL_DYNAMIC_DRAW);
+        glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+                     glamor_priv->vb, GL_DYNAMIC_DRAW);
     }
 
     if (!glamor_priv->render_nr_verts)
         return;
 
-    dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
+    glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -582,7 +580,6 @@ static void
 glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch;
     int stride;
     int vert_size;
 
@@ -605,25 +602,25 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+    glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
         if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
             glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
                 glamor_priv->vb_stride;
             glamor_priv->vbo_offset = 0;
-            dispatch->glBufferData(GL_ARRAY_BUFFER,
-                                   glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+            glBufferData(GL_ARRAY_BUFFER,
+                         glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
         }
 
-        glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+        glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
                                                      glamor_priv->vbo_offset,
                                                      vert_size,
                                                      GL_MAP_WRITE_BIT |
@@ -636,41 +633,41 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
         glamor_priv->vbo_offset = 0;
     }
 
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
     /* Set the vertex pointer. */
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, glamor_priv->vb_stride,
-                                    (void *) ((long) glamor_priv->vbo_offset));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, glamor_priv->vb_stride,
+                          (void *) ((long) glamor_priv->vbo_offset));
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     stride = 2;
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-                                    GL_FALSE, glamor_priv->vb_stride,
-                                    (void *) ((long) glamor_priv->vbo_offset +
-                                              stride * sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                          GL_FALSE, glamor_priv->vb_stride,
+                          (void *) ((long) glamor_priv->vbo_offset +
+                                    stride * sizeof(float)));
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     stride += 2;
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
+    glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
                                     GL_FALSE, glamor_priv->vb_stride,
                                     (void *) ((long) glamor_priv->vbo_offset +
                                               stride * sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
     stride += 2;
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
+    glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
                                     GL_FALSE, glamor_priv->vb_stride,
                                     (void *) ((long) glamor_priv->vbo_offset +
                                               stride * sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
     stride += 4;
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
+    glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
                                     GL_FALSE, glamor_priv->vb_stride,
                                     (void *) ((long) glamor_priv->vbo_offset +
                                               stride * sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
     glamor_put_dispatch(glamor_priv);
 }
@@ -701,7 +698,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
     GLfloat dst_xscale, dst_yscale;
     BoxRec bounds;
     PicturePtr temp_src = src;
-    glamor_gl_dispatch *dispatch = NULL;
     int vert_stride = 3;
     int ntriangle_per_loop;
     int nclip_rect;
@@ -815,6 +811,8 @@ _glamor_trapezoids_with_shader(CARD8 op,
         goto TRAPEZOID_OUT;
     }
 
+    glamor_get_dispatch(glamor_priv);
+
     box = REGION_RECTS(&region);
     nbox = REGION_NUM_RECTS(&region);
     pbox = box;
@@ -833,8 +831,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
     glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
                                     key.mask != SHADER_MASK_SOLID);
 
-    dispatch = glamor_get_dispatch(glamor_priv);
-
     glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
                                &dest_x_off, &dest_y_off);
 
@@ -974,19 +970,20 @@ _glamor_trapezoids_with_shader(CARD8 op,
     ret = TRUE;
 
  TRAPEZOID_RESET_GL:
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-    dispatch->glDisable(GL_BLEND);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glDisable(GL_TEXTURE_2D);
-    dispatch->glActiveTexture(GL_TEXTURE1);
-    dispatch->glDisable(GL_TEXTURE_2D);
+    glActiveTexture(GL_TEXTURE0);
+    glDisable(GL_TEXTURE_2D);
+    glActiveTexture(GL_TEXTURE1);
+    glDisable(GL_TEXTURE_2D);
 #endif
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
 
  TRAPEZOID_OUT:
     if (box) {
@@ -1002,10 +999,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
         }
     }
 
-    if (dispatch) {
-        glamor_put_dispatch(glamor_priv);
-    }
-
     return ret;
 }
 
@@ -1013,7 +1006,6 @@ void
 glamor_init_trapezoid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     GLint fs_prog, vs_prog;
 
     const char *trapezoid_vs =
@@ -1344,32 +1336,30 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
-    glamor_priv->trapezoid_prog = dispatch->glCreateProgram();
+    glamor_priv->trapezoid_prog = glCreateProgram();
 
-    vs_prog = glamor_compile_glsl_prog(dispatch,
-                                       GL_VERTEX_SHADER, trapezoid_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch,
-                                       GL_FRAGMENT_SHADER, trapezoid_fs);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, trapezoid_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, trapezoid_fs);
 
-    dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
+    glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
+    glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
 
-    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-                                   GLAMOR_VERTEX_POS, "v_positionsition");
-    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-                                   GLAMOR_VERTEX_SOURCE, "v_texcoord");
-    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-                                   GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
-    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-                                   GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
-    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-                                   GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
+    glBindAttribLocation(glamor_priv->trapezoid_prog,
+                         GLAMOR_VERTEX_POS, "v_positionsition");
+    glBindAttribLocation(glamor_priv->trapezoid_prog,
+                         GLAMOR_VERTEX_SOURCE, "v_texcoord");
+    glBindAttribLocation(glamor_priv->trapezoid_prog,
+                         GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
+    glBindAttribLocation(glamor_priv->trapezoid_prog,
+                         GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
+    glBindAttribLocation(glamor_priv->trapezoid_prog,
+                         GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
 
-    glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog);
+    glamor_link_glsl_prog(glamor_priv->trapezoid_prog);
 
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
 
     glamor_put_dispatch(glamor_priv);
 }
@@ -1378,11 +1368,10 @@ void
 glamor_fini_trapezoid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glDeleteProgram(glamor_priv->trapezoid_prog);
+    glamor_get_dispatch(glamor_priv);
+    glDeleteProgram(glamor_priv->trapezoid_prog);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -1392,7 +1381,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
                                        BoxRec *bounds)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     glamor_pixmap_private *pixmap_priv;
     PixmapPtr pixmap = NULL;
     GLint trapezoid_prog;
@@ -1425,20 +1413,20 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
         return FALSE;
     }
 
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
     pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
     /* Now draw the Trapezoid mask. */
-    dispatch->glUseProgram(trapezoid_prog);
+    glUseProgram(trapezoid_prog);
 
-    dispatch->glEnable(GL_BLEND);
-    dispatch->glBlendFunc(GL_ONE, GL_ONE);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE);
 
     nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
 
@@ -1565,36 +1553,35 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
             continue;
 
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-            dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+            glUnmapBuffer(GL_ARRAY_BUFFER);
         else {
-            dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-            dispatch->glBufferData(GL_ARRAY_BUFFER,
-                                   glamor_priv->vbo_offset,
-                                   glamor_priv->vb, GL_DYNAMIC_DRAW);
+            glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+            glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+                         glamor_priv->vb, GL_DYNAMIC_DRAW);
         }
 
 #ifndef GLAMOR_GLES2
-        dispatch->glDrawRangeElements(GL_TRIANGLES, 0,
-                                      glamor_priv->render_nr_verts,
-                                      (glamor_priv->render_nr_verts * 3) / 2,
-                                      GL_UNSIGNED_SHORT, NULL);
+        glDrawRangeElements(GL_TRIANGLES, 0,
+                            glamor_priv->render_nr_verts,
+                            (glamor_priv->render_nr_verts * 3) / 2,
+                            GL_UNSIGNED_SHORT, NULL);
 #else
-        dispatch->glDrawElements(GL_TRIANGLES,
-                                 (glamor_priv->render_nr_verts * 3) / 2,
-                                 GL_UNSIGNED_SHORT, NULL);
+        glDrawElements(GL_TRIANGLES,
+                       (glamor_priv->render_nr_verts * 3) / 2,
+                       GL_UNSIGNED_SHORT, NULL);
 #endif
     }
 
-    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-    dispatch->glBlendFunc(GL_ONE, GL_ZERO);
-    dispatch->glDisable(GL_BLEND);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
-    dispatch->glUseProgram(0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glBlendFunc(GL_ONE, GL_ZERO);
+    glDisable(GL_BLEND);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     return TRUE;
 }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index ea827df..d427360 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1828,13 +1828,11 @@ glamor_restore_current(ScreenPtr screen)
     glamor_egl_restore_context(screen);
 }
 
-static inline glamor_gl_dispatch *
+static inline void
 glamor_get_dispatch(glamor_screen_private * glamor_priv)
 {
     if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
         glamor_make_current(glamor_priv->screen);
-
-    return &glamor_priv->_dispatch;
 }
 
 static inline void
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index cbe07c8..89787a4 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -90,23 +90,22 @@ void
 glamor_init_xv_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
-    glamor_priv->xv_prog = dispatch->glCreateProgram();
+    glamor_get_dispatch(glamor_priv);
+    glamor_priv->xv_prog = glCreateProgram();
 
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps);
-    dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xv_ps);
+    glAttachShader(glamor_priv->xv_prog, vs_prog);
+    glAttachShader(glamor_priv->xv_prog, fs_prog);
 
-    dispatch->glBindAttribLocation(glamor_priv->xv_prog,
-                                   GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(glamor_priv->xv_prog,
-                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog);
+    glBindAttribLocation(glamor_priv->xv_prog,
+                         GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(glamor_priv->xv_prog,
+                         GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(glamor_priv->xv_prog);
 
     glamor_put_dispatch(glamor_priv);
 }
@@ -115,12 +114,11 @@ void
 glamor_fini_xv_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
-    glamor_gl_dispatch *dispatch;
 
     glamor_priv = glamor_get_screen_private(screen);
-    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_get_dispatch(glamor_priv);
 
-    dispatch->glDeleteProgram(glamor_priv->xv_prog);
+    glDeleteProgram(glamor_priv->xv_prog);
     glamor_put_dispatch(glamor_priv);
 }
 
@@ -278,7 +276,6 @@ glamor_display_textured_video(glamor_port_private *port_priv)
     glamor_pixmap_private *pixmap_priv =
         glamor_get_pixmap_private(port_priv->pPixmap);
     glamor_pixmap_private *src_pixmap_priv[3];
-    glamor_gl_dispatch *dispatch;
     float vertices[32], texcoords[8];
     BoxPtr box = REGION_RECTS(&port_priv->clip);
     int nBox = REGION_NUM_RECTS(&port_priv->clip);
@@ -327,62 +324,53 @@ glamor_display_textured_video(glamor_port_private *port_priv)
                                   &src_yscale[i]);
         }
     }
-    dispatch = glamor_get_dispatch(glamor_priv);
-    dispatch->glUseProgram(glamor_priv->xv_prog);
-
-    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
-    dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco);
-    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
-    dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
-    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco");
-    dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
-
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    dispatch->glActiveTexture(GL_TEXTURE1);
-    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    dispatch->glActiveTexture(GL_TEXTURE2);
-    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    dispatch->glTexParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    sampler_loc =
-        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
-    dispatch->glUniform1i(sampler_loc, 0);
-    sampler_loc =
-        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
-    dispatch->glUniform1i(sampler_loc, 1);
-    sampler_loc =
-        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
-    dispatch->glUniform1i(sampler_loc, 2);
-
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-                                    GL_FLOAT, GL_FALSE,
-                                    2 * sizeof(float), texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                                    GL_FALSE, 2 * sizeof(float), vertices);
-
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glamor_get_dispatch(glamor_priv);
+    glUseProgram(glamor_priv->xv_prog);
+
+    uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
+    glUniform4f(uloc, off[0], off[1], off[2], yco);
+    uloc = glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
+    glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
+    uloc = glGetUniformLocation(glamor_priv->xv_prog, "vco");
+    glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    glActiveTexture(GL_TEXTURE2);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
+    glUniform1i(sampler_loc, 0);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
+    glUniform1i(sampler_loc, 1);
+    sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
+    glUniform1i(sampler_loc, 2);
+
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                          GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                          GL_FALSE, 2 * sizeof(float), vertices);
+
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     for (i = 0; i < nBox; i++) {
         float off_x = box[i].x1 - port_priv->drw_x;
         float off_y = box[i].y1 - port_priv->drw_y;
@@ -418,13 +406,13 @@ glamor_display_textured_video(glamor_port_private *port_priv)
                                      srcy + srch,
                                      glamor_priv->yInverted, texcoords);
 
-        dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    dispatch->glUseProgram(0);
+    glUseProgram(0);
     glamor_put_dispatch(glamor_priv);
     DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
 }
commit f34dc7fa96457ea6a0703493d74e63cca357712e
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Fri Feb 14 00:31:38 2014 -0800

    XQuartz: pointer -> void *
    
    Fix build regression from 60014a4a98ff924ae7f6840781f768c1cc93bbab
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/quartzCocoa.m b/hw/xquartz/quartzCocoa.m
index db2b3cf..d21fb7d 100644
--- a/hw/xquartz/quartzCocoa.m
+++ b/hw/xquartz/quartzCocoa.m
@@ -48,9 +48,9 @@
  *  Clean out any autoreleased objects.
  */
 void
-QuartzBlockHandler(pointer blockData,
+QuartzBlockHandler(void *blockData,
                    OSTimePtr pTimeout,
-                   pointer pReadmask)
+                   void *pReadmask)
 {
     static NSAutoreleasePool *aPool = nil;
 
@@ -62,9 +62,9 @@ QuartzBlockHandler(pointer blockData,
  * QuartzWakeupHandler
  */
 void
-QuartzWakeupHandler(pointer blockData,
+QuartzWakeupHandler(void *blockData,
                     int result,
-                    pointer pReadmask)
+                    void *pReadmask)
 {
     // nothing here
 }
commit 72237e0908527e9261b91c7db99f32d895947d8d
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Feb 13 15:25:56 2014 -0800

    DIST_SUBDIRS needs to include glamor, even if it isn't built
    
    Otherwise, glamor won't get cleaned for 'make distclean'
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Makefile.am b/Makefile.am
index 7c93d8d..f0fa2d8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -111,7 +111,7 @@ DIST_SUBDIRS = \
 	composite \
 	glx \
 	exa \
-	$(GLAMOR_DIR) \
+	glamor \
 	config \
 	dri3 \
 	present \
commit 783991b1beeb71d91068601789d179d10eb8b544
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Thu Feb 13 17:36:34 2014 -0500

    config: fails to create tarball as xorg-server.conf file removed
    
    Just need to update EXTRA_DIST
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/Makefile.am b/config/Makefile.am
index e0f0a8d..c6350be 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -38,4 +38,4 @@ endif # !CONFIG_HAL
 
 endif # !CONFIG_UDEV
 
-EXTRA_DIST = xorg-server.conf x11-input.fdi 10-evdev.conf non-seat0.conf.multi-seat fdi2iclass.py 10-quirks.conf
+EXTRA_DIST = x11-input.fdi 10-evdev.conf non-seat0.conf.multi-seat fdi2iclass.py 10-quirks.conf
commit 30c3852bda7f60b0ffb1bb2f6ed8ba8800001b32
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Feb 9 16:56:40 2014 -0800

    Delete stray ; in struct _DeviceChangedEvent
    
    Caused Solaris Studio cc to complain in every file which included it:
     "../include/eventstr.h", line 179: warning: syntax error:
      empty member declaration
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/eventstr.h b/include/eventstr.h
index 3950584..cce903d 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -176,7 +176,7 @@ struct _DeviceChangedEvent {
     struct {
         uint32_t min;           /**< Minimum value */
         uint32_t max;           /**< Maximum value */
-        double value;           /**< Current value */;
+        double value;           /**< Current value */
         /* FIXME: frac parts of min/max */
         uint32_t resolution;    /**< Resolution counts/m */
         uint8_t mode;           /**< Relative or Absolute */
commit 5300212ce8e9364ba26497605f3edc089af20130
Merge: ae796d4 0b193b3
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Feb 9 16:05:42 2014 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit 0b193b3ac94e078d9291d1b1dfd4814e5f2d9e34
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 6 07:59:07 2014 +1000

    xfree86: use xnfstrdup in the Xorg -configure code
    
    Just for consistency, I'm pretty sure the code is generally not happy for
    malloc failures anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 6aaf634..967bfbc 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -159,8 +159,8 @@ configureInputSection(void)
 
     parsePrologue(XF86ConfInputPtr, XF86ConfInputRec)
 
-    ptr->inp_identifier = strdup("Keyboard0");
-    ptr->inp_driver = strdup("kbd");
+    ptr->inp_identifier = xnfstrdup("Keyboard0");
+    ptr->inp_driver = xnfstrdup("kbd");
     ptr->list.next = NULL;
 
     /* Crude mechanism to auto-detect mouse (os dependent) */
@@ -175,17 +175,17 @@ configureInputSection(void)
     }
 
     mouse = calloc(1, sizeof(XF86ConfInputRec));
-    mouse->inp_identifier = strdup("Mouse0");
-    mouse->inp_driver = strdup("mouse");
+    mouse->inp_identifier = xnfstrdup("Mouse0");
+    mouse->inp_driver = xnfstrdup("mouse");
     mouse->inp_option_lst =
-        xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
-                         strdup(DFLT_MOUSE_PROTO));
+        xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Protocol"),
+                         xnfstrdup(DFLT_MOUSE_PROTO));
     mouse->inp_option_lst =
-        xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
-                         strdup(DFLT_MOUSE_DEV));
+        xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Device"),
+                         xnfstrdup(DFLT_MOUSE_DEV));
     mouse->inp_option_lst =
-        xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
-                         strdup("4 5 6 7"));
+        xf86addNewOption(mouse->inp_option_lst, xnfstrdup("ZAxisMapping"),
+                         xnfstrdup("4 5 6 7"));
     ptr = (XF86ConfInputPtr) xf86addListItem((glp) ptr, (glp) mouse);
     return ptr;
 }
@@ -290,7 +290,7 @@ configureDeviceSection(int screennum)
             "        ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
             "        ### <percent>: \"<f>%\"\n"
             "        ### [arg]: arg optional\n";
-        ptr->dev_comment = strdup(descrip);
+        ptr->dev_comment = xnfstrdup(descrip);
         if (ptr->dev_comment) {
             for (p = DevToConfig[screennum].GDev.options; p->name != NULL; p++) {
                 char *p_e;
@@ -337,9 +337,9 @@ configureLayoutSection(void)
         iptr = malloc(sizeof(XF86ConfInputrefRec));
         iptr->list.next = NULL;
         iptr->iref_option_lst = NULL;
-        iptr->iref_inputdev_str = strdup("Mouse0");
+        iptr->iref_inputdev_str = xnfstrdup("Mouse0");
         iptr->iref_option_lst =
-            xf86addNewOption(iptr->iref_option_lst, strdup("CorePointer"),
+            xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CorePointer"),
                              NULL);
         ptr->lay_input_lst = (XF86ConfInputrefPtr)
             xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr);
@@ -351,9 +351,9 @@ configureLayoutSection(void)
         iptr = malloc(sizeof(XF86ConfInputrefRec));
         iptr->list.next = NULL;
         iptr->iref_option_lst = NULL;
-        iptr->iref_inputdev_str = strdup("Keyboard0");
+        iptr->iref_inputdev_str = xnfstrdup("Keyboard0");
         iptr->iref_option_lst =
-            xf86addNewOption(iptr->iref_option_lst, strdup("CoreKeyboard"),
+            xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CoreKeyboard"),
                              NULL);
         ptr->lay_input_lst = (XF86ConfInputrefPtr)
             xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr);
@@ -431,9 +431,9 @@ configureFilesSection(void)
     parsePrologue(XF86ConfFilesPtr, XF86ConfFilesRec)
 
         if (xf86ModulePath)
-        ptr->file_modulepath = strdup(xf86ModulePath);
+        ptr->file_modulepath = xnfstrdup(xf86ModulePath);
     if (defaultFontPath)
-        ptr->file_fontpath = strdup(defaultFontPath);
+        ptr->file_fontpath = xnfstrdup(defaultFontPath);
 
     return ptr;
 }
@@ -446,8 +446,8 @@ configureMonitorSection(int screennum)
 
     XNFasprintf(&tmp, "Monitor%d", screennum);
     ptr->mon_identifier = tmp;
-    ptr->mon_vendor = strdup("Monitor Vendor");
-    ptr->mon_modelname = strdup("Monitor Model");
+    ptr->mon_vendor = xnfstrdup("Monitor Vendor");
+    ptr->mon_modelname = xnfstrdup("Monitor Model");
 
     return ptr;
 }
@@ -491,7 +491,7 @@ configureDDCMonitorSection(int screennum)
 
     XNFasprintf(&tmp, "Monitor%d", screennum);
     ptr->mon_identifier = tmp;
-    ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
+    ptr->mon_vendor = xnfstrdup(ConfiguredMonitor->vendor.name);
     XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
 
     /* features in centimetres, we want millimetres */
@@ -529,7 +529,7 @@ configureDDCMonitorSection(int screennum)
 
     if (ConfiguredMonitor->features.dpms) {
         ptr->mon_option_lst =
-            xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
+            xf86addNewOption(ptr->mon_option_lst, xnfstrdup("DPMS"), NULL);
     }
 
     return ptr;
commit 7b1b7fb3be47672454837a3f7be2d1440433ec27
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 15:12:22 2014 +1000

    mi: fix printf warning about size_t format specifier
    
    mieq.c:290:26: warning: format '%u' expects argument of type 'unsigned int',
    but argument 2 has type 'size_t' [-Wformat=]
    
    pnprintf supports size_t since 5ea21560dd071ea4ab87430000d087fd5fe1f092
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/mi/mieq.c b/mi/mieq.c
index bc7f945..36aa213 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -286,7 +286,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
         else if (miEventQueue.dropped % QUEUE_DROP_BACKTRACE_FREQUENCY == 0 &&
                  miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY <=
                  QUEUE_DROP_BACKTRACE_MAX) {
-            ErrorFSigSafe("[mi] EQ overflow continuing.  %u events have been "
+            ErrorFSigSafe("[mi] EQ overflow continuing.  %zu events have been "
                          "dropped.\n", miEventQueue.dropped);
             if (miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY ==
                 QUEUE_DROP_BACKTRACE_MAX) {
commit ddeca927498c9df3b5e62c7bf05e31e2a3aeaa52
Author: Mark Kettenis <kettenis at openbsd.org>
Date:   Sun Dec 15 14:31:10 2013 +0100

    sync: Avoid ridiculously long timeouts
    
    On OpenBSD, passing a timeout longer than 100000000 seconds to select(2) will
    make it fail with EINVAL.  As this is original 4.4BSD behaviour it is not
    inconceivable that other systems suffer from the same problem.  And Linux,
    though not suffering from any 4.4BSD heritage, briefly did something similar:
    
    <https://lkml.org/lkml/2012/8/31/263>
    
    So avoid calling AdjustWaitForDelay() instead of setting the timeout to
    (effectively) ULONG_MAX milliseconds.
    
    Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
    Reviewed-by: Matthieu Herrb <matthieu at herrb.eu>

diff --git a/Xext/sync.c b/Xext/sync.c
index 97c9d51..755ed94 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2731,27 +2731,24 @@ IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask)
          * If we've been idle more than it, and someone wants to know about
          * that level-triggered, schedule an immediate wakeup.
          */
-        unsigned long timeout = -1;
 
         if (XSyncValueLessThan(idle, *greater)) {
             XSyncValue value;
             Bool overflow;
 
             XSyncValueSubtract(&value, *greater, idle, &overflow);
-            timeout = min(timeout, XSyncValueLow32(value));
+            AdjustWaitForDelay(wt, XSyncValueLow32(value));
         }
         else {
             for (list = counter->sync.pTriglist; list;
                  list = list->next) {
                 trig = list->pTrigger;
                 if (trig->CheckTrigger(trig, old_idle)) {
-                    timeout = min(timeout, 0);
+                    AdjustWaitForDelay(wt, 0);
                     break;
                 }
             }
         }
-
-        AdjustWaitForDelay(wt, timeout);
     }
 
     counter->value = old_idle;  /* pop */
commit ae796d43c934ba378c9a618adc81c6729a14b2f8
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Feb 6 19:17:50 2014 -0800

    ephyr: Repaint entire screen when colormap is updated
    
    Any time the colormap is changed, the entire screen needs to be
    repainted to match.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index da80c95..9681273 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1232,6 +1232,9 @@ ephyrGetColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
 void
 ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
 {
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = screen->driver;
     int min, max, p;
 
     /* XXX Not sure if this is right */
@@ -1251,6 +1254,18 @@ ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
                              pdefs->green >> 8, pdefs->blue >> 8);
         pdefs++;
     }
+    if (scrpriv->pDamage) {
+        BoxRec box;
+        RegionRec region;
+
+        box.x1 = 0;
+        box.y1 = 0;
+        box.x2 = pScreen->width;
+        box.y2 = pScreen->height;
+        RegionInit(&region, &box, 1);
+        DamageReportDamage(scrpriv->pDamage, &region);
+        RegionUninit(&region);
+    }
 }
 
 /* Mouse calls */
commit 9eecc9ac73aa06dca1420e0a89fb0cbd432a9bd7
Author: David Heidelberger <david.heidelberger at ixit.cz>
Date:   Fri Feb 7 02:06:04 2014 +0100

    configure.ac: add missing "test"
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/configure.ac b/configure.ac
index 93f7316..21a6591 100644
--- a/configure.ac
+++ b/configure.ac
@@ -841,7 +841,7 @@ if test "x$WITH_SYSTEMD_DAEMON" = xauto; then
 	WITH_SYSTEMD_DAEMON="$HAVE_SYSTEMD_DAEMON"
 fi
 if test "x$WITH_SYSTEMD_DAEMON" = xyes; then
-	if "x$HAVE_SYSTEMD_DAEMON" = xno; then
+	if test "x$HAVE_SYSTEMD_DAEMON" = xno; then
 		AC_MSG_ERROR([systemd support requested but no library has been found])
 	fi
 	AC_DEFINE(HAVE_SYSTEMD_DAEMON, 1, [Define to 1 if libsystemd-daemon is available])
commit 08c7df9b0870fadf7b4655825459ff2e5a5c47da
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Feb 3 17:38:24 2014 -0800

    __glGetProcAddress: explictly cast function pointers to void *
    
    Fixes Solaris Studio compiler warning & error:
    
    "glxext.c", line 557: warning: assignment type mismatch:
    	    pointer to void "=" pointer to function(void) returning void
    "glxext.c", line 559: error: operands have incompatible types:
    	     pointer to void ":" pointer to function(void) returning void
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxext.c b/glx/glxext.c
index 6a34ac2..c9b8cc5 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -554,9 +554,9 @@ __glXsetGetProcAddress(glx_gpa_proc get_proc_address)
 
 void *__glGetProcAddress(const char *proc)
 {
-    void *ret = _get_proc_address(proc);
+    void *ret = (void *) _get_proc_address(proc);
 
-    return ret ? ret : NoopDDA;
+    return ret ? ret : (void *) NoopDDA;
 }
 
 /*
commit 76eedb039fc8d515a76c1df944fd5a85ac674019
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jan 27 11:36:08 2014 -0800

    xfree86: Fix a compiler warning on 64-bit.
    
    asm/mtrr.h makes this an unsigned long on 32, but a u64 on 64.  Cast
    it to a long to win.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
index 824003d..47f5abc 100644
--- a/hw/xfree86/os-support/linux/lnx_video.c
+++ b/hw/xfree86/os-support/linux/lnx_video.c
@@ -204,7 +204,7 @@ mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size,
             xf86DrvMsgVerb(screenNum, X_WARNING, 0,
                            "Failed to remove MMIO "
                            "write-combining range (0x%lx,0x%lx)\n",
-                           gent.base, (unsigned long) gent.size);
+                           (unsigned long)gent.base, (unsigned long) gent.size);
         }
     }
     return wcreturn;
commit 9f8f6657cdd3a5b166771695addb6fe76d93c378
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jan 27 11:36:07 2014 -0800

    glx: Delete dead NV program string functions.
    
    These have been throwing a compiler warning about missing prototypes,
    since the generated code to define the prototypes stopped being
    generated (possibly because the code was dead).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/indirect_program.c b/glx/indirect_program.c
index fa4a240..d503262 100644
--- a/glx/indirect_program.c
+++ b/glx/indirect_program.c
@@ -122,25 +122,3 @@ __glXDispSwap_GetProgramStringARB(struct __GLXclientStateRec *cl, GLbyte * pc)
 
     return DoGetProgramString(cl, pc, get_program, get_program_string, True);
 }
-
-int
-__glXDisp_GetProgramStringNV(struct __GLXclientStateRec *cl, GLbyte * pc)
-{
-    PFNGLGETPROGRAMIVARBPROC get_program =
-        __glGetProcAddress("glGetProgramivARB");
-    PFNGLGETPROGRAMSTRINGARBPROC get_program_string =
-        __glGetProcAddress("glGetProgramStringARB");
-
-    return DoGetProgramString(cl, pc, get_program, get_program_string, False);
-}
-
-int
-__glXDispSwap_GetProgramStringNV(struct __GLXclientStateRec *cl, GLbyte * pc)
-{
-    PFNGLGETPROGRAMIVARBPROC get_program =
-        __glGetProcAddress("glGetProgramivARB");
-    PFNGLGETPROGRAMSTRINGARBPROC get_program_string =
-        __glGetProcAddress("glGetProgramStringARB");
-
-    return DoGetProgramString(cl, pc, get_program, get_program_string, True);
-}
commit 0c774d53c5c1e8845e7da9b01814d7b98f621f51
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jan 27 11:36:06 2014 -0800

    glx: Reduce compiler warnings by not requesting GL extension prototypes.
    
    They're not officially in the ABI, so you shouldn't use them anyway.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxserver.h b/glx/glxserver.h
index 7f36e5f..3f2ae35 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -46,7 +46,6 @@
 #include <resource.h>
 #include <scrnintstr.h>
 
-#define GL_GLEXT_PROTOTYPES     /* we want prototypes */
 #include <GL/gl.h>
 #include <GL/glext.h>
 #include <GL/glxproto.h>
commit 87c4551c9cc9e382e6cfb59df1759d27c776abc8
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Jan 27 11:36:05 2014 -0800

    glx: Stop relying on libGL ABI bugs for glGetCompressedTexImage().
    
    In theory, the linux libGL ABI exposes just GL 1.2 plus GLX 1.3.  But,
    thanks to libglapi, we're letting glGetCompressedTexImageARB() be
    exposed too.  The GLX code was inappropriately relying on it by using
    GL_GLEXT_PROTOTYPES.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/indirect_texture_compression.c b/glx/indirect_texture_compression.c
index 94de47d..2018de6 100644
--- a/glx/indirect_texture_compression.c
+++ b/glx/indirect_texture_compression.c
@@ -54,9 +54,11 @@ __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
                                  &compsize);
 
         if (compsize != 0) {
+            PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GetCompressedTexImageARB =
+                __glGetProcAddress("glGetCompressedTexImageARB");
             __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
             __glXClearErrorOccured();
-            glGetCompressedTexImageARB(target, level, answer);
+            GetCompressedTexImageARB(target, level, answer);
         }
 
         if (__glXErrorOccured()) {
@@ -96,9 +98,11 @@ __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc)
                                  &compsize);
 
         if (compsize != 0) {
+            PFNGLGETCOMPRESSEDTEXIMAGEARBPROC GetCompressedTexImageARB =
+                __glGetProcAddress("glGetCompressedTexImageARB");
             __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
             __glXClearErrorOccured();
-            glGetCompressedTexImageARB(target, level, answer);
+            GetCompressedTexImageARB(target, level, answer);
         }
 
         if (__glXErrorOccured()) {
commit bf4f02337c97ffc3f7fbba9dba8ab72fa6c4a5fd
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Jan 6 14:13:24 2014 +0000

    glx: Remove left-over glthread.c
    
    Commit be668096 "glx: convert to direct GL dispatch (v2)" removes glthread.c
    from Makefile.am along with the rest of the dispatch table code, but doesn't
    remove glthread.c itself.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glthread.c b/glx/glthread.c
deleted file mode 100644
index fd4c6cc..0000000
--- a/glx/glthread.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.1
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-/*
- * XXX There's probably some work to do in order to make this file
- * truly reusable outside of Mesa.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#include <X11/Xfuncproto.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "glthread.h"
-
-/*
- * This file should still compile even when THREADS is not defined.
- * This is to make things easier to deal with on the makefile scene..
- */
-#ifdef THREADS
-#include <errno.h>
-
-/*
- * Error messages
- */
-#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data"
-#define GET_TSD_ERROR "_glthread_: failed to get thread specific data"
-#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data"
-
-/*
- * Magic number to determine if a TSD object has been initialized.
- * Kind of a hack but there doesn't appear to be a better cross-platform
- * solution.
- */
-#define INIT_MAGIC 0xff8adc98
-
-/*
- * POSIX Threads -- The best way to go if your platform supports them.
- *                  Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly
- *                  has them, and many of the free Unixes now have them.
- *                  Be sure to use appropriate -mt or -D_REENTRANT type
- *                  compile flags when building.
- */
-#ifdef PTHREADS
-
-_X_EXPORT unsigned long
-_glthread_GetID(void)
-{
-    return (unsigned long) pthread_self();
-}
-
-void
-_glthread_InitTSD(_glthread_TSD * tsd)
-{
-    if (pthread_key_create(&tsd->key, NULL /*free */ ) != 0) {
-        perror(INIT_TSD_ERROR);
-        exit(-1);
-    }
-    tsd->initMagic = INIT_MAGIC;
-}
-
-void *
-_glthread_GetTSD(_glthread_TSD * tsd)
-{
-    if (tsd->initMagic != (int) INIT_MAGIC) {
-        _glthread_InitTSD(tsd);
-    }
-    return pthread_getspecific(tsd->key);
-}
-
-void
-_glthread_SetTSD(_glthread_TSD * tsd, void *ptr)
-{
-    if (tsd->initMagic != (int) INIT_MAGIC) {
-        _glthread_InitTSD(tsd);
-    }
-    if (pthread_setspecific(tsd->key, ptr) != 0) {
-        perror(SET_TSD_ERROR);
-        exit(-1);
-    }
-}
-
-#endif                          /* PTHREADS */
-
-/*
- * Win32 Threads.  The only available option for Windows 95/NT.
- * Be sure that you compile using the Multithreaded runtime, otherwise
- * bad things will happen.
- */
-#ifdef WIN32_THREADS
-
-void
-FreeTSD(_glthread_TSD * p)
-{
-    if (p->initMagic == INIT_MAGIC) {
-        TlsFree(p->key);
-        p->initMagic = 0;
-    }
-}
-
-void
-InsteadOf_exit(int nCode)
-{
-    DWORD dwErr = GetLastError();
-}
-
-unsigned long
-_glthread_GetID(void)
-{
-    return GetCurrentThreadId();
-}
-
-void
-_glthread_InitTSD(_glthread_TSD * tsd)
-{
-    tsd->key = TlsAlloc();
-    if (tsd->key == TLS_OUT_OF_INDEXES) {
-        perror("Mesa:_glthread_InitTSD");
-        InsteadOf_exit(-1);
-    }
-    tsd->initMagic = INIT_MAGIC;
-}
-
-void *
-_glthread_GetTSD(_glthread_TSD * tsd)
-{
-    if (tsd->initMagic != INIT_MAGIC) {
-        _glthread_InitTSD(tsd);
-    }
-    return TlsGetValue(tsd->key);
-}
-
-void
-_glthread_SetTSD(_glthread_TSD * tsd, void *ptr)
-{
-    /* the following code assumes that the _glthread_TSD has been initialized
-       to zero at creation */
-    if (tsd->initMagic != INIT_MAGIC) {
-        _glthread_InitTSD(tsd);
-    }
-    if (TlsSetValue(tsd->key, ptr) == 0) {
-        perror("Mesa:_glthread_SetTSD");
-        InsteadOf_exit(-1);
-    }
-}
-
-#endif                          /* WIN32_THREADS */
-
-#else                           /* THREADS */
-
-/*
- * no-op functions
- */
-
-_X_EXPORT unsigned long
-_glthread_GetID(void)
-{
-    return 0;
-}
-
-void
-_glthread_InitTSD(_glthread_TSD * tsd)
-{
-    (void) tsd;
-}
-
-void *
-_glthread_GetTSD(_glthread_TSD * tsd)
-{
-    (void) tsd;
-    return NULL;
-}
-
-void
-_glthread_SetTSD(_glthread_TSD * tsd, void *ptr)
-{
-    (void) tsd;
-    (void) ptr;
-}
-
-#endif                          /* THREADS */
commit 7305153643622269e14f3564f7a8a66ecaf49f78
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Feb 5 11:10:47 2014 -0500

    configure: Don't add GLX_SYS_LIBS to XORG_SYS_LIBS
    
    libglx.so is linked against libGL.so, but Xorg itself should not be.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index c6764f5..93f7316 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1853,7 +1853,7 @@ if test "x$XORG" = xyes; then
 	if test "x$PCI" = xyes; then
 		PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS)
 		SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $LIBPCIACCESS"
-		XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS $LIBDRM_LIBS"
+		XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $LIBDRM_LIBS"
 		XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS $LIBDRM_CFLAGS"
 
 		AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation])
commit c64130c13bd6914a998a8e8b808a6cedd18f9384
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 15:10:27 2014 +1000

    dix: fix a -Wshadow warning
    
    dispatch.c: In function 'SetVendorString':
    dispatch.c:481:29: warning: declaration of 'string' shadows a global declaration [-Wshadow]
     SetVendorString(const char *string)
                                 ^
    dispatch.c:135:21: warning: shadowed declaration is here [-Wshadow]
     typedef const char *string;
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 9a5658d..4f830f7 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -478,9 +478,9 @@ SetVendorRelease(int release)
 }
 
 void
-SetVendorString(const char *string)
+SetVendorString(const char *vendor)
 {
-    VendorString = string;
+    VendorString = vendor;
 }
 
 Bool
commit 72967d6c153b0d1109df23967e1a05c3c397a1e0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 14:32:23 2014 +1000

    xfree86: unconstify driver in the XF86ConfInputClassRec
    
    No const value is ever assigned to it, let's not pretend it's const.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index d352d4b..8f855ac 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -305,7 +305,7 @@ typedef struct {
 typedef struct {
     GenericListRec list;
     char *identifier;
-    const char *driver;
+    char *driver;
     struct xorg_list match_product;
     struct xorg_list match_vendor;
     struct xorg_list match_device;
commit f14d6647c0883d4e7e4de7645d7a18e4d301845e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 14:30:50 2014 +1000

    xfree86: unconstify another string
    
    Only Xorg -configure uses a hardcoded value here, so let's not change the rest
    of the server for that.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 5fc1399..6aaf634 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -337,7 +337,7 @@ configureLayoutSection(void)
         iptr = malloc(sizeof(XF86ConfInputrefRec));
         iptr->list.next = NULL;
         iptr->iref_option_lst = NULL;
-        iptr->iref_inputdev_str = "Mouse0";
+        iptr->iref_inputdev_str = strdup("Mouse0");
         iptr->iref_option_lst =
             xf86addNewOption(iptr->iref_option_lst, strdup("CorePointer"),
                              NULL);
@@ -351,7 +351,7 @@ configureLayoutSection(void)
         iptr = malloc(sizeof(XF86ConfInputrefRec));
         iptr->list.next = NULL;
         iptr->iref_option_lst = NULL;
-        iptr->iref_inputdev_str = "Keyboard0";
+        iptr->iref_inputdev_str = strdup("Keyboard0");
         iptr->iref_option_lst =
             xf86addNewOption(iptr->iref_option_lst, strdup("CoreKeyboard"),
                              NULL);
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 2871edd..d352d4b 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -288,7 +288,7 @@ typedef struct {
 typedef struct {
     GenericListRec list;
     XF86ConfInputPtr iref_inputdev;
-    const char *iref_inputdev_str;
+    char *iref_inputdev_str;
     XF86OptionPtr iref_option_lst;
 } XF86ConfInputrefRec, *XF86ConfInputrefPtr;
 
commit 46ae9d67e4118fa79bef0f9119d20559dfd6b6c0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 14:24:54 2014 +1000

    xfree86: un-constify inp_driver/inp_identifier
    
    The only place this isn't allocated is during Xorg -configure where we just
    statically assing "mouse"/"kbd" and the identifiers for it. Everywhere else
    it's strdup'd and then free'd already.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 30dc550..5fc1399 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -159,8 +159,8 @@ configureInputSection(void)
 
     parsePrologue(XF86ConfInputPtr, XF86ConfInputRec)
 
-        ptr->inp_identifier = "Keyboard0";
-    ptr->inp_driver = "kbd";
+    ptr->inp_identifier = strdup("Keyboard0");
+    ptr->inp_driver = strdup("kbd");
     ptr->list.next = NULL;
 
     /* Crude mechanism to auto-detect mouse (os dependent) */
@@ -175,8 +175,8 @@ configureInputSection(void)
     }
 
     mouse = calloc(1, sizeof(XF86ConfInputRec));
-    mouse->inp_identifier = "Mouse0";
-    mouse->inp_driver = "mouse";
+    mouse->inp_identifier = strdup("Mouse0");
+    mouse->inp_driver = strdup("mouse");
     mouse->inp_option_lst =
         xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
                          strdup(DFLT_MOUSE_PROTO));
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 0fcf405..2871edd 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -279,8 +279,8 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    const char *inp_identifier;
-    const char *inp_driver;
+    char *inp_identifier;
+    char *inp_driver;
     XF86OptionPtr inp_option_lst;
     char *inp_comment;
 } XF86ConfInputRec, *XF86ConfInputPtr;
commit 93bf9544712a39f10557533993d8826b2b67fc9a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 5 14:16:01 2014 +1000

    xfree86: device name and driver are not const char
    
    Allocated in one place, freed in another.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index f94261a..b6d1251 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -82,8 +82,8 @@ typedef struct _InputDriverRec {
 
 typedef struct _InputInfoRec {
     struct _InputInfoRec *next;
-    const char *name;
-    const char *driver;
+    char *name;
+    char *driver;
 
     int flags;
 
commit 25d10464f440b8b34594b7c988a99a830ea39a29
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 24 18:16:54 2014 +1000

    dix: fix button state check before changing a button mapping
    
    dev->button->down is a bitmask, not a normal array. Use the helper function to
    check, we technically allow the mapping to change after the physical button
    has been pressed (but not yet processed yet), so only check BUTTON_PROCESSED.
    
    From XSetPointerMapping(3):
    "If any of the buttons to be altered are logically in the down state,
    XSetPointerMapping returns MappingBusy, and the mapping is not changed."
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index a10a7c7..e5bcc31 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -60,7 +60,8 @@ check_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out,
     }
 
     for (i = 0; i < len; i++) {
-        if (dev->button->map[i + 1] != map[i] && dev->button->down[i + 1])
+        if (dev->button->map[i + 1] != map[i] &&
+            button_is_down(dev, i + 1, BUTTON_PROCESSED))
             return MappingBusy;
     }
 
commit 73926622b91fde01148727f26d6aad5e6827c1d2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 24 18:33:54 2014 +1000

    include: make the various button array lengths more obvious
    
    No functional changes, just making a better case for why MAP_LENGTH is 256.
    "But can't we remove MAP_LENGTH then?" I hear you say? "Why, yes. Go for it!"
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/include/input.h b/include/input.h
index 6f047ee..93c4510 100644
--- a/include/input.h
+++ b/include/input.h
@@ -95,8 +95,8 @@ SOFTWARE.
 
 #define NO_AXIS_LIMITS -1
 
-#define MAP_LENGTH	256
-#define DOWN_LENGTH	32      /* 256/8 => number of bytes to hold 256 bits */
+#define MAP_LENGTH	MAX_BUTTONS
+#define DOWN_LENGTH	(MAX_BUTTONS/8)      /* 256/8 => number of bytes to hold 256 bits */
 #define NullGrab ((GrabPtr)NULL)
 #define PointerRootWin ((WindowPtr)PointerRoot)
 #define NoneWin ((WindowPtr)None)
commit 87ca80a7196949597113225405f3e4ee03bbee13
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 24 18:32:54 2014 +1000

    dix: prevent a driver from initializing or submitting buttons > MAX_BUTTONS
    
    The server internally relies on arrays with a MAX_BUTTONS maximum size (which
    is the max the core protocol can transport). Make sure a driver adheres to
    that.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/devices.c b/dix/devices.c
index a875f03..1c86d52 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1279,6 +1279,7 @@ InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels,
 
     BUG_RETURN_VAL(dev == NULL, FALSE);
     BUG_RETURN_VAL(dev->button != NULL, FALSE);
+    BUG_RETURN_VAL(numButtons >= MAX_BUTTONS, FALSE);
 
     butc = calloc(1, sizeof(ButtonClassRec));
     if (!butc)
diff --git a/dix/getevents.c b/dix/getevents.c
index 646c723..ffa89fa 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1655,6 +1655,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     }
 #endif
 
+    BUG_RETURN_VAL(buttons >= MAX_BUTTONS, 0);
+
     /* refuse events from disabled devices */
     if (!pDev->enabled)
         return 0;
commit 14fb6cf92c009d726f0a6b6e8b89cc48f2dd50eb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 30 09:16:23 2014 +1000

    Revert "xfree86/common: handle string constants in xf86Xinput configuration"
    
    This reverts commit 22592855e90d23013ba7f9e945d567725cb44bf3.
    
    What warning was this supposed to fix?
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 3a01513..f6f2b90 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -539,7 +539,7 @@ MatchAttrToken(const char *attr, struct xorg_list *patterns,
      * match. Each list entry is a separate Match line of the same type.
      */
     xorg_list_for_each_entry(group, patterns, entry) {
-        const char *const *cur;
+        char *const *cur;
         Bool match = FALSE;
 
         for (cur = group->values; *cur; cur++)
@@ -598,7 +598,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
      * See if any of the device's tags match any of the MatchTag tokens.
      */
     if (!xorg_list_is_empty(&iclass->match_tag)) {
-        const char *const *tag;
+        char *const *tag;
         Bool match;
 
         if (!attrs->tags)
commit a553444b5841522836f7437ebb96e40be270fd8b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 30 09:12:41 2014 +1000

    Revert "xfree86/parser: make strings in xf86MatchGroup const"
    
    This reverts commit f71de60355cc76810657f40c7b5461af86b34bf7.
    
    What warnings?
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index 24a1246..c2fbd22 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -63,7 +63,7 @@ xf86ConfigSymTabRec InputClassTab[] = {
 #define TOKEN_SEP "|"
 
 static void
-add_group_entry(struct xorg_list *head, const char **values)
+add_group_entry(struct xorg_list *head, char **values)
 {
     xf86MatchGroup *group;
 
@@ -256,7 +256,7 @@ void
 xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
 {
     const xf86MatchGroup *group;
-    const char *const *cur;
+    char *const *cur;
 
     while (ptr) {
         fprintf(cf, "Section \"InputClass\"\n");
@@ -362,7 +362,7 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
 
     while (ptr) {
         xf86MatchGroup *group, *next;
-        const char **list;
+        char **list;
 
         TestFree(ptr->identifier);
         TestFree(ptr->driver);
@@ -370,55 +370,55 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
         xorg_list_for_each_entry_safe(group, next, &ptr->match_product, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_device, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_os, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_layout, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free((void *) *list);
+                free(*list);
             free(group);
         }
 
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 83607f2..0fcf405 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -299,7 +299,7 @@ typedef struct {
 
 typedef struct {
     struct xorg_list entry;
-    const char **values;
+    char **values;
 } xf86MatchGroup;
 
 typedef struct {
commit 45f1d527f39a296104f2fa79a774446e7e1560e0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 30 09:01:09 2014 +1000

    input: un-constify dev->name
    
    Fallout from fecc7eb1cf66db64728ee2d68cd9443df7e70879, and reverts most of the
    rest of that patch.
    
    The device name is allocated and may even change during PreInit. The const
    warnings came from the test codes, the correct fix here is to fix the test
    code.
    
    touch.c: In function ‘touch_init’:
    touch.c:254:14: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
         dev.name = "test device";
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9ebd733..26c628c 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1169,8 +1169,8 @@ IResetProc(ExtensionEntry * unused)
     EventSwapVector[DevicePropertyNotify] = NotImplemented;
     RestoreExtensionEvents();
 
-    free((void *) xi_all_devices.name);
-    free((void *) xi_all_master_devices.name);
+    free(xi_all_devices.name);
+    free(xi_all_master_devices.name);
 
     XIBarrierReset();
 }
diff --git a/dix/devices.c b/dix/devices.c
index 45de713..a875f03 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -955,7 +955,7 @@ CloseDevice(DeviceIntPtr dev)
     while (dev->xkb_interest)
         XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource);
 
-    free((void *) dev->name);
+    free(dev->name);
 
     classes = (ClassesPtr) &dev->key;
     FreeAllDeviceClasses(classes);
diff --git a/include/inputstr.h b/include/inputstr.h
index dfcf7c3..f6cfb04 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -542,7 +542,7 @@ typedef struct _DeviceIntRec {
     GrabInfoRec deviceGrab;     /* grab on the device */
     int type;                   /* MASTER_POINTER, MASTER_KEYBOARD, SLAVE */
     Atom xinput_type;
-    const char *name;
+    char *name;
     int id;
     KeyClassPtr key;
     ValuatorClassPtr valuator;
diff --git a/test/touch.c b/test/touch.c
index df1db11..981c694 100644
--- a/test/touch.c
+++ b/test/touch.c
@@ -40,7 +40,7 @@ touch_grow_queue(void)
     int i;
 
     memset(&dev, 0, sizeof(dev));
-    dev.name = "test device";
+    dev.name = xnfstrdup("test device");
     dev.id = 2;
     dev.valuator = &val;
     val.numAxes = 5;
@@ -82,6 +82,8 @@ touch_grow_queue(void)
         assert(t->client_id == 0);
         assert(t->ddx_id == 0);
     }
+
+    free(dev.name);
 }
 
 static void
@@ -95,7 +97,7 @@ touch_find_ddxid(void)
     int i;
 
     memset(&dev, 0, sizeof(dev));
-    dev.name = "test device";
+    dev.name = xnfstrdup("test device");
     dev.id = 2;
     dev.valuator = &val;
     val.numAxes = 5;
@@ -150,6 +152,8 @@ touch_find_ddxid(void)
     ProcessWorkQueue();
     ti = TouchFindByDDXID(&dev, 40, TRUE);
     assert(ti == &dev.last.touches[size]);
+
+    free(dev.name);
 }
 
 static void
@@ -164,7 +168,7 @@ touch_begin_ddxtouch(void)
     int size = 5;
 
     memset(&dev, 0, sizeof(dev));
-    dev.name = "test device";
+    dev.name = xnfstrdup("test device");
     dev.id = 2;
     dev.valuator = &val;
     val.numAxes = 5;
@@ -195,6 +199,8 @@ touch_begin_ddxtouch(void)
     assert(ti->client_id > last_client_id);
     assert(!ti->emulate_pointer);
     last_client_id = ti->client_id;
+
+    free(dev.name);
 }
 
 static void
@@ -212,7 +218,7 @@ touch_begin_touch(void)
     screenInfo.screens[0] = &screen;
 
     memset(&dev, 0, sizeof(dev));
-    dev.name = "test device";
+    dev.name = xnfstrdup("test device");
     dev.id = 2;
 
     memset(&sprite, 0, sizeof(sprite));
@@ -237,6 +243,8 @@ touch_begin_touch(void)
     assert(ti->emulate_pointer);
 
     assert(touch.num_touches == 1);
+
+    free(dev.name);
 }
 
 static void
@@ -251,7 +259,7 @@ touch_init(void)
     screenInfo.screens[0] = &screen;
 
     memset(&dev, 0, sizeof(dev));
-    dev.name = "test device";
+    dev.name = xnfstrdup("test device");
 
     memset(&sprite, 0, sizeof(sprite));
     dev.spriteInfo = &sprite;
@@ -264,6 +272,8 @@ touch_init(void)
     rc = InitTouchClassDeviceStruct(&dev, 1, XIDirectTouch, 2);
     assert(rc == TRUE);
     assert(dev.touch);
+
+    free(dev.name);
 }
 
 int
commit 675f215af291135ee3ece5414e4a5a2e89bf4ed3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 30 08:52:32 2014 +1000

    Revert "os: xstrtokenize takes and returns const char * now"
    
    This reverts commit d0339a5c66846c9f14e3b584e34688520a0916ab.
    
    seriously, what the fuck? Are we making xstrdup() return a const char now too?
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/include/misc.h b/include/misc.h
index 165d42e..17de710 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -246,7 +246,7 @@ padding_for_int32(const int bytes)
 }
 
 
-extern const char **xstrtokenize(const char *str, const char *separators);
+extern char **xstrtokenize(const char *str, const char *separators);
 extern void FormatInt64(int64_t num, char *string);
 extern void FormatUInt64(uint64_t num, char *string);
 extern void FormatUInt64Hex(uint64_t num, char *string);
diff --git a/os/utils.c b/os/utils.c
index dc18a67..497779b 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1973,10 +1973,10 @@ CheckUserAuthorization(void)
  * Tokenize a string into a NULL terminated array of strings. Always returns
  * an allocated array unless an error occurs.
  */
-const char **
+char **
 xstrtokenize(const char *str, const char *separators)
 {
-    const char **list, **nlist;
+    char **list, **nlist;
     char *tok, *tmp;
     unsigned num = 0, n;
 
@@ -2004,7 +2004,7 @@ xstrtokenize(const char *str, const char *separators)
  error:
     free(tmp);
     for (n = 0; n < num; n++)
-        free((void *) list[n]);
+        free(list[n]);
     free(list);
     return NULL;
 }
commit ce3df579e3f24a169189b288230959527e059080
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 30 08:50:06 2014 +1000

    input: un-constify InputAttributes
    
    Introduced in fecc7eb1cf66db64728ee2d68cd9443df7e70879 and reverts most of
    that but it's helpfully mixed with other stuff.
    
    InputAttributes are not const, they're strdup'd everywhere but the test code
    and freed properly. Revert the const char changes and fix the test up instead.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/config/udev.c b/config/udev.c
index 436b8f0..68ed348 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -242,16 +242,16 @@ device_added(struct udev_device *udev_device)
     free(config_info);
     input_option_free_list(&input_options);
 
-    free((void *) attrs.usb_id);
-    free((void *) attrs.pnp_id);
-    free((void *) attrs.product);
-    free((void *) attrs.device);
-    free((void *) attrs.vendor);
+    free(attrs.usb_id);
+    free(attrs.pnp_id);
+    free(attrs.product);
+    free(attrs.device);
+    free(attrs.vendor);
     if (attrs.tags) {
-        const char **tag = attrs.tags;
+        char **tag = attrs.tags;
 
         while (*tag) {
-            free((void *) *tag);
+            free(*tag);
             tag++;
         }
         free(attrs.tags);
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 3e1d75f..a10a7c7 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -351,7 +351,7 @@ DuplicateInputAttributes(InputAttributes * attrs)
 {
     InputAttributes *new_attr;
     int ntags = 0;
-    const char **tags, **new_tags;
+    char **tags, **new_tags;
 
     if (!attrs)
         return NULL;
@@ -403,20 +403,20 @@ DuplicateInputAttributes(InputAttributes * attrs)
 void
 FreeInputAttributes(InputAttributes * attrs)
 {
-    const char **tags;
+    char **tags;
 
     if (!attrs)
         return;
 
-    free((void *) attrs->product);
-    free((void *) attrs->vendor);
-    free((void *) attrs->device);
-    free((void *) attrs->pnp_id);
-    free((void *) attrs->usb_id);
+    free(attrs->product);
+    free(attrs->vendor);
+    free(attrs->device);
+    free(attrs->pnp_id);
+    free(attrs->usb_id);
 
     if ((tags = attrs->tags))
         while (*tags)
-            free((void *) *tags++);
+            free(*tags++);
 
     free(attrs->tags);
     free(attrs);
diff --git a/include/input.h b/include/input.h
index 455963f..6f047ee 100644
--- a/include/input.h
+++ b/include/input.h
@@ -221,12 +221,12 @@ typedef struct _InputOption InputOption;
 typedef struct _XI2Mask XI2Mask;
 
 typedef struct _InputAttributes {
-    const char *product;
-    const char *vendor;
-    const char *device;
-    const char *pnp_id;
-    const char *usb_id;
-    const char **tags;                /* null-terminated */
+    char *product;
+    char *vendor;
+    char *device;
+    char *pnp_id;
+    char *usb_id;
+    char **tags;                /* null-terminated */
     uint32_t flags;
 } InputAttributes;
 
diff --git a/test/input.c b/test/input.c
index aaa7a69..5813e6d 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1101,7 +1101,7 @@ xi_unregister_handlers(void)
 static void
 cmp_attr_fields(InputAttributes * attr1, InputAttributes * attr2)
 {
-    const char **tags1, **tags2;
+    char **tags1, **tags2;
 
     assert(attr1 && attr2);
     assert(attr1 != attr2);
@@ -1180,50 +1180,54 @@ cmp_attr_fields(InputAttributes * attr1, InputAttributes * attr2)
 static void
 dix_input_attributes(void)
 {
-    InputAttributes orig = { 0 };
+    InputAttributes *orig;
     InputAttributes *new;
-    const char *tags[4] = { "tag1", "tag2", "tag2", NULL };
 
     new = DuplicateInputAttributes(NULL);
     assert(!new);
 
-    new = DuplicateInputAttributes(&orig);
-    assert(memcmp(&orig, new, sizeof(InputAttributes)) == 0);
+    orig = calloc(1, sizeof(InputAttributes));
+    assert(orig);
 
-    orig.product = "product name";
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    new = DuplicateInputAttributes(orig);
+    assert(memcmp(orig, new, sizeof(InputAttributes)) == 0);
+
+    orig->product = xnfstrdup("product name");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.vendor = "vendor name";
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->vendor = xnfstrdup("vendor name");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.device = "device path";
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->device = xnfstrdup("device path");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.pnp_id = "PnPID";
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->pnp_id = xnfstrdup("PnPID");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.usb_id = "USBID";
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->usb_id = xnfstrdup("USBID");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.flags = 0xF0;
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->flags = 0xF0;
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
 
-    orig.tags = tags;
-    new = DuplicateInputAttributes(&orig);
-    cmp_attr_fields(&orig, new);
+    orig->tags = xstrtokenize("tag1 tag2 tag3", " ");
+    new = DuplicateInputAttributes(orig);
+    cmp_attr_fields(orig, new);
     FreeInputAttributes(new);
+
+    FreeInputAttributes(orig);
 }
 
 static void
commit 2fc38d1e299587d25ca8225051e0ea9403164b15
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 29 11:16:51 2014 +1000

    xkb: add a call to init an XkbRMLVOSet from const chars
    
    Just forcing everything to const char* is not helpful, compiler warnings are
    supposed to warn about broken code. Forcing everything to const when it
    clearly isn't less than ideal.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 258b22b..542d5ab 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -777,13 +777,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     MessageType from;
     const char *s;
     XkbRMLVOSet set;
-
-    /* Default options. */
-    set.rules = "base";
-    set.model = "pc105";
-    set.layout = "us";
-    set.variant = NULL;
-    set.options = NULL;
+    const char *rules;
 
     /*
      * Merge the ServerLayout and ServerFlags options.  The former have
@@ -963,9 +957,15 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
      * evdev rules set. */
 #if defined(linux)
     if (!xf86Info.forceInputDevices)
-        set.rules = "evdev";
+        rules = "evdev";
+    else
 #endif
+        rules = "base";
+
+    /* Xkb default options. */
+    XkbInitRules(&set, rules, "pc105", "us", NULL, NULL);
     XkbSetRulesDflts(&set);
+    XkbFreeRMLVOSet(&set, FALSE);
 
     xf86Info.useDefaultFontPath = TRUE;
     xf86Info.useDefaultFontPathFrom = X_DEFAULT;
diff --git a/include/xkbrules.h b/include/xkbrules.h
index 956eade..ab5b4b2 100644
--- a/include/xkbrules.h
+++ b/include/xkbrules.h
@@ -30,11 +30,11 @@
 /***====================================================================***/
 
 typedef struct _XkbRMLVOSet {
-    const char *rules;
-    const char *model;
-    const char *layout;
-    const char *variant;
-    const char *options;
+    char *rules;
+    char *model;
+    char *layout;
+    char *variant;
+    char *options;
 } XkbRMLVOSet;
 
 typedef struct _XkbRF_VarDefs {
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 0b9ca06..e799799 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -738,6 +738,14 @@ extern _X_EXPORT void XkbClearAllLatchesAndLocks(DeviceIntPtr /* dev */ ,
                                                  XkbEventCausePtr       /* cause */
     );
 
+extern _X_EXPORT void XkbInitRules(XkbRMLVOSet * /* rmlvo   */,
+                                   const char *  /* rules   */,
+                                   const char *  /* model   */,
+                                   const char *  /* layout  */,
+                                   const char *  /* variant */,
+                                   const char *  /* options */
+    ) ;
+
 extern _X_EXPORT void XkbGetRulesDflts(XkbRMLVOSet *    /* rmlvo */
     );
 
diff --git a/test/xkb.c b/test/xkb.c
index 955e72d..9047f59 100644
--- a/test/xkb.c
+++ b/test/xkb.c
@@ -82,15 +82,17 @@ xkb_get_rules_test(void)
 static void
 xkb_set_rules_test(void)
 {
-    XkbRMLVOSet rmlvo = {
-        .rules = "test-rules",
-        .model = "test-model",
-        .layout = "test-layout",
-        .variant = "test-variant",
-        .options = "test-options"
-    };
+    XkbRMLVOSet rmlvo;
     XkbRMLVOSet rmlvo_new = { NULL };
 
+    XkbInitRules(&rmlvo, "test-rules", "test-model", "test-layout",
+                         "test-variant", "test-options");
+    assert(rmlvo.rules);
+    assert(rmlvo.model);
+    assert(rmlvo.layout);
+    assert(rmlvo.variant);
+    assert(rmlvo.options);
+
     XkbSetRulesDflts(&rmlvo);
     XkbGetRulesDflts(&rmlvo_new);
 
@@ -106,6 +108,8 @@ xkb_set_rules_test(void)
     assert(strcmp(rmlvo.layout, rmlvo_new.layout) == 0);
     assert(strcmp(rmlvo.variant, rmlvo_new.variant) == 0);
     assert(strcmp(rmlvo.options, rmlvo_new.options) == 0);
+
+    XkbFreeRMLVOSet(&rmlvo, FALSE);
 }
 
 /**
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 22b971f..33420b6 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -129,11 +129,11 @@ XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
     if (!rmlvo)
         return;
 
-    free((void *) rmlvo->rules);
-    free((void *) rmlvo->model);
-    free((void *) rmlvo->layout);
-    free((void *) rmlvo->variant);
-    free((void *) rmlvo->options);
+    free(rmlvo->rules);
+    free(rmlvo->model);
+    free(rmlvo->layout);
+    free(rmlvo->variant);
+    free(rmlvo->options);
 
     if (freeRMLVO)
         free(rmlvo);
@@ -206,6 +206,21 @@ XkbWriteRulesProp(ClientPtr client, void *closure)
     return TRUE;
 }
 
+void
+XkbInitRules(XkbRMLVOSet *rmlvo,
+             const char *rules,
+             const char *model,
+             const char *layout,
+             const char *variant,
+             const char *options)
+{
+    rmlvo->rules = rules ? xnfstrdup(rules) : NULL;
+    rmlvo->model = model ? xnfstrdup(model) : NULL;
+    rmlvo->layout = layout ? xnfstrdup(layout) : NULL;
+    rmlvo->variant = variant ? xnfstrdup(variant) : NULL;
+    rmlvo->options = options ? xnfstrdup(options) : NULL;
+}
+
 static void
 XkbSetRulesUsed(XkbRMLVOSet * rmlvo)
 {
commit 6307d60dd592f4b438f880d02bde9fd8d50ae264
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 29 10:47:49 2014 +1000

    Xi: remove superfluous cast.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/Xi/listdev.c b/Xi/listdev.c
index 470fb52..6a10091 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -121,7 +121,7 @@ SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
 static void
 CopyDeviceName(char **namebuf, const char *name)
 {
-    char *nameptr = (char *) *namebuf;
+    char *nameptr = *namebuf;
 
     if (name) {
         *nameptr++ = strlen(name);
commit 83e38eb73fd8c852513aac2da2975b4c01070ec2
Author: Arun Raghavan <arun at accosted.net>
Date:   Mon Jan 6 20:29:50 2014 +0530

    edid: Add quirk for Sony Vaio Pro 13
    
    The detailed timings are for a 15.6" display when max image size
    correctly reports 13.3".
    
    Signed-off-by: Arun Raghavan <arun at accosted.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index a56f6ba..6fb0f9b 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -162,6 +162,11 @@ quirk_detailed_use_maximum_size(int scrnIndex, xf86MonPtr DDC)
         DDC->vendor.prod_id == 0x7f01)
         return TRUE;
 
+    /* Sony Vaio Pro 13 */
+    if (memcmp(DDC->vendor.name, "MEI", 4) == 0 &&
+        DDC->vendor.prod_id == 0x96a2)
+        return TRUE;
+
     return FALSE;
 }
 
commit bf83843b92ce21d11f6ff1a407ff3d014e017c9b
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Dec 19 14:10:18 2013 +0100

    xf86Events: add Enable/DisableInputDeviceForVTSwitch functions
    
    Factor this code out into functions so that it can be re-used for the
    systemd-logind device pause/resume paths.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 537d1d1..cec3135 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -215,6 +215,8 @@ extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
 
 /* xf86Events.c */
 
+typedef struct _InputInfoRec *InputInfoPtr;
+
 extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
 extern _X_EXPORT void *xf86AddInputHandler(int fd, InputHandlerProc proc,
                                              void *data);
@@ -236,6 +238,8 @@ extern _X_EXPORT void xf86PrintBacktrace(void);
 extern _X_EXPORT Bool xf86VTOwner(void);
 extern _X_EXPORT void xf86VTLeave(void);
 extern _X_EXPORT void xf86VTEnter(void);
+extern _X_EXPORT void xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo);
+extern _X_EXPORT void xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo);
 
 /* xf86Helper.c */
 
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index e0ec768..7b53949 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -408,6 +408,28 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
 }
 
 void
+xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo)
+{
+    if (!pInfo->dev)
+        return;
+
+    if (!pInfo->dev->enabled)
+        pInfo->flags |= XI86_DEVICE_DISABLED;
+
+    xf86ReleaseKeys(pInfo->dev);
+    ProcessInputEvents();
+    DisableDevice(pInfo->dev, TRUE);
+}
+
+void
+xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)
+{
+    if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
+        EnableDevice(pInfo->dev, TRUE);
+    pInfo->flags &= ~XI86_DEVICE_DISABLED;
+}
+
+void
 xf86VTLeave(void)
 {
     int i;
@@ -436,15 +458,8 @@ xf86VTLeave(void)
         else
             xf86DisableGeneralHandler(ih);
     }
-    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
-        if (pInfo->dev) {
-            if (!pInfo->dev->enabled)
-                pInfo->flags |= XI86_DEVICE_DISABLED;
-            xf86ReleaseKeys(pInfo->dev);
-            ProcessInputEvents();
-            DisableDevice(pInfo->dev, TRUE);
-        }
-    }
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+        xf86DisableInputDeviceForVTSwitch(pInfo);
 
     OsBlockSIGIO();
     for (i = 0; i < xf86NumScreens; i++)
@@ -494,13 +509,8 @@ switch_failed:
     }
     dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 
-    pInfo = xf86InputDevs;
-    while (pInfo) {
-        if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
-            EnableDevice(pInfo->dev, TRUE);
-        pInfo->flags &= ~XI86_DEVICE_DISABLED;
-        pInfo = pInfo->next;
-    }
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+        xf86EnableInputDeviceForVTSwitch(pInfo);
     for (ih = InputHandlers; ih; ih = ih->next) {
         if (ih->is_input)
             xf86EnableInputHandler(ih);
@@ -546,14 +556,8 @@ xf86VTEnter(void)
     /* Turn screen saver off when switching back */
     dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 
-    pInfo = xf86InputDevs;
-    while (pInfo) {
-        if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
-            EnableDevice(pInfo->dev, TRUE);
-        pInfo->flags &= ~XI86_DEVICE_DISABLED;
-        pInfo = pInfo->next;
-    }
-
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+        xf86EnableInputDeviceForVTSwitch(pInfo);
     for (ih = InputHandlers; ih; ih = ih->next) {
         if (ih->is_input)
             xf86EnableInputHandler(ih);
commit 48b489769e78fa20911630173ab708feecb0fb0e
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Dec 19 11:28:40 2013 +0100

    xf86Events: refactor xf86VTLeave error handling
    
    Use kernel goto style error handling for xf86VTSwitchAway() failure. This
    makes it much easier to read the straight path.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index e4ec177..e0ec768 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -454,62 +454,60 @@ xf86VTLeave(void)
 
     xf86AccessLeave();      /* We need this here, otherwise */
 
-    if (!xf86VTSwitchAway()) {
+    if (!xf86VTSwitchAway())
+        goto switch_failed;
+
+#ifdef XF86PM
+    if (xf86OSPMClose)
+        xf86OSPMClose();
+    xf86OSPMClose = NULL;
+#endif
+
+    for (i = 0; i < xf86NumScreens; i++) {
         /*
-         * switch failed
+         * zero all access functions to
+         * trap calls when switched away.
          */
+        xf86Screens[i]->vtSema = FALSE;
+    }
+    if (xorgHWAccess)
+        xf86DisableIO();
 
-        DebugF("xf86VTSwitch: Leave failed\n");
-        xf86AccessEnter();
-        for (i = 0; i < xf86NumScreens; i++) {
-            if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
-                FatalError("EnterVT failed for screen %d\n", i);
-        }
-        for (i = 0; i < xf86NumGPUScreens; i++) {
-            if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
-                FatalError("EnterVT failed for gpu screen %d\n", i);
-        }
-        if (!(dispatchException & DE_TERMINATE)) {
-            for (i = 0; i < xf86NumScreens; i++) {
-                if (xf86Screens[i]->EnableDisableFBAccess)
-                    (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
-            }
-        }
-        dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
-
-        pInfo = xf86InputDevs;
-        while (pInfo) {
-            if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
-                EnableDevice(pInfo->dev, TRUE);
-            pInfo->flags &= ~XI86_DEVICE_DISABLED;
-            pInfo = pInfo->next;
-        }
-        for (ih = InputHandlers; ih; ih = ih->next) {
-            if (ih->is_input)
-                xf86EnableInputHandler(ih);
-            else
-                xf86EnableGeneralHandler(ih);
-        }
-        OsReleaseSIGIO();
+    return;
 
+switch_failed:
+    DebugF("xf86VTSwitch: Leave failed\n");
+    xf86AccessEnter();
+    for (i = 0; i < xf86NumScreens; i++) {
+        if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
+            FatalError("EnterVT failed for screen %d\n", i);
     }
-    else {
-#ifdef XF86PM
-        if (xf86OSPMClose)
-            xf86OSPMClose();
-        xf86OSPMClose = NULL;
-#endif
-
+    for (i = 0; i < xf86NumGPUScreens; i++) {
+        if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
+            FatalError("EnterVT failed for gpu screen %d\n", i);
+    }
+    if (!(dispatchException & DE_TERMINATE)) {
         for (i = 0; i < xf86NumScreens; i++) {
-            /*
-             * zero all access functions to
-             * trap calls when switched away.
-             */
-            xf86Screens[i]->vtSema = FALSE;
+            if (xf86Screens[i]->EnableDisableFBAccess)
+                (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
         }
-        if (xorgHWAccess)
-            xf86DisableIO();
     }
+    dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+    pInfo = xf86InputDevs;
+    while (pInfo) {
+        if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
+            EnableDevice(pInfo->dev, TRUE);
+        pInfo->flags &= ~XI86_DEVICE_DISABLED;
+        pInfo = pInfo->next;
+    }
+    for (ih = InputHandlers; ih; ih = ih->next) {
+        if (ih->is_input)
+            xf86EnableInputHandler(ih);
+        else
+            xf86EnableGeneralHandler(ih);
+    }
+    OsReleaseSIGIO();
 }
 
 void
commit 78f0667d6df9cc43a397d9f1490e540936a435d6
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Dec 19 11:26:36 2013 +0100

    xf86Events: split xf86VTSwitch into xf86VTLeave and xf86VTEnter functions
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 89025fe..537d1d1 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -234,6 +234,8 @@ extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
 extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
 extern _X_EXPORT void xf86PrintBacktrace(void);
 extern _X_EXPORT Bool xf86VTOwner(void);
+extern _X_EXPORT void xf86VTLeave(void);
+extern _X_EXPORT void xf86VTEnter(void);
 
 /* xf86Helper.c */
 
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index cae7873..e4ec177 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -407,155 +407,74 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
     }
 }
 
-/*
- * xf86VTSwitch --
- *      Handle requests for switching the vt.
- */
-static void
-xf86VTSwitch(void)
+void
+xf86VTLeave(void)
 {
     int i;
     InputInfoPtr pInfo;
     IHPtr ih;
 
-    DebugF("xf86VTSwitch()\n");
-
-#ifdef XFreeXDGA
-    if (!DGAVTSwitch())
-        return;
+    DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
+           BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
+#ifdef DPMSExtension
+    if (DPMSPowerLevel != DPMSModeOn)
+        DPMSSet(serverClient, DPMSModeOn);
 #endif
+    for (i = 0; i < xf86NumScreens; i++) {
+        if (!(dispatchException & DE_TERMINATE))
+            if (xf86Screens[i]->EnableDisableFBAccess)
+                (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE);
+    }
 
     /*
-     * Since all screens are currently all in the same state it is sufficient
-     * check the first.  This might change in future.
+     * Keep the order: Disable Device > LeaveVT
+     *                        EnterVT > EnableDevice
      */
-    if (xf86VTOwner()) {
-
-        DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
-               BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
-#ifdef DPMSExtension
-        if (DPMSPowerLevel != DPMSModeOn)
-            DPMSSet(serverClient, DPMSModeOn);
-#endif
-        for (i = 0; i < xf86NumScreens; i++) {
-            if (!(dispatchException & DE_TERMINATE))
-                if (xf86Screens[i]->EnableDisableFBAccess)
-                    (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE);
-        }
-
-        /*
-         * Keep the order: Disable Device > LeaveVT
-         *                        EnterVT > EnableDevice
-         */
-        for (ih = InputHandlers; ih; ih = ih->next) {
-            if (ih->is_input)
-                xf86DisableInputHandler(ih);
-            else
-                xf86DisableGeneralHandler(ih);
-        }
-        for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
-            if (pInfo->dev) {
-                if (!pInfo->dev->enabled)
-                    pInfo->flags |= XI86_DEVICE_DISABLED;
-                xf86ReleaseKeys(pInfo->dev);
-                ProcessInputEvents();
-                DisableDevice(pInfo->dev, TRUE);
-            }
+    for (ih = InputHandlers; ih; ih = ih->next) {
+        if (ih->is_input)
+            xf86DisableInputHandler(ih);
+        else
+            xf86DisableGeneralHandler(ih);
+    }
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
+        if (pInfo->dev) {
+            if (!pInfo->dev->enabled)
+                pInfo->flags |= XI86_DEVICE_DISABLED;
+            xf86ReleaseKeys(pInfo->dev);
+            ProcessInputEvents();
+            DisableDevice(pInfo->dev, TRUE);
         }
+    }
 
-        OsBlockSIGIO();
-        for (i = 0; i < xf86NumScreens; i++)
-            xf86Screens[i]->LeaveVT(xf86Screens[i]);
-        for (i = 0; i < xf86NumGPUScreens; i++)
-            xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
-
-        xf86AccessLeave();      /* We need this here, otherwise */
-
-        if (!xf86VTSwitchAway()) {
-            /*
-             * switch failed
-             */
-
-            DebugF("xf86VTSwitch: Leave failed\n");
-            xf86AccessEnter();
-            for (i = 0; i < xf86NumScreens; i++) {
-                if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
-                    FatalError("EnterVT failed for screen %d\n", i);
-            }
-            for (i = 0; i < xf86NumGPUScreens; i++) {
-                if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
-                    FatalError("EnterVT failed for gpu screen %d\n", i);
-            }
-            if (!(dispatchException & DE_TERMINATE)) {
-                for (i = 0; i < xf86NumScreens; i++) {
-                    if (xf86Screens[i]->EnableDisableFBAccess)
-                        (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
-                }
-            }
-            dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
-
-            pInfo = xf86InputDevs;
-            while (pInfo) {
-                if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
-                    EnableDevice(pInfo->dev, TRUE);
-                pInfo->flags &= ~XI86_DEVICE_DISABLED;
-                pInfo = pInfo->next;
-            }
-            for (ih = InputHandlers; ih; ih = ih->next) {
-                if (ih->is_input)
-                    xf86EnableInputHandler(ih);
-                else
-                    xf86EnableGeneralHandler(ih);
-            }
-            OsReleaseSIGIO();
-
-        }
-        else {
-#ifdef XF86PM
-            if (xf86OSPMClose)
-                xf86OSPMClose();
-            xf86OSPMClose = NULL;
-#endif
+    OsBlockSIGIO();
+    for (i = 0; i < xf86NumScreens; i++)
+        xf86Screens[i]->LeaveVT(xf86Screens[i]);
+    for (i = 0; i < xf86NumGPUScreens; i++)
+        xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
 
-            for (i = 0; i < xf86NumScreens; i++) {
-                /*
-                 * zero all access functions to
-                 * trap calls when switched away.
-                 */
-                xf86Screens[i]->vtSema = FALSE;
-            }
-            if (xorgHWAccess)
-                xf86DisableIO();
-        }
-    }
-    else {
-        DebugF("xf86VTSwitch: Entering\n");
-        if (!xf86VTSwitchTo())
-            return;
+    xf86AccessLeave();      /* We need this here, otherwise */
 
-#ifdef XF86PM
-        xf86OSPMClose = xf86OSPMOpen();
-#endif
+    if (!xf86VTSwitchAway()) {
+        /*
+         * switch failed
+         */
 
-        if (xorgHWAccess)
-            xf86EnableIO();
+        DebugF("xf86VTSwitch: Leave failed\n");
         xf86AccessEnter();
         for (i = 0; i < xf86NumScreens; i++) {
-            xf86Screens[i]->vtSema = TRUE;
             if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
                 FatalError("EnterVT failed for screen %d\n", i);
         }
         for (i = 0; i < xf86NumGPUScreens; i++) {
-            xf86GPUScreens[i]->vtSema = TRUE;
             if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
                 FatalError("EnterVT failed for gpu screen %d\n", i);
         }
-        for (i = 0; i < xf86NumScreens; i++) {
-            if (xf86Screens[i]->EnableDisableFBAccess)
-                (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
+        if (!(dispatchException & DE_TERMINATE)) {
+            for (i = 0; i < xf86NumScreens; i++) {
+                if (xf86Screens[i]->EnableDisableFBAccess)
+                    (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
+            }
         }
-
-        /* Turn screen saver off when switching back */
         dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 
         pInfo = xf86InputDevs;
@@ -565,20 +484,114 @@ xf86VTSwitch(void)
             pInfo->flags &= ~XI86_DEVICE_DISABLED;
             pInfo = pInfo->next;
         }
-
         for (ih = InputHandlers; ih; ih = ih->next) {
             if (ih->is_input)
                 xf86EnableInputHandler(ih);
             else
                 xf86EnableGeneralHandler(ih);
         }
-#ifdef XSERVER_PLATFORM_BUS
-        /* check for any new output devices */
-        xf86platformVTProbe();
+        OsReleaseSIGIO();
+
+    }
+    else {
+#ifdef XF86PM
+        if (xf86OSPMClose)
+            xf86OSPMClose();
+        xf86OSPMClose = NULL;
 #endif
 
-        OsReleaseSIGIO();
+        for (i = 0; i < xf86NumScreens; i++) {
+            /*
+             * zero all access functions to
+             * trap calls when switched away.
+             */
+            xf86Screens[i]->vtSema = FALSE;
+        }
+        if (xorgHWAccess)
+            xf86DisableIO();
+    }
+}
+
+void
+xf86VTEnter(void)
+{
+    int i;
+    InputInfoPtr pInfo;
+    IHPtr ih;
+
+    DebugF("xf86VTSwitch: Entering\n");
+    if (!xf86VTSwitchTo())
+        return;
+
+#ifdef XF86PM
+    xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+    if (xorgHWAccess)
+        xf86EnableIO();
+    xf86AccessEnter();
+    for (i = 0; i < xf86NumScreens; i++) {
+        xf86Screens[i]->vtSema = TRUE;
+        if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
+            FatalError("EnterVT failed for screen %d\n", i);
+    }
+    for (i = 0; i < xf86NumGPUScreens; i++) {
+        xf86GPUScreens[i]->vtSema = TRUE;
+        if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
+            FatalError("EnterVT failed for gpu screen %d\n", i);
+    }
+    for (i = 0; i < xf86NumScreens; i++) {
+        if (xf86Screens[i]->EnableDisableFBAccess)
+            (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
+    }
+
+    /* Turn screen saver off when switching back */
+    dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+    pInfo = xf86InputDevs;
+    while (pInfo) {
+        if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
+            EnableDevice(pInfo->dev, TRUE);
+        pInfo->flags &= ~XI86_DEVICE_DISABLED;
+        pInfo = pInfo->next;
+    }
+
+    for (ih = InputHandlers; ih; ih = ih->next) {
+        if (ih->is_input)
+            xf86EnableInputHandler(ih);
+        else
+            xf86EnableGeneralHandler(ih);
     }
+#ifdef XSERVER_PLATFORM_BUS
+    /* check for any new output devices */
+    xf86platformVTProbe();
+#endif
+
+    OsReleaseSIGIO();
+}
+
+/*
+ * xf86VTSwitch --
+ *      Handle requests for switching the vt.
+ */
+static void
+xf86VTSwitch(void)
+{
+    DebugF("xf86VTSwitch()\n");
+
+#ifdef XFreeXDGA
+    if (!DGAVTSwitch())
+        return;
+#endif
+
+    /*
+     * Since all screens are currently all in the same state it is sufficient
+     * check the first.  This might change in future.
+     */
+    if (xf86VTOwner())
+        xf86VTLeave();
+    else
+        xf86VTEnter();
 }
 
 /* Input handler registration */
commit 33cec8af55d829cd77b297ae356ed7a00ce8523c
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Dec 17 09:29:07 2013 +0100

    dbus-core: Attempt to connect to dbus ASAP
    
    For systemd-logind integration we need the dbus connection to be available
    before enumerating input and gfx devices.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/config/dbus-core.c b/config/dbus-core.c
index 43d6281..b0fd92d 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -233,8 +233,8 @@ dbus_core_init(void)
     memset(&bus_info, 0, sizeof(bus_info));
     bus_info.fd = -1;
     bus_info.hooks = NULL;
-    bus_info.connection = NULL;
-    bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
+    if (!connect_to_bus())
+        bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
 
     return 1;
 }
commit 480590b90c3966536451d2a2fecc42a66082ed77
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Dec 4 11:10:06 2013 +0100

    dbus-core: Make dbus-core no longer mutually exclusive with udev
    
    With systemd-logind the dbus-core will be used for more then just config, so
    it should be possible to build it even when using a non dbus dependent config
    backend.
    
    This patch also removes the config_ prefix from the dbus-core symbols.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/config/Makefile.am b/config/Makefile.am
index 0740e46..e0f0a8d 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -2,12 +2,19 @@ AM_CFLAGS = $(DIX_CFLAGS)
 
 noinst_LTLIBRARIES = libconfig.la
 libconfig_la_SOURCES = config.c config-backends.h
+libconfig_la_LIBADD =
+
+if NEED_DBUS
+AM_CFLAGS += $(DBUS_CFLAGS)
+libconfig_la_SOURCES += dbus-core.c
+libconfig_la_LIBADD += $(DBUS_LIBS)
+endif
 
 if CONFIG_UDEV
 
 AM_CFLAGS += $(UDEV_CFLAGS)
 libconfig_la_SOURCES += udev.c
-libconfig_la_LIBADD = $(UDEV_LIBS)
+libconfig_la_LIBADD += $(UDEV_LIBS)
 
 if XORG
 xorgconfddir = $(datadir)/X11/$(XF86CONFIGDIR)
@@ -16,16 +23,10 @@ endif
 
 else
 
-if CONFIG_NEED_DBUS
-AM_CFLAGS += $(DBUS_CFLAGS)
-libconfig_la_SOURCES += dbus-core.c
-libconfig_la_LIBADD = $(DBUS_LIBS)
-
 if CONFIG_HAL
 AM_CFLAGS += $(HAL_CFLAGS)
 libconfig_la_SOURCES += hal.c
 libconfig_la_LIBADD += $(HAL_LIBS)
-endif
 
 else
 
@@ -33,7 +34,7 @@ if CONFIG_WSCONS
 libconfig_la_SOURCES += wscons.c
 endif # CONFIG_WSCONS
 
-endif # CONFIG_NEED_DBUS
+endif # !CONFIG_HAL
 
 endif # !CONFIG_UDEV
 
diff --git a/config/config-backends.h b/config/config-backends.h
index 5a715b3..5f07557 100644
--- a/config/config-backends.h
+++ b/config/config-backends.h
@@ -37,36 +37,10 @@ int config_udev_pre_init(void);
 int config_udev_init(void);
 void config_udev_fini(void);
 void config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback);
-#else
-
-#ifdef CONFIG_NEED_DBUS
-#include <dbus/dbus.h>
-
-typedef void (*config_dbus_core_connect_hook) (DBusConnection * connection,
-                                               void *data);
-typedef void (*config_dbus_core_disconnect_hook) (void *data);
-
-struct config_dbus_core_hook {
-    config_dbus_core_connect_hook connect;
-    config_dbus_core_disconnect_hook disconnect;
-    void *data;
-
-    struct config_dbus_core_hook *next;
-};
-
-int config_dbus_core_init(void);
-void config_dbus_core_fini(void);
-int config_dbus_core_add_hook(struct config_dbus_core_hook *hook);
-void config_dbus_core_remove_hook(struct config_dbus_core_hook *hook);
-#endif
-
-#ifdef CONFIG_HAL
+#elif defined(CONFIG_HAL)
 int config_hal_init(void);
 void config_hal_fini(void);
-#endif
-#endif
-
-#ifdef CONFIG_WSCONS
+#elif defined(CONFIG_WSCONS)
 int config_wscons_init(void);
 void config_wscons_fini(void);
 #endif
diff --git a/config/config.c b/config/config.c
index 554069f..760cf19 100644
--- a/config/config.c
+++ b/config/config.c
@@ -47,16 +47,9 @@ config_init(void)
 #ifdef CONFIG_UDEV
     if (!config_udev_init())
         ErrorF("[config] failed to initialise udev\n");
-#elif defined(CONFIG_NEED_DBUS)
-    if (config_dbus_core_init()) {
-#ifdef CONFIG_HAL
-        if (!config_hal_init())
-            ErrorF("[config] failed to initialise HAL\n");
-#endif
-    }
-    else {
-        ErrorF("[config] failed to initialise D-Bus core\n");
-    }
+#elif defined(CONFIG_HAL)
+    if (!config_hal_init())
+        ErrorF("[config] failed to initialise HAL\n");
 #elif defined(CONFIG_WSCONS)
     if (!config_wscons_init())
         ErrorF("[config] failed to initialise wscons\n");
@@ -68,11 +61,8 @@ config_fini(void)
 {
 #if defined(CONFIG_UDEV)
     config_udev_fini();
-#elif defined(CONFIG_NEED_DBUS)
-#ifdef CONFIG_HAL
+#elif defined(CONFIG_HAL)
     config_hal_fini();
-#endif
-    config_dbus_core_fini();
 #elif defined(CONFIG_WSCONS)
     config_wscons_fini();
 #endif
diff --git a/config/dbus-core.c b/config/dbus-core.c
index 768a984..43d6281 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -30,9 +30,9 @@
 #include <dbus/dbus.h>
 #include <sys/select.h>
 
-#include "config-backends.h"
 #include "dix.h"
 #include "os.h"
+#include "dbus-core.h"
 
 /* How often to attempt reconnecting when we get booted off the bus. */
 #define RECONNECT_DELAY (10 * 1000)     /* in ms */
@@ -41,7 +41,7 @@ struct dbus_core_info {
     int fd;
     DBusConnection *connection;
     OsTimerPtr timer;
-    struct config_dbus_core_hook *hooks;
+    struct dbus_core_hook *hooks;
 };
 static struct dbus_core_info bus_info;
 
@@ -74,7 +74,7 @@ block_handler(void *data, struct timeval **tv, void *read_mask)
 static void
 teardown(void)
 {
-    struct config_dbus_core_hook *hook;
+    struct dbus_core_hook *hook;
 
     if (bus_info.timer) {
         TimerFree(bus_info.timer);
@@ -112,7 +112,7 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
      * reconnect immediately (assuming it's just a restart).  The
      * connection isn't valid at this point, so throw it out immediately. */
     if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
-        DebugF("[config/dbus-core] disconnected from bus\n");
+        DebugF("[dbus-core] disconnected from bus\n");
         bus_info.connection = NULL;
         teardown();
 
@@ -136,12 +136,12 @@ static int
 connect_to_bus(void)
 {
     DBusError error;
-    struct config_dbus_core_hook *hook;
+    struct dbus_core_hook *hook;
 
     dbus_error_init(&error);
     bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
     if (!bus_info.connection || dbus_error_is_set(&error)) {
-        DebugF("[config/dbus-core] error connecting to system bus: %s (%s)\n",
+        LogMessage(X_ERROR, "dbus-core: error connecting to system bus: %s (%s)\n",
                error.name, error.message);
         goto err_begin;
     }
@@ -150,13 +150,13 @@ connect_to_bus(void)
     dbus_connection_set_exit_on_disconnect(bus_info.connection, FALSE);
 
     if (!dbus_connection_get_unix_fd(bus_info.connection, &bus_info.fd)) {
-        ErrorF("[config/dbus-core] couldn't get fd for system bus\n");
+        ErrorF("[dbus-core] couldn't get fd for system bus\n");
         goto err_unref;
     }
 
     if (!dbus_connection_add_filter(bus_info.connection, message_filter,
                                     &bus_info, NULL)) {
-        ErrorF("[config/dbus-core] couldn't add filter: %s (%s)\n", error.name,
+        ErrorF("[dbus-core] couldn't add filter: %s (%s)\n", error.name,
                error.message);
         goto err_fd;
     }
@@ -198,9 +198,9 @@ reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg)
 }
 
 int
-config_dbus_core_add_hook(struct config_dbus_core_hook *hook)
+dbus_core_add_hook(struct dbus_core_hook *hook)
 {
-    struct config_dbus_core_hook **prev;
+    struct dbus_core_hook **prev;
 
     for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next);
 
@@ -215,9 +215,9 @@ config_dbus_core_add_hook(struct config_dbus_core_hook *hook)
 }
 
 void
-config_dbus_core_remove_hook(struct config_dbus_core_hook *hook)
+dbus_core_remove_hook(struct dbus_core_hook *hook)
 {
-    struct config_dbus_core_hook **prev;
+    struct dbus_core_hook **prev;
 
     for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next) {
         if (*prev == hook) {
@@ -228,7 +228,7 @@ config_dbus_core_remove_hook(struct config_dbus_core_hook *hook)
 }
 
 int
-config_dbus_core_init(void)
+dbus_core_init(void)
 {
     memset(&bus_info, 0, sizeof(bus_info));
     bus_info.fd = -1;
@@ -240,7 +240,7 @@ config_dbus_core_init(void)
 }
 
 void
-config_dbus_core_fini(void)
+dbus_core_fini(void)
 {
     teardown();
 }
diff --git a/config/hal.c b/config/hal.c
index 2ead556..94cb6e7 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <sys/select.h>
 
+#include "dbus-core.h"
 #include "input.h"
 #include "inputstr.h"
 #include "hotplug.h"
@@ -631,7 +632,7 @@ connect_hook(DBusConnection * connection, void *data)
 
 static struct config_hal_info hal_info;
 
-static struct config_dbus_core_hook hook = {
+static struct dbus_core_hook hook = {
     .connect = connect_hook,
     .disconnect = disconnect_hook,
     .data = &hal_info,
@@ -644,7 +645,7 @@ config_hal_init(void)
     hal_info.system_bus = NULL;
     hal_info.hal_ctx = NULL;
 
-    if (!config_dbus_core_add_hook(&hook)) {
+    if (!dbus_core_add_hook(&hook)) {
         LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n");
         return 0;
     }
@@ -658,5 +659,5 @@ config_hal_init(void)
 void
 config_hal_fini(void)
 {
-    config_dbus_core_remove_hook(&hook);
+    dbus_core_remove_hook(&hook);
 }
diff --git a/configure.ac b/configure.ac
index 15edd3c..c6764f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -897,14 +897,14 @@ if test "x$CONFIG_HAL" = xyes; then
 	fi
 
 	AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
-	CONFIG_NEED_DBUS="yes"
+	NEED_DBUS="yes"
 fi
 AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
 
-if test "x$CONFIG_NEED_DBUS" = xyes; then
-        AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug])
+if test "x$NEED_DBUS" = xyes; then
+        AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core])
 fi
-AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes])
+AM_CONDITIONAL(NEED_DBUS, [test "x$NEED_DBUS" = xyes])
 
 if test "x$CONFIG_WSCONS" = xauto; then
 	case $host_os in
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 952bf37..ff4d38f 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -53,6 +53,7 @@
 #include "scrnintstr.h"
 #include "site.h"
 #include "mi.h"
+#include "dbus-core.h"
 
 #include "compiler.h"
 
@@ -456,6 +457,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
         if (xf86DoShowOptions)
             DoShowOptions();
 
+        dbus_core_init();
+
         /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
         xf86BusProbe();
 
@@ -1059,6 +1062,8 @@ ddxGiveUp(enum ExitCode error)
     if (xorgHWOpenConsole)
         xf86CloseConsole();
 
+    dbus_core_fini();
+
     xf86CloseLog(error);
 
     /* If an unexpected signal was caught, dump a core for debugging */
diff --git a/include/Makefile.am b/include/Makefile.am
index 93d8616..fa6da00 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -68,7 +68,7 @@ endif
 AM_CFLAGS = $(DIX_CFLAGS)
 
 EXTRA_DIST = 	\
-	busfault.h	\
+	busfault.h dbus-core.h \
 	dix-config-apple-verbatim.h \
 	dixfontstubs.h eventconvert.h eventstr.h inpututils.h \
 	protocol-versions.h \
diff --git a/include/dbus-core.h b/include/dbus-core.h
new file mode 100644
index 0000000..b2d6d1b
--- /dev/null
+++ b/include/dbus-core.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Author: Hans de Goede <hdegoede at redhat.com>
+ */
+
+#ifndef DBUS_CORE_H
+#define DBUS_CORE_H
+
+#ifdef NEED_DBUS
+typedef struct DBusConnection DBusConnection;
+
+typedef void (*dbus_core_connect_hook) (DBusConnection * connection,
+                                               void *data);
+typedef void (*dbus_core_disconnect_hook) (void *data);
+
+struct dbus_core_hook {
+    dbus_core_connect_hook connect;
+    dbus_core_disconnect_hook disconnect;
+    void *data;
+
+    struct dbus_core_hook *next;
+};
+
+int dbus_core_init(void);
+void dbus_core_fini(void);
+int dbus_core_add_hook(struct dbus_core_hook *hook);
+void dbus_core_remove_hook(struct dbus_core_hook *hook);
+
+#else
+
+#define dbus_core_init()
+#define dbus_core_fini()
+
+#endif
+
+#endif
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 8ffb53e..7c77956 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -414,8 +414,8 @@
 /* Use udev_enumerate_add_match_tag() */
 #undef HAVE_UDEV_ENUMERATE_ADD_MATCH_TAG
 
-/* Use D-Bus for input hotplug */
-#undef CONFIG_NEED_DBUS
+/* Enable D-Bus core */
+#undef NEED_DBUS
 
 /* Support HAL for hotplug */
 #undef CONFIG_HAL
commit c29454ae9d2e8e647732077fdfd97b351095f122
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 12 12:48:57 2013 +1000

    config: drop the dbus API
    
    This API has been disabled by default since 1.4, the first release it came in.
    There a no known users of it and even its direct replacement (HAL) has
    been superseeded by udev on supported platforms since 1.8.
    
    This code is untested, probably hasn't been compiled in years and should not
    be shipped.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/config/Makefile.am b/config/Makefile.am
index 327d07e..0740e46 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -21,13 +21,6 @@ AM_CFLAGS += $(DBUS_CFLAGS)
 libconfig_la_SOURCES += dbus-core.c
 libconfig_la_LIBADD = $(DBUS_LIBS)
 
-if CONFIG_DBUS_API
-dbusconfigdir = $(sysconfdir)/dbus-1/system.d
-dbusconfig_DATA = xorg-server.conf
-
-libconfig_la_SOURCES += dbus.c
-endif
-
 if CONFIG_HAL
 AM_CFLAGS += $(HAL_CFLAGS)
 libconfig_la_SOURCES += hal.c
diff --git a/config/config-backends.h b/config/config-backends.h
index 6423701..5a715b3 100644
--- a/config/config-backends.h
+++ b/config/config-backends.h
@@ -60,11 +60,6 @@ int config_dbus_core_add_hook(struct config_dbus_core_hook *hook);
 void config_dbus_core_remove_hook(struct config_dbus_core_hook *hook);
 #endif
 
-#ifdef CONFIG_DBUS_API
-int config_dbus_init(void);
-void config_dbus_fini(void);
-#endif
-
 #ifdef CONFIG_HAL
 int config_hal_init(void);
 void config_hal_fini(void);
diff --git a/config/config.c b/config/config.c
index d0889a3..554069f 100644
--- a/config/config.c
+++ b/config/config.c
@@ -49,10 +49,6 @@ config_init(void)
         ErrorF("[config] failed to initialise udev\n");
 #elif defined(CONFIG_NEED_DBUS)
     if (config_dbus_core_init()) {
-#ifdef CONFIG_DBUS_API
-        if (!config_dbus_init())
-            ErrorF("[config] failed to initialise D-Bus API\n");
-#endif
 #ifdef CONFIG_HAL
         if (!config_hal_init())
             ErrorF("[config] failed to initialise HAL\n");
@@ -76,9 +72,6 @@ config_fini(void)
 #ifdef CONFIG_HAL
     config_hal_fini();
 #endif
-#ifdef CONFIG_DBUS_API
-    config_dbus_fini();
-#endif
     config_dbus_core_fini();
 #elif defined(CONFIG_WSCONS)
     config_wscons_fini();
diff --git a/config/dbus.c b/config/dbus.c
deleted file mode 100644
index 99a1537..0000000
--- a/config/dbus.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright © 2006-2007 Daniel Stone
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Author: Daniel Stone <daniel at fooishbar.org>
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <dbus/dbus.h>
-#include <string.h>
-
-#include <X11/X.h>
-
-#include "config-backends.h"
-#include "opaque.h"             /* for 'display': there should be a better way. */
-#include "input.h"
-#include "inputstr.h"
-
-#define API_VERSION 2
-
-#define MATCH_RULE "type='method_call',interface='org.x.config.input'"
-
-#define MALFORMED_MSG "[config/dbus] malformed message, dropping"
-#define MALFORMED_MESSAGE() { DebugF(MALFORMED_MSG "\n"); \
-                            ret = BadValue; \
-                            goto unwind; }
-#define MALFORMED_MESSAGE_ERROR() { DebugF(MALFORMED_MSG ": %s, %s", \
-                                       error->name, error->message); \
-                                  ret = BadValue; \
-                                  goto unwind; }
-
-struct connection_info {
-    char busobject[32];
-    char busname[64];
-    DBusConnection *connection;
-};
-
-static void
-reset_info(struct connection_info *info)
-{
-    info->connection = NULL;
-    info->busname[0] = '\0';
-    info->busobject[0] = '\0';
-}
-
-static int
-add_device(DBusMessage * message, DBusMessage * reply, DBusError * error)
-{
-    DBusMessageIter iter, reply_iter, subiter;
-    InputOption *input_options = NULL;
-    int ret, err;
-    DeviceIntPtr dev = NULL;
-
-    dbus_message_iter_init_append(reply, &reply_iter);
-
-    if (!dbus_message_iter_init(message, &iter)) {
-        ErrorF("[config/dbus] couldn't initialise iterator\n");
-        MALFORMED_MESSAGE();
-    }
-
-    input_options = input_option_new(input_options, "_source", "client/dbus");
-    if (!input_options) {
-        ErrorF("[config/dbus] couldn't allocate first key/value pair\n");
-        ret = BadAlloc;
-        goto unwind;
-    }
-
-    /* signature should be [ss][ss]... */
-    while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
-        char *key, *value;
-
-        dbus_message_iter_recurse(&iter, &subiter);
-
-        if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
-            MALFORMED_MESSAGE();
-
-        dbus_message_iter_get_basic(&subiter, &key);
-        if (!key)
-            MALFORMED_MESSAGE();
-        /* The _ prefix refers to internal settings, and may not be given by
-         * the client. */
-        if (key[0] == '_') {
-            ErrorF("[config/dbus] attempted subterfuge: option name %s given\n",
-                   key);
-            MALFORMED_MESSAGE();
-        }
-
-        if (!dbus_message_iter_has_next(&subiter))
-            MALFORMED_MESSAGE();
-        dbus_message_iter_next(&subiter);
-        if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
-            MALFORMED_MESSAGE();
-
-        dbus_message_iter_get_basic(&subiter, &value);
-        if (!value)
-            MALFORMED_MESSAGE();
-
-        input_options = input_option_new(input_options, key, value);
-
-        dbus_message_iter_next(&iter);
-    }
-
-    ret = NewInputDeviceRequest(input_options, NULL, &dev);
-    if (ret != Success) {
-        DebugF("[config/dbus] NewInputDeviceRequest failed\n");
-        goto unwind;
-    }
-
-    if (!dev) {
-        DebugF("[config/dbus] NewInputDeviceRequest provided no device\n");
-        ret = BadImplementation;
-        goto unwind;
-    }
-
-    /* XXX: If we fail halfway through, we don't seem to have any way to
-     *      empty the iterator, so you'll end up with some device IDs,
-     *      plus an error.  This seems to be a shortcoming in the D-Bus
-     *      API. */
-    for (; dev; dev = dev->next) {
-        if (!dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32,
-                                            &dev->id)) {
-            ErrorF("[config/dbus] couldn't append to iterator\n");
-            ret = BadAlloc;
-            goto unwind;
-        }
-    }
-
- unwind:
-    if (ret != Success) {
-        if (dev)
-            RemoveDevice(dev, TRUE);
-
-        err = -ret;
-        dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
-    }
-
-    input_option_free_list(&input_options);
-
-    return ret;
-}
-
-static int
-remove_device(DBusMessage * message, DBusMessage * reply, DBusError * error)
-{
-    int deviceid, ret, err;
-    DeviceIntPtr dev;
-    DBusMessageIter iter, reply_iter;
-
-    dbus_message_iter_init_append(reply, &reply_iter);
-
-    if (!dbus_message_iter_init(message, &iter)) {
-        ErrorF("[config/dbus] failed to init iterator\n");
-        MALFORMED_MESSAGE();
-    }
-
-    if (!dbus_message_get_args(message, error, DBUS_TYPE_UINT32,
-                               &deviceid, DBUS_TYPE_INVALID)) {
-        MALFORMED_MESSAGE_ERROR();
-    }
-
-    dixLookupDevice(&dev, deviceid, serverClient, DixDestroyAccess);
-    if (!dev) {
-        DebugF("[config/dbus] bogus device id %d given\n", deviceid);
-        ret = BadMatch;
-        goto unwind;
-    }
-
-    DebugF("[config/dbus] removing device %s (id %d)\n", dev->name, deviceid);
-
-    /* Call PIE here so we don't try to dereference a device that's
-     * already been removed. */
-    OsBlockSignals();
-    ProcessInputEvents();
-    DeleteInputDeviceRequest(dev);
-    OsReleaseSignals();
-
-    ret = Success;
-
- unwind:
-    err = (ret == Success) ? ret : -ret;
-    dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
-
-    return ret;
-}
-
-static int
-list_devices(DBusMessage * message, DBusMessage * reply, DBusError * error)
-{
-    DeviceIntPtr dev;
-    DBusMessageIter iter, subiter;
-
-    dbus_message_iter_init_append(reply, &iter);
-
-    for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL,
-                                              &subiter)) {
-            ErrorF("[config/dbus] couldn't init container\n");
-            return BadAlloc;
-        }
-        if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UINT32,
-                                            &dev->id)) {
-            ErrorF("[config/dbus] couldn't append to iterator\n");
-            return BadAlloc;
-        }
-        if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING,
-                                            &dev->name)) {
-            ErrorF("[config/dbus] couldn't append to iterator\n");
-            return BadAlloc;
-        }
-        if (!dbus_message_iter_close_container(&iter, &subiter)) {
-            ErrorF("[config/dbus] couldn't close container\n");
-            return BadAlloc;
-        }
-    }
-
-    return Success;
-}
-
-static int
-get_version(DBusMessage * message, DBusMessage * reply, DBusError * error)
-{
-    DBusMessageIter iter;
-    unsigned int version = API_VERSION;
-
-    dbus_message_iter_init_append(reply, &iter);
-    if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &version)) {
-        ErrorF("[config/dbus] couldn't append version\n");
-        return BadAlloc;
-    }
-
-    return Success;
-}
-
-static DBusHandlerResult
-message_handler(DBusConnection * connection, DBusMessage * message, void *data)
-{
-    DBusError error;
-    DBusMessage *reply;
-    struct connection_info *info = data;
-
-    /* ret is the overall D-Bus handler result, whereas err is the internal
-     * X error from our individual functions. */
-    int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    int err;
-
-    DebugF("[config/dbus] received a message for %s\n",
-           dbus_message_get_interface(message));
-
-    dbus_error_init(&error);
-
-    reply = dbus_message_new_method_return(message);
-    if (!reply) {
-        ErrorF("[config/dbus] failed to create reply\n");
-        ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
-        goto err_start;
-    }
-
-    if (strcmp(dbus_message_get_member(message), "add") == 0)
-        err = add_device(message, reply, &error);
-    else if (strcmp(dbus_message_get_member(message), "remove") == 0)
-        err = remove_device(message, reply, &error);
-    else if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
-        err = list_devices(message, reply, &error);
-    else if (strcmp(dbus_message_get_member(message), "version") == 0)
-        err = get_version(message, reply, &error);
-    else
-        goto err_reply;
-
-    /* Failure to allocate is a special case. */
-    if (err == BadAlloc) {
-        ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
-        goto err_reply;
-    }
-
-    /* While failure here is always an OOM, we don't return that,
-     * since that would result in devices being double-added/removed. */
-    if (dbus_connection_send(info->connection, reply, NULL))
-        dbus_connection_flush(info->connection);
-    else
-        ErrorF("[config/dbus] failed to send reply\n");
-
-    ret = DBUS_HANDLER_RESULT_HANDLED;
-
- err_reply:
-    dbus_message_unref(reply);
- err_start:
-    dbus_error_free(&error);
-
-    return ret;
-}
-
-static void
-connect_hook(DBusConnection * connection, void *data)
-{
-    DBusError error;
-    DBusObjectPathVTable vtable = {.message_function = message_handler, };
-    struct connection_info *info = data;
-
-    info->connection = connection;
-
-    dbus_error_init(&error);
-
-    dbus_bus_request_name(info->connection, info->busname, 0, &error);
-    if (dbus_error_is_set(&error)) {
-        ErrorF("[config/dbus] couldn't take over org.x.config: %s (%s)\n",
-               error.name, error.message);
-        goto err_start;
-    }
-
-    /* blocks until we get a reply. */
-    dbus_bus_add_match(info->connection, MATCH_RULE, &error);
-    if (dbus_error_is_set(&error)) {
-        ErrorF("[config/dbus] couldn't add match: %s (%s)\n", error.name,
-               error.message);
-        goto err_name;
-    }
-
-    if (!dbus_connection_register_object_path(info->connection,
-                                              info->busobject, &vtable, info)) {
-        ErrorF("[config/dbus] couldn't register object path\n");
-        goto err_match;
-    }
-
-    DebugF("[dbus] registered %s, %s\n", info->busname, info->busobject);
-
-    dbus_error_free(&error);
-
-    return;
-
- err_match:
-    dbus_bus_remove_match(info->connection, MATCH_RULE, &error);
- err_name:
-    dbus_bus_release_name(info->connection, info->busname, &error);
- err_start:
-    dbus_error_free(&error);
-
-    reset_info(info);
-}
-
-static void
-disconnect_hook(void *data)
-{
-}
-
-#if 0
-void
-pre_disconnect_hook(void)
-{
-    DBusError error;
-
-    dbus_error_init(&error);
-    dbus_connection_unregister_object_path(connection_data->connection,
-                                           connection_data->busobject);
-    dbus_bus_remove_match(connection_data->connection, MATCH_RULE, &error);
-    dbus_bus_release_name(connection_data->connection,
-                          connection_data->busname, &error);
-    dbus_error_free(&error);
-}
-#endif
-
-static struct connection_info connection_data;
-
-static struct config_dbus_core_hook core_hook = {
-    .connect = connect_hook,
-    .disconnect = disconnect_hook,
-    .data = &connection_data,
-};
-
-int
-config_dbus_init(void)
-{
-    snprintf(connection_data.busname, sizeof(connection_data.busname),
-             "org.x.config.display%d", atoi(display));
-    snprintf(connection_data.busobject, sizeof(connection_data.busobject),
-             "/org/x/config/%d", atoi(display));
-
-    return config_dbus_core_add_hook(&core_hook);
-}
-
-void
-config_dbus_fini(void)
-{
-    config_dbus_core_remove_hook(&core_hook);
-    connection_data.busname[0] = '\0';
-    connection_data.busobject[0] = '\0';
-}
diff --git a/config/xorg-server.conf b/config/xorg-server.conf
deleted file mode 100644
index 47a9a78..0000000
--- a/config/xorg-server.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
-	<policy context="default">
-		<allow own="org.x.config.display0"/>
-		<allow send_destination="org.x.config.display0"/>
-		<allow send_interface="org.x.config.display0"/>
-		<allow own="org.x.config.display1"/>
-		<allow send_destination="org.x.config.display1"/>
-		<allow send_interface="org.x.config.display1"/>
-	</policy>
-</busconfig>
diff --git a/configure.ac b/configure.ac
index d15f1a1..15edd3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -614,7 +614,6 @@ AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--enable-xf86bigfont], [Build XF86
 AC_ARG_ENABLE(dpms,           AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
 AC_ARG_ENABLE(config-udev,    AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
 AC_ARG_ENABLE(config-udev-kms,    AS_HELP_STRING([--enable-config-udev-kms], [Build udev kms support (default: auto)]), [CONFIG_UDEV_KMS=$enableval], [CONFIG_UDEV_KMS=auto])
-AC_ARG_ENABLE(config-dbus,    AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
 AC_ARG_ENABLE(config-hal,     AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
 AC_ARG_ENABLE(config-wscons,  AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto])
 AC_ARG_ENABLE(xfree86-utils,     AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
@@ -703,7 +702,6 @@ dnl DDX Detection... Yes, it's ugly to have it here... but we need to
 dnl handle this early on so that we don't require unsupported extensions
 case $host_os in
 	cygwin* | mingw*)
-		CONFIG_DBUS_API=no
 		CONFIG_HAL=no
 		CONFIG_UDEV=no
 		CONFIG_UDEV_KMS=no
@@ -851,9 +849,8 @@ if test "x$WITH_SYSTEMD_DAEMON" = xyes; then
 fi
 AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test "x$HAVE_SYSTEMD_DAEMON" = "xyes"])
 
-if test "x$CONFIG_UDEV" = xyes &&
- { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
-	AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
+if test "x$CONFIG_UDEV" = xyes && test "x$CONFIG_HAL" = xyes; then
+	AC_MSG_ERROR([Hotplugging through both libudev and hal not allowed])
 fi
 
 PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no])
@@ -862,7 +859,6 @@ if test "x$CONFIG_UDEV" = xauto; then
 fi
 AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
 if test "x$CONFIG_UDEV" = xyes; then
-	CONFIG_DBUS_API=no
 	CONFIG_HAL=no
 	if test "x$CONFIG_UDEV_KMS" = xauto; then
 		CONFIG_UDEV_KMS="$HAVE_LIBUDEV"
@@ -885,28 +881,12 @@ if test "x$CONFIG_UDEV" = xyes; then
 fi
 AM_CONDITIONAL(CONFIG_UDEV_KMS, [test "x$CONFIG_UDEV_KMS" = xyes])
 
-dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
-dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
-dnl API.
 PKG_CHECK_MODULES(DBUS, $LIBDBUS, [HAVE_DBUS=yes], [HAVE_DBUS=no])
 if test "x$HAVE_DBUS" = xyes; then
 	AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
 fi
 AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
 
-if test "x$CONFIG_DBUS_API" = xauto; then
-	CONFIG_DBUS_API="$HAVE_DBUS"
-fi
-if test "x$CONFIG_DBUS_API" = xyes; then
-	if ! test "x$HAVE_DBUS" = xyes; then
-		AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
-	fi
-
-	AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
-	CONFIG_NEED_DBUS="yes"
-fi
-AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
-
 PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no])
 if test "x$CONFIG_HAL" = xauto; then
 	CONFIG_HAL="$HAVE_HAL"
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index acb55f8..8ffb53e 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -417,9 +417,6 @@
 /* Use D-Bus for input hotplug */
 #undef CONFIG_NEED_DBUS
 
-/* Support the D-Bus hotplug API */
-#undef CONFIG_DBUS_API
-
 /* Support HAL for hotplug */
 #undef CONFIG_HAL
 
commit 46cf2a60934076bf568062eb83121ce90b6ff596
Author: Laércio de Sousa <lbsousajr at gmail.com>
Date:   Thu Dec 12 14:22:48 2013 -0200

    xfree86: Keep a non-seat0 X server from touching VTs (#71258)
    
    Updated patch following Hans de Goede's advice.
    
    If -seat option is passed with a value different from seat0,
    X server won't call xf86OpenConsole().
    
    This is needed to avoid any race condition between seat0 and
    non-seat0 X servers. If a non-seat0 X server opens a given VT
    before a seat0 one which expects to open the same VT, one can
    get an inactive systemd-logind graphical session for seat0.
    
    This patch was first tested in a multiseat setup with multiple
    video cards and works quite well.
    
    I suppose it can also make things like DontVTSwitch and -sharevts
    meaningless for non-seat0 seats, so it may fix bug #69477, too.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=71258
           https://bugs.freedesktop.org/show_bug.cgi?id=69477 (maybe)
    
    See also: http://lists.x.org/archives/xorg-devel/2013-October/038391.html
              https://bugzilla.redhat.com/show_bug.cgi?id=1018196
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 9c8a86a..952bf37 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -544,7 +544,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             if (NEED_IO_ENABLED(flags))
                 want_hw_access = TRUE;
 
-            if (!(flags & HW_SKIP_CONSOLE))
+            /* Non-seat0 X servers should not open console */
+            if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0())
                 xorgHWOpenConsole = TRUE;
         }
 
commit b3d3ffd19937827bcbdb833a628f9b1814a6e189
Author: Łukasz Stelmach <l.stelmach at samsung.com>
Date:   Mon Nov 25 11:54:07 2013 +0100

    configure.ac: enable systemd socket activation in libxtrans
    
    Signed-off-by: Łukasz Stelmach <l.stelmach at samsung.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Acked-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index d5f8b68..d15f1a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -800,7 +800,7 @@ FIXESPROTO="fixesproto >= 5.0"
 DAMAGEPROTO="damageproto >= 1.1"
 XCMISCPROTO="xcmiscproto >= 1.2.0"
 BIGREQSPROTO="bigreqsproto >= 1.1.0"
-XTRANS="xtrans >= 1.3.2"
+XTRANS="xtrans >= 1.3.3"
 PRESENTPROTO="presentproto >= 1.0"
 
 dnl List of libraries that require a specific version
@@ -831,6 +831,26 @@ AC_SUBST(SDK_REQUIRED_MODULES)
 
 REQUIRED_MODULES="$FIXESPROTO $DAMAGEPROTO $XCMISCPROTO $XTRANS $BIGREQSPROTO $SDK_REQUIRED_MODULES"
 
+dnl systemd socket activation
+dnl activate the code in libxtrans that grabs systemd's socket fds
+AC_ARG_WITH([systemd-daemon],
+	AS_HELP_STRING([--with-systemd-daemon],
+		[support systemd socket activation (default: auto)]),
+	[WITH_SYSTEMD_DAEMON=$withval], [WITH_SYSTEMD_DAEMON=auto])
+PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
+                  [HAVE_SYSTEMD_DAEMON=yes], [HAVE_SYSTEMD_DAEMON=no])
+if test "x$WITH_SYSTEMD_DAEMON" = xauto; then
+	WITH_SYSTEMD_DAEMON="$HAVE_SYSTEMD_DAEMON"
+fi
+if test "x$WITH_SYSTEMD_DAEMON" = xyes; then
+	if "x$HAVE_SYSTEMD_DAEMON" = xno; then
+		AC_MSG_ERROR([systemd support requested but no library has been found])
+	fi
+	AC_DEFINE(HAVE_SYSTEMD_DAEMON, 1, [Define to 1 if libsystemd-daemon is available])
+	REQUIRED_LIBS="$REQUIRED_LIBS libsystemd-daemon"
+fi
+AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test "x$HAVE_SYSTEMD_DAEMON" = "xyes"])
+
 if test "x$CONFIG_UDEV" = xyes &&
  { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
 	AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index ced3ba1..acb55f8 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -199,6 +199,9 @@
 /* Define to 1 if you have the `strndup' function. */
 #undef HAVE_STRNDUP
 
+/* Define to 1 if libsystemd-daemon is available */
+#undef HAVE_SYSTEMD_DAEMON
+
 /* Define to 1 if SYSV IPC is available */
 #undef HAVE_SYSV_IPC
 
commit 435098a0dce6bca8870ec9725bf0af0969cd84fa
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 28 20:27:52 2014 -0800

    Add RANDR 1.4 requests & events to dix/protocol.txt
    
    Checked against randrproto.txt & randr.h
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/protocol.txt b/dix/protocol.txt
index 8e152ed..f83f38c 100644
--- a/dix/protocol.txt
+++ b/dix/protocol.txt
@@ -311,11 +311,22 @@ R028 RANDR:GetPanning
 R029 RANDR:SetPanning
 R030 RANDR:SetOutputPrimary
 R031 RANDR:GetOutputPrimary
+R032 RANDR:RRGetProviders
+R033 RANDR:RRGetProviderInfo
+R034 RANDR:RRSetProviderOffloadSink
+R035 RANDR:RRSetProviderOutputSource
+R036 RANDR:RRListProviderProperties
+R037 RANDR:RRQueryProviderProperty
+R038 RANDR:RRConfigureProviderProperty
+R039 RANDR:RRChangeProviderProperty
+R040 RANDR:RRDeleteProviderProperty
+R041 RANDR:RRGetProviderProperty
 V000 RANDR:ScreenChangeNotify
 V001 RANDR:Notify
 E000 RANDR:BadRROutput
 E001 RANDR:BadRRCrtc
 E002 RANDR:BadRRMode
+E003 RANDR:BadRRProvider
 R000 RECORD:QueryVersion
 R001 RECORD:CreateContext
 R002 RECORD:RegisterClients
commit c1ac89c793614797e08d3d8e7fc9ba55be899130
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 28 20:27:51 2014 -0800

    xf86DeleteScreen: move check for NULL pScrn before first dereference
    
    Flagged by cppcheck 1.62:
    [hw/xfree86/common/xf86Helper.c:220] -> [hw/xfree86/common/xf86Helper.c:231]:
     (warning) Possible null pointer dereference: pScrn - otherwise it is
     redundant to check it against null.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 2c0629d..12a8771 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -217,6 +217,10 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
     int i;
     int scrnIndex;
     Bool is_gpu = FALSE;
+
+    if (!pScrn)
+        return;
+
     if (pScrn->is_gpu) {
         /* First check if the screen is valid */
         if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
@@ -228,9 +232,6 @@ xf86DeleteScreen(ScrnInfoPtr pScrn)
             return;
     }
 
-    if (!pScrn)
-        return;
-
     scrnIndex = pScrn->scrnIndex;
     /* If a FreeScreen function is defined, call it here */
     if (pScrn->FreeScreen != NULL)
commit e6733ae91b7be52930f22a87de15fa05819ef948
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 28 20:27:50 2014 -0800

    On realloc failure, free font_path_string instead of leaking it
    
    Flagged by cppcheck 1.62:
    [dix/dixfonts.c:1792]: (error) Common realloc mistake:
     'font_path_string' nulled but not freed upon failure
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 341ca3f..83d2539 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -1792,11 +1792,14 @@ GetFontPath(ClientPtr client, int *count, int *length, unsigned char **result)
         fpe = font_path_elements[i];
         len += fpe->name_length + 1;
     }
-    font_path_string = (unsigned char *) realloc(font_path_string, len);
-    if (!font_path_string)
+    c = realloc(font_path_string, len);
+    if (c == NULL) {
+        free(font_path_string);
+        font_path_string = NULL;
         return BadAlloc;
+    }
 
-    c = font_path_string;
+    font_path_string = c;
     *length = 0;
     for (i = 0; i < num_fpes; i++) {
         fpe = font_path_elements[i];
commit 910b5b245425f0a866a703303b78768b0de5cb2b
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 28 20:27:49 2014 -0800

    Link libvgahw with $(PCIACCESS_LIBS) as well
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/vgahw/Makefile.am b/hw/xfree86/vgahw/Makefile.am
index f0b6574..4b718b4 100644
--- a/hw/xfree86/vgahw/Makefile.am
+++ b/hw/xfree86/vgahw/Makefile.am
@@ -1,5 +1,6 @@
 module_LTLIBRARIES = libvgahw.la
 libvgahw_la_LDFLAGS = -avoid-version
+libvgahw_la_LIBADD = $(PCIACCESS_LIBS)
 libvgahw_la_SOURCES = vgaHW.c vgaHWmodule.c
 AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c
 AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
commit da1660deeb9032ecca61f4bcdc9fc2eec2ada445
Merge: 0fbb3d7 9fc1916
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Jan 27 19:02:15 2014 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit 0fbb3d711efec5222a57b45a70d28fc98380f3a1
Merge: 7ddef4f b98e493
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Jan 27 14:11:09 2014 -0800

    Merge remote-tracking branch 'anholt/glamor-reformat'
    
    Conflicts:
    	Makefile.am
    
    Conflict caused by adding PSEUDORAMIX and GLAMOR directory defines in
    separate branches

diff --cc Makefile.am
index b296e0c,fb527a8..7c93d8d
--- a/Makefile.am
+++ b/Makefile.am
@@@ -27,10 -27,10 +27,14 @@@ if PRESEN
  PRESENT_DIR=present
  endif
  
 +if PSEUDORAMIX
 +PSEUDORAMIX_DIR=pseudoramiX
 +endif
 +
+ if GLAMOR
+ GLAMOR_DIR=glamor
+ endif
+ 
  SUBDIRS = \
  	doc \
  	man \
commit 7ddef4f7033c10b6e92866182d4475a4d49c5083
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 14:30:28 2014 -0800

    Add _XITYPEDEF_POINTER to dix-config.h
    
    Just like the pointer type from Xdefs.h, the Pointer type from
    XIproto.h collides with local declarations of variables using the same
    name. XIproto.h can use _XITYPEDEF_POINTER to avoid declaring the
    unnecessary pointer type.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 55cfe47..30456cb 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -472,6 +472,9 @@
 /* Don't let Xdefs.h define 'pointer' */
 #define _XTYPEDEF_POINTER       1
 
+/* Don't let XIproto define 'Pointer' */
+#define _XITYPEDEF_POINTER      1
+
 /* Ask fontsproto to make font path element names const */
 #define FONT_PATH_ELEMENT_NAME_CONST    1
 
commit 0b5a87f37d5dcd2ebff977a3b9a50a75ace93c83
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 19:17:24 2014 -0800

    pseudoramiX: Only compile on XQUARTZ and XWIN
    
    PseudoramiXExtensionInit() is not defined in extinit.h if it won't be
    used and we get a compiler warning when compiling the pseudoramiX code.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/Makefile.am b/Makefile.am
index add69d1..b296e0c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,10 @@ if PRESENT
 PRESENT_DIR=present
 endif
 
+if PSEUDORAMIX
+PSEUDORAMIX_DIR=pseudoramiX
+endif
+
 SUBDIRS = \
 	doc \
 	man \
@@ -37,11 +41,11 @@ SUBDIRS = \
 	Xext \
 	miext \
 	os \
-	pseudoramiX \
 	randr \
 	render  \
 	Xi \
 	xkb \
+	$(PSEUDORAMIX_DIR) \
 	$(DBE_DIR) \
 	$(RECORD_DIR) \
 	xfixes \
diff --git a/configure.ac b/configure.ac
index 560c460..0312c4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2174,6 +2174,8 @@ if test "x$XQUARTZ" = xyes; then
 	fi
 fi
 
+AM_CONDITIONAL(PSEUDORAMIX, [test "x$XQUARTZ" = xyes -o "x$XWIN" = xyes ])
+
 # Support for objc in autotools is minimal and not documented.
 OBJC='$(CC)'
 OBJCLD='$(CCLD)'
commit 61cb6c9aa95aa369573c4e02c023bbc33c7678c9
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 19:16:36 2014 -0800

    pseudoramiX: Add _X_ATTRIBUTE_PRINTF attributes to debug functions.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/pseudoramiX/pseudoramiX.c b/pseudoramiX/pseudoramiX.c
index 23dbc73..f47c783 100644
--- a/pseudoramiX/pseudoramiX.c
+++ b/pseudoramiX/pseudoramiX.c
@@ -100,6 +100,10 @@ static unsigned long pseudoramiXGeneration = 0;
 
 static void
 PseudoramiXTrace(const char *format, ...)
+    _X_ATTRIBUTE_PRINTF(1, 2);
+
+static void
+PseudoramiXTrace(const char *format, ...)
 {
     va_list ap;
 
@@ -110,6 +114,10 @@ PseudoramiXTrace(const char *format, ...)
 
 static void
 PseudoramiXDebug(const char *format, ...)
+    _X_ATTRIBUTE_PRINTF(1, 2);
+
+static void
+PseudoramiXDebug(const char *format, ...)
 {
     va_list ap;
 
commit 9e45a1a030a5e70318441f33a132269a19a43df5
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 18:00:53 2013 +0900

    Warning fixes in glx
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 8c10586..5d1a45b 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -461,7 +461,7 @@ create_driver_context(__GLXDRIcontext * context,
         unsigned dri_err = 0;
         unsigned major_ver;
         unsigned minor_ver;
-        uint32_t flags;
+        uint32_t flags = 0;
         int reset;
         int api = __DRI_API_OPENGL;
 
diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
index fc90272..69d4b29 100644
--- a/glx/glxdricommon.c
+++ b/glx/glxdricommon.c
@@ -226,7 +226,7 @@ glxConvertConfigs(const __DRIcoreExtension * core,
     }
 
     for (i = 0; configs[i]; i++) {
-        int renderType = 0;
+        unsigned int renderType = 0;
         if (core->getConfigAttrib(configs[i], __DRI_ATTRIB_RENDER_TYPE,
                                   &renderType)) {
             if (render_type_is_pbuffer_only(renderType) &&
commit b98e49379c8d7cecce991207048489f51b10028c
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 15:00:19 2013 -0800

    glamor: Remove more out-of-tree compat code.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b04fa46..dc38730 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -54,19 +54,6 @@
 #include "glamor_debug.h"
 
 #include <list.h>
-/* The list.h rename all the function to add xorg_ prefix.
-   We add hack here to avoid the compile error when using
-   old version xserver header file.
-   These will be removed in future. */
-#ifndef xorg_list_entry
-#define xorg_list list
-#define xorg_list_for_each_entry list_for_each_entry
-#define xorg_list_for_each_entry_safe list_for_each_entry_safe
-#define xorg_list_del list_del
-#define xorg_list_add list_add
-#define xorg_list_append list_append
-#define xorg_list_init list_init
-#endif
 
 struct glamor_pixmap_private;
 
commit 40a8186f0f78b7c36ef7e3d902c53bdc9bb7c650
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 12:22:08 2013 -0800

    glamor: Remove an extra copy of RegionNil().
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 967e228..3b6b2ed 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -123,7 +123,7 @@ glamor_composite_rectangles(CARD8 op,
     if (!num_rects)
         return;
 
-    if (region_is_empty(dst->pCompositeClip)) {
+    if (RegionNil(dst->pCompositeClip)) {
         DEBUGF("%s: empty clip, skipping\n", __FUNCTION__);
         return;
     }
@@ -212,7 +212,7 @@ glamor_composite_rectangles(CARD8 op,
 
     if (dst->pCompositeClip->data &&
         (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
-         region_is_empty(&region))) {
+         RegionNil(&region))) {
         DEBUGF("%s: zero-intersection between rectangles and clip\n",
                __FUNCTION__);
         pixman_region_fini(&region);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 151a65e..ea827df 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -815,12 +815,6 @@ glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
     }
 }
 
-static inline Bool
-region_is_empty(pixman_region16_t * region)
-{
-    return region->data && region->data->numRects == 0;
-}
-
 #ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #endif
commit d26f5335151a9e962afa4bbf29ca5b94660a33ca
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:35:53 2013 -0800

    glamor: Hook the module back up to the build.
    
    For now we're just building an uninstalled library.  The extra EGL
    stubs are required so that we can get the DIX building and usable
    without pulling in the xf86 DDX code in glamor_egl.c.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Makefile.am b/Makefile.am
index add69d1..fb527a8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,10 @@ if PRESENT
 PRESENT_DIR=present
 endif
 
+if GLAMOR
+GLAMOR_DIR=glamor
+endif
+
 SUBDIRS = \
 	doc \
 	man \
@@ -51,6 +55,7 @@ SUBDIRS = \
 	$(PRESENT_DIR) \
 	$(DRI3_DIR) \
 	exa \
+	$(GLAMOR_DIR) \
 	config \
 	hw \
 	test
@@ -102,6 +107,7 @@ DIST_SUBDIRS = \
 	composite \
 	glx \
 	exa \
+	$(GLAMOR_DIR) \
 	config \
 	dri3 \
 	present \
diff --git a/configure.ac b/configure.ac
index 560c460..20e3f18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -636,6 +636,7 @@ AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest serv
 AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
 AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
 AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
+AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
 dnl kdrive and its subsystems
 AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
 AC_ARG_ENABLE(xephyr,         AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
@@ -2063,6 +2064,14 @@ AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
 AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
 AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 AM_CONDITIONAL([XORG_BUS_PLATFORM], [test "x$CONFIG_UDEV_KMS" = xyes])
+
+dnl glamor
+AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes])
+if test "x$GLAMOR" = xyes; then
+	AC_DEFINE(GLAMOR, 1, [Build glamor])
+	PKG_CHECK_MODULES([GLAMOR], [egl gl])
+fi
+
 dnl XWin DDX
 
 AC_MSG_CHECKING([whether to build XWin DDX])
@@ -2432,6 +2441,7 @@ doc/Makefile
 doc/dtrace/Makefile
 man/Makefile
 fb/Makefile
+glamor/Makefile
 record/Makefile
 config/Makefile
 mi/Makefile
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 90d80a7..3fe2530 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -1,14 +1,8 @@
-lib_LTLIBRARIES = libglamor.la
+noinst_LTLIBRARIES = libglamor.la libglamor_egl_stubs.la
 
-if GLAMOR_GLES2
-libglamor_la_LIBADD = $(GLESV2_LIBS)
-else
-libglamor_la_LIBADD = $(GL_LIBS)
-endif
+libglamor_la_LIBADD = $(GLAMOR_LIBS)
 
-AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
-
-libglamor_la_LDFLAGS = -version-info 0:0:0
+AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
@@ -48,21 +42,6 @@ libglamor_la_SOURCES = \
 	glamor_utils.h\
 	glamor.h
 
-sdk_HEADERS = glamor.h
-
-if EGL
-LIBGLAMOREGL = libglamoregl.la
-module_LTLIBRARIES = $(LIBGLAMOREGL)
-libglamoregl_la_DEPENDENCIES = libglamor.la
-libglamoregl_la_LDFLAGS = -avoid-version -module
-libglamoregl_la_LIBADD = $(EGL_LIBS) $(GLX_SYS_LIBS) $(GBM_LIBS) libglamor.la
-libglamoregl_la_SOURCES = glamor_eglmodule.c glamor_egl.c
-libglamoregl_la_CFLAGS = \
-	$(AM_CFLAGS) \
-	$(GLX_DEFINES) \
-	$(LIBDRM_CFLAGS) \
-	$(EGL_CFLAGS) \
-	$(GBM_CFLAGS)
-endif
-
+libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
 
+sdk_HEADERS = glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 188aef5..feb110a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -261,6 +261,7 @@ glamor_set_debug_level(int *debug_level)
 
 int glamor_debug_level;
 
+
 /** Set up glamor for an already-configured GL context. */
 Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
new file mode 100644
index 0000000..1449d08
--- /dev/null
+++ b/glamor/glamor_egl_stubs.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/** @file glamor_egl_stubs.c
+ *
+ * Stubbed out glamor_egl.c functions for servers other than Xorg.
+ */
+
+#include "glamor_priv.h"
+
+void
+glamor_egl_screen_init(ScreenPtr screen)
+{
+}
+
+void
+glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+}
+
+void
+glamor_egl_make_current(ScreenPtr screen)
+{
+}
+
+void
+glamor_egl_restore_context(ScreenPtr screen)
+{
+}
+
+int
+glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
+                                 PixmapPtr pixmap,
+                                 unsigned int tex,
+                                 Bool want_name, CARD16 *stride, CARD32 *size)
+{
+    return 0;
+}
+
+unsigned int
+glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
+{
+    return 0;
+}
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 55cfe47..247b114 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -475,4 +475,7 @@
 /* Ask fontsproto to make font path element names const */
 #define FONT_PATH_ELEMENT_NAME_CONST    1
 
+/* Build GLAMOR */
+#undef GLAMOR
+
 #endif /* _DIX_CONFIG_H_ */
commit 54e78ec31e030d488765341a0c143c5a060c3768
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 22 15:03:26 2014 -0800

    glamor: Convert use of the old "pointer" typedef to "void *".
    
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index f1805e0..05f565b 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -411,13 +411,13 @@ extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
                                                 GCPtr pGC, int x, int y,
                                                 unsigned int nglyph,
                                                 CharInfoPtr *ppci,
-                                                pointer pglyphBase);
+                                                void *pglyphBase);
 
 extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                                                int x, int y,
                                                unsigned int nglyph,
                                                CharInfoPtr *ppci,
-                                               pointer pglyphBase);
+                                               void *pglyphBase);
 
 extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
                                             DrawablePtr pDrawable, int w, int h,
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 9908c06..6f754ce 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -31,7 +31,7 @@
 static Bool
 _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                         int x, int y, unsigned int nglyph,
-                        CharInfoPtr *ppci, pointer pglyphBase, Bool fallback)
+                        CharInfoPtr *ppci, void *pglyphBase, Bool fallback)
 {
     if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
         && glamor_ddx_fallback_check_gc(pGC))
@@ -44,7 +44,7 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 void
 glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                        int x, int y, unsigned int nglyph,
-                       CharInfoPtr *ppci, pointer pglyphBase)
+                       CharInfoPtr *ppci, void *pglyphBase)
 {
     _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
                             TRUE);
@@ -53,7 +53,7 @@ glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 Bool
 glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                           int x, int y, unsigned int nglyph,
-                          CharInfoPtr *ppci, pointer pglyphBase)
+                          CharInfoPtr *ppci, void *pglyphBase)
 {
     return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
                                    pglyphBase, FALSE);
@@ -62,7 +62,7 @@ glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
 static Bool
 _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                        int x, int y, unsigned int nglyph,
-                       CharInfoPtr *ppci, pointer pglyphBase, Bool fallback)
+                       CharInfoPtr *ppci, void *pglyphBase, Bool fallback)
 {
     if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
         && glamor_ddx_fallback_check_gc(pGC))
@@ -75,7 +75,7 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 void
 glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                       int x, int y, unsigned int nglyph,
-                      CharInfoPtr *ppci, pointer pglyphBase)
+                      CharInfoPtr *ppci, void *pglyphBase)
 {
     _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
                            TRUE);
@@ -84,7 +84,7 @@ glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 Bool
 glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                          int x, int y, unsigned int nglyph,
-                         CharInfoPtr *ppci, pointer pglyphBase)
+                         CharInfoPtr *ppci, void *pglyphBase)
 {
     return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
                                   pglyphBase, FALSE);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8ccf4fa..b04fa46 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -925,11 +925,11 @@ RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 
 void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                             int x, int y, unsigned int nglyph,
-                            CharInfoPtr *ppci, pointer pglyphBase);
+                            CharInfoPtr *ppci, void *pglyphBase);
 
 void glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                            int x, int y, unsigned int nglyph,
-                           CharInfoPtr *ppci, pointer pglyphBase);
+                           CharInfoPtr *ppci, void *pglyphBase);
 
 void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
                         DrawablePtr pDrawable, int w, int h, int x, int y);
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 6e91a0c..cbe07c8 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -154,7 +154,7 @@ static XF86ImageRec Images[NUM_IMAGES] = {
 };
 
 static void
-glamor_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
+glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
 {
     glamor_port_private *port_priv = (glamor_port_private *) data;
     int i;
@@ -172,7 +172,7 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
 
 static int
 glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
-                             Atom attribute, INT32 value, pointer data)
+                             Atom attribute, INT32 value, void *data)
 {
     glamor_port_private *port_priv = (glamor_port_private *) data;
 
@@ -195,7 +195,7 @@ glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
 
 static int
 glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
-                             Atom attribute, INT32 *value, pointer data)
+                             Atom attribute, INT32 *value, void *data)
 {
     glamor_port_private *port_priv = (glamor_port_private *) data;
 
@@ -222,7 +222,7 @@ glamor_xv_query_best_size(ScrnInfoPtr pScrn,
                           Bool motion,
                           short vid_w, short vid_h,
                           short drw_w, short drw_h,
-                          unsigned int *p_w, unsigned int *p_h, pointer data)
+                          unsigned int *p_w, unsigned int *p_h, void *data)
 {
     *p_w = drw_w;
     *p_h = drw_h;
@@ -440,7 +440,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
                     short width,
                     short height,
                     Bool sync,
-                    RegionPtr clipBoxes, pointer data, DrawablePtr pDrawable)
+                    RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
 {
     ScreenPtr screen = xf86ScrnToScreen(pScrn);
     glamor_port_private *port_priv = (glamor_port_private *) data;
@@ -622,7 +622,7 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports)
 
         REGION_NULL(pScreen, &pPriv->clip);
 
-        adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
+        adapt->pPortPrivates[i].ptr = (void *) (pPriv);
     }
     return adapt;
 }
commit 3c3a4eeaa1f24b7534b332739158a2a36987ea6b
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:45:33 2013 -0800

    glamor: Silence warnings for non-debug builds.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index afb76f6..ff58725 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -54,6 +54,7 @@ _glamor_get_spans(DrawablePtr drawable,
                                                                   depth),
                                                  readpixels_dst, 0,
                                                  GLAMOR_ACCESS_RO);
+        (void)data;
         assert(data == readpixels_dst);
         readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
     }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 52bcf43..4a3a97c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -869,7 +869,7 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
                     const PictFormatShort mask, enum shader_in in_ca)
 {
     PictFormatShort new_vis;
-    int src_type, mask_type, src_bpp, mask_bpp;
+    int src_type, mask_type, src_bpp;
     int i;
 
     if (src == mask) {
@@ -877,9 +877,8 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
         return TRUE;
     }
     src_bpp = PICT_FORMAT_BPP(src);
-    mask_bpp = PICT_FORMAT_BPP(mask);
 
-    assert(src_bpp == mask_bpp);
+    assert(src_bpp == PICT_FORMAT_BPP(mask));
 
     new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
 
commit 9af66851e2770bcd8408a0e5ddf8bb8ea816feaa
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jan 24 10:58:04 2014 -0800

    glamor: Disable definitions of GL extension prototypes to avoid warnings.
    
    We're not using the extension prototypes, since you have to dlsym them
    anyway.  Disabling their definitions prevents them from being defined
    twice (once by gl.h, once by glext.h).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9f0c558..8ccf4fa 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -35,8 +35,6 @@
 #endif
 #include "glamor.h"
 
-#define GL_GLEXT_PROTOTYPES
-
 #ifdef GLAMOR_GLES2
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
commit a7b8ce8b4207a93c0455a0b796cfc47917c04a9c
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:41:33 2013 -0800

    glamor: Drop xfree86 dependencies from this dix module.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 15a8b74..90d80a7 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -6,7 +6,7 @@ else
 libglamor_la_LIBADD = $(GL_LIBS)
 endif
 
-AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(LIBDRM_CFLAGS)
+AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 
 libglamor_la_LDFLAGS = -version-info 0:0:0
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 7dc2973..f1805e0 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -30,14 +30,12 @@
 #define GLAMOR_H
 
 #include <scrnintstr.h>
-#include <xf86.h>
-#include <xf86str.h>
 #include <pixmapstr.h>
 #include <gcstruct.h>
 #include <picturestr.h>
 #include <fb.h>
 #include <fbpict.h>
-#include <xf86xv.h>
+
 /*
  * glamor_pixmap_type : glamor pixmap's type.
  * @MEMORY: pixmap is in memory.
commit 7759e4d090f56cdcad1c8a2acb2c1be20021de5d
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:43:48 2013 -0800

    glamor: Disable the XV code for now.
    
    We're going to want to make this DIX code instead of XF86 if at all
    possible, but for now just disable it so we can work on the rest of
    the build.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index da1ad3d..7dc2973 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -437,7 +437,9 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC,
 extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
                                            int mode, int n, DDXPointPtr points);
 
+#if 0
 extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen,
                                                     int num_texture_ports);
+#endif
 
 #endif                          /* GLAMOR_H */
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index bdc4c73..6e91a0c 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -627,9 +627,11 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports)
     return adapt;
 }
 #else
+#if 0
 XF86VideoAdaptorPtr
 glamor_xv_init(ScreenPtr screen, int num_texture_ports)
 {
     return NULL;
 }
 #endif
+#endif
commit b3acb47e98023da898ffc4b6a5bac38a78bd7727
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Oct 30 11:30:23 2013 -0400

    glamor: Use dix-config.h not project config.h
    
    v2: Also edit the one in glamor_egl.c (by anholt)
    v3: Also edit the one in glamor_eglmodule.c (by anholt)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index b30eeec..2f97a83 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -27,9 +27,7 @@
  *
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "dix-config.h"
 
 #define GLAMOR_FOR_XORG
 #include <xorg-server.h>
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index e7c8eda..5ddd602 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -27,9 +27,7 @@
  *    Zhigang Gong <zhigang.gong at gmail.com>
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "dix-config.h"
 
 #include <xorg-server.h>
 #define GLAMOR_FOR_XORG
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c733b90..9f0c558 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -27,9 +27,7 @@
 #ifndef GLAMOR_PRIV_H
 #define GLAMOR_PRIV_H
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "dix-config.h"
 
 #include <xorg-server.h>
 #ifndef DEBUG
commit 6cc0b7b01599b94af07e9fc8b16134f751ede077
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Oct 30 11:05:40 2013 -0400

    glamor/egl: Remove glapi awareness
    
    We only needed this because glx was directly bashing glapi tables.
    Since that's not the case anymore, we should just MakeCurrent like a
    real GL app.
    
    v2: Hand-resolve against rebase onto newer server (by anholt)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 6c80f24..15a8b74 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -46,8 +46,7 @@ libglamor_la_SOURCES = \
 	glamor_compositerects.c\
 	glamor_xv.c\
 	glamor_utils.h\
-	glamor.h\
-	glapi.h
+	glamor.h
 
 sdk_HEADERS = glamor.h
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 4257808..b30eeec 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -61,9 +61,6 @@
 
 #include "glamor.h"
 #include "glamor_gl_dispatch.h"
-#ifdef GLX_USE_SHARED_DISPATCH
-#include "glapi.h"
-#endif
 
 static const char glamor_name[] = "glamor";
 
@@ -93,8 +90,6 @@ struct glamor_egl_screen_private {
     struct gbm_device *gbm;
 #endif
     int has_gem;
-    void *glamor_context;
-    void *current_context;
     int gl_context_depth;
     int dri3_capable;
 
@@ -115,7 +110,6 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
         scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
 
-#ifdef GLX_USE_SHARED_DISPATCH
 _X_EXPORT void
 glamor_egl_make_current(ScreenPtr screen)
 {
@@ -126,9 +120,7 @@ glamor_egl_make_current(ScreenPtr screen)
     if (glamor_egl->gl_context_depth++)
         return;
 
-    GET_CURRENT_CONTEXT(glamor_egl->current_context);
-
-    if (glamor_egl->glamor_context != glamor_egl->current_context) {
+    if (glamor_egl->context != eglGetCurrentContext()) {
         eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
         if (!eglMakeCurrent(glamor_egl->display,
@@ -149,14 +141,9 @@ glamor_egl_restore_context(ScreenPtr screen)
     if (--glamor_egl->gl_context_depth)
         return;
 
-    if (glamor_egl->current_context &&
-        glamor_egl->glamor_context != glamor_egl->current_context)
-        SET_CURRENT_CONTEXT(glamor_egl->current_context);
+    eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+                   EGL_NO_SURFACE, EGL_NO_CONTEXT);
 }
-#else
-#define glamor_egl_make_current(x)
-#define glamor_egl_restore_context(s)
-#endif
 
 static EGLImageKHR
 _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
@@ -796,19 +783,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
                    "Failed to make EGL context current\n");
         return FALSE;
     }
-#ifdef GLX_USE_SHARED_DISPATCH
-    GET_CURRENT_CONTEXT(glamor_egl->glamor_context);
-#endif
     glamor_egl->saved_free_screen = scrn->FreeScreen;
     scrn->FreeScreen = glamor_egl_free_screen;
 #ifdef GLAMOR_GLES2
     xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n");
-#ifdef GLX_USE_SHARED_DISPATCH
     xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                "Glamor is using GLES2 but GLX needs GL. "
                "Indirect GLX may not work correctly.\n");
 #endif
-#endif
     return TRUE;
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 49d2ff7..151a65e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1834,7 +1834,6 @@ glamor_restore_current(ScreenPtr screen)
     glamor_egl_restore_context(screen);
 }
 
-#ifdef GLX_USE_SHARED_DISPATCH
 static inline glamor_gl_dispatch *
 glamor_get_dispatch(glamor_screen_private * glamor_priv)
 {
@@ -1850,19 +1849,5 @@ glamor_put_dispatch(glamor_screen_private * glamor_priv)
     if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
         glamor_restore_current(glamor_priv->screen);
 }
-#else
-#warning "Indirect GLX may be broken, need to implement context switch."
-static inline glamor_gl_dispatch *
-glamor_get_dispatch(glamor_screen_private * glamor_priv)
-{
-    return &glamor_priv->_dispatch;
-}
-
-static inline void
-glamor_put_dispatch(glamor_screen_private * glamor_priv)
-{
-}
-
-#endif
 
 #endif
diff --git a/glamor/glapi.h b/glamor/glapi.h
deleted file mode 100644
index f61fc84..0000000
--- a/glamor/glapi.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-/**
- * \mainpage Mesa GL API Module
- *
- * \section GLAPIIntroduction Introduction
- *
- * The Mesa GL API module is responsible for dispatching all the
- * gl*() functions.  All GL functions are dispatched by jumping through
- * the current dispatch table (basically a struct full of function
- * pointers.)
- *
- * A per-thread current dispatch table and per-thread current context
- * pointer are managed by this module too.
- *
- * This module is intended to be non-Mesa-specific so it can be used
- * with the X/DRI libGL also.
- */
-
-#ifndef _GLAPI_H
-#define _GLAPI_H
-
-#define GL_GLEXT_PROTOTYPES
-
-#if GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include <GL/gl.h>
-#include "GL/glext.h"
-#endif
-
-/* Is this needed?  It is incomplete anyway. */
-#ifdef USE_MGL_NAMESPACE
-#define _glapi_set_dispatch _mglapi_set_dispatch
-#define _glapi_get_dispatch _mglapi_get_dispatch
-#define _glapi_set_context _mglapi_set_context
-#define _glapi_get_context _mglapi_get_context
-#define _glapi_Dispatch _mglapi_Dispatch
-#define _glapi_Context _mglapi_Context
-#endif
-
-typedef void (*_glapi_proc) (void);
-struct _glapi_table;
-
-#if defined (GLX_USE_TLS)
-
-extern __thread struct _glapi_table *_glapi_tls_Dispatch
-    __attribute__ ((tls_model("initial-exec")));
-
-extern __thread void *_glapi_tls_Context
-    __attribute__ ((tls_model("initial-exec")));
-
-extern const struct _glapi_table *_glapi_Dispatch;
-extern const void *_glapi_Context;
-
-#define GET_DISPATCH() _glapi_tls_Dispatch
-#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_tls_Context
-#define SET_CURRENT_CONTEXT(C)  _glapi_tls_Context = (void*)C
-
-#else
-
-extern struct _glapi_table *_glapi_Dispatch;
-extern void *_glapi_Context;
-
-#ifdef THREADS
-
-#define GET_DISPATCH() \
-     (_X_LIKELY(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
-
-#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) \
-     (_X_LIKELY(_glapi_Context) ? _glapi_Context : _glapi_get_context())
-
-#define SET_CURRENT_CONTEXT(C) do { if (_X_LIKELY(_glapi_Context))      \
-					_glapi_Context = (void*)C; \
-				     else \
-					_glapi_set_context(C); } while(0)
-
-#else
-
-#define GET_DISPATCH() _glapi_Dispatch
-#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_Context
-#define SET_CURRENT_CONTEXT(C)  _glapi_Context = (void*)C
-
-#endif
-
-#endif                          /* defined (GLX_USE_TLS) */
-
-extern void
- _glapi_set_context(void *context);
-
-extern void *_glapi_get_context(void);
-
-#endif
commit 0c5a7c208601110a0b36d24cdacb4d844af03f75
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 17 16:32:17 2013 -0800

    glamor: Remove compat code for building out of tree.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 5eefd8e..6c80f24 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -11,7 +11,6 @@ AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(LIBDRM_CFLAGS)
 libglamor_la_LDFLAGS = -version-info 0:0:0
 
 libglamor_la_SOURCES = \
-	compat-api.h \
 	glamor.c \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
diff --git a/glamor/compat-api.h b/glamor/compat-api.h
deleted file mode 100644
index 1608478..0000000
--- a/glamor/compat-api.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Author: Dave Airlie <airlied at redhat.com>
- */
-
-/* this file provides API compat between server post 1.13 and pre it,
-   it should be reused inside as many drivers as possible */
-#ifndef COMPAT_API_H
-#define COMPAT_API_H
-
-#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR
-#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum]
-#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p
-#endif
-
-#ifndef XF86_HAS_SCRN_CONV
-#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum]
-#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex]
-#endif
-
-#ifndef XF86_SCRN_INTERFACE
-
-#define SCRN_ARG_TYPE int
-#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = xf86Screens[(arg1)]
-
-#define SCREEN_ARG_TYPE int
-#define SCREEN_PTR(arg1) ScreenPtr screen = screenInfo.screens[(arg1)]
-
-#define SCREEN_INIT_ARGS_DECL int scrnIndex, ScreenPtr screen, int argc, char **argv
-
-#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer timeout, pointer read_mask
-#define BLOCKHANDLER_ARGS arg, blockData, timeout, read_mask
-
-#define WAKEUPHANDLER_ARGS_DECL int arg, pointer wakeupData, unsigned long result, pointer read_mask
-#define WAKEUPHANDLER_ARGS arg, wakeupData, result, read_mask
-
-#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr screen
-#define CLOSE_SCREEN_ARGS scrnIndex, screen
-
-#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags
-#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0
-
-#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags
-#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0
-
-#define FREE_SCREEN_ARGS_DECL int arg, int flags
-#define FREE_SCREEN_ARGS	arg, flags
-
-#define VT_FUNC_ARGS_DECL int arg, int flags
-#define VT_FUNC_ARGS(flags) scrn->scrnIndex, (flags)
-
-#define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex)
-
-#else
-#define SCRN_ARG_TYPE ScrnInfoPtr
-#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = (arg1)
-
-#define SCREEN_ARG_TYPE ScreenPtr
-#define SCREEN_PTR(arg1) ScreenPtr screen = (arg1)
-
-#define SCREEN_INIT_ARGS_DECL ScreenPtr screen, int argc, char **argv
-
-#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer timeout, pointer read_mask
-#define BLOCKHANDLER_ARGS arg, timeout, read_mask
-
-#define WAKEUPHANDLER_ARGS_DECL ScreenPtr arg, unsigned long result, pointer read_mask
-#define WAKEUPHANDLER_ARGS arg, result, read_mask
-
-#define CLOSE_SCREEN_ARGS_DECL ScreenPtr screen
-#define CLOSE_SCREEN_ARGS screen
-
-#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y
-#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y
-
-#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode
-#define SWITCH_MODE_ARGS(arg, m) arg, m
-
-#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg
-#define FREE_SCREEN_ARGS	arg
-
-#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg
-#define VT_FUNC_ARGS(flags) scrn
-
-#define XF86_ENABLEDISABLEFB_ARG(x) (x)
-
-#endif
-#endif
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 37136af..188aef5 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -495,7 +495,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
 }
 
 Bool
-glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
+glamor_close_screen(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
     PixmapPtr screen_pixmap;
@@ -539,7 +539,7 @@ glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
 
     glamor_release_screen_priv(screen);
 
-    return screen->CloseScreen(CLOSE_SCREEN_ARGS);
+    return screen->CloseScreen(screen);
 }
 
 void
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4e47523..da1ad3d 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -116,11 +116,7 @@ extern _X_EXPORT void glamor_fini(ScreenPtr screen);
  * screen pixmap which must be a glamor pixmap and requires
  * the internal data structure still exist at that time.
  * Otherwise, the glamor internal structure will not be freed.*/
-#ifndef XF86_SCRN_INTERFACE
-extern _X_EXPORT Bool glamor_close_screen(int scrnIndex, ScreenPtr screen);
-#else
 extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen);
-#endif
 
 /* Let glamor to know the screen's fbo. The low level
  * driver should already assign a tex
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index c65f701..4257808 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -60,7 +60,6 @@
 #include <EGL/eglext.h>
 
 #include "glamor.h"
-#include "compat-api.h"
 #include "glamor_gl_dispatch.h"
 #ifdef GLX_USE_SHARED_DISPATCH
 #include "glapi.h"
@@ -610,7 +609,7 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 }
 
 static Bool
-glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
+glamor_egl_close_screen(ScreenPtr screen)
 {
     ScrnInfoPtr scrn;
     struct glamor_egl_screen_private *glamor_egl;
@@ -638,7 +637,7 @@ glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 
     screen->CloseScreen = glamor_egl->saved_close_screen;
 
-    return screen->CloseScreen(CLOSE_SCREEN_ARGS);
+    return screen->CloseScreen(screen);
 }
 
 static Bool
@@ -672,17 +671,10 @@ glamor_egl_screen_init(ScreenPtr screen)
 }
 
 static void
-glamor_egl_free_screen(FREE_SCREEN_ARGS_DECL)
+glamor_egl_free_screen(ScrnInfoPtr scrn)
 {
-    ScrnInfoPtr scrn;
     struct glamor_egl_screen_private *glamor_egl;
 
-#ifndef XF86_SCRN_INTERFACE
-    scrn = xf86Screens[arg];
-#else
-    scrn = arg;
-#endif
-
     glamor_egl = glamor_egl_get_screen_private(scrn);
     if (glamor_egl != NULL) {
 
@@ -694,7 +686,7 @@ glamor_egl_free_screen(FREE_SCREEN_ARGS_DECL)
 #endif
         scrn->FreeScreen = glamor_egl->saved_free_screen;
         free(glamor_egl);
-        scrn->FreeScreen(FREE_SCREEN_ARGS);
+        scrn->FreeScreen(scrn);
     }
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 08b6bb0..c733b90 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -36,7 +36,6 @@
 #define NDEBUG
 #endif
 #include "glamor.h"
-#include "compat-api.h"
 
 #define GL_GLEXT_PROTOTYPES
 
commit 82efb90efba685678638f94804d773b59ca1643f
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Oct 30 09:56:46 2013 -0400

    glamor: Remove copy of sna's compiler.h
    
    Xfuncproto.h has equivalents for these already.
    
    v2: Adjust a couple more likelies after the rebase (anholt)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2fd521f..5eefd8e 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -12,7 +12,6 @@ libglamor_la_LDFLAGS = -version-info 0:0:0
 
 libglamor_la_SOURCES = \
 	compat-api.h \
-	compiler.h \
 	glamor.c \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
diff --git a/glamor/compiler.h b/glamor/compiler.h
deleted file mode 100644
index 5f2d4ea..0000000
--- a/glamor/compiler.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Chris Wilson <chris at chris-wilson.co.uk>
- *
- *    Copied from sna 
- *
- */
-
-#ifndef _GLAMOR_COMPILER_H_
-#define _GLAMOR_COMPILER_H_
-
-#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
-#define likely(expr) (__builtin_expect (!!(expr), 1))
-#define unlikely(expr) (__builtin_expect (!!(expr), 0))
-#define noinline __attribute__((noinline))
-#define fastcall __attribute__((regparm(3)))
-#define must_check __attribute__((warn_unused_result))
-#define constant __attribute__((const))
-#else
-#define likely(expr) (expr)
-#define unlikely(expr) (expr)
-#define noinline
-#define fastcall
-#define must_check
-#define constant
-#endif
-
-#ifdef HAVE_VALGRIND
-#define VG(x) x
-#else
-#define VG(x)
-#endif
-
-#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
-
-#define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)]))
-
-#endif                          /* _SNA_COMPILER_H_ */
diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index a0d5980..967e228 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -246,7 +246,7 @@ glamor_composite_rectangles(CARD8 op,
         goto done;
     }
     else {
-        if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {
+        if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {
             int error;
 
             source = CreateSolidPicture(0, color, &error);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 3aef7fc..d59e620 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -203,7 +203,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 
     pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
 
-    if (unlikely(nbox * 4 * 2 > ARRAY_SIZE(vertices))) {
+    if (_X_UNLIKELY(nbox * 4 * 2 > ARRAY_SIZE(vertices))) {
         int allocated_box;
 
         if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) {
@@ -220,7 +220,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
         }
     }
 
-    if (unlikely(nbox > 1))
+    if (_X_UNLIKELY(nbox > 1))
         dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
     dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 1c0f9f5..3586b33 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -191,7 +191,7 @@ find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask)
 
     bits_mask = ((1LL << bits_cnt) - 1);
 
-    if (unlikely(bits_cnt > 56)) {
+    if (_X_UNLIKELY(bits_cnt > 56)) {
         while (bits) {
             if ((bits & bits_mask) == bits_mask) {
                 *pbits_mask = bits_mask << idx;
@@ -751,7 +751,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs,
         left_to_right = TRUE;
         cur_list = list++;
 
-        if (unlikely(!first_list)) {
+        if (_X_UNLIKELY(!first_list)) {
             pixman_region_init_with_extents(&current_region, extents);
             pixman_region_union(&list_region, &list_region, &current_region);
             first = TRUE;
@@ -821,7 +821,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs,
                 }
             }
             else {
-                if (unlikely(!first_list)) {
+                if (_X_UNLIKELY(!first_list)) {
                     current_box.x1 = x1;
                     current_box.y1 = y1;
                     current_box.x2 = x2;
@@ -1709,7 +1709,7 @@ _glamor_glyphs(CARD8 op,
     format = mask_format->depth << 24 | mask_format->format;
 
     fixed_list = calloc(fixed_size, sizeof(*fixed_list));
-    if (unlikely(fixed_list == NULL))
+    if (_X_UNLIKELY(fixed_list == NULL))
         fixed_size = 0;
     fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
                                         format, dst->pDrawable->pScreen,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d4f5371..08b6bb0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,8 +31,6 @@
 #include "config.h"
 #endif
 
-#include "compiler.h"
-
 #include <xorg-server.h>
 #ifndef DEBUG
 #define NDEBUG
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b27c56c..49d2ff7 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -59,7 +59,7 @@
 
 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h)			\
   do {								\
-	if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
+	if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {	\
 		w = priv->large.box.x2 - priv->large.box.x1;	\
 		h = priv->large.box.y2 - priv->large.box.y1;	\
 	} else {						\
@@ -80,7 +80,7 @@
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
    do {								\
-	if (unlikely(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) {  \
+	if (_X_UNLIKELY(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) {  \
 		*(_xoff_) = - (_priv_)->large.box.x1;	\
 		*(_yoff_) = - (_priv_)->large.box.y1;	\
 	} else {						\
@@ -314,7 +314,7 @@
 				     texcoord, yInverted)		\
   do {									\
 	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
-	if (likely(yInverted))						\
+	if (_X_LIKELY(yInverted))					\
 		(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
 	else								\
 		(texcoord)[1] = t_from_x_coord_y(yscale, _ty_);		\
@@ -337,7 +337,7 @@
     tx += fbo_x_off;							\
     ty += fbo_y_off;							\
     (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
-    if (likely(yInverted))							\
+    if (_X_LIKELY(yInverted))						\
       (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty);		\
     else								\
       (texcoord)[1] = t_from_x_coord_y(yscale, ty);			\
@@ -432,7 +432,7 @@
 							 texcoords,	\
 							 stride)	\
   do {									\
-    if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {			\
+    if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {		\
 	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
 						 yscale, _x1_, _y1_,	\
 						 _x2_, _y2_, yInverted,	\
@@ -505,7 +505,7 @@
     (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    if (likely(yInverted)) {							\
+    if (_X_LIKELY(yInverted)) {						\
       (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1);	\
       (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\
     }									\
@@ -521,7 +521,7 @@
 				     x1, y1, x2, y2,			\
                                      yInverted, vertices, stride)	\
   do {									\
-     if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {				\
+     if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
 	float tx1, tx2, ty1, ty2;					\
 	int fbo_x_off, fbo_y_off;					\
 	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
@@ -551,7 +551,7 @@
 					    _x1_, _y1_, _x2_, _y2_,	\
 	                                    yInverted, vertices, stride)\
   do {									\
-     if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {				\
+     if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
 	float tx1, tx2, ty1, ty2;					\
 	if (repeat_type == RepeatPad) {					\
 		tx1 = _x1_ - priv->large.box.x1;			\
@@ -591,7 +591,7 @@
 	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (likely(yInverted)) {						\
+	if (_X_LIKELY(yInverted)) {					\
 	    (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);	\
 	    (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2);	\
 	}								\
@@ -610,7 +610,7 @@
 	(vertices)[2] = (x2);					\
 	(vertices)[4] = (vertices)[2];				\
 	(vertices)[6] = (vertices)[0];				\
-	if (likely(yInverted)) {					\
+	if (_X_LIKELY(yInverted)) {				\
 	    (vertices)[1] = (y1);				\
 	    (vertices)[5] = (y2);				\
 	}							\
@@ -629,7 +629,7 @@
 	(vertices)[1*stride] = (x2);				\
 	(vertices)[2*stride] = (vertices)[1*stride];		\
 	(vertices)[3*stride] = (vertices)[0];			\
-	if (likely(yInverted)) {				\
+	if (_X_LIKELY(yInverted)) {				\
 	    (vertices)[1] = (y1);				\
 	    (vertices)[2*stride + 1] = (y2);			\
 	}							\
@@ -645,7 +645,7 @@
 					yInverted, vertices)		\
     do {								\
 	(vertices)[0] = v_from_x_coord_x(xscale, x);			\
-	if (likely(yInverted)) {						\
+	if (_X_LIKELY(yInverted)) {					\
 	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y);	\
 	} else {							\
 	    (vertices)[1] = v_from_x_coord_y(yscale, y);		\
@@ -673,7 +673,7 @@
 	(vertices)[2] = (x2);						\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (likely(yInverted)) {						\
+	if (_X_LIKELY(yInverted)) {	    				\
 	    (vertices)[1] = (y1);					\
 	    (vertices)[7] = (y2);					\
 	}								\
@@ -699,7 +699,7 @@
 					x2 + fbo_x_off);		\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    if (likely(yInverted)) {							\
+    if (_X_LIKELY(yInverted)) {						\
       (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale,		\
 				y1 + fbo_y_off);			\
       (vertices)[2 * stride + 1] = _t5_ =				\
@@ -742,7 +742,7 @@
 	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (likely(yInverted)) {						\
+	if (_X_LIKELY(yInverted)) {	    				\
 	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);	\
 	    (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2);	\
 	}								\
@@ -758,7 +758,7 @@
                                 yInverted, pt)			\
     do {							\
         (pt)[0] = t_from_x_coord_x(xscale, x);			\
-        if (likely(yInverted)) {					\
+        if (_X_LIKELY(yInverted)) {				\
             (pt)[1] = t_from_x_coord_y_inverted(yscale, y);	\
         } else {						\
             (pt)[1] = t_from_x_coord_y(yscale, y);		\
@@ -769,7 +769,7 @@
 				 yInverted, c)		\
     do {						\
         (c)[0] = (float)x;				\
-        if (likely(yInverted)) {				\
+        if (_X_LIKELY(yInverted)) {	    		\
             (c)[1] = (float)y;				\
         } else {					\
             (c)[1] = (float)height - (float)y;		\
diff --git a/glamor/glapi.h b/glamor/glapi.h
index 481e4ba..f61fc84 100644
--- a/glamor/glapi.h
+++ b/glamor/glapi.h
@@ -88,12 +88,12 @@ extern void *_glapi_Context;
 #ifdef THREADS
 
 #define GET_DISPATCH() \
-     (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
+     (_X_LIKELY(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
 
 #define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) \
-     (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context())
+     (_X_LIKELY(_glapi_Context) ? _glapi_Context : _glapi_get_context())
 
-#define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context))   \
+#define SET_CURRENT_CONTEXT(C) do { if (_X_LIKELY(_glapi_Context))      \
 					_glapi_Context = (void*)C; \
 				     else \
 					_glapi_set_context(C); } while(0)
commit 714926b090344a17a2f7aee9f4bc6aea4e45f48c
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 9 18:23:39 2014 +0800

    glamor: Fix up some indentation damage on header prototypes.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 96fb404..d4f5371 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -641,10 +641,8 @@ Bool glamor_fill(DrawablePtr drawable,
 Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
                   unsigned char alu, unsigned long planemask,
                   unsigned long fg_pixel);
-Bool
-
-glamor_solid_boxes(PixmapPtr pixmap,
-                   BoxPtr box, int nbox, unsigned long fg_pixel);
+Bool glamor_solid_boxes(PixmapPtr pixmap,
+                        BoxPtr box, int nbox, unsigned long fg_pixel);
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
@@ -655,12 +653,9 @@ void glamor_init_solid_shader(ScreenPtr screen);
 void glamor_fini_solid_shader(ScreenPtr screen);
 
 /* glamor_getspans.c */
-void
-
-
-glamor_get_spans(DrawablePtr drawable,
-                 int wmax,
-                 DDXPointPtr points, int *widths, int nspans, char *dst_start);
+void glamor_get_spans(DrawablePtr drawable,
+                      int wmax, DDXPointPtr points, int *widths,
+                      int nspans, char *dst_start);
 
 /* glamor_glyphs.c */
 void glamor_glyphs_fini(ScreenPtr screen);
@@ -676,41 +671,32 @@ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
                       DDXPointPtr points, int *widths, int n, int sorted);
 
 /* glamor_polyfillrect.c */
-void
-
-glamor_poly_fill_rect(DrawablePtr drawable,
-                      GCPtr gc, int nrect, xRectangle *prect);
+void glamor_poly_fill_rect(DrawablePtr drawable,
+                           GCPtr gc, int nrect, xRectangle *prect);
 
 /* glamor_polylines.c */
-void
-
-
-glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-                  DDXPointPtr points);
+void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+                       DDXPointPtr points);
 
 /* glamor_putimage.c */
-void
-
-
-glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                 int w, int h, int leftPad, int format, char *bits);
+void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                      int w, int h, int leftPad, int format, char *bits);
 void glamor_init_putimage_shaders(ScreenPtr screen);
 void glamor_fini_putimage_shaders(ScreenPtr screen);
 
 /* glamor_render.c */
-Bool
-
-glamor_composite_clipped_region(CARD8 op,
-                                PicturePtr source,
-                                PicturePtr mask,
-                                PicturePtr dest,
-                                glamor_pixmap_private *soruce_pixmap_priv,
-                                glamor_pixmap_private *mask_pixmap_priv,
-                                glamor_pixmap_private *dest_pixmap_priv,
-                                RegionPtr region,
-                                int x_source,
-                                int y_source,
-                                int x_mask, int y_mask, int x_dest, int y_dest);
+Bool glamor_composite_clipped_region(CARD8 op,
+                                     PicturePtr source,
+                                     PicturePtr mask,
+                                     PicturePtr dest,
+                                     glamor_pixmap_private *soruce_pixmap_priv,
+                                     glamor_pixmap_private *mask_pixmap_priv,
+                                     glamor_pixmap_private *dest_pixmap_priv,
+                                     RegionPtr region,
+                                     int x_source,
+                                     int y_source,
+                                     int x_mask, int y_mask,
+                                     int x_dest, int y_dest);
 
 void glamor_composite(CARD8 op,
                       PicturePtr pSrc,
@@ -750,12 +736,10 @@ Bool glamor_composite_choose_shader(CARD8 op,
                                     struct blendinfo *op_info,
                                     PictFormatShort *psaved_source_format);
 
-void
-
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
-                                  struct shader_key *key,
-                                  glamor_composite_shader *shader,
-                                  struct blendinfo *op_info);
+void glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+                                       struct shader_key *key,
+                                       glamor_composite_shader *shader,
+                                       struct blendinfo *op_info);
 
 void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
 void glamor_emit_composite_vert(ScreenPtr screen,
@@ -792,14 +776,11 @@ PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen,
                                                    PictFormatShort format);
 
 /* glamor_triangles.c */
-void
-
-
-glamor_triangles(CARD8 op,
-                 PicturePtr pSrc,
-                 PicturePtr pDst,
-                 PictFormatPtr maskFormat,
-                 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
+void glamor_triangles(CARD8 op,
+                      PicturePtr pSrc,
+                      PicturePtr pDst,
+                      PictFormatPtr maskFormat,
+                      INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
 
 /* glamor_pixmap.c */
 
@@ -839,86 +820,72 @@ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
  * the fbo has valid texture and attach to a valid fb.
  * If the fbo already has a valid glfbo then do nothing.
  */
-Bool
- glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
+Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
  * uploading feature. The pixmap must be a software pixmap.
  * This function will change current FBO and current shaders.
  */
-enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
-                                                          pixmap);
-
-Bool
-
-glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
-                                    int h, int stride, void *bits, int pbo);
-
-PixmapPtr
-
-glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
-                      int w, int h, glamor_access_t access);
-void
-
-glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
-                      int w, int h, glamor_access_t access);
-
-glamor_pixmap_clipped_regions
-    *glamor_compute_clipped_regions(glamor_pixmap_private *priv,
-                                    RegionPtr region, int *clipped_nbox,
-                                    int repeat_type, int reverse,
-                                    int upsidedown);
-
-glamor_pixmap_clipped_regions
-    *glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
-                                        RegionPtr region, int *n_region,
-                                        int inner_block_w, int inner_block_h,
-                                        int reverse, int upsidedown);
-
-glamor_pixmap_clipped_regions
-    *glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
-                                              struct pixman_transform
-                                              *transform, RegionPtr region,
-                                              int *n_region, int dx, int dy,
-                                              int repeat_type, int reverse,
-                                              int upsidedown);
-
-Bool
-
-glamor_composite_largepixmap_region(CARD8 op,
-                                    PicturePtr source,
-                                    PicturePtr mask,
-                                    PicturePtr dest,
-                                    glamor_pixmap_private *source_pixmap_priv,
-                                    glamor_pixmap_private *mask_pixmap_priv,
-                                    glamor_pixmap_private *dest_pixmap_priv,
-                                    RegionPtr region, Bool force_clip,
-                                    INT16 x_source,
-                                    INT16 y_source,
-                                    INT16 x_mask,
-                                    INT16 y_mask,
-                                    INT16 x_dest, INT16 y_dest,
-                                    CARD16 width, CARD16 height);
-
-Bool
-
-glamor_get_transform_block_size(struct pixman_transform *transform,
-                                int block_w, int block_h,
-                                int *transformed_block_w,
-                                int *transformed_block_h);
-
-void
-
-glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
-                                     struct pixman_transform *transform);
+enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr pixmap);
+
+Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
+                                         int h, int stride, void *bits,
+                                         int pbo);
+
+PixmapPtr glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
+                                int w, int h, glamor_access_t access);
+void glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
+                           int w, int h, glamor_access_t access);
+
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions(glamor_pixmap_private *priv,
+                               RegionPtr region, int *clipped_nbox,
+                               int repeat_type, int reverse,
+                               int upsidedown);
+
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+                                   RegionPtr region, int *n_region,
+                                   int inner_block_w, int inner_block_h,
+                                   int reverse, int upsidedown);
+
+glamor_pixmap_clipped_regions *
+glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+                                         struct pixman_transform *transform,
+                                         RegionPtr region,
+                                         int *n_region, int dx, int dy,
+                                         int repeat_type, int reverse,
+                                         int upsidedown);
+
+Bool glamor_composite_largepixmap_region(CARD8 op,
+                                         PicturePtr source,
+                                         PicturePtr mask,
+                                         PicturePtr dest,
+                                         glamor_pixmap_private *source_pixmap_priv,
+                                         glamor_pixmap_private *mask_pixmap_priv,
+                                         glamor_pixmap_private *dest_pixmap_priv,
+                                         RegionPtr region, Bool force_clip,
+                                         INT16 x_source,
+                                         INT16 y_source,
+                                         INT16 x_mask,
+                                         INT16 y_mask,
+                                         INT16 x_dest, INT16 y_dest,
+                                         CARD16 width, CARD16 height);
+
+Bool glamor_get_transform_block_size(struct pixman_transform *transform,
+                                     int block_w, int block_h,
+                                     int *transformed_block_w,
+                                     int *transformed_block_h);
+
+void glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
+                                          struct pixman_transform *transform);
 
 /**
  * Upload a picture to gl texture. Similar to the
  * glamor_upload_pixmap_to_texture. Used in rendering.
  **/
-enum glamor_pixmap_status
- glamor_upload_picture_to_texture(PicturePtr picture);
+enum glamor_pixmap_status glamor_upload_picture_to_texture(PicturePtr picture);
 
 /**
  * Upload bits to a pixmap's texture. This function will
@@ -939,77 +906,54 @@ int glamor_create_picture(PicturePtr picture);
 
 void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
 
-Bool
- glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
+Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
 
 void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access);
 
 void glamor_destroy_picture(PicturePtr picture);
 
 /* fixup a fbo to the exact size as the pixmap. */
-Bool
-
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
-
-void
-
-glamor_picture_format_fixup(PicturePtr picture,
-                            glamor_pixmap_private *pixmap_priv);
-
-void
-
-glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
-                 unsigned int format, unsigned long planeMask, char *d);
-
-void
-
-glamor_add_traps(PicturePtr pPicture,
-                 INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
-
-RegionPtr
-
-glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-                  int srcx, int srcy, int w, int h, int dstx, int dsty,
-                  unsigned long bitPlane);
-
-void
-
-glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                       int x, int y, unsigned int nglyph,
-                       CharInfoPtr *ppci, pointer pglyphBase);
-
-void
+Bool glamor_fixup_pixmap_priv(ScreenPtr screen,
+                              glamor_pixmap_private *pixmap_priv);
 
-glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                      int x, int y, unsigned int nglyph,
-                      CharInfoPtr *ppci, pointer pglyphBase);
+void glamor_picture_format_fixup(PicturePtr picture,
+                                 glamor_pixmap_private *pixmap_priv);
 
-void
+void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+                      unsigned int format, unsigned long planeMask, char *d);
 
-glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
-                   DrawablePtr pDrawable, int w, int h, int x, int y);
+void glamor_add_traps(PicturePtr pPicture,
+                      INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
 
-void
+RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+                            int srcx, int srcy, int w, int h,
+                            int dstx, int dsty,
+                            unsigned long bitPlane);
 
-glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-                  DDXPointPtr ppt);
+void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                            int x, int y, unsigned int nglyph,
+                            CharInfoPtr *ppci, pointer pglyphBase);
 
-void
+void glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                           int x, int y, unsigned int nglyph,
+                           CharInfoPtr *ppci, pointer pglyphBase);
 
-glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-                    xSegment *pSeg);
+void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
+                        DrawablePtr pDrawable, int w, int h, int x, int y);
 
-void
+void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+                       DDXPointPtr ppt);
 
-glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-                 DDXPointPtr ppt);
+void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+                         xSegment *pSeg);
 
-void
+void glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+                      DDXPointPtr ppt);
 
-glamor_composite_rectangles(CARD8 op,
-                            PicturePtr dst,
-                            xRenderColor *color,
-                            int num_rects, xRectangle *rects);
+void glamor_composite_rectangles(CARD8 op,
+                                 PicturePtr dst,
+                                 xRenderColor *color,
+                                 int num_rects, xRectangle *rects);
 
 /* glamor_xv */
 typedef struct {
commit 7f6e865359c2d055db4eb7d82b4779b3d7c5d264
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 27 11:46:30 2013 -0800

    glamor: Fix some indent damage of putting a ' ' after the '*' for pointers.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 216fab4..37136af 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -206,7 +206,7 @@ Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
     glamor_screen_private
-        * glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+        *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
     if (glamor_priv->dri3_enabled)
         glamor_egl_destroy_textured_pixmap(pixmap);
     else
@@ -473,7 +473,7 @@ glamor_release_screen_priv(ScreenPtr screen)
 }
 
 _X_EXPORT void
-glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private * priv)
+glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
 {
     glamor_pixmap_private *old_priv;
     glamor_pixmap_fbo *fbo;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 1507565..4e47523 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -366,7 +366,7 @@ extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
                                            PicturePtr src, PicturePtr dst,
                                            PictFormatPtr mask_format,
                                            INT16 x_src, INT16 y_src,
-                                           int ntrap, xTrapezoid * traps);
+                                           int ntrap, xTrapezoid *traps);
 
 extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
                                        PicturePtr src,
@@ -374,14 +374,14 @@ extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
                                        PictFormatPtr mask_format,
                                        INT16 x_src,
                                        INT16 y_src, int nlist,
-                                       GlyphListPtr list, GlyphPtr * glyphs);
+                                       GlyphListPtr list, GlyphPtr *glyphs);
 
 extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
                                           PicturePtr pSrc,
                                           PicturePtr pDst,
                                           PictFormatPtr maskFormat,
                                           INT16 xSrc, INT16 ySrc,
-                                          int ntris, xTriangle * tris);
+                                          int ntris, xTriangle *tris);
 
 extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 
@@ -395,7 +395,7 @@ extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
 
 extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op,
                                                 PicturePtr pDst,
-                                                xRenderColor * color,
+                                                xRenderColor *color,
                                                 int nRect, xRectangle *rects);
 
 extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
@@ -405,7 +405,7 @@ extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
 extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
                                           INT16 x_off,
                                           INT16 y_off, int ntrap,
-                                          xTrap * traps);
+                                          xTrap *traps);
 
 extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst,
                                            GCPtr pGC, int srcx, int srcy, int w,
@@ -416,13 +416,13 @@ extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst,
 extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
                                                 GCPtr pGC, int x, int y,
                                                 unsigned int nglyph,
-                                                CharInfoPtr * ppci,
+                                                CharInfoPtr *ppci,
                                                 pointer pglyphBase);
 
 extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                                                int x, int y,
                                                unsigned int nglyph,
-                                               CharInfoPtr * ppci,
+                                               CharInfoPtr *ppci,
                                                pointer pglyphBase);
 
 extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
@@ -433,7 +433,7 @@ extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
                                            int mode, int npt, DDXPointPtr ppt);
 
 extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
-                                             int nseg, xSegment * pSeg);
+                                             int nseg, xSegment *pSeg);
 
 extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC,
                                           int mode, int npt, DDXPointPtr ppt);
diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c
index 7a918b7..655d87e 100644
--- a/glamor/glamor_addtraps.c
+++ b/glamor/glamor_addtraps.c
@@ -31,7 +31,7 @@
 static Bool
 _glamor_add_traps(PicturePtr pPicture,
                   INT16 x_off,
-                  INT16 y_off, int ntrap, xTrap * traps, Bool fallback)
+                  INT16 y_off, int ntrap, xTrap *traps, Bool fallback)
 {
     if (!fallback
         && (!pPicture->pDrawable
@@ -48,14 +48,14 @@ _glamor_add_traps(PicturePtr pPicture,
 
 void
 glamor_add_traps(PicturePtr pPicture,
-                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
+                 INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
 {
     _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
 }
 
 Bool
 glamor_add_traps_nf(PicturePtr pPicture,
-                    INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
+                    INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
 {
     return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 76d5ddf..d94e530 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -71,7 +71,7 @@ cache_hbucket(int size)
 }
 
 static glamor_pixmap_fbo *
-glamor_pixmap_fbo_cache_get(glamor_screen_private * glamor_priv,
+glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
                             int w, int h, GLenum format, int flag)
 {
     struct xorg_list *cache;
@@ -127,7 +127,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private * glamor_priv,
 }
 
 void
-glamor_purge_fbo(glamor_pixmap_fbo * fbo)
+glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
     glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
 
@@ -143,7 +143,7 @@ glamor_purge_fbo(glamor_pixmap_fbo * fbo)
 }
 
 static void
-glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo * fbo)
+glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
     struct xorg_list *cache;
     int n_format;
@@ -176,7 +176,7 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo * fbo)
 }
 
 static void
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo * fbo)
+glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
     glamor_gl_dispatch *dispatch;
     int status;
@@ -225,7 +225,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo * fbo)
 }
 
 glamor_pixmap_fbo *
-glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv,
+glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
                            int w, int h, GLenum format, GLint tex, int flag)
 {
     glamor_pixmap_fbo *fbo;
@@ -259,7 +259,7 @@ glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv,
 }
 
 void
-glamor_fbo_expire(glamor_screen_private * glamor_priv)
+glamor_fbo_expire(glamor_screen_private *glamor_priv)
 {
     struct xorg_list *cache;
     glamor_pixmap_fbo *fbo_entry, *tmp;
@@ -323,7 +323,7 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 }
 
 void
-glamor_destroy_fbo(glamor_pixmap_fbo * fbo)
+glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 {
     xorg_list_del(&fbo->list);
     glamor_pixmap_fbo_cache_put(fbo);
@@ -331,7 +331,7 @@ glamor_destroy_fbo(glamor_pixmap_fbo * fbo)
 }
 
 static int
-_glamor_create_tex(glamor_screen_private * glamor_priv,
+_glamor_create_tex(glamor_screen_private *glamor_priv,
                    int w, int h, GLenum format)
 {
     glamor_gl_dispatch *dispatch;
@@ -361,7 +361,7 @@ _glamor_create_tex(glamor_screen_private * glamor_priv,
 }
 
 glamor_pixmap_fbo *
-glamor_create_fbo(glamor_screen_private * glamor_priv,
+glamor_create_fbo(glamor_screen_private *glamor_priv,
                   int w, int h, GLenum format, int flag)
 {
     glamor_pixmap_fbo *fbo;
@@ -394,10 +394,10 @@ glamor_create_fbo(glamor_screen_private * glamor_priv,
 }
 
 static glamor_pixmap_fbo *
-_glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+_glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                          int w, int h, GLenum format, int flag,
                          int block_w, int block_h,
-                         glamor_pixmap_private * pixmap_priv, int has_fbo)
+                         glamor_pixmap_private *pixmap_priv, int has_fbo)
 {
     int block_wcnt;
     int block_hcnt;
@@ -468,10 +468,10 @@ _glamor_create_fbo_array(glamor_screen_private * glamor_priv,
 /* Create a fbo array to cover the w*h region, by using block_w*block_h
  * block.*/
 glamor_pixmap_fbo *
-glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                         int w, int h, GLenum format, int flag,
                         int block_w, int block_h,
-                        glamor_pixmap_private * pixmap_priv)
+                        glamor_pixmap_private *pixmap_priv)
 {
     pixmap_priv->large.block_w = block_w;
     pixmap_priv->large.block_h = block_h;
@@ -480,7 +480,7 @@ glamor_create_fbo_array(glamor_screen_private * glamor_priv,
 }
 
 glamor_pixmap_fbo *
-glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv)
+glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
 {
     glamor_pixmap_fbo *fbo;
 
@@ -497,7 +497,7 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv)
 
 /* The pixmap must not be attached to another fbo. */
 void
-glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo)
+glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 {
     glamor_pixmap_private *pixmap_priv;
 
@@ -528,7 +528,7 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo)
 }
 
 void
-glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv)
+glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
 {
     glamor_pixmap_fbo *fbo;
 
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index ac97157..9908c06 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -31,7 +31,7 @@
 static Bool
 _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                         int x, int y, unsigned int nglyph,
-                        CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+                        CharInfoPtr *ppci, pointer pglyphBase, Bool fallback)
 {
     if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
         && glamor_ddx_fallback_check_gc(pGC))
@@ -44,7 +44,7 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 void
 glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                        int x, int y, unsigned int nglyph,
-                       CharInfoPtr * ppci, pointer pglyphBase)
+                       CharInfoPtr *ppci, pointer pglyphBase)
 {
     _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
                             TRUE);
@@ -53,7 +53,7 @@ glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 Bool
 glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                           int x, int y, unsigned int nglyph,
-                          CharInfoPtr * ppci, pointer pglyphBase)
+                          CharInfoPtr *ppci, pointer pglyphBase)
 {
     return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
                                    pglyphBase, FALSE);
@@ -62,7 +62,7 @@ glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
 static Bool
 _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                        int x, int y, unsigned int nglyph,
-                       CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+                       CharInfoPtr *ppci, pointer pglyphBase, Bool fallback)
 {
     if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
         && glamor_ddx_fallback_check_gc(pGC))
@@ -75,7 +75,7 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 void
 glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                       int x, int y, unsigned int nglyph,
-                      CharInfoPtr * ppci, pointer pglyphBase)
+                      CharInfoPtr *ppci, pointer pglyphBase)
 {
     _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
                            TRUE);
@@ -84,7 +84,7 @@ glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 Bool
 glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
                          int x, int y, unsigned int nglyph,
-                         CharInfoPtr * ppci, pointer pglyphBase)
+                         CharInfoPtr *ppci, pointer pglyphBase)
 {
     return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
                                   pglyphBase, FALSE);
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index ed7cfc2..1c0f9f5 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -387,7 +387,7 @@ glamor_glyphs_init(ScreenPtr pScreen)
  */
 static void
 glamor_glyph_cache_upload_glyph(ScreenPtr screen,
-                                glamor_glyph_cache_t * cache,
+                                glamor_glyph_cache_t *cache,
                                 GlyphPtr glyph, int x, int y)
 {
     PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
@@ -465,7 +465,7 @@ glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 /* Cut and paste from render/glyph.c - probably should export it instead */
 static void
 glamor_glyph_extents(int nlist,
-                     GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
+                     GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents)
 {
     int x1, x2, y1, y2;
     int x, y, n;
@@ -610,12 +610,12 @@ struct glamor_glyph_list {
 
 static Bool
 glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
-                     GlyphPtr * cur_glyphs,
+                     GlyphPtr *cur_glyphs,
                      GlyphPtr ** head_glyphs,
                      GlyphListPtr cur_list,
                      int cur_pos, int cur_x, int cur_y,
                      int x1, int y1, int x2, int y2,
-                     GlyphListPtr * head_list,
+                     GlyphListPtr *head_list,
                      int *head_pos,
                      int *head_x,
                      int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents)
@@ -695,7 +695,7 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
  **/
 
 static int
-glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
+glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs,
                         PictFormatShort mask_format,
                         ScreenPtr screen, Bool check_fake_overlap,
                         struct glamor_glyph_list *fixed_list, int fixed_size)
@@ -1053,7 +1053,7 @@ glamor_glyph_size_to_mask(int size)
 }
 
 static PicturePtr
-glamor_glyph_cache(glamor_screen_private * glamor, GlyphPtr glyph, int *out_x,
+glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
                    int *out_y)
 {
     ScreenPtr screen = glamor->screen;
@@ -1219,8 +1219,8 @@ glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg)
 }
 
 static glamor_glyph_cache_result_t
-glamor_buffer_glyph(glamor_screen_private * glamor_priv,
-                    glamor_glyph_buffer_t * buffer,
+glamor_buffer_glyph(glamor_screen_private *glamor_priv,
+                    glamor_glyph_buffer_t *buffer,
                     PictFormatShort format,
                     GlyphPtr glyph, struct glamor_glyph *priv,
                     int x_glyph, int y_glyph,
@@ -1318,7 +1318,7 @@ glamor_buffer_glyph(glamor_screen_private * glamor_priv,
 }
 
 static void
-glamor_buffer_glyph_clip(glamor_screen_private * glamor_priv,
+glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
                          BoxPtr rects,
                          int nrect, PictFormatShort format,
                          GlyphPtr glyph, struct glamor_glyph *priv,
@@ -1373,7 +1373,7 @@ glamor_glyphs_via_mask(CARD8 op,
                        PictFormatPtr mask_format,
                        INT16 x_src,
                        INT16 y_src,
-                       int nlist, GlyphListPtr list, GlyphPtr * glyphs,
+                       int nlist, GlyphListPtr list, GlyphPtr *glyphs,
                        Bool use_mask_cache)
 {
     PixmapPtr mask_pixmap = 0;
@@ -1591,7 +1591,7 @@ glamor_glyphs_to_dst(CARD8 op,
                      PicturePtr dst,
                      INT16 x_src,
                      INT16 y_src,
-                     int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+                     int nlist, GlyphListPtr list, GlyphPtr *glyphs)
 {
     ScreenPtr screen = dst->pDrawable->pScreen;
     int x = 0, y = 0;
@@ -1653,7 +1653,7 @@ glamor_glyphs_to_dst(CARD8 op,
 
 #define MAX_FIXED_SIZE
 static void
-glamor_glyphs_reset_buffer(glamor_glyph_buffer_t * buffer)
+glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer)
 {
     buffer->count = 0;
     buffer->source = NULL;
@@ -1666,7 +1666,7 @@ _glamor_glyphs(CARD8 op,
                PictFormatPtr mask_format,
                INT16 x_src,
                INT16 y_src, int nlist, GlyphListPtr list,
-               GlyphPtr * glyphs, Bool fallback)
+               GlyphPtr *glyphs, Bool fallback)
 {
     PictFormatShort format;
     int fixed_size, fixed_cnt = 0;
@@ -1784,7 +1784,7 @@ glamor_glyphs(CARD8 op,
               PicturePtr dst,
               PictFormatPtr mask_format,
               INT16 x_src,
-              INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+              INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
 {
     _glamor_glyphs(op, src, dst, mask_format, x_src,
                    y_src, nlist, list, glyphs, TRUE);
@@ -1796,7 +1796,7 @@ glamor_glyphs_nf(CARD8 op,
                  PicturePtr dst,
                  PictFormatPtr mask_format,
                  INT16 x_src,
-                 INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+                 INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
 {
     return _glamor_glyphs(op, src, dst, mask_format, x_src,
                           y_src, nlist, list, glyphs, FALSE);
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index e7c872d..df2ccb8 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -765,7 +765,7 @@ glamor_fini_gradient_shader(ScreenPtr screen)
 }
 
 static void
-_glamor_gradient_convert_trans_matrix(PictTransform * from, float to[3][3],
+_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
                                       int width, int height, int normalize)
 {
     /*
@@ -825,9 +825,9 @@ _glamor_gradient_convert_trans_matrix(PictTransform * from, float to[3][3],
 
 static int
 _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
-                                        glamor_screen_private * glamor_priv,
+                                        glamor_screen_private *glamor_priv,
                                         PicturePtr dst_picture,
-                                        GLfloat * xscale, GLfloat * yscale,
+                                        GLfloat *xscale, GLfloat *yscale,
                                         int x_source, int y_source,
                                         float vertices[8],
                                         float tex_vertices[8],
@@ -909,8 +909,8 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 }
 
 static int
-_glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
-                           GLfloat * stop_colors, GLfloat * n_stops)
+_glamor_gradient_set_stops(PicturePtr src_picture, PictGradient *pgradient,
+                           GLfloat *stop_colors, GLfloat *n_stops)
 {
     int i;
     int count = 1;
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index b9c140b..b8c0640 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -144,7 +144,7 @@ __glamor_compute_clipped_regions(int block_w,
  */
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv,
+glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
                                    RegionPtr region,
                                    int *n_region,
                                    int inner_block_w, int inner_block_h,
@@ -325,7 +325,7 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
  *
  */
 static glamor_pixmap_clipped_regions *
-_glamor_compute_clipped_regions(glamor_pixmap_private * pixmap_priv,
+_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
                                 RegionPtr region, int *n_region,
                                 int repeat_type, int is_transform,
                                 int reverse, int upsidedown)
@@ -659,7 +659,7 @@ _glamor_compute_clipped_regions(glamor_pixmap_private * pixmap_priv,
 }
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private * priv, RegionPtr region,
+glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
                                int *n_region, int repeat_type,
                                int reverse, int upsidedown)
 {
@@ -671,8 +671,8 @@ glamor_compute_clipped_regions(glamor_pixmap_private * priv, RegionPtr region,
  * by default. Or just use region32 for repeat cases?
  **/
 glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv,
-                                         struct pixman_transform * transform,
+glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+                                         struct pixman_transform *transform,
                                          RegionPtr region, int *n_region,
                                          int dx, int dy, int repeat_type,
                                          int reverse, int upsidedown)
@@ -736,9 +736,9 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv,
  * if the clipped result cross the region boundary.
  */
 static void
-glamor_merge_clipped_regions(glamor_pixmap_private * pixmap_priv,
+glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
                              int repeat_type,
-                             glamor_pixmap_clipped_regions * clipped_regions,
+                             glamor_pixmap_clipped_regions *clipped_regions,
                              int *n_regions, int *need_clean_fbo)
 {
     BoxPtr temp_extent;
@@ -954,7 +954,7 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
 }
 
 static void
-_glamor_process_transformed_clipped_region(glamor_pixmap_private * priv,
+_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
                                            int repeat_type,
                                            glamor_pixmap_clipped_regions *
                                            clipped_regions, int *n_regions,
@@ -1004,9 +1004,9 @@ glamor_composite_largepixmap_region(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
                                     PicturePtr dest,
-                                    glamor_pixmap_private * source_pixmap_priv,
-                                    glamor_pixmap_private * mask_pixmap_priv,
-                                    glamor_pixmap_private * dest_pixmap_priv,
+                                    glamor_pixmap_private *source_pixmap_priv,
+                                    glamor_pixmap_private *mask_pixmap_priv,
+                                    glamor_pixmap_private *dest_pixmap_priv,
                                     RegionPtr region, Bool force_clip,
                                     INT16 x_source,
                                     INT16 y_source,
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index f2afbc3..f51a7e4 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -126,7 +126,7 @@ glamor_destroy_picture(PicturePtr picture)
 
 void
 glamor_picture_format_fixup(PicturePtr picture,
-                            glamor_pixmap_private * pixmap_priv)
+                            glamor_pixmap_private *pixmap_priv)
 {
     pixmap_priv->base.picture = picture;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 69e581c..f7de59c 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -63,7 +63,7 @@ glamor_pixmap_fini(ScreenPtr screen)
 }
 
 void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0,
+glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
                                   int width, int height)
 {
     glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
@@ -81,7 +81,7 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0,
 }
 
 void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
+glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
     int w, h;
 
@@ -90,7 +90,7 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 }
 
 int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
 {
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         return -1;
@@ -1226,7 +1226,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 /* fixup a fbo to the exact size as the pixmap. */
 /* XXX LARGE pixmap? */
 Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv)
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 {
     glamor_pixmap_fbo *old_fbo;
     glamor_pixmap_fbo *new_fbo = NULL;
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
index 99c4de9..1484d80 100644
--- a/glamor/glamor_polyops.c
+++ b/glamor/glamor_polyops.c
@@ -57,7 +57,7 @@ glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 static Bool
 _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-                     xSegment * pSeg, Bool fallback)
+                     xSegment *pSeg, Bool fallback)
 {
     if (!fallback && glamor_ddx_fallback_check_gc(pGC)
         && glamor_ddx_fallback_check_pixmap(pDrawable))
@@ -69,14 +69,14 @@ _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 }
 
 void
-glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
+glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg)
 {
     _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE);
 }
 
 Bool
 glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-                       xSegment * pSeg)
+                       xSegment *pSeg)
 {
     return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 39226a8..96fb404 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -511,7 +511,7 @@ glamor_get_screen_private(ScreenPtr screen)
 }
 
 static inline void
-glamor_set_screen_private(ScreenPtr screen, glamor_screen_private * priv)
+glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
 {
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv);
 }
@@ -530,7 +530,7 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
     return priv;
 }
 
-void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private * priv);
+void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
@@ -552,23 +552,23 @@ Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 
 glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private *
                                             pixmap_priv);
-void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo);
+void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
 glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
                                               glamor_priv, int w, int h,
                                               GLenum format, GLint tex,
                                               int flag);
-glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private * glamor_priv, int w,
+glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
                                      int h, GLenum format, int flag);
-void glamor_destroy_fbo(glamor_pixmap_fbo * fbo);
-void glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv);
-void glamor_purge_fbo(glamor_pixmap_fbo * fbo);
+void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
+void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
+void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
 Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
-void glamor_fbo_expire(glamor_screen_private * glamor_priv);
+void glamor_fbo_expire(glamor_screen_private *glamor_priv);
 
-glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
                                            int w, int h, GLenum format,
                                            int flag, int block_w, int block_h,
                                            glamor_pixmap_private *);
@@ -603,20 +603,20 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
                     unsigned char alu, unsigned long planemask,
                     unsigned long fg_pixel, unsigned long bg_pixel,
                     int stipple_x, int stipple_y);
-GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
+GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type,
                                const char *source);
-void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog);
+void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
-                                    unsigned long fg_pixel, GLfloat * color);
+                                    unsigned long fg_pixel, GLfloat *color);
 
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv);
+int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
 void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
  * */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv);
+void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
 
 glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
                                                   int y, int w, int h,
@@ -669,7 +669,7 @@ void glamor_glyphs(CARD8 op,
                    PicturePtr pDst,
                    PictFormatPtr maskFormat,
                    INT16 xSrc,
-                   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
+                   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
 
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
@@ -704,9 +704,9 @@ glamor_composite_clipped_region(CARD8 op,
                                 PicturePtr source,
                                 PicturePtr mask,
                                 PicturePtr dest,
-                                glamor_pixmap_private * soruce_pixmap_priv,
-                                glamor_pixmap_private * mask_pixmap_priv,
-                                glamor_pixmap_private * dest_pixmap_priv,
+                                glamor_pixmap_private *soruce_pixmap_priv,
+                                glamor_pixmap_private *mask_pixmap_priv,
+                                glamor_pixmap_private *dest_pixmap_priv,
                                 RegionPtr region,
                                 int x_source,
                                 int y_source,
@@ -727,10 +727,10 @@ void glamor_fini_composite_shaders(ScreenPtr screen);
 void glamor_composite_glyph_rects(CARD8 op,
                                   PicturePtr src, PicturePtr mask,
                                   PicturePtr dst, int nrect,
-                                  glamor_composite_rect_t * rects);
+                                  glamor_composite_rect_t *rects);
 void glamor_composite_rects(CARD8 op,
                             PicturePtr pDst,
-                            xRenderColor * color, int nRect, xRectangle *rects);
+                            xRenderColor *color, int nRect, xRectangle *rects);
 void glamor_init_trapezoid_shader(ScreenPtr screen);
 void glamor_fini_trapezoid_shader(ScreenPtr screen);
 PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
@@ -742,19 +742,19 @@ Bool glamor_composite_choose_shader(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
                                     PicturePtr dest,
-                                    glamor_pixmap_private * source_pixmap_priv,
-                                    glamor_pixmap_private * mask_pixmap_priv,
-                                    glamor_pixmap_private * dest_pixmap_priv,
+                                    glamor_pixmap_private *source_pixmap_priv,
+                                    glamor_pixmap_private *mask_pixmap_priv,
+                                    glamor_pixmap_private *dest_pixmap_priv,
                                     struct shader_key *s_key,
                                     glamor_composite_shader ** shader,
                                     struct blendinfo *op_info,
-                                    PictFormatShort * psaved_source_format);
+                                    PictFormatShort *psaved_source_format);
 
 void
 
-glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv,
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
                                   struct shader_key *key,
-                                  glamor_composite_shader * shader,
+                                  glamor_composite_shader *shader,
                                   struct blendinfo *op_info);
 
 void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
@@ -767,7 +767,7 @@ void glamor_emit_composite_vert(ScreenPtr screen,
 void glamor_trapezoids(CARD8 op,
                        PicturePtr src, PicturePtr dst,
                        PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-                       int ntrap, xTrapezoid * traps);
+                       int ntrap, xTrapezoid *traps);
 
 /* glamor_tile.c */
 Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
@@ -865,19 +865,19 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
                       int w, int h, glamor_access_t access);
 
 glamor_pixmap_clipped_regions
-    *glamor_compute_clipped_regions(glamor_pixmap_private * priv,
+    *glamor_compute_clipped_regions(glamor_pixmap_private *priv,
                                     RegionPtr region, int *clipped_nbox,
                                     int repeat_type, int reverse,
                                     int upsidedown);
 
 glamor_pixmap_clipped_regions
-    *glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv,
+    *glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
                                         RegionPtr region, int *n_region,
                                         int inner_block_w, int inner_block_h,
                                         int reverse, int upsidedown);
 
 glamor_pixmap_clipped_regions
-    *glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv,
+    *glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
                                               struct pixman_transform
                                               *transform, RegionPtr region,
                                               int *n_region, int dx, int dy,
@@ -890,9 +890,9 @@ glamor_composite_largepixmap_region(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
                                     PicturePtr dest,
-                                    glamor_pixmap_private * source_pixmap_priv,
-                                    glamor_pixmap_private * mask_pixmap_priv,
-                                    glamor_pixmap_private * dest_pixmap_priv,
+                                    glamor_pixmap_private *source_pixmap_priv,
+                                    glamor_pixmap_private *mask_pixmap_priv,
+                                    glamor_pixmap_private *dest_pixmap_priv,
                                     RegionPtr region, Bool force_clip,
                                     INT16 x_source,
                                     INT16 y_source,
@@ -949,12 +949,12 @@ void glamor_destroy_picture(PicturePtr picture);
 /* fixup a fbo to the exact size as the pixmap. */
 Bool
 
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv);
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
 
 void
 
 glamor_picture_format_fixup(PicturePtr picture,
-                            glamor_pixmap_private * pixmap_priv);
+                            glamor_pixmap_private *pixmap_priv);
 
 void
 
@@ -964,7 +964,7 @@ glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
 void
 
 glamor_add_traps(PicturePtr pPicture,
-                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps);
+                 INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
 
 RegionPtr
 
@@ -976,13 +976,13 @@ void
 
 glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                        int x, int y, unsigned int nglyph,
-                       CharInfoPtr * ppci, pointer pglyphBase);
+                       CharInfoPtr *ppci, pointer pglyphBase);
 
 void
 
 glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                       int x, int y, unsigned int nglyph,
-                      CharInfoPtr * ppci, pointer pglyphBase);
+                      CharInfoPtr *ppci, pointer pglyphBase);
 
 void
 
@@ -997,7 +997,7 @@ glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 void
 
 glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-                    xSegment * pSeg);
+                    xSegment *pSeg);
 
 void
 
@@ -1008,7 +1008,7 @@ void
 
 glamor_composite_rectangles(CARD8 op,
                             PicturePtr dst,
-                            xRenderColor * color,
+                            xRenderColor *color,
                             int num_rects, xRectangle *rects);
 
 /* glamor_xv */
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 10cb24a..52bcf43 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -62,7 +62,7 @@ static struct blendinfo composite_op_info[] = {
 
 #define RepeatFix			10
 static GLuint
-glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
+glamor_create_composite_fs(glamor_gl_dispatch *dispatch,
                            struct shader_key *key)
 {
     const char *repeat_define =
@@ -273,7 +273,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 }
 
 static GLuint
-glamor_create_composite_vs(glamor_gl_dispatch * dispatch,
+glamor_create_composite_vs(glamor_gl_dispatch *dispatch,
                            struct shader_key *key)
 {
     const char *main_opening =
@@ -312,7 +312,7 @@ glamor_create_composite_vs(glamor_gl_dispatch * dispatch,
 
 static void
 glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
-                               glamor_composite_shader * shader)
+                               glamor_composite_shader *shader)
 {
     GLuint vs, fs, prog;
     GLint source_sampler_uniform_location, mask_sampler_uniform_location;
@@ -530,9 +530,9 @@ glamor_set_composite_op(ScreenPtr screen,
 }
 
 static void
-glamor_set_composite_texture(glamor_screen_private * glamor_priv, int unit,
+glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
                              PicturePtr picture,
-                             glamor_pixmap_private * pixmap_priv,
+                             glamor_pixmap_private *pixmap_priv,
                              GLuint wh_location, GLuint repeat_location)
 {
     glamor_gl_dispatch *dispatch;
@@ -624,7 +624,7 @@ glamor_set_composite_texture(glamor_screen_private * glamor_priv, int unit,
 }
 
 static void
-glamor_set_composite_solid(glamor_gl_dispatch * dispatch, float *color,
+glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color,
                            GLint uniform_location)
 {
     dispatch->glUniform4fv(uniform_location, 1, color);
@@ -924,7 +924,7 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
 }
 
 static void
-glamor_set_normalize_tcoords_generic(glamor_pixmap_private * priv,
+glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
                                      int repeat_type,
                                      float *matrix,
                                      float xscale, float yscale,
@@ -961,13 +961,13 @@ glamor_composite_choose_shader(CARD8 op,
                                PicturePtr source,
                                PicturePtr mask,
                                PicturePtr dest,
-                               glamor_pixmap_private * source_pixmap_priv,
-                               glamor_pixmap_private * mask_pixmap_priv,
-                               glamor_pixmap_private * dest_pixmap_priv,
+                               glamor_pixmap_private *source_pixmap_priv,
+                               glamor_pixmap_private *mask_pixmap_priv,
+                               glamor_pixmap_private *dest_pixmap_priv,
                                struct shader_key *s_key,
                                glamor_composite_shader ** shader,
                                struct blendinfo *op_info,
-                               PictFormatShort * psaved_source_format)
+                               PictFormatShort *psaved_source_format)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
     PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
@@ -1224,9 +1224,9 @@ glamor_composite_choose_shader(CARD8 op,
 }
 
 void
-glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv,
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
                                   struct shader_key *key,
-                                  glamor_composite_shader * shader,
+                                  glamor_composite_shader *shader,
                                   struct blendinfo *op_info)
 {
     glamor_gl_dispatch *dispatch;
@@ -1279,10 +1279,10 @@ glamor_composite_with_shader(CARD8 op,
                              PicturePtr source,
                              PicturePtr mask,
                              PicturePtr dest,
-                             glamor_pixmap_private * source_pixmap_priv,
-                             glamor_pixmap_private * mask_pixmap_priv,
-                             glamor_pixmap_private * dest_pixmap_priv,
-                             int nrect, glamor_composite_rect_t * rects,
+                             glamor_pixmap_private *source_pixmap_priv,
+                             glamor_pixmap_private *mask_pixmap_priv,
+                             glamor_pixmap_private *dest_pixmap_priv,
+                             int nrect, glamor_composite_rect_t *rects,
                              Bool two_pass_ca)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
@@ -1540,9 +1540,9 @@ glamor_composite_clipped_region(CARD8 op,
                                 PicturePtr source,
                                 PicturePtr mask,
                                 PicturePtr dest,
-                                glamor_pixmap_private * source_pixmap_priv,
-                                glamor_pixmap_private * mask_pixmap_priv,
-                                glamor_pixmap_private * dest_pixmap_priv,
+                                glamor_pixmap_private *source_pixmap_priv,
+                                glamor_pixmap_private *mask_pixmap_priv,
+                                glamor_pixmap_private *dest_pixmap_priv,
                                 RegionPtr region,
                                 int x_source,
                                 int y_source,
@@ -1981,7 +1981,7 @@ glamor_composite_nf(CARD8 op,
 
 static void
 glamor_get_src_rect_extent(int nrect,
-                           glamor_composite_rect_t * rects, BoxPtr extent)
+                           glamor_composite_rect_t *rects, BoxPtr extent)
 {
     extent->x1 = MAXSHORT;
     extent->y1 = MAXSHORT;
@@ -2003,7 +2003,7 @@ glamor_get_src_rect_extent(int nrect,
 
 static void
 glamor_composite_src_rect_translate(int nrect,
-                                    glamor_composite_rect_t * rects,
+                                    glamor_composite_rect_t *rects,
                                     int x, int y)
 {
     while (nrect--) {
@@ -2016,7 +2016,7 @@ glamor_composite_src_rect_translate(int nrect,
 void
 glamor_composite_glyph_rects(CARD8 op,
                              PicturePtr src, PicturePtr mask, PicturePtr dst,
-                             int nrect, glamor_composite_rect_t * rects)
+                             int nrect, glamor_composite_rect_t *rects)
 {
     int n;
     PicturePtr temp_src = NULL;
@@ -2108,7 +2108,7 @@ glamor_composite_glyph_rects(CARD8 op,
 static Bool
 _glamor_composite_rects(CARD8 op,
                         PicturePtr pDst,
-                        xRenderColor * color,
+                        xRenderColor *color,
                         int nRect, xRectangle *rects, Bool fallback)
 {
     miCompositeRects(op, pDst, color, nRect, rects);
@@ -2118,7 +2118,7 @@ _glamor_composite_rects(CARD8 op,
 void
 glamor_composite_rects(CARD8 op,
                        PicturePtr pDst,
-                       xRenderColor * color, int nRect, xRectangle *rects)
+                       xRenderColor *color, int nRect, xRectangle *rects)
 {
     _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
 }
@@ -2126,7 +2126,7 @@ glamor_composite_rects(CARD8 op,
 Bool
 glamor_composite_rects_nf(CARD8 op,
                           PicturePtr pDst,
-                          xRenderColor * color, int nRect, xRectangle *rects)
+                          xRenderColor *color, int nRect, xRectangle *rects)
 {
     return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
 }
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 2c66cea..cd99a47 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -37,7 +37,7 @@
 #include "fbpict.h"
 
 static xFixed
-_glamor_linefixedX(xLineFixed * l, xFixed y, Bool ceil)
+_glamor_linefixedX(xLineFixed *l, xFixed y, Bool ceil)
 {
     xFixed dx = l->p2.x - l->p1.x;
     xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
@@ -49,7 +49,7 @@ _glamor_linefixedX(xLineFixed * l, xFixed y, Bool ceil)
 }
 
 static xFixed
-_glamor_linefixedY(xLineFixed * l, xFixed x, Bool ceil)
+_glamor_linefixedY(xLineFixed *l, xFixed x, Bool ceil)
 {
     xFixed dy = l->p2.y - l->p1.y;
     xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
@@ -75,7 +75,7 @@ _glamor_linefixedY(xLineFixed * l, xFixed x, Bool ceil)
      && point[1] <= IntToxFixed(rect->y2))
 
 static xFixed
-_glamor_lines_crossfixedY(xLineFixed * l, xLineFixed * r)
+_glamor_lines_crossfixedY(xLineFixed *l, xLineFixed *r)
 {
     xFixed dx1 = l->p2.x - l->p1.x;
     xFixed dx2 = r->p2.x - r->p1.x;
@@ -103,7 +103,7 @@ _glamor_lines_crossfixedY(xLineFixed * l, xLineFixed * r)
 }
 
 static Bool
-point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
+point_inside_trapezoid(int point[2], xTrapezoid *trap, xFixed cut_y)
 {
     int ret = TRUE;
     int tmp;
@@ -225,7 +225,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 }
 
 static Bool
-_glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
+_glamor_clip_trapezoid_vertex(xTrapezoid *trap, BoxPtr pbox,
                               int vertex[6], int *num)
 {
     xFixed edge_cross_y = 0xFFFFFFFF;
@@ -1388,8 +1388,8 @@ glamor_fini_trapezoid_shader(ScreenPtr screen)
 
 static Bool
 _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
-                                       xTrapezoid * traps, int ntrap,
-                                       BoxRec * bounds)
+                                       xTrapezoid *traps, int ntrap,
+                                       BoxRec *bounds)
 {
     glamor_screen_private *glamor_priv;
     glamor_gl_dispatch *dispatch;
@@ -1642,7 +1642,7 @@ glamor_create_mask_picture(ScreenPtr screen,
 }
 
 static int
-_glamor_trapezoid_bounds(int ntrap, xTrapezoid * traps, BoxPtr box)
+_glamor_trapezoid_bounds(int ntrap, xTrapezoid *traps, BoxPtr box)
 {
     int has_large_trapezoid = 0;
 
@@ -1695,7 +1695,7 @@ static Bool
 _glamor_trapezoids(CARD8 op,
                    PicturePtr src, PicturePtr dst,
                    PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-                   int ntrap, xTrapezoid * traps, Bool fallback)
+                   int ntrap, xTrapezoid *traps, Bool fallback)
 {
     ScreenPtr screen = dst->pDrawable->pScreen;
     BoxRec bounds;
@@ -1834,7 +1834,7 @@ void
 glamor_trapezoids(CARD8 op,
                   PicturePtr src, PicturePtr dst,
                   PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-                  int ntrap, xTrapezoid * traps)
+                  int ntrap, xTrapezoid *traps)
 {
     DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
 
@@ -1846,7 +1846,7 @@ Bool
 glamor_trapezoids_nf(CARD8 op,
                      PicturePtr src, PicturePtr dst,
                      PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-                     int ntrap, xTrapezoid * traps)
+                     int ntrap, xTrapezoid *traps)
 {
     DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
 
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 8e4c292..bdc4c73 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -271,7 +271,7 @@ static REF_TRANSFORM trans[2] = {
 };
 
 static void
-glamor_display_textured_video(glamor_port_private * port_priv)
+glamor_display_textured_video(glamor_port_private *port_priv)
 {
     ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
commit 5f57d436c391c51f3f90958b033f6ee3eb7a1136
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 24 15:59:14 2013 -0800

    glamor: Fix some mangling of shader strings by indent.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4213961..4eac856 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -151,7 +151,8 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "void main()\n"
         "{\n"
         "	gl_Position = v_position;\n"
-        "	source_texture = v_texcoord0.xy;\n" "}\n";
+        "	source_texture = v_texcoord0.xy;\n"
+        "}\n";
 
     const char *common_source =
         GLAMOR_DEFAULT_PRECISION
@@ -186,7 +187,8 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "	  	gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
         "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
-        "    } \n" "}\n";
+        "    } \n"
+        "}\n";
 
     const char *set_alpha_source =
         "void main()\n"
@@ -208,7 +210,8 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
         "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
         "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
         "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
-        "    } \n" "}\n";
+        "    } \n"
+        "}\n";
     GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
     GLint sampler_uniform_location;
     char *source;
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 47d27bc..3aef7fc 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -140,10 +140,17 @@ glamor_init_solid_shader(ScreenPtr screen)
     glamor_gl_dispatch *dispatch;
     const char *solid_vs =
         "attribute vec4 v_position;"
-        "void main()\n" "{\n" "       gl_Position = v_position;\n" "}\n";
+        "void main()\n"
+        "{\n"
+        "       gl_Position = v_position;\n"
+        "}\n";
     const char *solid_fs =
-        GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
-        "void main()\n" "{\n" "	gl_FragColor = color;\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "uniform vec4 color;\n"
+        "void main()\n"
+        "{\n"
+        "	gl_FragColor = color;\n"
+        "}\n";
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index df6c3bb..e7c872d 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -85,7 +85,84 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
 
     /* Because the array access for shader is very slow, the performance is very low
        if use array. So use global uniform to replace for it if the number of n_stops is small. */
-    const char *gradient_fs_getcolor_no_array = GLAMOR_DEFAULT_PRECISION "uniform int n_stop;\n" "uniform float stop0;\n" "uniform float stop1;\n" "uniform float stop2;\n" "uniform float stop3;\n" "uniform float stop4;\n" "uniform float stop5;\n" "uniform float stop6;\n" "uniform float stop7;\n" "uniform vec4 stop_color0;\n" "uniform vec4 stop_color1;\n" "uniform vec4 stop_color2;\n" "uniform vec4 stop_color3;\n" "uniform vec4 stop_color4;\n" "uniform vec4 stop_color5;\n" "uniform vec4 stop_color6;\n" "uniform vec4 stop_color7;\n" "\n" "vec4 get_color(float stop_len)\n" "{\n" "    float stop_after;\n" "    float stop_before;\n" "    vec4 stop_color_before;\n" "    vec4 stop_color_after;\n" "    float new_alpha; \n" "    vec4 gradient_color;\n" "    float percentage; \n" "    \n" "    if((stop_len < stop0) && (n_stop >= 1)) {\n" "        stop_color_before = stop_color0;\n" "        stop_color_after = stop_color0;\n" "        stop_after = stop0;\n" "        stop_before = stop0;\n" "  
   } else if((stop_len < stop1) && (n_stop >= 2)) {\n" "        stop_color_before = stop_color0;\n" "        stop_color_after = stop_color1;\n" "        stop_after = stop1;\n" "        stop_before = stop0;\n" "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n" "        stop_color_before = stop_color1;\n" "        stop_color_after = stop_color2;\n" "        stop_after = stop2;\n" "        stop_before = stop1;\n" "    } else if((stop_len < stop3) && (n_stop >= 4)){\n" "        stop_color_before = stop_color2;\n" "        stop_color_after = stop_color3;\n" "        stop_after = stop3;\n" "        stop_before = stop2;\n" "    } else if((stop_len < stop4) && (n_stop >= 5)){\n" "        stop_color_before = stop_color3;\n" "        stop_color_after = stop_color4;\n" "        stop_after = stop4;\n" "        stop_before = stop3;\n" "    } else if((stop_len < stop5) && (n_stop >= 6)){\n" "        stop_color_before = stop_color4;\n" "        stop_color_after = stop_color5;\n" "        stop
 _after = stop5;\n" "        stop_before = stop4;\n" "    } else if((stop_len < stop6) && (n_stop >= 7)){\n" "        stop_color_before = stop_color5;\n" "        stop_color_after = stop_color6;\n" "        stop_after = stop6;\n" "        stop_before = stop5;\n" "    } else if((stop_len < stop7) && (n_stop >= 8)){\n" "        stop_color_before = stop_color6;\n" "        stop_color_after = stop_color7;\n" "        stop_after = stop7;\n" "        stop_before = stop6;\n" "    } else {\n" "        stop_color_before = stop_color7;\n" "        stop_color_after = stop_color7;\n" "        stop_after = stop7;\n" "        stop_before = stop7;\n" "    }\n" "    if(stop_after - stop_before > 2.0)\n" "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+    const char *gradient_fs_getcolor_no_array =
+        GLAMOR_DEFAULT_PRECISION
+        "uniform int n_stop;\n"
+        "uniform float stop0;\n"
+        "uniform float stop1;\n"
+        "uniform float stop2;\n"
+        "uniform float stop3;\n"
+        "uniform float stop4;\n"
+        "uniform float stop5;\n"
+        "uniform float stop6;\n"
+        "uniform float stop7;\n"
+        "uniform vec4 stop_color0;\n"
+        "uniform vec4 stop_color1;\n"
+        "uniform vec4 stop_color2;\n"
+        "uniform vec4 stop_color3;\n"
+        "uniform vec4 stop_color4;\n"
+        "uniform vec4 stop_color5;\n"
+        "uniform vec4 stop_color6;\n"
+        "uniform vec4 stop_color7;\n"
+        "\n"
+        "vec4 get_color(float stop_len)\n"
+        "{\n"
+        "    float stop_after;\n"
+        "    float stop_before;\n"
+        "    vec4 stop_color_before;\n"
+        "    vec4 stop_color_after;\n"
+        "    float new_alpha; \n"
+        "    vec4 gradient_color;\n"
+        "    float percentage; \n"
+        "    \n"
+        "    if((stop_len < stop0) && (n_stop >= 1)) {\n"
+        "        stop_color_before = stop_color0;\n"
+        "        stop_color_after = stop_color0;\n"
+        "        stop_after = stop0;\n"
+        "        stop_before = stop0;\n"
+        "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
+        "        stop_color_before = stop_color0;\n"
+        "        stop_color_after = stop_color1;\n"
+        "        stop_after = stop1;\n"
+        "        stop_before = stop0;\n"
+        "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
+        "        stop_color_before = stop_color1;\n"
+        "        stop_color_after = stop_color2;\n"
+        "        stop_after = stop2;\n"
+        "        stop_before = stop1;\n"
+        "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
+        "        stop_color_before = stop_color2;\n"
+        "        stop_color_after = stop_color3;\n"
+        "        stop_after = stop3;\n"
+        "        stop_before = stop2;\n"
+        "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
+        "        stop_color_before = stop_color3;\n"
+        "        stop_color_after = stop_color4;\n"
+        "        stop_after = stop4;\n"
+        "        stop_before = stop3;\n"
+        "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
+        "        stop_color_before = stop_color4;\n"
+        "        stop_color_after = stop_color5;\n"
+        "        stop_after = stop5;\n"
+        "        stop_before = stop4;\n"
+        "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
+        "        stop_color_before = stop_color5;\n"
+        "        stop_color_after = stop_color6;\n"
+        "        stop_after = stop6;\n"
+        "        stop_before = stop5;\n"
+        "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
+        "        stop_color_before = stop_color6;\n"
+        "        stop_color_after = stop_color7;\n"
+        "        stop_after = stop7;\n"
+        "        stop_before = stop6;\n"
+        "    } else {\n"
+        "        stop_color_before = stop_color7;\n"
+        "        stop_color_after = stop_color7;\n"
+        "        stop_after = stop7;\n"
+        "        stop_before = stop7;\n"
+        "    }\n"
+        "    if(stop_after - stop_before > 2.0)\n"
+        "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
         "    else if(stop_after - stop_before < 0.000001)\n"
         "        percentage = 0.0;\n"
         "    else \n"
@@ -95,7 +172,9 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
         "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
         "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
         "                          new_alpha);\n"
-        "    \n" "    return gradient_color;\n" "}\n";
+        "    \n"
+        "    return gradient_color;\n"
+        "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
     dispatch = glamor_get_dispatch(glamor_priv);
@@ -137,7 +216,8 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         "void main()\n"
         "{\n"
         "    gl_Position = v_position;\n"
-        "    source_texture = v_texcoord.xy;\n" "}\n";
+        "    source_texture = v_texcoord.xy;\n"
+        "}\n";
 
     /*
      *     Refer to pixman radial gradient.
@@ -375,7 +455,8 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
         "void main()\n"
         "{\n"
         "    gl_Position = v_position;\n"
-        "    source_texture = v_texcoord.xy;\n" "}\n";
+        "    source_texture = v_texcoord.xy;\n"
+        "}\n";
 
     /*
      *                                      |
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 5d06912..6b25bec 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -38,20 +38,29 @@ glamor_init_putimage_shaders(ScreenPtr screen)
 #if 0
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *xybitmap_vs =
-        "uniform float x_bias;\n" "uniform float x_scale;\n"
-        "uniform float y_bias;\n" "uniform float y_scale;\n"
-        "varying vec2 bitmap_coords;\n" "void main()\n" "{\n"
+        "uniform float x_bias;\n"
+        "uniform float x_scale;\n"
+        "uniform float y_bias;\n"
+        "uniform float y_scale;\n"
+        "varying vec2 bitmap_coords;\n"
+        "void main()\n"
+        "{\n"
         "	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
         "			   (gl_Vertex.y + y_bias) * y_scale,\n"
         "			   0,\n"
         "			   1);\n"
-        "	bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n";
+        "	bitmap_coords = gl_MultiTexCoord0.xy;\n"
+        "}\n";
     const char *xybitmap_fs =
-        "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n"
-        "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n"
+        "uniform vec4 fg, bg;\n"
+        "varying vec2 bitmap_coords;\n"
+        "uniform sampler2D bitmap_sampler;\n"
+        "void main()\n"
+        "{\n"
         "	float bitmap_value = texture2D(bitmap_sampler,\n"
         "				       bitmap_coords).x;\n"
-        "	gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n";
+        "	gl_FragColor = mix(bg, fg, bitmap_value);\n"
+        "}\n";
     GLint fs_prog, vs_prog, prog;
     GLint sampler_uniform_location;
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d6ccf81..10cb24a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -99,7 +99,9 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
         "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
         "		else \n"
         "			rel_tex.y = fract(rel_tex.y)/wh.y;\n"
-        "    } \n" "   return rel_tex; \n" "}\n";
+        "    } \n"
+        "   return rel_tex; \n"
+        "}\n";
     /* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
      * rel_sampler will recalculate the texture coords.*/
     const char *rel_sampler =
@@ -121,7 +123,10 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
     const char *source_solid_fetch =
         GLAMOR_DEFAULT_PRECISION
         "uniform vec4 source;\n"
-        "vec4 get_source()\n" "{\n" "	return source;\n" "}\n";
+        "vec4 get_source()\n"
+        "{\n"
+        "	return source;\n"
+        "}\n";
     const char *source_alpha_pixmap_fetch =
         GLAMOR_DEFAULT_PRECISION
         "varying vec2 source_texture;\n"
@@ -136,7 +141,8 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
         "				   source_wh, source_repeat_mode, 0);\n"
         "}\n";
     const char *source_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 source_texture;\n"
         "uniform sampler2D source_sampler;\n"
         "uniform vec4 source_wh;\n"
         "vec4 get_source()\n"
@@ -148,10 +154,15 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
         "				   source_wh, source_repeat_mode, 1);\n"
         "}\n";
     const char *mask_solid_fetch =
-        GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
-        "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "uniform vec4 mask;\n"
+        "vec4 get_mask()\n"
+        "{\n"
+        "	return mask;\n"
+        "}\n";
     const char *mask_alpha_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 mask_texture;\n"
         "uniform sampler2D mask_sampler;\n"
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
@@ -163,7 +174,8 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
         "				   mask_wh, mask_repeat_mode, 0);\n"
         "}\n";
     const char *mask_pixmap_fetch =
-        GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 mask_texture;\n"
         "uniform sampler2D mask_sampler;\n"
         "uniform vec4 mask_wh;\n"
         "vec4 get_mask()\n"
@@ -175,17 +187,29 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
         "				   mask_wh, mask_repeat_mode, 1);\n"
         "}\n";
     const char *in_source_only =
-        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-        "	gl_FragColor = get_source();\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "void main()\n"
+        "{\n"
+        "	gl_FragColor = get_source();\n"
+        "}\n";
     const char *in_normal =
-        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-        "	gl_FragColor = get_source() * get_mask().a;\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "void main()\n"
+        "{\n"
+        "	gl_FragColor = get_source() * get_mask().a;\n"
+        "}\n";
     const char *in_ca_source =
-        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-        "	gl_FragColor = get_source() * get_mask();\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "void main()\n"
+        "{\n"
+        "	gl_FragColor = get_source() * get_mask();\n"
+        "}\n";
     const char *in_ca_alpha =
-        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-        "	gl_FragColor = get_source().a * get_mask();\n" "}\n";
+        GLAMOR_DEFAULT_PRECISION
+        "void main()\n"
+        "{\n"
+        "	gl_FragColor = get_source().a * get_mask();\n"
+        "}\n";
     char *source;
     const char *source_fetch;
     const char *mask_fetch = "";
@@ -258,7 +282,9 @@ glamor_create_composite_vs(glamor_gl_dispatch * dispatch,
         "attribute vec4 v_texcoord1;\n"
         "varying vec2 source_texture;\n"
         "varying vec2 mask_texture;\n"
-        "void main()\n" "{\n" "	gl_Position = v_position;\n";
+        "void main()\n"
+        "{\n"
+        "	gl_Position = v_position;\n";
     const char *source_coords = "	source_texture = v_texcoord0.xy;\n";
     const char *mask_coords = "	mask_texture = v_texcoord1.xy;\n";
     const char *main_closing = "}\n";
@@ -1165,7 +1191,7 @@ glamor_composite_choose_shader(CARD8 op,
 
     *shader = glamor_lookup_composite_shader(screen, &key);
     if ((*shader)->prog == 0) {
-        glamor_fallback("no shader program for this" "render acccel mode\n");
+        glamor_fallback("no shader program for this render acccel mode\n");
         goto fail;
     }
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 0012653..9c8e521 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -45,7 +45,8 @@ glamor_init_tile_shader(ScreenPtr screen)
         "void main()\n"
         "{\n"
         "       gl_Position = v_position;\n"
-        "       tile_texture = v_texcoord0.xy;\n" "}\n";
+        "       tile_texture = v_texcoord0.xy;\n"
+        "}\n";
     const char *tile_fs =
         GLAMOR_DEFAULT_PRECISION
         "varying vec2 tile_texture;\n"
@@ -56,7 +57,8 @@ glamor_init_tile_shader(ScreenPtr screen)
         "   vec2 rel_tex;"
         "   rel_tex = tile_texture * wh; \n"
         "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
-        "	gl_FragColor = texture2D(sampler, rel_tex);\n" "}\n";
+        "	gl_FragColor = texture2D(sampler, rel_tex);\n"
+        "}\n";
     GLint fs_prog, vs_prog;
     GLint sampler_uniform_location;
 
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index c7f7a62..2c66cea 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1018,7 +1018,8 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 
     const char *trapezoid_vs =
         GLAMOR_DEFAULT_PRECISION
-        "attribute vec4 v_position;\n" "attribute vec2 v_texcoord;\n"
+        "attribute vec4 v_position;\n"
+        "attribute vec2 v_texcoord;\n"
         /* v_top_bottom, v_left_param and v_right_param contain the
            constant value for all the vertex of one rect. Using uniform
            is more suitable but we need to reset the uniform variables
@@ -1056,7 +1057,8 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "    trap_right_x = v_right_param.x;\n"
         "    trap_right_y = v_right_param.y;\n"
         "    trap_right_slope = v_right_param.z;\n"
-        "    trap_right_vertical_f = v_right_param.w;\n" "}\n";
+        "    trap_right_vertical_f = v_right_param.w;\n"
+        "}\n";
 
     /*
      * Because some GL fill function do not support the MultSample
@@ -1158,7 +1160,9 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "            || (x_up_cut_left > source_texture.x + x_per_pix/2.0  &&  \n"
         "                   x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) {  \n"
         //            The complete outside. At Left or Right of the trapezoide.
-        "             return 0.0;  \n" "        }  \n" "    }  \n"
+        "             return 0.0;  \n"
+        "        }  \n"
+        "    }  \n"
         //   Get here, the pix is partly inside the trapezoid.
         "    {  \n"
         "        float percent = 0.0;  \n"
@@ -1336,7 +1340,8 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "void main()  \n"
         "{  \n"
         "    float alpha_val = get_alpha_val();  \n"
-        "    gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val);  \n" "}\n";
+        "    gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val);  \n"
+        "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
     dispatch = glamor_get_dispatch(glamor_priv);
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 237a272..8e4c292 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -58,8 +58,11 @@ typedef struct tagREF_TRANSFORM {
 static const char *xv_vs = "attribute vec4 v_position;\n"
     "attribute vec4 v_texcoord0;\n"
     "varying vec2 tcs;\n"
-    "void main()\n" "{\n" "     gl_Position = v_position;\n"
-    "tcs = v_texcoord0.xy;\n" "}\n";
+    "void main()\n"
+    "{\n"
+    "     gl_Position = v_position;\n"
+    "tcs = v_texcoord0.xy;\n"
+    "}\n";
 
 static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
     "uniform sampler2D y_sampler;\n"
@@ -71,14 +74,17 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
     "varying vec2 tcs;\n"
     "float sample;\n"
     "vec4 temp1;\n"
-    "void main()\n" "{\n"
+    "void main()\n"
+    "{\n"
     "sample = texture2D(y_sampler, tcs).w;\n"
     "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
     "sample = texture2D(u_sampler, tcs).w;\n"
     "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
     "sample = texture2D(v_sampler, tcs).w;\n"
     "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
-    "temp1.w = 1.0;\n" "gl_FragColor = temp1;\n" "}\n";
+    "temp1.w = 1.0;\n"
+    "gl_FragColor = temp1;\n"
+    "}\n";
 
 void
 glamor_init_xv_shader(ScreenPtr screen)
commit d84d71029ae9e462559d64eff7259e2cc7732fac
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:59:07 2013 -0800

    glamor: Apply x-indent.sh.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/compiler.h b/glamor/compiler.h
index fa28959..5f2d4ea 100644
--- a/glamor/compiler.h
+++ b/glamor/compiler.h
@@ -56,4 +56,4 @@
 
 #define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)]))
 
-#endif /* _SNA_COMPILER_H_ */
+#endif                          /* _SNA_COMPILER_H_ */
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 93d3c5e..216fab4 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -54,197 +54,192 @@ DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 PixmapPtr
 glamor_get_drawable_pixmap(DrawablePtr drawable)
 {
-	if (drawable->type == DRAWABLE_WINDOW)
-		return drawable->
-		    pScreen->GetWindowPixmap((WindowPtr) drawable);
-	else
-		return (PixmapPtr) drawable;
+    if (drawable->type == DRAWABLE_WINDOW)
+        return drawable->pScreen->GetWindowPixmap((WindowPtr) drawable);
+    else
+        return (PixmapPtr) drawable;
 }
 
 _X_EXPORT void
 glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 {
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-
-	pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
-					glamor_pixmap_private_key);
-	if (pixmap_priv == NULL) {
-		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
-		glamor_set_pixmap_private(pixmap, pixmap_priv);
-		pixmap_priv->base.pixmap = pixmap;
-		pixmap_priv->base.glamor_priv = glamor_priv;
-	}
-	pixmap_priv->type = type;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+
+    pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
+                                   glamor_pixmap_private_key);
+    if (pixmap_priv == NULL) {
+        pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
+        glamor_set_pixmap_private(pixmap, pixmap_priv);
+        pixmap_priv->base.pixmap = pixmap;
+        pixmap_priv->base.glamor_priv = glamor_priv;
+    }
+    pixmap_priv->type = type;
 }
 
 _X_EXPORT void
 glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv;
-	glamor_pixmap_fbo *fbo;
-	GLenum format;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (pixmap_priv->base.fbo) {
-		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-		glamor_destroy_fbo(fbo);
-	}
-
-	gl_iformat_for_depth(pixmap->drawable.depth, &format);
-	fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
-					 pixmap->drawable.height,
-					 format, tex, 0);
-
-	if (fbo == NULL) {
-		ErrorF("XXX fail to create fbo.\n");
-		return;
-	}
-
-	glamor_pixmap_attach_fbo(pixmap, fbo);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv;
+    glamor_pixmap_fbo *fbo;
+    GLenum format;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (pixmap_priv->base.fbo) {
+        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+        glamor_destroy_fbo(fbo);
+    }
+
+    gl_iformat_for_depth(pixmap->drawable.depth, &format);
+    fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
+                                     pixmap->drawable.height, format, tex, 0);
+
+    if (fbo == NULL) {
+        ErrorF("XXX fail to create fbo.\n");
+        return;
+    }
+
+    glamor_pixmap_attach_fbo(pixmap, fbo);
 }
 
 void
 glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
 {
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv;
 
-	glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
-	pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
-	glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
+    glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
+    pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
+    glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
 
-	pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
-	pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
+    pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
+    pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
 
-	glamor_priv->back_pixmap = back_pixmap;
+    glamor_priv->back_pixmap = back_pixmap;
 }
 
 PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
-		     unsigned int usage)
+                     unsigned int usage)
 {
-	PixmapPtr pixmap;
-	glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_pixmap_fbo *fbo;
-	int pitch;
-	GLenum format;
-
-	if (w > 32767 || h > 32767)
-		return NullPixmap;
-
-	if ((usage == GLAMOR_CREATE_PIXMAP_CPU
-	     || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
-		|| (w == 0 && h == 0)
-		|| !glamor_check_pixmap_fbo_depth(depth))
-	    || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
-		!glamor_check_fbo_size(glamor_priv, w, h)))
-		return fbCreatePixmap(screen, w, h, depth, usage);
-	else
-		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
-
-	pixmap_priv = calloc(1, sizeof(*pixmap_priv));
-
-	if (!pixmap_priv) {
-		fbDestroyPixmap(pixmap);
-		return fbCreatePixmap(screen, w, h, depth, usage);
-	}
-	glamor_set_pixmap_private(pixmap, pixmap_priv);
-
-	if (usage == GLAMOR_CREATE_PIXMAP_MAP)
-		type = GLAMOR_MEMORY_MAP;
-
-	pixmap_priv->base.pixmap = pixmap;
-	pixmap_priv->base.glamor_priv = glamor_priv;
-
-	gl_iformat_for_depth(depth, &format);
-
-	pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
-	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
-
-	if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) {
-		pixmap_priv->type = type;
-		fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
-	}
-	else {
-		DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h);
-		pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
-		fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
-					      glamor_priv->max_fbo_size,
-					      glamor_priv->max_fbo_size,
-					      pixmap_priv);
-	}
-
-	if (fbo == NULL) {
-		fbDestroyPixmap(pixmap);
-		free(pixmap_priv);
-		return fbCreatePixmap(screen, w, h, depth, usage);
-	}
-
-	glamor_pixmap_attach_fbo(pixmap, fbo);
-
-	return pixmap;
+    PixmapPtr pixmap;
+    glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_fbo *fbo;
+    int pitch;
+    GLenum format;
+
+    if (w > 32767 || h > 32767)
+        return NullPixmap;
+
+    if ((usage == GLAMOR_CREATE_PIXMAP_CPU
+         || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
+         || (w == 0 && h == 0)
+         || !glamor_check_pixmap_fbo_depth(depth))
+        || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
+            !glamor_check_fbo_size(glamor_priv, w, h)))
+        return fbCreatePixmap(screen, w, h, depth, usage);
+    else
+        pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
+
+    pixmap_priv = calloc(1, sizeof(*pixmap_priv));
+
+    if (!pixmap_priv) {
+        fbDestroyPixmap(pixmap);
+        return fbCreatePixmap(screen, w, h, depth, usage);
+    }
+    glamor_set_pixmap_private(pixmap, pixmap_priv);
+
+    if (usage == GLAMOR_CREATE_PIXMAP_MAP)
+        type = GLAMOR_MEMORY_MAP;
+
+    pixmap_priv->base.pixmap = pixmap;
+    pixmap_priv->base.glamor_priv = glamor_priv;
+
+    gl_iformat_for_depth(depth, &format);
+
+    pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
+    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+
+    if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) {
+        pixmap_priv->type = type;
+        fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
+    }
+    else {
+        DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h);
+        pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
+        fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
+                                      glamor_priv->max_fbo_size,
+                                      glamor_priv->max_fbo_size, pixmap_priv);
+    }
+
+    if (fbo == NULL) {
+        fbDestroyPixmap(pixmap);
+        free(pixmap_priv);
+        return fbCreatePixmap(screen, w, h, depth, usage);
+    }
+
+    glamor_pixmap_attach_fbo(pixmap, fbo);
+
+    return pixmap;
 }
 
 void
 glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 {
-	if (pixmap->refcnt == 1) {
-		glamor_pixmap_private *pixmap_priv;
+    if (pixmap->refcnt == 1) {
+        glamor_pixmap_private *pixmap_priv;
 
-		pixmap_priv = glamor_get_pixmap_private(pixmap);
-		if (pixmap_priv != NULL)
-			glamor_pixmap_destroy_fbo(pixmap_priv);
-	}
+        pixmap_priv = glamor_get_pixmap_private(pixmap);
+        if (pixmap_priv != NULL)
+            glamor_pixmap_destroy_fbo(pixmap_priv);
+    }
 }
 
 Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
-	glamor_screen_private
-	  *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-	if (glamor_priv->dri3_enabled)
-		glamor_egl_destroy_textured_pixmap(pixmap);
-	else
-		glamor_destroy_textured_pixmap(pixmap);
-	return fbDestroyPixmap(pixmap);
+    glamor_screen_private
+        * glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+    if (glamor_priv->dri3_enabled)
+        glamor_egl_destroy_textured_pixmap(pixmap);
+    else
+        glamor_destroy_textured_pixmap(pixmap);
+    return fbDestroyPixmap(pixmap);
 }
 
 void
 glamor_block_handler(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_priv->tick++;
-	dispatch->glFlush();
-	glamor_fbo_expire(glamor_priv);
-	glamor_put_dispatch(glamor_priv);
-	if (glamor_priv->state == RENDER_STATE
-	    && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
-		glamor_priv->state = IDLE_STATE;
-		glamor_priv->render_idle_cnt = 0;
-	}
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_priv->tick++;
+    dispatch->glFlush();
+    glamor_fbo_expire(glamor_priv);
+    glamor_put_dispatch(glamor_priv);
+    if (glamor_priv->state == RENDER_STATE
+        && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
+        glamor_priv->state = IDLE_STATE;
+        glamor_priv->render_idle_cnt = 0;
+    }
 }
 
 static void
-_glamor_block_handler(void *data, OSTimePtr timeout,
-		      void *last_select_mask)
+_glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
-	glamor_screen_private *glamor_priv = data;
-	glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glFlush();
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv = data;
+    glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
+
+    dispatch->glFlush();
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
@@ -255,12 +250,13 @@ _glamor_wakeup_handler(void *data, int result, void *last_select_mask)
 static void
 glamor_set_debug_level(int *debug_level)
 {
-	char *debug_level_string;
-	debug_level_string = getenv("GLAMOR_DEBUG");
-	if (debug_level_string
-	    && sscanf(debug_level_string, "%d", debug_level) == 1)
-		return;
-	*debug_level = 0;
+    char *debug_level_string;
+
+    debug_level_string = getenv("GLAMOR_DEBUG");
+    if (debug_level_string
+        && sscanf(debug_level_string, "%d", debug_level) == 1)
+        return;
+    *debug_level = 0;
 }
 
 int glamor_debug_level;
@@ -269,360 +265,350 @@ int glamor_debug_level;
 Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
 {
-	glamor_screen_private *glamor_priv;
-	int gl_version;
+    glamor_screen_private *glamor_priv;
+    int gl_version;
 
 #ifdef RENDER
-	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
+    PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
-	if (flags & ~GLAMOR_VALID_FLAGS) {
-		ErrorF("glamor_init: Invalid flags %x\n", flags);
-		return FALSE;
-	}
-	glamor_priv = calloc(1, sizeof(*glamor_priv));
-	if (glamor_priv == NULL)
-		return FALSE;
-
-	if (flags & GLAMOR_INVERTED_Y_AXIS) {
-		glamor_priv->yInverted = 1;
-	} else
-		glamor_priv->yInverted = 0;
-
-	if (!dixRegisterPrivateKey
-	    (glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate screen private\n",
-			   screen->myNum);
-		goto fail;
-	}
-
-	glamor_set_screen_private(screen, glamor_priv);
-
-	if (!dixRegisterPrivateKey
-	    (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate pixmap private\n",
-			   screen->myNum);
-		goto fail;;
-	}
-
-	gl_version = glamor_gl_get_version();
+    if (flags & ~GLAMOR_VALID_FLAGS) {
+        ErrorF("glamor_init: Invalid flags %x\n", flags);
+        return FALSE;
+    }
+    glamor_priv = calloc(1, sizeof(*glamor_priv));
+    if (glamor_priv == NULL)
+        return FALSE;
+
+    if (flags & GLAMOR_INVERTED_Y_AXIS) {
+        glamor_priv->yInverted = 1;
+    }
+    else
+        glamor_priv->yInverted = 0;
+
+    if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to allocate screen private\n",
+                   screen->myNum);
+        goto fail;
+    }
+
+    glamor_set_screen_private(screen, glamor_priv);
+
+    if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to allocate pixmap private\n",
+                   screen->myNum);
+        goto fail;;
+    }
+
+    gl_version = glamor_gl_get_version();
 
 #ifndef GLAMOR_GLES2
-	if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
-		ErrorF("Require OpenGL version 1.3 or latter.\n");
-		goto fail;
-	}
+    if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
+        ErrorF("Require OpenGL version 1.3 or latter.\n");
+        goto fail;
+    }
 #else
-	if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
-		ErrorF("Require Open GLES2.0 or latter.\n");
-		goto fail;
-	}
+    if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
+        ErrorF("Require Open GLES2.0 or latter.\n");
+        goto fail;
+    }
 #endif
 
-	glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version);
+    glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version);
 
 #ifdef GLAMOR_GLES2
-	if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
-		ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
-		goto fail;
-	}
+    if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
+        ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
+        goto fail;
+    }
 #endif
 
-	glamor_priv->has_pack_invert =
-	    glamor_gl_has_extension("GL_MESA_pack_invert");
-	glamor_priv->has_fbo_blit =
-	    glamor_gl_has_extension("GL_EXT_framebuffer_blit");
-	glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
-					     &glamor_priv->max_fbo_size);
+    glamor_priv->has_pack_invert =
+        glamor_gl_has_extension("GL_MESA_pack_invert");
+    glamor_priv->has_fbo_blit =
+        glamor_gl_has_extension("GL_EXT_framebuffer_blit");
+    glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
+                                         &glamor_priv->max_fbo_size);
 #ifdef MAX_FBO_SIZE
-	glamor_priv->max_fbo_size = MAX_FBO_SIZE;
+    glamor_priv->max_fbo_size = MAX_FBO_SIZE;
 #endif
 
-	glamor_set_debug_level(&glamor_debug_level);
+    glamor_set_debug_level(&glamor_debug_level);
 
 #ifdef GLAMOR_GLES2
-	glamor_priv->gl_flavor = GLAMOR_GL_ES2;
+    glamor_priv->gl_flavor = GLAMOR_GL_ES2;
 #else
-	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+    glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
 #endif
-	/* If we are using egl screen, call egl screen init to
-	 * register correct close screen function. */
-	if (flags & GLAMOR_USE_EGL_SCREEN)
-		glamor_egl_screen_init(screen);
+    /* If we are using egl screen, call egl screen init to
+     * register correct close screen function. */
+    if (flags & GLAMOR_USE_EGL_SCREEN)
+        glamor_egl_screen_init(screen);
 
-	glamor_priv->saved_procs.close_screen = screen->CloseScreen;
-	screen->CloseScreen = glamor_close_screen;
+    glamor_priv->saved_procs.close_screen = screen->CloseScreen;
+    screen->CloseScreen = glamor_close_screen;
 
-	if (flags & GLAMOR_USE_SCREEN) {
-		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
-						    _glamor_wakeup_handler,
-						    glamor_priv)) {
-			goto fail;
-		}
+    if (flags & GLAMOR_USE_SCREEN) {
+        if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
+                                            _glamor_wakeup_handler,
+                                            glamor_priv)) {
+            goto fail;
+        }
 
-		glamor_priv->saved_procs.create_gc = screen->CreateGC;
-		screen->CreateGC = glamor_create_gc;
+        glamor_priv->saved_procs.create_gc = screen->CreateGC;
+        screen->CreateGC = glamor_create_gc;
 
-		glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
-		screen->CreatePixmap = glamor_create_pixmap;
+        glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
+        screen->CreatePixmap = glamor_create_pixmap;
 
-		glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
-		screen->DestroyPixmap = glamor_destroy_pixmap;
+        glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
+        screen->DestroyPixmap = glamor_destroy_pixmap;
 
-		glamor_priv->saved_procs.get_spans = screen->GetSpans;
-		screen->GetSpans = glamor_get_spans;
+        glamor_priv->saved_procs.get_spans = screen->GetSpans;
+        screen->GetSpans = glamor_get_spans;
 
-		glamor_priv->saved_procs.get_image = screen->GetImage;
-		screen->GetImage = glamor_get_image;
+        glamor_priv->saved_procs.get_image = screen->GetImage;
+        screen->GetImage = glamor_get_image;
 
-		glamor_priv->saved_procs.change_window_attributes =
-		    screen->ChangeWindowAttributes;
-		screen->ChangeWindowAttributes =
-		    glamor_change_window_attributes;
+        glamor_priv->saved_procs.change_window_attributes =
+            screen->ChangeWindowAttributes;
+        screen->ChangeWindowAttributes = glamor_change_window_attributes;
 
-		glamor_priv->saved_procs.copy_window = screen->CopyWindow;
-		screen->CopyWindow = glamor_copy_window;
+        glamor_priv->saved_procs.copy_window = screen->CopyWindow;
+        screen->CopyWindow = glamor_copy_window;
 
-		glamor_priv->saved_procs.bitmap_to_region =
-		    screen->BitmapToRegion;
-		screen->BitmapToRegion = glamor_bitmap_to_region;
-	}
+        glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
+        screen->BitmapToRegion = glamor_bitmap_to_region;
+    }
 #ifdef RENDER
-	if (flags & GLAMOR_USE_PICTURE_SCREEN) {
-		glamor_priv->saved_procs.composite = ps->Composite;
-		ps->Composite = glamor_composite;
-
+    if (flags & GLAMOR_USE_PICTURE_SCREEN) {
+        glamor_priv->saved_procs.composite = ps->Composite;
+        ps->Composite = glamor_composite;
 
-		glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
-		ps->Trapezoids = glamor_trapezoids;
+        glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
+        ps->Trapezoids = glamor_trapezoids;
 
+        glamor_priv->saved_procs.triangles = ps->Triangles;
+        ps->Triangles = glamor_triangles;
 
-		glamor_priv->saved_procs.triangles = ps->Triangles;
-		ps->Triangles = glamor_triangles;
+        glamor_priv->saved_procs.addtraps = ps->AddTraps;
+        ps->AddTraps = glamor_add_traps;
 
-		glamor_priv->saved_procs.addtraps = ps->AddTraps;
-		ps->AddTraps = glamor_add_traps;
+    }
 
-	}
+    glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
+    ps->CompositeRects = glamor_composite_rectangles;
 
-	glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
-	ps->CompositeRects = glamor_composite_rectangles;
+    glamor_priv->saved_procs.glyphs = ps->Glyphs;
+    ps->Glyphs = glamor_glyphs;
 
-	glamor_priv->saved_procs.glyphs = ps->Glyphs;
-	ps->Glyphs = glamor_glyphs;
+    glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
+    ps->UnrealizeGlyph = glamor_glyph_unrealize;
 
-	glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
-	ps->UnrealizeGlyph = glamor_glyph_unrealize;
+    glamor_priv->saved_procs.create_picture = ps->CreatePicture;
+    ps->CreatePicture = glamor_create_picture;
 
-	glamor_priv->saved_procs.create_picture = ps->CreatePicture;
-	ps->CreatePicture = glamor_create_picture;
+    glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = glamor_set_window_pixmap;
 
-	glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
-	screen->SetWindowPixmap = glamor_set_window_pixmap;
-
-	glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
-	ps->DestroyPicture = glamor_destroy_picture;
-	glamor_init_composite_shaders(screen);
+    glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
+    ps->DestroyPicture = glamor_destroy_picture;
+    glamor_init_composite_shaders(screen);
 #endif
-	glamor_init_pixmap_fbo(screen);
-	glamor_init_solid_shader(screen);
-	glamor_init_tile_shader(screen);
+    glamor_init_pixmap_fbo(screen);
+    glamor_init_solid_shader(screen);
+    glamor_init_tile_shader(screen);
 #ifdef GLAMOR_TRAPEZOID_SHADER
-	glamor_init_trapezoid_shader(screen);
+    glamor_init_trapezoid_shader(screen);
 #endif
-	glamor_init_putimage_shaders(screen);
-	glamor_init_finish_access_shaders(screen);
+    glamor_init_putimage_shaders(screen);
+    glamor_init_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
-	glamor_init_gradient_shader(screen);
+    glamor_init_gradient_shader(screen);
 #endif
 #ifdef GLAMOR_XV
-	glamor_init_xv_shader(screen);
+    glamor_init_xv_shader(screen);
 #endif
-	glamor_pixmap_init(screen);
+    glamor_pixmap_init(screen);
 
-	glamor_priv->flags = flags;
-	glamor_priv->screen = screen;
+    glamor_priv->flags = flags;
+    glamor_priv->screen = screen;
 
-	return TRUE;
+    return TRUE;
 
-      fail:
-	free(glamor_priv);
-	glamor_set_screen_private(screen, NULL);
-	return FALSE;
+ fail:
+    free(glamor_priv);
+    glamor_set_screen_private(screen, NULL);
+    return FALSE;
 }
 
 static void
 glamor_release_screen_priv(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
+    glamor_screen_private *glamor_priv;
 
-	glamor_priv = glamor_get_screen_private(screen);
+    glamor_priv = glamor_get_screen_private(screen);
 #ifdef GLAMOR_XV
-	glamor_fini_xv_shader(screen);
+    glamor_fini_xv_shader(screen);
 #endif
 #ifdef RENDER
-	glamor_fini_composite_shaders(screen);
+    glamor_fini_composite_shaders(screen);
 #endif
-	glamor_fini_pixmap_fbo(screen);
-	glamor_fini_solid_shader(screen);
-	glamor_fini_tile_shader(screen);
+    glamor_fini_pixmap_fbo(screen);
+    glamor_fini_solid_shader(screen);
+    glamor_fini_tile_shader(screen);
 #ifdef GLAMOR_TRAPEZOID_SHADER
-	glamor_fini_trapezoid_shader(screen);
+    glamor_fini_trapezoid_shader(screen);
 #endif
-	glamor_fini_putimage_shaders(screen);
-	glamor_fini_finish_access_shaders(screen);
+    glamor_fini_putimage_shaders(screen);
+    glamor_fini_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
-	glamor_fini_gradient_shader(screen);
+    glamor_fini_gradient_shader(screen);
 #endif
-	glamor_pixmap_fini(screen);
-	free(glamor_priv);
+    glamor_pixmap_fini(screen);
+    free(glamor_priv);
 
-	glamor_set_screen_private(screen, NULL);
+    glamor_set_screen_private(screen, NULL);
 }
 
 _X_EXPORT void
-glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
+glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private * priv)
 {
-	glamor_pixmap_private *old_priv;
-	glamor_pixmap_fbo *fbo;
-
-	old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
-
-	if (priv) {
-		assert(old_priv == NULL);
-	} else {
-		if (old_priv == NULL)
-			return;
-		fbo = glamor_pixmap_detach_fbo(old_priv);
-		glamor_purge_fbo(fbo);
-		free(old_priv);
-	}
-
-	dixSetPrivate(&pixmap->devPrivates,
-		      glamor_pixmap_private_key,
-		      priv);
+    glamor_pixmap_private *old_priv;
+    glamor_pixmap_fbo *fbo;
+
+    old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+
+    if (priv) {
+        assert(old_priv == NULL);
+    }
+    else {
+        if (old_priv == NULL)
+            return;
+        fbo = glamor_pixmap_detach_fbo(old_priv);
+        glamor_purge_fbo(fbo);
+        free(old_priv);
+    }
+
+    dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv);
 }
 
 Bool
 glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
-	glamor_screen_private *glamor_priv;
-	PixmapPtr screen_pixmap;
-	int flags;
+    glamor_screen_private *glamor_priv;
+    PixmapPtr screen_pixmap;
+    int flags;
+
 #ifdef RENDER
-	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
+    PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
-	glamor_priv = glamor_get_screen_private(screen);
-	flags = glamor_priv->flags;
-	glamor_glyphs_fini(screen);
-	screen->CloseScreen = glamor_priv->saved_procs.close_screen;
-	if (flags & GLAMOR_USE_SCREEN) {
-
-		screen->CreateGC = glamor_priv->saved_procs.create_gc;
-		screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
-		screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
-		screen->GetSpans = glamor_priv->saved_procs.get_spans;
-		screen->ChangeWindowAttributes =
-		    glamor_priv->saved_procs.change_window_attributes;
-		screen->CopyWindow = glamor_priv->saved_procs.copy_window;
-		screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
-	}
+    glamor_priv = glamor_get_screen_private(screen);
+    flags = glamor_priv->flags;
+    glamor_glyphs_fini(screen);
+    screen->CloseScreen = glamor_priv->saved_procs.close_screen;
+    if (flags & GLAMOR_USE_SCREEN) {
+
+        screen->CreateGC = glamor_priv->saved_procs.create_gc;
+        screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+        screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+        screen->GetSpans = glamor_priv->saved_procs.get_spans;
+        screen->ChangeWindowAttributes =
+            glamor_priv->saved_procs.change_window_attributes;
+        screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+        screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+    }
 #ifdef RENDER
-	if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
-
-		ps->Composite = glamor_priv->saved_procs.composite;
-		ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
-		ps->Triangles = glamor_priv->saved_procs.triangles;
-		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
-	}
-	ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
-	ps->Glyphs = glamor_priv->saved_procs.glyphs;
-	ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
-	screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
+    if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
+
+        ps->Composite = glamor_priv->saved_procs.composite;
+        ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
+        ps->Triangles = glamor_priv->saved_procs.triangles;
+        ps->CreatePicture = glamor_priv->saved_procs.create_picture;
+    }
+    ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
+    ps->Glyphs = glamor_priv->saved_procs.glyphs;
+    ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
+    screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
 #endif
-	screen_pixmap = screen->GetScreenPixmap(screen);
-	glamor_set_pixmap_private(screen_pixmap, NULL);
-	if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
-		glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
+    screen_pixmap = screen->GetScreenPixmap(screen);
+    glamor_set_pixmap_private(screen_pixmap, NULL);
+    if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
+        glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
 
-	glamor_release_screen_priv(screen);
+    glamor_release_screen_priv(screen);
 
-	return screen->CloseScreen(CLOSE_SCREEN_ARGS);
+    return screen->CloseScreen(CLOSE_SCREEN_ARGS);
 }
 
-
 void
 glamor_fini(ScreenPtr screen)
 {
-	/* Do nothing currently. */
+    /* Do nothing currently. */
 }
 
-void glamor_enable_dri3(ScreenPtr screen)
+void
+glamor_enable_dri3(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_priv->dri3_enabled = TRUE;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    glamor_priv->dri3_enabled = TRUE;
 }
 
-Bool glamor_is_dri3_support_enabled(ScreenPtr screen)
+Bool
+glamor_is_dri3_support_enabled(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	return glamor_priv->dri3_enabled;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    return glamor_priv->dri3_enabled;
 }
 
 int
-glamor_dri3_fd_from_pixmap (ScreenPtr screen,
-                            PixmapPtr pixmap,
-                            CARD16 *stride,
-                            CARD32 *size)
+glamor_dri3_fd_from_pixmap(ScreenPtr screen,
+                           PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
 {
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
-		return -1;
-	switch (pixmap_priv->type)
-	{
-		case GLAMOR_TEXTURE_DRM:
-		case GLAMOR_TEXTURE_ONLY:
-			glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
-			return glamor_egl_dri3_fd_name_from_tex(screen,
-								pixmap,
-								pixmap_priv->base.fbo->tex,
-								FALSE,
-								stride,
-								size);
-		default: break;
-	}
-	return -1;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
+        return -1;
+    switch (pixmap_priv->type) {
+    case GLAMOR_TEXTURE_DRM:
+    case GLAMOR_TEXTURE_ONLY:
+        glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+        return glamor_egl_dri3_fd_name_from_tex(screen,
+                                                pixmap,
+                                                pixmap_priv->base.fbo->tex,
+                                                FALSE, stride, size);
+    default:
+        break;
+    }
+    return -1;
 }
 
 int
-glamor_dri3_name_from_pixmap (PixmapPtr pixmap)
+glamor_dri3_name_from_pixmap(PixmapPtr pixmap)
 {
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
-		return -1;
-	switch (pixmap_priv->type)
-	{
-		case GLAMOR_TEXTURE_DRM:
-		case GLAMOR_TEXTURE_ONLY:
-			glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
-			return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
-								pixmap,
-								pixmap_priv->base.fbo->tex,
-								TRUE,
-								NULL,
-								NULL);
-		default: break;
-	}
-	return -1;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
+        return -1;
+    switch (pixmap_priv->type) {
+    case GLAMOR_TEXTURE_DRM:
+    case GLAMOR_TEXTURE_ONLY:
+        glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+        return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
+                                                pixmap,
+                                                pixmap_priv->base.fbo->tex,
+                                                TRUE, NULL, NULL);
+    default:
+        break;
+    }
+    return -1;
 }
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 1bb48ed..1507565 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -48,15 +48,15 @@
  * @DRM_ONLY: pixmap is in a external DRM buffer.
  * @TEXTURE_ONLY: pixmap is in an internal texture.
  */
-typedef enum  glamor_pixmap_type {
-	GLAMOR_MEMORY,
-	GLAMOR_MEMORY_MAP,
-	GLAMOR_TEXTURE_DRM,
-	GLAMOR_SEPARATE_TEXTURE,
-	GLAMOR_DRM_ONLY,
-	GLAMOR_TEXTURE_ONLY,
-	GLAMOR_TEXTURE_LARGE,
-	GLAMOR_TEXTURE_PACK
+typedef enum glamor_pixmap_type {
+    GLAMOR_MEMORY,
+    GLAMOR_MEMORY_MAP,
+    GLAMOR_TEXTURE_DRM,
+    GLAMOR_SEPARATE_TEXTURE,
+    GLAMOR_DRM_ONLY,
+    GLAMOR_TEXTURE_ONLY,
+    GLAMOR_TEXTURE_LARGE,
+    GLAMOR_TEXTURE_PACK
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
@@ -122,11 +122,11 @@ extern _X_EXPORT Bool glamor_close_screen(int scrnIndex, ScreenPtr screen);
 extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen);
 #endif
 
-
 /* Let glamor to know the screen's fbo. The low level
  * driver should already assign a tex
  * to this pixmap through the set_pixmap_texture. */
-extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap);
+extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
+                                               PixmapPtr *back_pixmap);
 
 /* @glamor_glyphs_init: Initialize glyphs internal data structures.
  *
@@ -139,13 +139,14 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPt
 extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
 
 extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
-						unsigned int tex);
+                                                unsigned int tex);
 
-extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type);
+extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap,
+                                             glamor_pixmap_type_t type);
 extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
-extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
-						unsigned int usage);
+extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
+                                                int depth, unsigned int usage);
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 
@@ -160,14 +161,21 @@ extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
  * Used by the DRI2 page flip. This function will exchange the KHR images and
  * fbos of the two pixmaps.
  * */
-extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back);
+extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front,
+                                                  PixmapPtr back);
 
-extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
+extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
+                                                  PixmapPtr back);
 
 /* The DDX is not supposed to call these three functions */
 extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
-extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h);
-extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16*, CARD32*);
+extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr
+                                                                       screen,
+                                                                       int w,
+                                                                       int h);
+extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
+                                                      unsigned int, Bool,
+                                                      CARD16 *, CARD32 *);
 
 /* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled.
  *
@@ -194,10 +202,9 @@ extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen);
  * content.
  * Returns the fd on success, -1 on error.
  * */
-extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen,
-						 PixmapPtr pixmap,
-						 CARD16 *stride,
-						 CARD32 *size);
+extern _X_EXPORT int glamor_dri3_fd_from_pixmap(ScreenPtr screen,
+                                                PixmapPtr pixmap,
+                                                CARD16 *stride, CARD32 *size);
 
 /* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap.
  *
@@ -208,7 +215,7 @@ extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen,
  * glamor DRI3 support to be activated.
  * Returns the name on success, -1 on error.
  * */
-extern _X_EXPORT int glamor_dri3_name_from_pixmap (PixmapPtr pixmap);
+extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap);
 
 /* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd.
  *
@@ -222,13 +229,13 @@ extern _X_EXPORT int glamor_dri3_name_from_pixmap (PixmapPtr pixmap);
  *
  * Returns a valid pixmap if the import succeeded, else NULL.
  * */
-extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
-							   int fd,
-							   CARD16 width,
-							   CARD16 height,
-							   CARD16 stride,
-							   CARD8 depth,
-							   CARD8 bpp);
+extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
+                                                          int fd,
+                                                          CARD16 width,
+                                                          CARD16 height,
+                                                          CARD16 stride,
+                                                          CARD8 depth,
+                                                          CARD8 bpp);
 
 #ifdef GLAMOR_FOR_XORG
 
@@ -265,8 +272,7 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
  * screen pixmap is a special, we handle it separately in this function.
  */
 extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
-							int handle,
-							int stride);
+                                                        int handle, int stride);
 
 /* @glamor_egl_create_textured_screen_ext:
  *
@@ -275,9 +281,10 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
  * the DDX's close screen, we have to free all the glamor related resources.
  */
 extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen,
-							    int handle,
-							    int stride,
-							    PixmapPtr *back_pixmap);
+                                                            int handle,
+                                                            int stride,
+                                                            PixmapPtr
+                                                            *back_pixmap);
 
 /*
  * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
@@ -292,8 +299,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen,
  * as well. Return true if successful, otherwise return FALSE.
  */
 extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
-							int handle,
-							int stride);
+                                                        int handle, int stride);
 
 /*
  * @glamor_egl_create_textured_pixmap_from_bo: Try to create a textured pixmap
@@ -305,8 +311,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
  * This function is similar to glamor_egl_create_textured_pixmap.
  */
 extern _X_EXPORT Bool
-	glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
-						      void *bo);
+ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo);
 
 #endif
 
@@ -314,119 +319,129 @@ extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 
-extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
+extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
+                                         DrawablePtr drawable);
 /* Glamor rendering/drawing functions with XXX_nf.
  * nf means no fallback within glamor internal if possible. If glamor
  * fail to accelerate the operation, glamor will return a false, and the
  * caller need to implement fallback method. Return a true means the
  * rendering request get done successfully. */
 extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
-					   GCPtr gc,
-					   int n, DDXPointPtr points,
-					   int *widths, int sorted);
+                                           GCPtr gc,
+                                           int n, DDXPointPtr points,
+                                           int *widths, int sorted);
 
 extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
-					       GCPtr gc,
-					       int nrect,
-					       xRectangle * prect);
+                                               GCPtr gc,
+                                               int nrect, xRectangle *prect);
 
 extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
-					  GCPtr gc, int depth, int x, int y,
-					  int w, int h, int left_pad,
-					  int image_format, char *bits);
+                                          GCPtr gc, int depth, int x, int y,
+                                          int w, int h, int left_pad,
+                                          int image_format, char *bits);
 
 extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
-					    DrawablePtr dst,
-					    GCPtr gc,
-					    BoxPtr box,
-					    int nbox,
-					    int dx,
-					    int dy,
-					    Bool reverse,
-					    Bool upsidedown, Pixel bitplane,
-					    void *closure);
+                                            DrawablePtr dst,
+                                            GCPtr gc,
+                                            BoxPtr box,
+                                            int nbox,
+                                            int dx,
+                                            int dy,
+                                            Bool reverse,
+                                            Bool upsidedown, Pixel bitplane,
+                                            void *closure);
 
 extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
-					  PicturePtr source,
-					  PicturePtr mask,
-					  PicturePtr dest,
-					  INT16 x_source,
-					  INT16 y_source,
-					  INT16 x_mask,
-					  INT16 y_mask,
-					  INT16 x_dest, INT16 y_dest,
-					  CARD16 width, CARD16 height);
+                                          PicturePtr source,
+                                          PicturePtr mask,
+                                          PicturePtr dest,
+                                          INT16 x_source,
+                                          INT16 y_source,
+                                          INT16 x_mask,
+                                          INT16 y_mask,
+                                          INT16 x_dest, INT16 y_dest,
+                                          CARD16 width, CARD16 height);
 
 extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
-					   PicturePtr src, PicturePtr dst,
-					   PictFormatPtr mask_format,
-					   INT16 x_src, INT16 y_src,
-					   int ntrap, xTrapezoid * traps);
+                                           PicturePtr src, PicturePtr dst,
+                                           PictFormatPtr mask_format,
+                                           INT16 x_src, INT16 y_src,
+                                           int ntrap, xTrapezoid * traps);
 
 extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
-				       PicturePtr src,
-				       PicturePtr dst,
-				       PictFormatPtr mask_format,
-				       INT16 x_src,
-				       INT16 y_src, int nlist,
-				       GlyphListPtr list, GlyphPtr * glyphs);
+                                       PicturePtr src,
+                                       PicturePtr dst,
+                                       PictFormatPtr mask_format,
+                                       INT16 x_src,
+                                       INT16 y_src, int nlist,
+                                       GlyphListPtr list, GlyphPtr * glyphs);
 
 extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
-					  PicturePtr pSrc,
-					  PicturePtr pDst,
-					  PictFormatPtr maskFormat,
-					  INT16 xSrc, INT16 ySrc,
-					  int ntris, xTriangle * tris);
-
+                                          PicturePtr pSrc,
+                                          PicturePtr pDst,
+                                          PictFormatPtr maskFormat,
+                                          INT16 xSrc, INT16 ySrc,
+                                          int ntris, xTriangle * tris);
 
 extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 
-extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
-					  DDXPointPtr points, int *widths, int n, int sorted);
+extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc,
+                                          char *src, DDXPointPtr points,
+                                          int *widths, int n, int sorted);
 
 extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
-					  DDXPointPtr points, int *widths, int count, char *dst);
+                                          DDXPointPtr points, int *widths,
+                                          int count, char *dst);
 
-extern _X_EXPORT Bool glamor_composite_rects_nf (CARD8         op,
-						 PicturePtr    pDst,
-						 xRenderColor  *color,
-						 int           nRect,
-						 xRectangle    *rects);
+extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op,
+                                                PicturePtr pDst,
+                                                xRenderColor * color,
+                                                int nRect, xRectangle *rects);
 
-extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h,
-					  unsigned int format, unsigned long planeMask, char *d);
+extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
+                                          int w, int h, unsigned int format,
+                                          unsigned long planeMask, char *d);
 
 extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
-					  INT16 x_off,
-					  INT16 y_off, int ntrap, xTrap * traps);
-
-extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-					   int srcx, int srcy, int w, int h, int dstx, int dsty,
-					   unsigned long bitPlane, RegionPtr *pRegion);
-
-extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
-						int x, int y, unsigned int nglyph,
-						CharInfoPtr * ppci, pointer pglyphBase);
+                                          INT16 x_off,
+                                          INT16 y_off, int ntrap,
+                                          xTrap * traps);
+
+extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst,
+                                           GCPtr pGC, int srcx, int srcy, int w,
+                                           int h, int dstx, int dsty,
+                                           unsigned long bitPlane,
+                                           RegionPtr *pRegion);
+
+extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
+                                                GCPtr pGC, int x, int y,
+                                                unsigned int nglyph,
+                                                CharInfoPtr * ppci,
+                                                pointer pglyphBase);
 
 extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
-					       int x, int y, unsigned int nglyph,
-					       CharInfoPtr * ppci, pointer pglyphBase);
+                                               int x, int y,
+                                               unsigned int nglyph,
+                                               CharInfoPtr * ppci,
+                                               pointer pglyphBase);
 
 extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
-					    DrawablePtr pDrawable, int w, int h, int x, int y);
+                                            DrawablePtr pDrawable, int w, int h,
+                                            int x, int y);
 
-extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-					   DDXPointPtr ppt);
+extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
+                                           int mode, int npt, DDXPointPtr ppt);
 
-extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-					     xSegment *pSeg);
+extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
+                                             int nseg, xSegment * pSeg);
 
-extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-					  DDXPointPtr ppt);
+extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC,
+                                          int mode, int npt, DDXPointPtr ppt);
 
-extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
-					   DDXPointPtr points);
+extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
+                                           int mode, int n, DDXPointPtr points);
 
-extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports);
+extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen,
+                                                    int num_texture_ports);
 
-#endif /* GLAMOR_H */
+#endif                          /* GLAMOR_H */
diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c
index ac85296..7a918b7 100644
--- a/glamor/glamor_addtraps.c
+++ b/glamor/glamor_addtraps.c
@@ -30,36 +30,32 @@
 
 static Bool
 _glamor_add_traps(PicturePtr pPicture,
-		  INT16 x_off, 
-		  INT16 y_off, int ntrap, xTrap * traps,
-		  Bool fallback)
+                  INT16 x_off,
+                  INT16 y_off, int ntrap, xTrap * traps, Bool fallback)
 {
-	if (!fallback
-	    && ( !pPicture->pDrawable 
-		 || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
-		return FALSE;
+    if (!fallback
+        && (!pPicture->pDrawable
+            || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
+        return FALSE;
 
-	if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
-		fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
-		glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW);
-	}
+    if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
+        fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
+        glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW);
+    }
 
-	return TRUE;
+    return TRUE;
 }
 
 void
 glamor_add_traps(PicturePtr pPicture,
-		 INT16 x_off, 
-		 INT16 y_off, int ntrap, xTrap * traps)
+                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
 {
-	_glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
+    _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
 }
 
 Bool
 glamor_add_traps_nf(PicturePtr pPicture,
-		    INT16 x_off, 
-		    INT16 y_off, int ntrap, xTrap * traps)
+                    INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
 {
-	return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
+    return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
 }
-
diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 1a57699..a0d5980 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -36,243 +36,241 @@
  * compositeRects acceleration implementation
  */
 
-static int16_t bound(int16_t a, uint16_t b)
+static int16_t
+bound(int16_t a, uint16_t b)
 {
-	int v = (int)a + (int)b;
-	if (v > MAXSHORT)
-		return MAXSHORT;
-	return v;
+    int v = (int) a + (int) b;
+
+    if (v > MAXSHORT)
+        return MAXSHORT;
+    return v;
 }
 
 static Bool
-_pixman_region_init_clipped_rectangles(pixman_region16_t *region,
-				       unsigned int num_rects,
-				       xRectangle *rects,
-				       int tx, int ty,
-				       BoxPtr extents)
+_pixman_region_init_clipped_rectangles(pixman_region16_t * region,
+                                       unsigned int num_rects,
+                                       xRectangle *rects,
+                                       int tx, int ty, BoxPtr extents)
 {
-	pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
-	pixman_bool_t ret;
-	unsigned int i, j;
-
-	if (num_rects > ARRAY_SIZE(stack_boxes)) {
-		boxes = malloc(sizeof(pixman_box16_t) * num_rects);
-		if (boxes == NULL)
-			return FALSE;
-	}
-
-	for (i = j = 0; i < num_rects; i++) {
-		boxes[j].x1 = rects[i].x + tx;
-		if (boxes[j].x1 < extents->x1)
-			boxes[j].x1 = extents->x1;
-
-		boxes[j].y1 = rects[i].y + ty;
-		if (boxes[j].y1 < extents->y1)
-			boxes[j].y1 = extents->y1;
-
-		boxes[j].x2 = bound(rects[i].x + tx, rects[i].width);
-		if (boxes[j].x2 > extents->x2)
-			boxes[j].x2 = extents->x2;
-
-		boxes[j].y2 = bound(rects[i].y + ty, rects[i].height);
-		if (boxes[j].y2 > extents->y2)
-			boxes[j].y2 = extents->y2;
-
-		if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1)
-			j++;
-	}
-
-	ret = FALSE;
-	if (j)
-	    ret = pixman_region_init_rects(region, boxes, j);
-
-	if (boxes != stack_boxes)
-		free(boxes);
-
-	DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n",
-	     __FUNCTION__, num_rects,
-	     region->extents.x1, region->extents.y1,
-	     region->extents.x2, region->extents.y2,
-	     j);
-	return ret;
+    pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
+    pixman_bool_t ret;
+    unsigned int i, j;
+
+    if (num_rects > ARRAY_SIZE(stack_boxes)) {
+        boxes = malloc(sizeof(pixman_box16_t) * num_rects);
+        if (boxes == NULL)
+            return FALSE;
+    }
+
+    for (i = j = 0; i < num_rects; i++) {
+        boxes[j].x1 = rects[i].x + tx;
+        if (boxes[j].x1 < extents->x1)
+            boxes[j].x1 = extents->x1;
+
+        boxes[j].y1 = rects[i].y + ty;
+        if (boxes[j].y1 < extents->y1)
+            boxes[j].y1 = extents->y1;
+
+        boxes[j].x2 = bound(rects[i].x + tx, rects[i].width);
+        if (boxes[j].x2 > extents->x2)
+            boxes[j].x2 = extents->x2;
+
+        boxes[j].y2 = bound(rects[i].y + ty, rects[i].height);
+        if (boxes[j].y2 > extents->y2)
+            boxes[j].y2 = extents->y2;
+
+        if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1)
+            j++;
+    }
+
+    ret = FALSE;
+    if (j)
+        ret = pixman_region_init_rects(region, boxes, j);
+
+    if (boxes != stack_boxes)
+        free(boxes);
+
+    DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n",
+           __FUNCTION__, num_rects,
+           region->extents.x1, region->extents.y1,
+           region->extents.x2, region->extents.y2, j);
+    return ret;
 }
 
-
 void
-glamor_composite_rectangles(CARD8	 op,
-			 PicturePtr	 dst,
-			 xRenderColor	*color,
-			 int		 num_rects,
-			 xRectangle	*rects)
+glamor_composite_rectangles(CARD8 op,
+                            PicturePtr dst,
+                            xRenderColor * color,
+                            int num_rects, xRectangle *rects)
 {
-	PixmapPtr pixmap;
-	struct glamor_pixmap_private *priv;
-	pixman_region16_t region;
-	pixman_box16_t *boxes;
-	int dst_x, dst_y;
-	int num_boxes;
-	PicturePtr source = NULL;
-	Bool need_free_region = FALSE;
-
-	DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n",
-	     __FUNCTION__, op,
-	     (color->alpha >> 8 << 24) |
-	     (color->red   >> 8 << 16) |
-	     (color->green >> 8 << 8) |
-	     (color->blue  >> 8 << 0),
-	     num_rects,
-	     rects[0].x, rects[0].y, rects[0].width, rects[0].height);
-
-	if (!num_rects)
-		return;
-
-	if (region_is_empty(dst->pCompositeClip)) {
-		DEBUGF("%s: empty clip, skipping\n", __FUNCTION__);
-		return;
-	}
-
-	if ((color->red|color->green|color->blue|color->alpha) <= 0x00ff) {
-		switch (op) {
-		case PictOpOver:
-		case PictOpOutReverse:
-		case PictOpAdd:
-			return;
-		case  PictOpInReverse:
-		case  PictOpSrc:
-			op = PictOpClear;
-			break;
-		case  PictOpAtopReverse:
-			op = PictOpOut;
-			break;
-		case  PictOpXor:
-			op = PictOpOverReverse;
-			break;
-		}
-	}
-	if (color->alpha <= 0x00ff) {
-		switch (op) {
-		case PictOpOver:
-		case PictOpOutReverse:
-			return;
-		case  PictOpInReverse:
-			op = PictOpClear;
-			break;
-		case  PictOpAtopReverse:
-			op = PictOpOut;
-			break;
-		case  PictOpXor:
-			op = PictOpOverReverse;
-			break;
-		}
-	} else if (color->alpha >= 0xff00) {
-		switch (op) {
-		case PictOpOver:
-			op = PictOpSrc;
-			break;
-		case PictOpInReverse:
-			return;
-		case PictOpOutReverse:
-			op = PictOpClear;
-			break;
-		case  PictOpAtopReverse:
-			op = PictOpOverReverse;
-			break;
-		case  PictOpXor:
-			op = PictOpOut;
-			break;
-		}
-	}
-	DEBUGF("%s: converted to op %d\n", __FUNCTION__, op);
-
-	if (!_pixman_region_init_clipped_rectangles(&region,
-						    num_rects, rects,
-						    dst->pDrawable->x,
-						    dst->pDrawable->y,
-						    &dst->pCompositeClip->extents))
-	{
-		DEBUGF("%s: allocation failed for region\n", __FUNCTION__);
-		return;
-	}
-
-	pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
-	priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
-		goto fallback;
-	if (dst->alphaMap) {
-		DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__);
-		goto fallback;
-	}
-
-	need_free_region = TRUE;
-
-	DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n",
-	     __FUNCTION__,
-	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
-	     RegionExtents(&region)->x2, RegionExtents(&region)->y2,
-	     RegionNumRects(&region));
-
-	if (dst->pCompositeClip->data &&
-	    (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
-	     region_is_empty(&region))) {
-		DEBUGF("%s: zero-intersection between rectangles and clip\n",
-		     __FUNCTION__);
-		pixman_region_fini(&region);
-		return;
-	}
-
-	DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n",
-	     __FUNCTION__,
-	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
-	     RegionExtents(&region)->x2, RegionExtents(&region)->y2,
-	     RegionNumRects(&region));
-
-	glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
-	pixman_region_translate(&region, dst_x, dst_y);
-
-	DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
-	     __FUNCTION__, dst_x, dst_y,
-	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
-	     RegionExtents(&region)->x2, RegionExtents(&region)->y2);
-
-
-	boxes = pixman_region_rectangles(&region, &num_boxes);
-	if (op == PictOpSrc || op == PictOpClear) {
-		CARD32 pixel;
-		if (op == PictOpClear)
-			pixel = 0;
-		else
-			miRenderColorToPixel(dst->pFormat, color, &pixel);
-		glamor_solid_boxes(pixmap, boxes, num_boxes, pixel);
-
-		goto done;
-	} else {
-		if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {
-			int error;
-
-			source = CreateSolidPicture(0, color, &error);
-			if (!source)
-				goto done;
-			if (glamor_composite_clipped_region(op, source,
-						NULL, dst,
-						NULL, NULL, priv,
-						&region,
-						0,0,0,0,0,0))
-				goto done;
-		}
-	}
-fallback:
-	miCompositeRects(op, dst, color, num_rects, rects);
-done:
-	/* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must
-	 * manually append the damaged regions ourselves.
-	 */
-	DamageRegionAppend(&pixmap->drawable, &region);
-	DamageRegionProcessPending(&pixmap->drawable);
-
-	if (need_free_region)
-		pixman_region_fini(&region);
-	if (source)
-		FreePicture(source, 0);
-	return;
+    PixmapPtr pixmap;
+    struct glamor_pixmap_private *priv;
+    pixman_region16_t region;
+    pixman_box16_t *boxes;
+    int dst_x, dst_y;
+    int num_boxes;
+    PicturePtr source = NULL;
+    Bool need_free_region = FALSE;
+
+    DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n",
+           __FUNCTION__, op,
+           (color->alpha >> 8 << 24) |
+           (color->red >> 8 << 16) |
+           (color->green >> 8 << 8) |
+           (color->blue >> 8 << 0),
+           num_rects, rects[0].x, rects[0].y, rects[0].width, rects[0].height);
+
+    if (!num_rects)
+        return;
+
+    if (region_is_empty(dst->pCompositeClip)) {
+        DEBUGF("%s: empty clip, skipping\n", __FUNCTION__);
+        return;
+    }
+
+    if ((color->red | color->green | color->blue | color->alpha) <= 0x00ff) {
+        switch (op) {
+        case PictOpOver:
+        case PictOpOutReverse:
+        case PictOpAdd:
+            return;
+        case PictOpInReverse:
+        case PictOpSrc:
+            op = PictOpClear;
+            break;
+        case PictOpAtopReverse:
+            op = PictOpOut;
+            break;
+        case PictOpXor:
+            op = PictOpOverReverse;
+            break;
+        }
+    }
+    if (color->alpha <= 0x00ff) {
+        switch (op) {
+        case PictOpOver:
+        case PictOpOutReverse:
+            return;
+        case PictOpInReverse:
+            op = PictOpClear;
+            break;
+        case PictOpAtopReverse:
+            op = PictOpOut;
+            break;
+        case PictOpXor:
+            op = PictOpOverReverse;
+            break;
+        }
+    }
+    else if (color->alpha >= 0xff00) {
+        switch (op) {
+        case PictOpOver:
+            op = PictOpSrc;
+            break;
+        case PictOpInReverse:
+            return;
+        case PictOpOutReverse:
+            op = PictOpClear;
+            break;
+        case PictOpAtopReverse:
+            op = PictOpOverReverse;
+            break;
+        case PictOpXor:
+            op = PictOpOut;
+            break;
+        }
+    }
+    DEBUGF("%s: converted to op %d\n", __FUNCTION__, op);
+
+    if (!_pixman_region_init_clipped_rectangles(&region,
+                                                num_rects, rects,
+                                                dst->pDrawable->x,
+                                                dst->pDrawable->y,
+                                                &dst->pCompositeClip->extents))
+    {
+        DEBUGF("%s: allocation failed for region\n", __FUNCTION__);
+        return;
+    }
+
+    pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+    priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
+        goto fallback;
+    if (dst->alphaMap) {
+        DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__);
+        goto fallback;
+    }
+
+    need_free_region = TRUE;
+
+    DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n",
+           __FUNCTION__,
+           RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+           RegionExtents(&region)->x2, RegionExtents(&region)->y2,
+           RegionNumRects(&region));
+
+    if (dst->pCompositeClip->data &&
+        (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
+         region_is_empty(&region))) {
+        DEBUGF("%s: zero-intersection between rectangles and clip\n",
+               __FUNCTION__);
+        pixman_region_fini(&region);
+        return;
+    }
+
+    DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n",
+           __FUNCTION__,
+           RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+           RegionExtents(&region)->x2, RegionExtents(&region)->y2,
+           RegionNumRects(&region));
+
+    glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
+    pixman_region_translate(&region, dst_x, dst_y);
+
+    DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
+           __FUNCTION__, dst_x, dst_y,
+           RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+           RegionExtents(&region)->x2, RegionExtents(&region)->y2);
+
+    boxes = pixman_region_rectangles(&region, &num_boxes);
+    if (op == PictOpSrc || op == PictOpClear) {
+        CARD32 pixel;
+
+        if (op == PictOpClear)
+            pixel = 0;
+        else
+            miRenderColorToPixel(dst->pFormat, color, &pixel);
+        glamor_solid_boxes(pixmap, boxes, num_boxes, pixel);
+
+        goto done;
+    }
+    else {
+        if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {
+            int error;
+
+            source = CreateSolidPicture(0, color, &error);
+            if (!source)
+                goto done;
+            if (glamor_composite_clipped_region(op, source,
+                                                NULL, dst,
+                                                NULL, NULL, priv,
+                                                &region, 0, 0, 0, 0, 0, 0))
+                goto done;
+        }
+    }
+ fallback:
+    miCompositeRects(op, dst, color, num_rects, rects);
+ done:
+    /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must
+     * manually append the damaged regions ourselves.
+     */
+    DamageRegionAppend(&pixmap->drawable, &region);
+    DamageRegionProcessPending(&pixmap->drawable);
+
+    if (need_free_region)
+        pixman_region_fini(&region);
+    if (source)
+        FreePicture(source, 0);
+    return;
 }
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 4e6f953..2735ba0 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -34,643 +34,624 @@
 #ifndef GLAMOR_GLES2
 static Bool
 glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
-			    DrawablePtr dst,
-			    GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
+                            DrawablePtr dst,
+                            GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
 {
-	ScreenPtr screen = dst->pScreen;
-	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-	glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-	int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
-	int fbo_x_off, fbo_y_off;
-	int src_fbo_x_off, src_fbo_y_off;
-
-	if (!glamor_priv->has_fbo_blit) {
-		glamor_delayed_fallback(screen,
-					"no EXT_framebuffer_blit\n");
-		return FALSE;
-	}
-	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-
-	if (gc) {
-		if (gc->alu != GXcopy) {
-			glamor_delayed_fallback(screen, "non-copy ALU\n");
-			return FALSE;
-		}
-	}
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
-		glamor_delayed_fallback(screen, "no src fbo\n");
-		return FALSE;
-	}
-
-	if (glamor_set_destination_pixmap(dst_pixmap))
-		return FALSE;
-
-	pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
-	pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
-				    src_pixmap_priv->base.fbo->fb);
-	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
-				   &dst_y_off);
-	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
-				   &src_y_off);
-	dst_x_off += fbo_x_off;
-	dst_y_off += fbo_y_off;
-	src_y_off += dy + src_fbo_y_off;
-	src_x_off += src_fbo_x_off;
-
-	for (i = 0; i < nbox; i++) {
-		if (glamor_priv->yInverted) {
-			dispatch->glBlitFramebuffer((box[i].x1 + dx +
-						     src_x_off),
-						    (box[i].y1 +
-						     src_y_off),
-						    (box[i].x2 + dx +
-						     src_x_off),
-						    (box[i].y2 +
-						     src_y_off),
-						    (box[i].x1 +
-						     dst_x_off),
-						    (box[i].y1 +
-						     dst_y_off),
-						    (box[i].x2 +
-						     dst_x_off),
-						    (box[i].y2 +
-						     dst_y_off),
-						    GL_COLOR_BUFFER_BIT,
-						    GL_NEAREST);
-		} else {
-			int flip_dst_y1 =
-			    dst_pixmap->drawable.height - (box[i].y2 +
-							   dst_y_off);
-			int flip_dst_y2 =
-			    dst_pixmap->drawable.height - (box[i].y1 +
-							   dst_y_off);
-			int flip_src_y1 =
-			    src_pixmap->drawable.height - (box[i].y2 +
-							   src_y_off);
-			int flip_src_y2 =
-			    src_pixmap->drawable.height - (box[i].y1 +
-							   src_y_off);
-
-			dispatch->glBlitFramebuffer(box[i].x1 + dx +
-						    src_x_off,
-						    flip_src_y1,
-						    box[i].x2 + dx +
-						    src_x_off,
-						    flip_src_y2,
-						    box[i].x1 +
-						    dst_x_off,
-						    flip_dst_y1,
-						    box[i].x2 +
-						    dst_x_off,
-						    flip_dst_y2,
-						    GL_COLOR_BUFFER_BIT,
-						    GL_NEAREST);
-		}
-	}
-	glamor_put_dispatch(glamor_priv);
-	glamor_priv->state = BLIT_STATE;
-	return TRUE;
+    ScreenPtr screen = dst->pScreen;
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+    int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
+    int fbo_x_off, fbo_y_off;
+    int src_fbo_x_off, src_fbo_y_off;
+
+    if (!glamor_priv->has_fbo_blit) {
+        glamor_delayed_fallback(screen, "no EXT_framebuffer_blit\n");
+        return FALSE;
+    }
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+
+    if (gc) {
+        if (gc->alu != GXcopy) {
+            glamor_delayed_fallback(screen, "non-copy ALU\n");
+            return FALSE;
+        }
+    }
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+        glamor_delayed_fallback(screen, "no src fbo\n");
+        return FALSE;
+    }
+
+    if (glamor_set_destination_pixmap(dst_pixmap))
+        return FALSE;
+
+    pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
+    pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
+                                src_pixmap_priv->base.fbo->fb);
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    dst_x_off += fbo_x_off;
+    dst_y_off += fbo_y_off;
+    src_y_off += dy + src_fbo_y_off;
+    src_x_off += src_fbo_x_off;
+
+    for (i = 0; i < nbox; i++) {
+        if (glamor_priv->yInverted) {
+            dispatch->glBlitFramebuffer((box[i].x1 + dx +
+                                         src_x_off),
+                                        (box[i].y1 +
+                                         src_y_off),
+                                        (box[i].x2 + dx +
+                                         src_x_off),
+                                        (box[i].y2 +
+                                         src_y_off),
+                                        (box[i].x1 +
+                                         dst_x_off),
+                                        (box[i].y1 +
+                                         dst_y_off),
+                                        (box[i].x2 +
+                                         dst_x_off),
+                                        (box[i].y2 +
+                                         dst_y_off),
+                                        GL_COLOR_BUFFER_BIT, GL_NEAREST);
+        }
+        else {
+            int flip_dst_y1 =
+                dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
+            int flip_dst_y2 =
+                dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
+            int flip_src_y1 =
+                src_pixmap->drawable.height - (box[i].y2 + src_y_off);
+            int flip_src_y2 =
+                src_pixmap->drawable.height - (box[i].y1 + src_y_off);
+
+            dispatch->glBlitFramebuffer(box[i].x1 + dx +
+                                        src_x_off,
+                                        flip_src_y1,
+                                        box[i].x2 + dx +
+                                        src_x_off,
+                                        flip_src_y2,
+                                        box[i].x1 +
+                                        dst_x_off,
+                                        flip_dst_y1,
+                                        box[i].x2 +
+                                        dst_x_off,
+                                        flip_dst_y2,
+                                        GL_COLOR_BUFFER_BIT, GL_NEAREST);
+        }
+    }
+    glamor_put_dispatch(glamor_priv);
+    glamor_priv->state = BLIT_STATE;
+    return TRUE;
 }
 #endif
 
 static Bool
 glamor_copy_n_to_n_textured(DrawablePtr src,
-			    DrawablePtr dst,
-			    GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
+                            DrawablePtr dst,
+                            GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(dst->pScreen);
-	glamor_gl_dispatch *dispatch;
-	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-	int i;
-	float vertices[8], texcoords[8];
-	glamor_pixmap_private *src_pixmap_priv;
-	glamor_pixmap_private *dst_pixmap_priv;
-	int src_x_off, src_y_off, dst_x_off, dst_y_off;
-	enum glamor_pixmap_status src_status = GLAMOR_NONE;
-	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-
-	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-
-	if (!src_pixmap_priv->base.gl_fbo) {
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(dst->pScreen);
+    glamor_gl_dispatch *dispatch;
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    int i;
+    float vertices[8], texcoords[8];
+    glamor_pixmap_private *src_pixmap_priv;
+    glamor_pixmap_private *dst_pixmap_priv;
+    int src_x_off, src_y_off, dst_x_off, dst_y_off;
+    enum glamor_pixmap_status src_status = GLAMOR_NONE;
+    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+
+    if (!src_pixmap_priv->base.gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
-		return FALSE;
+        glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
+        return FALSE;
 #else
-		src_status = glamor_upload_pixmap_to_texture(src_pixmap);
-		if (src_status != GLAMOR_UPLOAD_DONE)
-			return FALSE;
+        src_status = glamor_upload_pixmap_to_texture(src_pixmap);
+        if (src_status != GLAMOR_UPLOAD_DONE)
+            return FALSE;
 
-		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+        src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 #endif
-	}
+    }
 
+    pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
-	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
 
-	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
-				   &dst_y_off);
+    dispatch = glamor_get_dispatch(glamor_priv);
 
-	dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), vertices);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    dx += src_x_off;
+    dy += src_y_off;
 
-	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
-				   &src_y_off);
-	dx += src_x_off;
-	dy += src_y_off;
-
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D,
-				src_pixmap_priv->base.fbo->tex);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
 #ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_S,
-				  GL_CLAMP_TO_BORDER);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_T,
-				  GL_CLAMP_TO_BORDER);
+    dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 #endif
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-					GL_FLOAT, GL_FALSE,
-					2 * sizeof(float),
-					texcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-	dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
-			      REVERT_NONE);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
-			      SWAP_NONE_UPLOADING);
-
-	for (i = 0; i < nbox; i++) {
-
-		glamor_set_normalize_vcoords(dst_pixmap_priv,
-					     dst_xscale, dst_yscale,
-					     box[i].x1 + dst_x_off,
-					     box[i].y1 + dst_y_off,
-					     box[i].x2 + dst_x_off,
-					     box[i].y2 + dst_y_off,
-					     glamor_priv->yInverted,
-					     vertices);
-
-		glamor_set_normalize_tcoords(src_pixmap_priv,
-					     src_xscale,
-					     src_yscale,
-					     box[i].x1 + dx,
-					     box[i].y1 + dy,
-					     box[i].x2 + dx,
-					     box[i].y2 + dy,
-					     glamor_priv->yInverted,
-					     texcoords);
-		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-	}
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                                    GL_FLOAT, GL_FALSE,
+                                    2 * sizeof(float), texcoords);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+    dispatch->glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE);
+    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
+                          SWAP_NONE_UPLOADING);
+
+    for (i = 0; i < nbox; i++) {
+
+        glamor_set_normalize_vcoords(dst_pixmap_priv,
+                                     dst_xscale, dst_yscale,
+                                     box[i].x1 + dst_x_off,
+                                     box[i].y1 + dst_y_off,
+                                     box[i].x2 + dst_x_off,
+                                     box[i].y2 + dst_y_off,
+                                     glamor_priv->yInverted, vertices);
+
+        glamor_set_normalize_tcoords(src_pixmap_priv,
+                                     src_xscale,
+                                     src_yscale,
+                                     box[i].x1 + dx,
+                                     box[i].y1 + dy,
+                                     box[i].x2 + dx,
+                                     box[i].y2 + dy,
+                                     glamor_priv->yInverted, texcoords);
+        dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-	dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUseProgram(0);
-	/* The source texture is bound to a fbo, we have to flush it here. */
-	glamor_put_dispatch(glamor_priv);
-	glamor_priv->state = RENDER_STATE;
-	glamor_priv->render_idle_cnt = 0;
-	return TRUE;
+    dispatch->glUseProgram(0);
+    /* The source texture is bound to a fbo, we have to flush it here. */
+    glamor_put_dispatch(glamor_priv);
+    glamor_priv->state = RENDER_STATE;
+    glamor_priv->render_idle_cnt = 0;
+    return TRUE;
 }
 
 static Bool
 __glamor_copy_n_to_n(DrawablePtr src,
-		     DrawablePtr dst,
-		     GCPtr gc,
-		     BoxPtr box,
-		     int nbox,
-		     int dx,
-		     int dy,
-		     Bool reverse,
-		     Bool upsidedown, Pixel bitplane,
-		     void *closure)
+                     DrawablePtr dst,
+                     GCPtr gc,
+                     BoxPtr box,
+                     int nbox,
+                     int dx,
+                     int dy,
+                     Bool reverse,
+                     Bool upsidedown, Pixel bitplane, void *closure)
 {
-	PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
-	DrawablePtr temp_src = src;
-	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
-	glamor_screen_private *glamor_priv;
-	BoxRec bound;
-	ScreenPtr screen;
-	int temp_dx = dx;
-	int temp_dy = dy;
-	int src_x_off, src_y_off, dst_x_off, dst_y_off;
-	int i;
-	int overlaped = 0;
-	Bool ret = FALSE;
-
-	dst_pixmap = glamor_get_drawable_pixmap(dst);
-	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-	src_pixmap = glamor_get_drawable_pixmap(src);
-	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	screen = dst_pixmap->drawable.pScreen;
-	glamor_priv = glamor_get_screen_private(dst->pScreen);
-	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
-				   &src_y_off);
-
-	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
-				   &dst_y_off);
-
-	if (src_pixmap_priv->base.fbo
-		&& src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
-		int x_shift = abs(src_x_off - dx - dst_x_off);
-		int y_shift = abs(src_y_off - dy - dst_y_off);
-		for (i = 0; i < nbox; i++) {
-			if (x_shift < abs(box[i].x2 - box[i].x1)
-			    && y_shift < abs(box[i].y2 - box[i].y1)) {
-				overlaped = 1;
-				break;
-			}
-		}
-	}
-	DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
-		box[0].x1, box[0].y1,
-		box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
-		dx, dy,
-		src_pixmap, dst_pixmap);
+    PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
+    DrawablePtr temp_src = src;
+    glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+    glamor_screen_private *glamor_priv;
+    BoxRec bound;
+    ScreenPtr screen;
+    int temp_dx = dx;
+    int temp_dy = dy;
+    int src_x_off, src_y_off, dst_x_off, dst_y_off;
+    int i;
+    int overlaped = 0;
+    Bool ret = FALSE;
+
+    dst_pixmap = glamor_get_drawable_pixmap(dst);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    src_pixmap = glamor_get_drawable_pixmap(src);
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+    screen = dst_pixmap->drawable.pScreen;
+    glamor_priv = glamor_get_screen_private(dst->pScreen);
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+
+    if (src_pixmap_priv->base.fbo
+        && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
+        int x_shift = abs(src_x_off - dx - dst_x_off);
+        int y_shift = abs(src_y_off - dy - dst_y_off);
+
+        for (i = 0; i < nbox; i++) {
+            if (x_shift < abs(box[i].x2 - box[i].x1)
+                && y_shift < abs(box[i].y2 - box[i].y1)) {
+                overlaped = 1;
+                break;
+            }
+        }
+    }
+    DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
+           box[0].x1, box[0].y1,
+           box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
+           dx, dy, src_pixmap, dst_pixmap);
 #ifndef GLAMOR_GLES2
-	if (!overlaped &&
-	    (glamor_priv->state != RENDER_STATE
-	     || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
-	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
-					   dy)) {
-		ret = TRUE;
-		goto done;
-	}
+    if (!overlaped &&
+        (glamor_priv->state != RENDER_STATE
+         || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
+        && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
+        ret = TRUE;
+        goto done;
+    }
 #endif
-	glamor_calculate_boxes_bound(&bound, box, nbox);
-
-	/*  Overlaped indicate the src and dst are the same pixmap. */
-	if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
-			  && (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
-			      * 4 >
-			      src_pixmap->drawable.width *
-			      src_pixmap->drawable.height)
-		             || !(glamor_check_fbo_size(glamor_priv,
-					src_pixmap->drawable.width,
-					src_pixmap->drawable.height))))) {
-
-		temp_pixmap = glamor_create_pixmap(screen,
-						   bound.x2 - bound.x1,
-						   bound.y2 - bound.y1,
-						   src_pixmap->
-						   drawable.depth,
-						   overlaped ? 0 :
-						   GLAMOR_CREATE_PIXMAP_CPU);
-		assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
-		assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
-		if (!temp_pixmap)
-			goto done;
-		glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
-		temp_src = &temp_pixmap->drawable;
-
-		if (overlaped)
-			glamor_copy_n_to_n_textured(src, temp_src, gc, box,
-						    nbox,
-						    temp_dx + bound.x1,
-						    temp_dy + bound.y1);
-		else
-			fbCopyNtoN(src, temp_src, gc, box, nbox,
-				   temp_dx + bound.x1, temp_dy + bound.y1,
-				   reverse, upsidedown, bitplane, closure);
-		glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
-		temp_dx = -bound.x1;
-		temp_dy = -bound.y1;
-	} else {
-		temp_dx = dx;
-		temp_dy = dy;
-		temp_src = src;
-	}
-
-	if (glamor_copy_n_to_n_textured
-	    (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
-		ret = TRUE;
-	}
-done:
-	if (temp_src != src)
-		glamor_destroy_pixmap(temp_pixmap);
-	return ret;
+    glamor_calculate_boxes_bound(&bound, box, nbox);
+
+    /*  Overlaped indicate the src and dst are the same pixmap. */
+    if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
+                      && (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
+                           * 4 >
+                           src_pixmap->drawable.width *
+                           src_pixmap->drawable.height)
+                          || !(glamor_check_fbo_size(glamor_priv,
+                                                     src_pixmap->drawable.width,
+                                                     src_pixmap->drawable.
+                                                     height))))) {
+
+        temp_pixmap = glamor_create_pixmap(screen,
+                                           bound.x2 - bound.x1,
+                                           bound.y2 - bound.y1,
+                                           src_pixmap->drawable.depth,
+                                           overlaped ? 0 :
+                                           GLAMOR_CREATE_PIXMAP_CPU);
+        assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
+        assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
+        if (!temp_pixmap)
+            goto done;
+        glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
+        temp_src = &temp_pixmap->drawable;
+
+        if (overlaped)
+            glamor_copy_n_to_n_textured(src, temp_src, gc, box,
+                                        nbox,
+                                        temp_dx + bound.x1, temp_dy + bound.y1);
+        else
+            fbCopyNtoN(src, temp_src, gc, box, nbox,
+                       temp_dx + bound.x1, temp_dy + bound.y1,
+                       reverse, upsidedown, bitplane, closure);
+        glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
+        temp_dx = -bound.x1;
+        temp_dy = -bound.y1;
+    }
+    else {
+        temp_dx = dx;
+        temp_dy = dy;
+        temp_src = src;
+    }
+
+    if (glamor_copy_n_to_n_textured
+        (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
+        ret = TRUE;
+    }
+ done:
+    if (temp_src != src)
+        glamor_destroy_pixmap(temp_pixmap);
+    return ret;
 }
 
 static Bool
 _glamor_copy_n_to_n(DrawablePtr src,
-		    DrawablePtr dst,
-		    GCPtr gc,
-		    BoxPtr box,
-		    int nbox,
-		    int dx,
-		    int dy,
-		    Bool reverse,
-		    Bool upsidedown, Pixel bitplane,
-		    void *closure, Bool fallback)
+                    DrawablePtr dst,
+                    GCPtr gc,
+                    BoxPtr box,
+                    int nbox,
+                    int dx,
+                    int dy,
+                    Bool reverse,
+                    Bool upsidedown, Pixel bitplane,
+                    void *closure, Bool fallback)
 {
-	PixmapPtr dst_pixmap, src_pixmap;
-	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	BoxPtr extent;
-	RegionRec region;
-	int src_x_off, src_y_off, dst_x_off, dst_y_off;
-	Bool ok = FALSE;
-	int force_clip = 0;
-
-	if (nbox == 0)
-		return TRUE;
-	dst_pixmap = glamor_get_drawable_pixmap(dst);
-	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-	src_pixmap = glamor_get_drawable_pixmap(src);
-	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-
-	glamor_priv = glamor_get_screen_private(dst->pScreen);
-
-	DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
-		box[0].x1, box[0].y1,
-		box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
-		dx, dy,
-		src_pixmap, dst_pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
-		goto fall_back;
-
-	if (gc) {
-		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-			goto fall_back;
-		dispatch = glamor_get_dispatch(glamor_priv);
-		if (!glamor_set_alu(dispatch, gc->alu)) {
-			glamor_put_dispatch(glamor_priv);
-			goto fail;
-		}
-		glamor_put_dispatch(glamor_priv);
-	}
-
-	if (!src_pixmap_priv) {
-		glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
-		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	}
-
-	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
-				   &src_y_off);
-	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
-				   &dst_y_off);
-
-	RegionInitBoxes(&region, box, nbox);
-	extent = RegionExtents(&region);
-
-	if (!glamor_check_fbo_size(glamor_priv,
-		extent->x2 - extent->x1, extent->y2 - extent->y1)
-	   && (src_pixmap_priv->type == GLAMOR_MEMORY
-		|| (src_pixmap_priv == dst_pixmap_priv))) {
-		force_clip = 1;
-	}
-
-	if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-	    || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-			glamor_pixmap_clipped_regions *clipped_dst_regions;
-			int n_dst_region, i, j;
-			PixmapPtr temp_source_pixmap;
-			glamor_pixmap_private *temp_source_priv = NULL;
-
-			RegionTranslate(&region, dst_x_off, dst_y_off);
-			if (!force_clip)
-				clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
-										     &region, &n_dst_region, 0,
-										     reverse, upsidedown);
-			else
-				clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
-										         &region, &n_dst_region,
-											 glamor_priv->max_fbo_size,
-											 glamor_priv->max_fbo_size,
-											 reverse, upsidedown);
-			for(i = 0; i < n_dst_region; i++)
-			{
-				int n_src_region;
-				glamor_pixmap_clipped_regions *clipped_src_regions;
-				BoxPtr current_boxes;
-				int n_current_boxes;
-
-				SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
-
-				temp_source_pixmap = NULL;
-				if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-					RegionTranslate(clipped_dst_regions[i].region,
-							-dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy);
-					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
-											     clipped_dst_regions[i].region,
-											     &n_src_region, 0,
-											     reverse, upsidedown);
-					DEBUGF("Source is large pixmap.\n");
-					for (j = 0; j < n_src_region; j++)
-					{
-						if (src_pixmap_priv != dst_pixmap_priv)
-							SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
-						else if (src_pixmap_priv == dst_pixmap_priv &&
-						    clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) {
-							/* source and the dest are the same, but need different block_idx.
-							 * we create a empty pixmap and fill the required source fbo and box to
-							 * it. It's a little hacky, but avoid extra copy. */
-							temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0,
-												  src->depth, 0);
-							if (!temp_source_pixmap) {
-								ok = FALSE;
-								goto fail;
-							}
-							src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
-										      src_pixmap->drawable.width,
-										      src_pixmap->drawable.height,
-										      0, 0, src_pixmap->devKind, NULL);
-							temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap);
-							*temp_source_priv = *src_pixmap_priv;
-							temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx];
-							temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx];
-							temp_source_priv->base.pixmap = temp_source_pixmap;
-						}
-						assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv
-							&& (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx)));
-
-						RegionTranslate(clipped_src_regions[j].region,
-								-src_x_off - dx,
-								-src_y_off - dy);
-						current_boxes = RegionRects(clipped_src_regions[j].region);
-						n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
-						DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
-							clipped_dst_regions[i].block_idx,
-							clipped_src_regions[j].block_idx);
-						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
-							current_boxes[0].x1, current_boxes[0].y1,
-							current_boxes[0].x2, current_boxes[0].y2,
-							dx, dy, src_pixmap, dst_pixmap);
-						if (!temp_source_pixmap)
-							ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
-										  n_current_boxes, dx, dy, reverse,
-										  upsidedown, bitplane, closure);
-						else {
-							ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
-										  dst, gc, current_boxes,
-										  n_current_boxes, dx, dy, reverse,
-										  upsidedown, bitplane, closure);
-							temp_source_priv->type = GLAMOR_MEMORY;
-							temp_source_priv->base.fbo = NULL;
-							glamor_destroy_pixmap(temp_source_pixmap);
-							temp_source_pixmap = NULL;
-						}
-
-						RegionDestroy(clipped_src_regions[j].region);
-						if (!ok) {
-							assert(0);
-							goto fail;
-						}
-					}
-
-					if (n_src_region == 0)
-						ok = TRUE;
-					free(clipped_src_regions);
-				} else {
-					RegionTranslate(clipped_dst_regions[i].region,
-							- dst_x_off,
-							- dst_y_off);
-					current_boxes = RegionRects(clipped_dst_regions[i].region);
-					n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
-
-						DEBUGF("dest pixmap fbo idx %d \n",
-							clipped_dst_regions[i].block_idx);
-						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
-							current_boxes[0].x1, current_boxes[0].y1,
-							current_boxes[0].x2, current_boxes[0].y2,
-							dx, dy, src_pixmap, dst_pixmap);
-
-					ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
-								  n_current_boxes, dx, dy, reverse,
-								  upsidedown, bitplane, closure);
-
-				}
-				RegionDestroy(clipped_dst_regions[i].region);
-			}
-		if (n_dst_region == 0)
-			ok = TRUE;
-		free(clipped_dst_regions);
-		RegionUninit(&region);
-	} else {
-		ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
-					  reverse, upsidedown, bitplane,
-					  closure);
-	}
-
-fail:
-	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_put_dispatch(glamor_priv);
-
-	if (ok)
-		return TRUE;
-fall_back:
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(src)
-	    && glamor_ddx_fallback_check_pixmap(dst))
-		goto done;
-
-	if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
-	    || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
-		LogMessage(X_WARNING,
-			   "Access a DRM only pixmap is not allowed within glamor.\n");
-		return TRUE;
-	}
-	glamor_report_delayed_fallbacks(src->pScreen);
-	glamor_report_delayed_fallbacks(dst->pScreen);
-
-	glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
-			glamor_get_drawable_location(src),
-			glamor_get_drawable_location(dst));
-
-	if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
-		if (dst == src
-		    || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
-			fbCopyNtoN(src, dst, gc, box, nbox,
-				   dx, dy, reverse, upsidedown, bitplane,
-				   closure);
-			if (dst != src)
-				glamor_finish_access(src, GLAMOR_ACCESS_RO);
-		}
-		glamor_finish_access(dst, GLAMOR_ACCESS_RW);
-	}
-	ok = TRUE;
-
-      done:
-	glamor_clear_delayed_fallbacks(src->pScreen);
-	glamor_clear_delayed_fallbacks(dst->pScreen);
-	return ok;
+    PixmapPtr dst_pixmap, src_pixmap;
+    glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    BoxPtr extent;
+    RegionRec region;
+    int src_x_off, src_y_off, dst_x_off, dst_y_off;
+    Bool ok = FALSE;
+    int force_clip = 0;
+
+    if (nbox == 0)
+        return TRUE;
+    dst_pixmap = glamor_get_drawable_pixmap(dst);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    src_pixmap = glamor_get_drawable_pixmap(src);
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+
+    glamor_priv = glamor_get_screen_private(dst->pScreen);
+
+    DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
+           box[0].x1, box[0].y1,
+           box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
+           dx, dy, src_pixmap, dst_pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
+        goto fall_back;
+
+    if (gc) {
+        if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+            goto fall_back;
+        dispatch = glamor_get_dispatch(glamor_priv);
+        if (!glamor_set_alu(dispatch, gc->alu)) {
+            glamor_put_dispatch(glamor_priv);
+            goto fail;
+        }
+        glamor_put_dispatch(glamor_priv);
+    }
+
+    if (!src_pixmap_priv) {
+        glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
+        src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+    }
+
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+
+    RegionInitBoxes(&region, box, nbox);
+    extent = RegionExtents(&region);
+
+    if (!glamor_check_fbo_size(glamor_priv,
+                               extent->x2 - extent->x1, extent->y2 - extent->y1)
+        && (src_pixmap_priv->type == GLAMOR_MEMORY
+            || (src_pixmap_priv == dst_pixmap_priv))) {
+        force_clip = 1;
+    }
+
+    if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+        || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        glamor_pixmap_clipped_regions *clipped_dst_regions;
+        int n_dst_region, i, j;
+        PixmapPtr temp_source_pixmap;
+        glamor_pixmap_private *temp_source_priv = NULL;
+
+        RegionTranslate(&region, dst_x_off, dst_y_off);
+        if (!force_clip)
+            clipped_dst_regions =
+                glamor_compute_clipped_regions(dst_pixmap_priv, &region,
+                                               &n_dst_region, 0, reverse,
+                                               upsidedown);
+        else
+            clipped_dst_regions =
+                glamor_compute_clipped_regions_ext(dst_pixmap_priv, &region,
+                                                   &n_dst_region,
+                                                   glamor_priv->max_fbo_size,
+                                                   glamor_priv->max_fbo_size,
+                                                   reverse, upsidedown);
+        for (i = 0; i < n_dst_region; i++) {
+            int n_src_region;
+            glamor_pixmap_clipped_regions *clipped_src_regions;
+            BoxPtr current_boxes;
+            int n_current_boxes;
+
+            SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
+                                   clipped_dst_regions[i].block_idx);
+
+            temp_source_pixmap = NULL;
+            if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                RegionTranslate(clipped_dst_regions[i].region,
+                                -dst_x_off + src_x_off + dx,
+                                -dst_y_off + src_y_off + dy);
+                clipped_src_regions =
+                    glamor_compute_clipped_regions(src_pixmap_priv,
+                                                   clipped_dst_regions[i].
+                                                   region, &n_src_region, 0,
+                                                   reverse, upsidedown);
+                DEBUGF("Source is large pixmap.\n");
+                for (j = 0; j < n_src_region; j++) {
+                    if (src_pixmap_priv != dst_pixmap_priv)
+                        SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
+                                               clipped_src_regions[j].
+                                               block_idx);
+                    else if (src_pixmap_priv == dst_pixmap_priv &&
+                             clipped_src_regions[j].block_idx !=
+                             clipped_dst_regions[i].block_idx) {
+                        /* source and the dest are the same, but need different block_idx.
+                         * we create a empty pixmap and fill the required source fbo and box to
+                         * it. It's a little hacky, but avoid extra copy. */
+                        temp_source_pixmap =
+                            glamor_create_pixmap(src->pScreen, 0, 0, src->depth,
+                                                 0);
+                        if (!temp_source_pixmap) {
+                            ok = FALSE;
+                            goto fail;
+                        }
+                        src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
+                                                         src_pixmap->drawable.
+                                                         width,
+                                                         src_pixmap->drawable.
+                                                         height, 0, 0,
+                                                         src_pixmap->devKind,
+                                                         NULL);
+                        temp_source_priv =
+                            glamor_get_pixmap_private(temp_source_pixmap);
+                        *temp_source_priv = *src_pixmap_priv;
+                        temp_source_priv->large.box =
+                            src_pixmap_priv->large.
+                            box_array[clipped_src_regions[j].block_idx];
+                        temp_source_priv->base.fbo =
+                            src_pixmap_priv->large.
+                            fbo_array[clipped_src_regions[j].block_idx];
+                        temp_source_priv->base.pixmap = temp_source_pixmap;
+                    }
+                    assert(temp_source_pixmap ||
+                           !(src_pixmap_priv == dst_pixmap_priv &&
+                             (clipped_src_regions[j].block_idx !=
+                              clipped_dst_regions[i].block_idx)));
+
+                    RegionTranslate(clipped_src_regions[j].region,
+                                    -src_x_off - dx, -src_y_off - dy);
+                    current_boxes = RegionRects(clipped_src_regions[j].region);
+                    n_current_boxes =
+                        RegionNumRects(clipped_src_regions[j].region);
+                    DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
+                           clipped_dst_regions[i].block_idx,
+                           clipped_src_regions[j].block_idx);
+                    DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
+                           current_boxes[0].x1, current_boxes[0].y1,
+                           current_boxes[0].x2, current_boxes[0].y2, dx, dy,
+                           src_pixmap, dst_pixmap);
+                    if (!temp_source_pixmap)
+                        ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
+                                                  n_current_boxes, dx, dy,
+                                                  reverse, upsidedown, bitplane,
+                                                  closure);
+                    else {
+                        ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
+                                                  dst, gc, current_boxes,
+                                                  n_current_boxes, dx, dy,
+                                                  reverse, upsidedown, bitplane,
+                                                  closure);
+                        temp_source_priv->type = GLAMOR_MEMORY;
+                        temp_source_priv->base.fbo = NULL;
+                        glamor_destroy_pixmap(temp_source_pixmap);
+                        temp_source_pixmap = NULL;
+                    }
+
+                    RegionDestroy(clipped_src_regions[j].region);
+                    if (!ok) {
+                        assert(0);
+                        goto fail;
+                    }
+                }
+
+                if (n_src_region == 0)
+                    ok = TRUE;
+                free(clipped_src_regions);
+            }
+            else {
+                RegionTranslate(clipped_dst_regions[i].region,
+                                -dst_x_off, -dst_y_off);
+                current_boxes = RegionRects(clipped_dst_regions[i].region);
+                n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
+
+                DEBUGF("dest pixmap fbo idx %d \n",
+                       clipped_dst_regions[i].block_idx);
+                DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
+                       current_boxes[0].x1, current_boxes[0].y1,
+                       current_boxes[0].x2, current_boxes[0].y2,
+                       dx, dy, src_pixmap, dst_pixmap);
+
+                ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
+                                          n_current_boxes, dx, dy, reverse,
+                                          upsidedown, bitplane, closure);
+
+            }
+            RegionDestroy(clipped_dst_regions[i].region);
+        }
+        if (n_dst_region == 0)
+            ok = TRUE;
+        free(clipped_dst_regions);
+        RegionUninit(&region);
+    }
+    else {
+        ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
+                                  reverse, upsidedown, bitplane, closure);
+    }
+
+ fail:
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_set_alu(dispatch, GXcopy);
+    glamor_put_dispatch(glamor_priv);
+
+    if (ok)
+        return TRUE;
+ fall_back:
+    if (!fallback && glamor_ddx_fallback_check_pixmap(src)
+        && glamor_ddx_fallback_check_pixmap(dst))
+        goto done;
+
+    if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
+        || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
+        LogMessage(X_WARNING,
+                   "Access a DRM only pixmap is not allowed within glamor.\n");
+        return TRUE;
+    }
+    glamor_report_delayed_fallbacks(src->pScreen);
+    glamor_report_delayed_fallbacks(dst->pScreen);
+
+    glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
+                    glamor_get_drawable_location(src),
+                    glamor_get_drawable_location(dst));
+
+    if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
+        if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+            fbCopyNtoN(src, dst, gc, box, nbox,
+                       dx, dy, reverse, upsidedown, bitplane, closure);
+            if (dst != src)
+                glamor_finish_access(src, GLAMOR_ACCESS_RO);
+        }
+        glamor_finish_access(dst, GLAMOR_ACCESS_RW);
+    }
+    ok = TRUE;
+
+ done:
+    glamor_clear_delayed_fallbacks(src->pScreen);
+    glamor_clear_delayed_fallbacks(dst->pScreen);
+    return ok;
 }
 
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-		 int srcx, int srcy, int width, int height, int dstx,
-		 int dsty)
+                 int srcx, int srcy, int width, int height, int dstx, int dsty)
 {
-	RegionPtr region;
-	region = miDoCopy(src, dst, gc,
-			  srcx, srcy, width, height,
-			  dstx, dsty, glamor_copy_n_to_n, 0, NULL);
+    RegionPtr region;
 
-	return region;
+    region = miDoCopy(src, dst, gc,
+                      srcx, srcy, width, height,
+                      dstx, dsty, glamor_copy_n_to_n, 0, NULL);
+
+    return region;
 }
 
 void
 glamor_copy_n_to_n(DrawablePtr src,
-		   DrawablePtr dst,
-		   GCPtr gc,
-		   BoxPtr box,
-		   int nbox,
-		   int dx,
-		   int dy,
-		   Bool reverse,
-		   Bool upsidedown, Pixel bitplane,
-		   void *closure)
+                   DrawablePtr dst,
+                   GCPtr gc,
+                   BoxPtr box,
+                   int nbox,
+                   int dx,
+                   int dy,
+                   Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
 {
-	_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
-			    dy, reverse, upsidedown, bitplane, closure, TRUE);
+    _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
+                        dy, reverse, upsidedown, bitplane, closure, TRUE);
 }
 
 Bool
 glamor_copy_n_to_n_nf(DrawablePtr src,
-		   DrawablePtr dst,
-		   GCPtr gc,
-		   BoxPtr box,
-		   int nbox,
-		   int dx,
-		   int dy,
-		   Bool reverse,
-		   Bool upsidedown, Pixel bitplane,
-		   void *closure)
+                      DrawablePtr dst,
+                      GCPtr gc,
+                      BoxPtr box,
+                      int nbox,
+                      int dx,
+                      int dy,
+                      Bool reverse,
+                      Bool upsidedown, Pixel bitplane, void *closure)
 {
-	return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
-				    dy, reverse, upsidedown, bitplane, closure, FALSE);
+    return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
+                               dy, reverse, upsidedown, bitplane, closure,
+                               FALSE);
 }
-
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
index 3f2652a..c42d33e 100644
--- a/glamor/glamor_copyplane.c
+++ b/glamor/glamor_copyplane.c
@@ -30,43 +30,43 @@
 
 static Bool
 _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		   int srcx, int srcy, int w, int h, int dstx, int dsty,
-		   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
+                   int srcx, int srcy, int w, int h, int dstx, int dsty,
+                   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
 {
-	if (!fallback 
-	    && glamor_ddx_fallback_check_gc(pGC)
-	    && glamor_ddx_fallback_check_pixmap(pSrc)
-	    && glamor_ddx_fallback_check_pixmap(pDst))
-		goto fail;
+    if (!fallback && glamor_ddx_fallback_check_gc(pGC)
+        && glamor_ddx_fallback_check_pixmap(pSrc)
+        && glamor_ddx_fallback_check_pixmap(pDst))
+        goto fail;
 
-	glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
-	glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
-	*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
-			  dstx, dsty, bitPlane);
-	glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
-	glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
-	return TRUE;
+    glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
+    glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
+    *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
+                           dstx, dsty, bitPlane);
+    glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
+    glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
+    return TRUE;
 
  fail:
-	return FALSE;
+    return FALSE;
 }
 
 RegionPtr
 glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		  int srcx, int srcy, int w, int h, int dstx, int dsty,
-		  unsigned long bitPlane)
+                  int srcx, int srcy, int w, int h, int dstx, int dsty,
+                  unsigned long bitPlane)
 {
-	RegionPtr ret;
-	_glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
-			   dstx, dsty, bitPlane, &ret, TRUE);
-	return ret;
+    RegionPtr ret;
+
+    _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
+                       dstx, dsty, bitPlane, &ret, TRUE);
+    return ret;
 }
 
 Bool
 glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		     int srcx, int srcy, int w, int h, int dstx, int dsty,
-		     unsigned long bitPlane, RegionPtr *pRegion)
+                     int srcx, int srcy, int w, int h, int dstx, int dsty,
+                     unsigned long bitPlane, RegionPtr *pRegion)
 {
-	return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
-				  dstx, dsty, bitPlane, pRegion, FALSE);
+    return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
+                              dstx, dsty, bitPlane, pRegion, FALSE);
 }
diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c
index b181ff5..1ced4b3 100644
--- a/glamor/glamor_copywindow.c
+++ b/glamor/glamor_copywindow.c
@@ -29,30 +29,28 @@
  */
 
 void
-glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
-		   RegionPtr src_region)
+glamor_copy_window(WindowPtr win, DDXPointRec old_origin, RegionPtr src_region)
 {
-	RegionRec dst_region;
-	int dx, dy;
-	PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
+    RegionRec dst_region;
+    int dx, dy;
+    PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
 
-	dx = old_origin.x - win->drawable.x;
-	dy = old_origin.y - win->drawable.y;
-	REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
+    dx = old_origin.x - win->drawable.x;
+    dy = old_origin.y - win->drawable.y;
+    REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
 
-	REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
+    REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
 
-	REGION_INTERSECT(win->drawable.pScreen, &dst_region,
-			 &win->borderClip, src_region);
+    REGION_INTERSECT(win->drawable.pScreen, &dst_region,
+                     &win->borderClip, src_region);
 #ifdef COMPOSITE
-	if (pixmap->screen_x || pixmap->screen_y)
-		REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
-				 -pixmap->screen_x, -pixmap->screen_y);
+    if (pixmap->screen_x || pixmap->screen_y)
+        REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
+                         -pixmap->screen_x, -pixmap->screen_y);
 #endif
 
-	miCopyRegion(&pixmap->drawable, &pixmap->drawable,
-		     NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0,
-		     NULL);
+    miCopyRegion(&pixmap->drawable, &pixmap->drawable,
+                 NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL);
 
-	REGION_UNINIT(win->drawable.pScreen, &dst_region);
+    REGION_UNINIT(win->drawable.pScreen, &dst_region);
 }
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index eb1a08d..4213961 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -38,76 +38,76 @@
 const Bool
 glamor_get_drawable_location(const DrawablePtr drawable)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(drawable->pScreen);
-	if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0)
-		return 'm';
-	if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
-		return 's';
-	else
-		return 'f';
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(drawable->pScreen);
+    if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0)
+        return 'm';
+    if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
+        return 's';
+    else
+        return 'f';
 }
 
 GLint
 glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
-			 const char *source)
+                         const char *source)
 {
-	GLint ok;
-	GLint prog;
-
-	prog = dispatch->glCreateShader(type);
-	dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL);
-	dispatch->glCompileShader(prog);
-	dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
-	if (!ok) {
-		GLchar *info;
-		GLint size;
-
-		dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
-		info = malloc(size);
-		if (info) {
-			dispatch->glGetShaderInfoLog(prog, size, NULL, info);
-			ErrorF("Failed to compile %s: %s\n",
-			       type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
-			ErrorF("Program source:\n%s", source);
-			free(info);
-		} else
-			ErrorF("Failed to get shader compilation info.\n");
-		FatalError("GLSL compile failure\n");
-	}
-
-	return prog;
+    GLint ok;
+    GLint prog;
+
+    prog = dispatch->glCreateShader(type);
+    dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL);
+    dispatch->glCompileShader(prog);
+    dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+    if (!ok) {
+        GLchar *info;
+        GLint size;
+
+        dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+        info = malloc(size);
+        if (info) {
+            dispatch->glGetShaderInfoLog(prog, size, NULL, info);
+            ErrorF("Failed to compile %s: %s\n",
+                   type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
+            ErrorF("Program source:\n%s", source);
+            free(info);
+        }
+        else
+            ErrorF("Failed to get shader compilation info.\n");
+        FatalError("GLSL compile failure\n");
+    }
+
+    return prog;
 }
 
 void
 glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog)
 {
-	GLint ok;
+    GLint ok;
 
-	dispatch->glLinkProgram(prog);
-	dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
-	if (!ok) {
-		GLchar *info;
-		GLint size;
+    dispatch->glLinkProgram(prog);
+    dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+    if (!ok) {
+        GLchar *info;
+        GLint size;
 
-		dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
-		info = malloc(size);
+        dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+        info = malloc(size);
 
-		dispatch->glGetProgramInfoLog(prog, size, NULL, info);
-		ErrorF("Failed to link: %s\n", info);
-		FatalError("GLSL link failure\n");
-	}
+        dispatch->glGetProgramInfoLog(prog, size, NULL, info);
+        ErrorF("Failed to link: %s\n", info);
+        FatalError("GLSL link failure\n");
+    }
 }
 
-
 Bool
 glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	return glamor_download_pixmap_to_cpu(pixmap, access);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
+    return glamor_download_pixmap_to_cpu(pixmap, access);
 }
 
 /*
@@ -142,221 +142,202 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	const char *vs_source =
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord0;\n"
-	    "varying vec2 source_texture;\n"
-	    "void main()\n"
-	    "{\n"
-	    "	gl_Position = v_position;\n"
-	    "	source_texture = v_texcoord0.xy;\n" "}\n";
-
-	const char *common_source =
-	    GLAMOR_DEFAULT_PRECISION
-	    "varying vec2 source_texture;\n"
-	    "uniform sampler2D sampler;\n"
-	    "uniform int revert;\n"
-	    "uniform int swap_rb;\n"
-
-	    "#define REVERT_NONE       			0\n"
-	    "#define REVERT_NORMAL     			1\n"
-	    "#define SWAP_NONE_DOWNLOADING  		0\n"
-	    "#define SWAP_DOWNLOADING  			1\n"
-	    "#define SWAP_UPLOADING	  		2\n"
-	    "#define SWAP_NONE_UPLOADING		3\n";
-
-	const char *fs_source =
-	    "void main()\n"
-	    "{\n"
-	    "   if (revert == REVERT_NONE) \n"
-	    "    { \n"
-	    "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
-	    "     else \n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
-	    "    } \n"
-	    "   else \n"
-	    "    { \n"
-	    "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).argb;\n"
-	    "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
-	    "     else if (swap_rb == SWAP_UPLOADING)\n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
-	    "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-	    "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
-	    "    } \n" "}\n";
-
-	const char *set_alpha_source =
-	    "void main()\n"
-	    "{\n"
-	    "   if (revert == REVERT_NONE) \n"
-	    "    { \n"
-	    "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
-	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
-	    "     else \n"
-	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
-	    "    } \n"
-	    "   else \n"
-	    "    { \n"
-	    "     if (swap_rb == SWAP_DOWNLOADING)   \n"
-	    "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
-	    "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
-	    "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
-	    "     else if (swap_rb == SWAP_UPLOADING)\n"
-	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
-	    "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
-	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
-	    "    } \n"
-	    "}\n";
-	GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
-	GLint sampler_uniform_location;
-	char *source;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  glamor_get_dispatch(glamor_priv);
-	glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
-	glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
-				     vs_source);
-
-	XNFasprintf(&source, "%s%s", common_source, fs_source);
-	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-				     source);
-	free(source);
-
-	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
-				 vs_prog);
-	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
-				 fs_prog);
-
-	avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
-				     vs_source);
-
-	XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
-	set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-						  source);
-	free(source);
-
-	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
-				 avs_prog);
-	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
-				 set_alpha_prog);
-
-	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
-				       GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
-				       GLAMOR_VERTEX_SOURCE,
-				       "v_texcoord0");
-	glamor_link_glsl_prog(dispatch,
-			      glamor_priv->finish_access_prog[0]);
-
-	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
-				       GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
-				       GLAMOR_VERTEX_SOURCE,
-				       "v_texcoord0");
-	glamor_link_glsl_prog(dispatch,
-			      glamor_priv->finish_access_prog[1]);
-
-	glamor_priv->finish_access_revert[0] =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
-				 "revert");
-
-	glamor_priv->finish_access_swap_rb[0] =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
-				 "swap_rb");
-	sampler_uniform_location =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
-				 "sampler");
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-	dispatch->glUniform1i(sampler_uniform_location, 0);
-	dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
-	dispatch->glUseProgram(0);
-
-	glamor_priv->finish_access_revert[1] =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
-				 "revert");
-	glamor_priv->finish_access_swap_rb[1] =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
-				 "swap_rb");
-	sampler_uniform_location =
-	    dispatch->
-	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
-				 "sampler");
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
-	dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0);
-	dispatch->glUniform1i(sampler_uniform_location, 0);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    const char *vs_source =
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord0;\n"
+        "varying vec2 source_texture;\n"
+        "void main()\n"
+        "{\n"
+        "	gl_Position = v_position;\n"
+        "	source_texture = v_texcoord0.xy;\n" "}\n";
+
+    const char *common_source =
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 source_texture;\n"
+        "uniform sampler2D sampler;\n"
+        "uniform int revert;\n"
+        "uniform int swap_rb;\n"
+        "#define REVERT_NONE       			0\n"
+        "#define REVERT_NORMAL     			1\n"
+        "#define SWAP_NONE_DOWNLOADING  		0\n"
+        "#define SWAP_DOWNLOADING  			1\n"
+        "#define SWAP_UPLOADING	  		2\n"
+        "#define SWAP_NONE_UPLOADING		3\n";
+
+    const char *fs_source =
+        "void main()\n"
+        "{\n"
+        "   if (revert == REVERT_NONE) \n"
+        "    { \n"
+        "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+        "     else \n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+        "    } \n"
+        "   else \n"
+        "    { \n"
+        "     if (swap_rb == SWAP_DOWNLOADING)   \n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+        "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+        "     else if (swap_rb == SWAP_UPLOADING)\n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
+        "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
+        "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+        "    } \n" "}\n";
+
+    const char *set_alpha_source =
+        "void main()\n"
+        "{\n"
+        "   if (revert == REVERT_NONE) \n"
+        "    { \n"
+        "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+        "     else \n"
+        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+        "    } \n"
+        "   else \n"
+        "    { \n"
+        "     if (swap_rb == SWAP_DOWNLOADING)   \n"
+        "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
+        "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
+        "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+        "     else if (swap_rb == SWAP_UPLOADING)\n"
+        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
+        "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
+        "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
+        "    } \n" "}\n";
+    GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
+    GLint sampler_uniform_location;
+    char *source;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
+    glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
+
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+
+    XNFasprintf(&source, "%s%s", common_source, fs_source);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
+    free(source);
+
+    dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
+    dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
+
+    avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+
+    XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
+    set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+                                              source);
+    free(source);
+
+    dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
+    dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
+                             set_alpha_prog);
+
+    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
+                                   GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
+                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]);
+
+    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
+                                   GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
+                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]);
+
+    glamor_priv->finish_access_revert[0] =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
+                                       "revert");
+
+    glamor_priv->finish_access_swap_rb[0] =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
+                                       "swap_rb");
+    sampler_uniform_location =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0],
+                                       "sampler");
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+    dispatch->glUniform1i(sampler_uniform_location, 0);
+    dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0);
+    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
+    dispatch->glUseProgram(0);
+
+    glamor_priv->finish_access_revert[1] =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
+                                       "revert");
+    glamor_priv->finish_access_swap_rb[1] =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
+                                       "swap_rb");
+    sampler_uniform_location =
+        dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1],
+                                       "sampler");
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
+    dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0);
+    dispatch->glUniform1i(sampler_uniform_location, 0);
+    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_finish_access_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  glamor_get_dispatch(glamor_priv);
-	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
-	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
+    dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(drawable->pScreen);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(drawable->pScreen);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
-		return;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
+        return;
 
-	if (access_mode != GLAMOR_ACCESS_RO) {
-		glamor_restore_pixmap_to_texture(pixmap);
-	}
+    if (access_mode != GLAMOR_ACCESS_RO) {
+        glamor_restore_pixmap_to_texture(pixmap);
+    }
 
-	if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
-		glamor_gl_dispatch *dispatch;
+    if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
+        glamor_gl_dispatch *dispatch;
 
-		assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+        assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
 
-		dispatch = glamor_get_dispatch(glamor_priv);
-		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-		dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
-		glamor_put_dispatch(glamor_priv);
+        dispatch = glamor_get_dispatch(glamor_priv);
+        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+        dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
+        glamor_put_dispatch(glamor_priv);
 
-		pixmap_priv->base.fbo->pbo_valid = FALSE;
-		pixmap_priv->base.fbo->pbo = 0;
-	} else {
-		free(pixmap->devPrivate.ptr);
-	}
+        pixmap_priv->base.fbo->pbo_valid = FALSE;
+        pixmap_priv->base.fbo->pbo = 0;
+    }
+    else {
+        free(pixmap->devPrivate.ptr);
+    }
 
-	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
-		pixmap->devKind = pixmap_priv->base.drm_stride;
+    if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
+        pixmap->devKind = pixmap_priv->base.drm_stride;
 
-	if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
-		pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
+    if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
+        pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
 
-	pixmap->devPrivate.ptr = NULL;
+    pixmap->devPrivate.ptr = NULL;
 }
 
-
 /**
  * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
  * current fill style.
@@ -368,22 +349,19 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 Bool
 glamor_prepare_access_gc(GCPtr gc)
 {
-	if (gc->stipple) {
-		if (!glamor_prepare_access
-		    (&gc->stipple->drawable, GLAMOR_ACCESS_RO))
-			return FALSE;
-	}
-	if (gc->fillStyle == FillTiled) {
-		if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
-					   GLAMOR_ACCESS_RO)) {
-			if (gc->stipple)
-				glamor_finish_access(&gc->
-						     stipple->drawable, 
-						     GLAMOR_ACCESS_RO);
-			return FALSE;
-		}
-	}
-	return TRUE;
+    if (gc->stipple) {
+        if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
+            return FALSE;
+    }
+    if (gc->fillStyle == FillTiled) {
+        if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
+                                   GLAMOR_ACCESS_RO)) {
+            if (gc->stipple)
+                glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
+            return FALSE;
+        }
+    }
+    return TRUE;
 }
 
 /**
@@ -392,45 +370,44 @@ glamor_prepare_access_gc(GCPtr gc)
 void
 glamor_finish_access_gc(GCPtr gc)
 {
-	if (gc->fillStyle == FillTiled)
-		glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO);
-	if (gc->stipple)
-		glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
+    if (gc->fillStyle == FillTiled)
+        glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO);
+    if (gc->stipple)
+        glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
 }
 
 Bool
 glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
-	       int x, int y, int width, int height,
-	       unsigned char alu, unsigned long planemask,
-	       unsigned long fg_pixel, unsigned long bg_pixel,
-	       int stipple_x, int stipple_y)
+               int x, int y, int width, int height,
+               unsigned char alu, unsigned long planemask,
+               unsigned long fg_pixel, unsigned long bg_pixel,
+               int stipple_x, int stipple_y)
 {
-	glamor_fallback("stubbed out stipple depth %d\n",
-			pixmap->drawable.depth);
-	return FALSE;
+    glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
+    return FALSE;
 }
 
 GCOps glamor_gc_ops = {
-	.FillSpans = glamor_fill_spans,
-	.SetSpans = glamor_set_spans,
-	.PutImage = glamor_put_image,
-	.CopyArea = glamor_copy_area,
-	.CopyPlane = glamor_copy_plane,
-	.PolyPoint = glamor_poly_point,
-	.Polylines = glamor_poly_lines,
-	.PolySegment = glamor_poly_segment,
-	.PolyRectangle = miPolyRectangle,
-	.PolyArc = miPolyArc,
-	.FillPolygon = miFillPolygon,
-	.PolyFillRect = glamor_poly_fill_rect,
-	.PolyFillArc = miPolyFillArc,
-	.PolyText8 = miPolyText8,
-	.PolyText16 = miPolyText16,
-	.ImageText8 = miImageText8,
-	.ImageText16 = miImageText16,
-	.ImageGlyphBlt = glamor_image_glyph_blt, //miImageGlyphBlt,
-	.PolyGlyphBlt = glamor_poly_glyph_blt, //miPolyGlyphBlt,
-	.PushPixels = glamor_push_pixels, //miPushPixels,
+    .FillSpans = glamor_fill_spans,
+    .SetSpans = glamor_set_spans,
+    .PutImage = glamor_put_image,
+    .CopyArea = glamor_copy_area,
+    .CopyPlane = glamor_copy_plane,
+    .PolyPoint = glamor_poly_point,
+    .Polylines = glamor_poly_lines,
+    .PolySegment = glamor_poly_segment,
+    .PolyRectangle = miPolyRectangle,
+    .PolyArc = miPolyArc,
+    .FillPolygon = miFillPolygon,
+    .PolyFillRect = glamor_poly_fill_rect,
+    .PolyFillArc = miPolyFillArc,
+    .PolyText8 = miPolyText8,
+    .PolyText16 = miPolyText16,
+    .ImageText8 = miImageText8,
+    .ImageText16 = miImageText16,
+    .ImageGlyphBlt = glamor_image_glyph_blt,    //miImageGlyphBlt,
+    .PolyGlyphBlt = glamor_poly_glyph_blt,      //miPolyGlyphBlt,
+    .PushPixels = glamor_push_pixels,   //miPushPixels,
 };
 
 /**
@@ -440,104 +417,94 @@ GCOps glamor_gc_ops = {
 void
 glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
-	/* fbValidateGC will do direct access to pixmaps if the tiling has changed.
-	 * Preempt fbValidateGC by doing its work and masking the change out, so
-	 * that we can do the Prepare/finish_access.
-	 */
+    /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
+     * Preempt fbValidateGC by doing its work and masking the change out, so
+     * that we can do the Prepare/finish_access.
+     */
 #ifdef FB_24_32BIT
-	if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
-		gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
-		fbGetRotatedPixmap(gc) = 0;
-	}
-
-	if (gc->fillStyle == FillTiled) {
-		PixmapPtr old_tile, new_tile;
-
-		old_tile = gc->tile.pixmap;
-		if (old_tile->drawable.bitsPerPixel !=
-		    drawable->bitsPerPixel) {
-			new_tile = fbGetRotatedPixmap(gc);
-			if (!new_tile ||
-			    new_tile->drawable.bitsPerPixel !=
-			    drawable->bitsPerPixel) {
-				if (new_tile)
-					gc->pScreen->DestroyPixmap
-					    (new_tile);
-				/* fb24_32ReformatTile will do direct access of a newly-
-				 * allocated pixmap.
-				 */
-				glamor_fallback
-				    ("GC %p tile FB_24_32 transformat %p.\n",
-				     gc, old_tile);
-
-				if (glamor_prepare_access
-				    (&old_tile->drawable,
-				     GLAMOR_ACCESS_RO)) {
-					new_tile =
-					    fb24_32ReformatTile
-					    (old_tile,
-					     drawable->bitsPerPixel);
-					glamor_finish_access
-					    (&old_tile->drawable, GLAMOR_ACCESS_RO);
-				}
-			}
-			if (new_tile) {
-				fbGetRotatedPixmap(gc) = old_tile;
-				gc->tile.pixmap = new_tile;
-				changes |= GCTile;
-			}
-		}
-	}
+    if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
+        gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
+        fbGetRotatedPixmap(gc) = 0;
+    }
+
+    if (gc->fillStyle == FillTiled) {
+        PixmapPtr old_tile, new_tile;
+
+        old_tile = gc->tile.pixmap;
+        if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
+            new_tile = fbGetRotatedPixmap(gc);
+            if (!new_tile ||
+                new_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
+                if (new_tile)
+                    gc->pScreen->DestroyPixmap(new_tile);
+                /* fb24_32ReformatTile will do direct access of a newly-
+                 * allocated pixmap.
+                 */
+                glamor_fallback
+                    ("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile);
+
+                if (glamor_prepare_access
+                    (&old_tile->drawable, GLAMOR_ACCESS_RO)) {
+                    new_tile =
+                        fb24_32ReformatTile(old_tile, drawable->bitsPerPixel);
+                    glamor_finish_access(&old_tile->drawable, GLAMOR_ACCESS_RO);
+                }
+            }
+            if (new_tile) {
+                fbGetRotatedPixmap(gc) = old_tile;
+                gc->tile.pixmap = new_tile;
+                changes |= GCTile;
+            }
+        }
+    }
 #endif
-	if (changes & GCTile) {
-		if (!gc->tileIsPixel) {
-			glamor_pixmap_private *pixmap_priv =
-			    glamor_get_pixmap_private(gc->tile.pixmap);
-			if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-			    && FbEvenTile(gc->tile.pixmap->drawable.width *
-					  drawable->bitsPerPixel)) {
-				glamor_fallback
-				    ("GC %p tile changed %p.\n", gc,
-				     gc->tile.pixmap);
-				if (glamor_prepare_access
-				    (&gc->tile.pixmap->drawable,
-				     GLAMOR_ACCESS_RW)) {
-					fbPadPixmap(gc->tile.pixmap);
-					glamor_finish_access
-					    (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW);
-				}
-			}
-		}
-		/* Mask out the GCTile change notification, now that we've done FB's
-		 * job for it.
-		 */
-		changes &= ~GCTile;
-	}
-
-	if (changes & GCStipple && gc->stipple) {
-		/* We can't inline stipple handling like we do for GCTile because
-		 * it sets fbgc privates.
-		 */
-		if (glamor_prepare_access
-		    (&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
-			fbValidateGC(gc, changes, drawable);
-			glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW);
-		}
-	} else {
-		fbValidateGC(gc, changes, drawable);
-	}
-
-	gc->ops = &glamor_gc_ops;
+    if (changes & GCTile) {
+        if (!gc->tileIsPixel) {
+            glamor_pixmap_private *pixmap_priv =
+                glamor_get_pixmap_private(gc->tile.pixmap);
+            if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+                && FbEvenTile(gc->tile.pixmap->drawable.width *
+                              drawable->bitsPerPixel)) {
+                glamor_fallback
+                    ("GC %p tile changed %p.\n", gc, gc->tile.pixmap);
+                if (glamor_prepare_access
+                    (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) {
+                    fbPadPixmap(gc->tile.pixmap);
+                    glamor_finish_access
+                        (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW);
+                }
+            }
+        }
+        /* Mask out the GCTile change notification, now that we've done FB's
+         * job for it.
+         */
+        changes &= ~GCTile;
+    }
+
+    if (changes & GCStipple && gc->stipple) {
+        /* We can't inline stipple handling like we do for GCTile because
+         * it sets fbgc privates.
+         */
+        if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
+            fbValidateGC(gc, changes, drawable);
+            glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW);
+        }
+    }
+    else {
+        fbValidateGC(gc, changes, drawable);
+    }
+
+    gc->ops = &glamor_gc_ops;
 }
 
 static GCFuncs glamor_gc_funcs = {
-	glamor_validate_gc,
-	miChangeGC,
-	miCopyGC,
-	miDestroyGC,
-	miChangeClip,
-	miDestroyClip,
-	miCopyClip
+    glamor_validate_gc,
+    miChangeGC,
+    miCopyGC,
+    miDestroyGC,
+    miChangeClip,
+    miDestroyClip,
+    miCopyClip
 };
 
 /**
@@ -547,66 +514,69 @@ static GCFuncs glamor_gc_funcs = {
 int
 glamor_create_gc(GCPtr gc)
 {
-	if (!fbCreateGC(gc))
-		return FALSE;
+    if (!fbCreateGC(gc))
+        return FALSE;
 
-	gc->funcs = &glamor_gc_funcs;
+    gc->funcs = &glamor_gc_funcs;
 
-	return TRUE;
+    return TRUE;
 }
 
 RegionPtr
 glamor_bitmap_to_region(PixmapPtr pixmap)
 {
-	RegionPtr ret;
-	glamor_fallback("pixmap %p \n", pixmap);
-	if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
-		return NULL;
-	ret = fbPixmapToRegion(pixmap);
-	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
-	return ret;
+    RegionPtr ret;
+
+    glamor_fallback("pixmap %p \n", pixmap);
+    if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
+        return NULL;
+    ret = fbPixmapToRegion(pixmap);
+    glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+    return ret;
 }
 
 /* Borrow from cairo. */
 Bool
 glamor_gl_has_extension(const char *extension)
 {
-	const char *pext;
-	int ext_len;
-	ext_len = strlen(extension);
+    const char *pext;
+    int ext_len;
+
+    ext_len = strlen(extension);
 
-	pext = (const char*)glGetString(GL_EXTENSIONS);
+    pext = (const char *) glGetString(GL_EXTENSIONS);
 
-	if (pext == NULL || extension == NULL)
-		return FALSE;
+    if (pext == NULL || extension == NULL)
+        return FALSE;
 
-	while ((pext = strstr(pext, extension)) != NULL) {
-		if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
-			return TRUE;
-		pext += ext_len;
-	}
-	return FALSE;
+    while ((pext = strstr(pext, extension)) != NULL) {
+        if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+            return TRUE;
+        pext += ext_len;
+    }
+    return FALSE;
 }
 
 int
 glamor_gl_get_version(void)
 {
-	int major, minor;
-	const char *version = (const char *) glGetString(GL_VERSION);
-	const char *dot = version == NULL ? NULL : strchr(version, '.');
-	const char *major_start = dot;
-
-	/* Sanity check */
-	if (dot == NULL || dot == version || *(dot + 1) == '\0') {
-		major = 0;
-		minor = 0;
-	} else {
-		/* Find the start of the major version in the string */
-		while (major_start > version && *major_start != ' ')
-			--major_start;
-		major = strtol(major_start, NULL, 10);
-		minor = strtol(dot + 1, NULL, 10);
-	}
-
-	return GLAMOR_GL_VERSION_ENCODE(major, minor);
+    int major, minor;
+    const char *version = (const char *) glGetString(GL_VERSION);
+    const char *dot = version == NULL ? NULL : strchr(version, '.');
+    const char *major_start = dot;
+
+    /* Sanity check */
+    if (dot == NULL || dot == version || *(dot + 1) == '\0') {
+        major = 0;
+        minor = 0;
+    }
+    else {
+        /* Find the start of the major version in the string */
+        while (major_start > version && *major_start != ' ')
+            --major_start;
+        major = strtol(major_start, NULL, 10);
+        minor = strtol(dot + 1, NULL, 10);
+    }
+
+    return GLAMOR_GL_VERSION_ENCODE(major, minor);
 }
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index f0c969b..638bee2 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -29,7 +29,6 @@
 #ifndef __GLAMOR_DEBUG_H__
 #define __GLAMOR_DEBUG_H__
 
-
 #define GLAMOR_DELAYED_STRING_MAX 64
 
 #define GLAMOR_DEBUG_NONE                     0
@@ -51,9 +50,6 @@ AbortServer(void)
     exit(1);                                            \
   } while(0)
 
-
-
-
 #define __debug_output_message(_format_, _prefix_, ...) \
   LogMessageVerb(X_NONE, 0,				\
 		 "%32s:\t" _format_ ,		\
@@ -69,7 +65,6 @@ AbortServer(void)
 			     ##__VA_ARGS__);		\
   } while(0)
 
-
 #define glamor_fallback(_format_,...)			\
   do {							\
     if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK)	\
@@ -77,8 +72,6 @@ AbortServer(void)
 			     "Glamor fallback",		\
 			     ##__VA_ARGS__);} while(0)
 
-
-
 #define glamor_delayed_fallback(_screen_, _format_,...)			\
   do {									\
     if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK)  {			\
@@ -90,7 +83,6 @@ AbortServer(void)
 	       "glamor delayed fallback: \t%s " _format_ ,		\
                __FUNCTION__, ##__VA_ARGS__); } } while(0)
 
-
 #define glamor_clear_delayed_fallbacks(_screen_)			\
   do {									\
     if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) {			\
@@ -112,5 +104,4 @@ AbortServer(void)
 #define DEBUGRegionPrint(x) do {} while (0)
 //#define DEBUGRegionPrint RegionPrint
 
-
 #endif
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index ff4c0bd..c65f701 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -69,41 +69,42 @@
 static const char glamor_name[] = "glamor";
 
 static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
-DevPrivateKey glamor_egl_pixmap_private_key = &glamor_egl_pixmap_private_key_index;
+DevPrivateKey glamor_egl_pixmap_private_key =
+    &glamor_egl_pixmap_private_key_index;
 
 static void
 glamor_identify(int flags)
 {
-	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n",
-		glamor_name);
+    xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n",
+            glamor_name);
 }
 
 struct glamor_egl_screen_private {
-	EGLDisplay display;
-	EGLContext context;
-	EGLint major, minor;
-
-	CreateScreenResourcesProcPtr CreateScreenResources;
-	CloseScreenProcPtr CloseScreen;
-	int fd;
-	EGLImageKHR front_image;
-	PixmapPtr *back_pixmap;
-	int cpp;
+    EGLDisplay display;
+    EGLContext context;
+    EGLint major, minor;
+
+    CreateScreenResourcesProcPtr CreateScreenResources;
+    CloseScreenProcPtr CloseScreen;
+    int fd;
+    EGLImageKHR front_image;
+    PixmapPtr *back_pixmap;
+    int cpp;
 #ifdef GLAMOR_HAS_GBM
-	struct gbm_device *gbm;
+    struct gbm_device *gbm;
 #endif
-	int has_gem;
-	void *glamor_context;
-	void *current_context;
-	int gl_context_depth;
-	int dri3_capable;
-
-	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
-	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
-	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
-	struct glamor_gl_dispatch *dispatch;
-	CloseScreenProcPtr saved_close_screen;
-	xf86FreeScreenProc *saved_free_screen;
+    int has_gem;
+    void *glamor_context;
+    void *current_context;
+    int gl_context_depth;
+    int dri3_capable;
+
+    PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
+    PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
+    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
+    struct glamor_gl_dispatch *dispatch;
+    CloseScreenProcPtr saved_close_screen;
+    xf86FreeScreenProc *saved_free_screen;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
@@ -111,46 +112,47 @@ int xf86GlamorEGLPrivateIndex = -1;
 static struct glamor_egl_screen_private *
 glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 {
-	return (struct glamor_egl_screen_private *)
-	    scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
+    return (struct glamor_egl_screen_private *)
+        scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
+
 #ifdef GLX_USE_SHARED_DISPATCH
 _X_EXPORT void
 glamor_egl_make_current(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-
-	if (glamor_egl->gl_context_depth++)
-		return;
-
-	GET_CURRENT_CONTEXT(glamor_egl->current_context);
-
-	if (glamor_egl->glamor_context != glamor_egl->current_context) {
-		eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
-			       EGL_NO_SURFACE, EGL_NO_CONTEXT);
-		if (!eglMakeCurrent(glamor_egl->display,
-				    EGL_NO_SURFACE, EGL_NO_SURFACE,
-				    glamor_egl->context)) {
-			FatalError("Failed to make EGL context current\n");
-		}
-	}
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+
+    if (glamor_egl->gl_context_depth++)
+        return;
+
+    GET_CURRENT_CONTEXT(glamor_egl->current_context);
+
+    if (glamor_egl->glamor_context != glamor_egl->current_context) {
+        eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+                       EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        if (!eglMakeCurrent(glamor_egl->display,
+                            EGL_NO_SURFACE, EGL_NO_SURFACE,
+                            glamor_egl->context)) {
+            FatalError("Failed to make EGL context current\n");
+        }
+    }
 }
 
 _X_EXPORT void
 glamor_egl_restore_context(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
 
-	if (--glamor_egl->gl_context_depth)
-		return;
+    if (--glamor_egl->gl_context_depth)
+        return;
 
-	if (glamor_egl->current_context &&
-	    glamor_egl->glamor_context != glamor_egl->current_context)
-		SET_CURRENT_CONTEXT(glamor_egl->current_context);
+    if (glamor_egl->current_context &&
+        glamor_egl->glamor_context != glamor_egl->current_context)
+        SET_CURRENT_CONTEXT(glamor_egl->current_context);
 }
 #else
 #define glamor_egl_make_current(x)
@@ -159,598 +161,591 @@ glamor_egl_restore_context(ScreenPtr screen)
 
 static EGLImageKHR
 _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
-			 int width, int height, int stride, int name, int depth)
+                         int width, int height, int stride, int name, int depth)
 {
-	EGLImageKHR image;
-	EGLint attribs[] = {
-		EGL_WIDTH, 0,
-		EGL_HEIGHT, 0,
-		EGL_DRM_BUFFER_STRIDE_MESA, 0,
-		EGL_DRM_BUFFER_FORMAT_MESA,
-		EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-		EGL_DRM_BUFFER_USE_MESA,
-		EGL_DRM_BUFFER_USE_SHARE_MESA |
-		    EGL_DRM_BUFFER_USE_SCANOUT_MESA,
-		EGL_NONE
-	};
-	attribs[1] = width;
-	attribs[3] = height;
-	attribs[5] = stride;
-	if (depth != 32 && depth != 24)
-		return EGL_NO_IMAGE_KHR;
-	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-						 glamor_egl->context,
-						 EGL_DRM_BUFFER_MESA,
-						 (void *) (uintptr_t)name, attribs);
-	if (image == EGL_NO_IMAGE_KHR)
-		return EGL_NO_IMAGE_KHR;
-
-
-	return image;
+    EGLImageKHR image;
+
+    EGLint attribs[] = {
+        EGL_WIDTH, 0,
+        EGL_HEIGHT, 0,
+        EGL_DRM_BUFFER_STRIDE_MESA, 0,
+        EGL_DRM_BUFFER_FORMAT_MESA,
+        EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+        EGL_DRM_BUFFER_USE_MESA,
+        EGL_DRM_BUFFER_USE_SHARE_MESA | EGL_DRM_BUFFER_USE_SCANOUT_MESA,
+        EGL_NONE
+    };
+    attribs[1] = width;
+    attribs[3] = height;
+    attribs[5] = stride;
+    if (depth != 32 && depth != 24)
+        return EGL_NO_IMAGE_KHR;
+    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+                                             glamor_egl->context,
+                                             EGL_DRM_BUFFER_MESA,
+                                             (void *) (uintptr_t) name,
+                                             attribs);
+    if (image == EGL_NO_IMAGE_KHR)
+        return EGL_NO_IMAGE_KHR;
+
+    return image;
 }
 
 static int
 glamor_get_flink_name(int fd, int handle, int *name)
 {
-	struct drm_gem_flink flink;
-	flink.handle = handle;
-	if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
-		return FALSE;
-	*name = flink.name;
-	return TRUE;
+    struct drm_gem_flink flink;
+
+    flink.handle = handle;
+    if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
+        return FALSE;
+    *name = flink.name;
+    return TRUE;
 }
 
 static Bool
 glamor_create_texture_from_image(struct glamor_egl_screen_private
-				 *glamor_egl,
-				 EGLImageKHR image, GLuint * texture)
+                                 *glamor_egl,
+                                 EGLImageKHR image, GLuint * texture)
 {
-	glamor_egl->dispatch->glGenTextures(1, texture);
-	glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture);
-	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
-					      GL_TEXTURE_MIN_FILTER,
-					      GL_NEAREST);
-	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
-					      GL_TEXTURE_MAG_FILTER,
-					      GL_NEAREST);
-
-	(glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D,
-						      image);
-	glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0);
-	return TRUE;
+    glamor_egl->dispatch->glGenTextures(1, texture);
+    glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture);
+    glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                          GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                          GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    (glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D, image);
+    glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0);
+    return TRUE;
 }
 
 unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen,
-					 int w,
-					 int h)
+glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	EGLImageKHR image;
-	GLuint texture;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLImageKHR image;
+    GLuint texture;
+
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
-	struct gbm_bo *bo;
-	EGLNativePixmapType native_pixmap;
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-	bo = gbm_bo_create (glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
-				      GBM_BO_USE_RENDERING |
-				      GBM_BO_USE_SCANOUT);
-	if (!bo)
-		return 0;
-
-	/* If the following assignment raises an error or a warning
-	 * then that means EGLNativePixmapType is not struct gbm_bo *
-	 * on your platform: This code won't work and you should not
-	 * compile with dri3 support enabled */
-	native_pixmap = bo;
-
-	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-						 EGL_NO_CONTEXT,
-						 EGL_NATIVE_PIXMAP_KHR,
-						 native_pixmap, NULL);
-	gbm_bo_destroy(bo);
-	if (image == EGL_NO_IMAGE_KHR)
-		return 0;
-	glamor_create_texture_from_image(glamor_egl, image, &texture);
-	glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-
-	return texture;
+    struct gbm_bo *bo;
+    EGLNativePixmapType native_pixmap;
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+    bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
+                       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+    if (!bo)
+        return 0;
+
+    /* If the following assignment raises an error or a warning
+     * then that means EGLNativePixmapType is not struct gbm_bo *
+     * on your platform: This code won't work and you should not
+     * compile with dri3 support enabled */
+    native_pixmap = bo;
+
+    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+                                             EGL_NO_CONTEXT,
+                                             EGL_NATIVE_PIXMAP_KHR,
+                                             native_pixmap, NULL);
+    gbm_bo_destroy(bo);
+    if (image == EGL_NO_IMAGE_KHR)
+        return 0;
+    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+
+    return texture;
 #else
-	return 0; /* this path should never happen */
+    return 0;                   /* this path should never happen */
 #endif
 }
 
 Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	PixmapPtr	screen_pixmap;
-
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-	screen_pixmap = screen->GetScreenPixmap(screen);
-
-	if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create textured screen.");
-		return FALSE;
-	}
-
-	glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
-						    glamor_egl_pixmap_private_key);
-	glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
-	return TRUE;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    PixmapPtr screen_pixmap;
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+    screen_pixmap = screen->GetScreenPixmap(screen);
+
+    if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Failed to create textured screen.");
+        return FALSE;
+    }
+
+    glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
+                                               glamor_egl_pixmap_private_key);
+    glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
+    return TRUE;
 }
 
 Bool
 glamor_egl_create_textured_screen_ext(ScreenPtr screen,
-				      int handle,
-				      int stride,
-				      PixmapPtr *back_pixmap)
+                                      int handle,
+                                      int stride, PixmapPtr *back_pixmap)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
 
-	glamor_egl = glamor_egl_get_screen_private(scrn);
+    glamor_egl = glamor_egl_get_screen_private(scrn);
 
-	glamor_egl->back_pixmap = back_pixmap;
-	if (!glamor_egl_create_textured_screen(screen, handle, stride))
-		return FALSE;
-	return TRUE;
+    glamor_egl->back_pixmap = back_pixmap;
+    if (!glamor_egl_create_textured_screen(screen, handle, stride))
+        return FALSE;
+    return TRUE;
 }
 
 static Bool
 glamor_egl_check_has_gem(int fd)
 {
-	struct drm_gem_flink flink;
-	flink.handle = 0;
+    struct drm_gem_flink flink;
 
-	ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
-	if (errno == ENOENT || errno == EINVAL)
-		return TRUE;
-	return FALSE;
+    flink.handle = 0;
+
+    ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
+    if (errno == ENOENT || errno == EINVAL)
+        return TRUE;
+    return FALSE;
 }
 
 Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	EGLImageKHR image;
-	GLuint texture;
-	int name;
-	Bool ret = FALSE;
-
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-
-	glamor_egl_make_current(screen);
-	if (glamor_egl->has_gem) {
-		if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-				   "Couldn't flink pixmap handle\n");
-			glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-			assert(0);
-			return FALSE;
-		}
-	} else
-		name = handle;
-
-	image = _glamor_egl_create_image(glamor_egl,
-					 pixmap->drawable.width,
-					 pixmap->drawable.height,
-					 ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
-					 name,
-					 pixmap->drawable.depth);
-	if (image == EGL_NO_IMAGE_KHR) {
-		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-		goto done;
-	}
-	glamor_create_texture_from_image(glamor_egl, image, &texture);
-	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
-	glamor_set_pixmap_texture(pixmap, texture);
-	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
-		      image);
-	ret = TRUE;
-
-done:
-	glamor_egl_restore_context(screen);
-	return ret;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLImageKHR image;
+    GLuint texture;
+    int name;
+    Bool ret = FALSE;
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+
+    glamor_egl_make_current(screen);
+    if (glamor_egl->has_gem) {
+        if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                       "Couldn't flink pixmap handle\n");
+            glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+            assert(0);
+            return FALSE;
+        }
+    }
+    else
+        name = handle;
+
+    image = _glamor_egl_create_image(glamor_egl,
+                                     pixmap->drawable.width,
+                                     pixmap->drawable.height,
+                                     ((stride * 8 +
+                                       7) / pixmap->drawable.bitsPerPixel),
+                                     name, pixmap->drawable.depth);
+    if (image == EGL_NO_IMAGE_KHR) {
+        glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+        goto done;
+    }
+    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+    glamor_set_pixmap_texture(pixmap, texture);
+    dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image);
+    ret = TRUE;
+
+ done:
+    glamor_egl_restore_context(screen);
+    return ret;
 }
 
 Bool
 glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	EGLImageKHR image;
-	GLuint texture;
-	Bool ret = FALSE;
-
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-
-	glamor_egl_make_current(screen);
-
-	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-						 glamor_egl->context,
-						 EGL_NATIVE_PIXMAP_KHR,
-						 bo, NULL);
-	if (image == EGL_NO_IMAGE_KHR) {
-		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-		goto done;
-	}
-	glamor_create_texture_from_image(glamor_egl, image, &texture);
-	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
-	glamor_set_pixmap_texture(pixmap, texture);
-	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
-		      image);
-	ret = TRUE;
-
-done:
-	glamor_egl_restore_context(screen);
-	return ret;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLImageKHR image;
+    GLuint texture;
+    Bool ret = FALSE;
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+
+    glamor_egl_make_current(screen);
+
+    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+                                             glamor_egl->context,
+                                             EGL_NATIVE_PIXMAP_KHR, bo, NULL);
+    if (image == EGL_NO_IMAGE_KHR) {
+        glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+        goto done;
+    }
+    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+    glamor_set_pixmap_texture(pixmap, texture);
+    dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image);
+    ret = TRUE;
+
+ done:
+    glamor_egl_restore_context(screen);
+    return ret;
 }
 
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
-int glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd);
-void glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name);
+int glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd);
+void glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name);
 int
-glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd)
+glamor_get_fd_from_bo(int gbm_fd, struct gbm_bo *bo, int *fd)
 {
-	union gbm_bo_handle handle;
-	struct drm_prime_handle args;
-
-	handle = gbm_bo_get_handle(bo);
-	args.handle = handle.u32;
-	args.flags = DRM_CLOEXEC;
-	if (ioctl (gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
-		return FALSE;
-	*fd = args.fd;
-	return TRUE;
+    union gbm_bo_handle handle;
+    struct drm_prime_handle args;
+
+    handle = gbm_bo_get_handle(bo);
+    args.handle = handle.u32;
+    args.flags = DRM_CLOEXEC;
+    if (ioctl(gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
+        return FALSE;
+    *fd = args.fd;
+    return TRUE;
 }
 
 void
-glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name)
+glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
 {
-	union gbm_bo_handle handle;
+    union gbm_bo_handle handle;
 
-	handle = gbm_bo_get_handle(bo);
-	if (!glamor_get_flink_name(gbm_fd, handle.u32, name))
-		*name = -1;
+    handle = gbm_bo_get_handle(bo);
+    if (!glamor_get_flink_name(gbm_fd, handle.u32, name))
+        *name = -1;
 }
 #endif
 
-int glamor_egl_dri3_fd_name_from_tex (ScreenPtr screen,
-				      PixmapPtr pixmap,
-				      unsigned int tex,
-				      Bool want_name,
-				      CARD16 *stride,
-				      CARD32 *size)
+int
+glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
+                                 PixmapPtr pixmap,
+                                 unsigned int tex,
+                                 Bool want_name, CARD16 *stride, CARD32 *size)
 {
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	EGLImageKHR image;
-	struct gbm_bo* bo;
-	int fd = -1;
-
-	EGLint attribs[] = {
-		EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
-		EGL_GL_TEXTURE_LEVEL_KHR, 0,
-		EGL_NONE
-	};
-
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-
-	glamor_egl_make_current(screen);
-
-	image = dixLookupPrivate(&pixmap->devPrivates,
-				 glamor_egl_pixmap_private_key);
-
-	if (image == EGL_NO_IMAGE_KHR || image == NULL)
-	{
-		image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-							 glamor_egl->context,
-							 EGL_GL_TEXTURE_2D_KHR,
-							 (EGLClientBuffer)(uintptr_t)tex, attribs);
-		if (image == EGL_NO_IMAGE_KHR)
-			goto failure;
-
-		dixSetPrivate(&pixmap->devPrivates,
-			      glamor_egl_pixmap_private_key,
-			      image);
-		glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
-	}
-
-	bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
-	if (!bo)
-		goto failure;
-
-	pixmap->devKind = gbm_bo_get_stride(bo);
-
-	if (want_name)
-	{
-		if (glamor_egl->has_gem)
-			glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
-	}
-	else
-	{
-		if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd))
-		{
-			*stride = pixmap->devKind;
-			*size = pixmap->devKind * gbm_bo_get_height(bo);
-		}
-	}
-
-	gbm_bo_destroy(bo);
-failure:
-	glamor_egl_restore_context(screen);
-	return fd;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    EGLImageKHR image;
+    struct gbm_bo *bo;
+    int fd = -1;
+
+    EGLint attribs[] = {
+        EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+        EGL_GL_TEXTURE_LEVEL_KHR, 0,
+        EGL_NONE
+    };
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+
+    glamor_egl_make_current(screen);
+
+    image = dixLookupPrivate(&pixmap->devPrivates,
+                             glamor_egl_pixmap_private_key);
+
+    if (image == EGL_NO_IMAGE_KHR || image == NULL) {
+        image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+                                                 glamor_egl->context,
+                                                 EGL_GL_TEXTURE_2D_KHR,
+                                                 (EGLClientBuffer) (uintptr_t)
+                                                 tex, attribs);
+        if (image == EGL_NO_IMAGE_KHR)
+            goto failure;
+
+        dixSetPrivate(&pixmap->devPrivates,
+                      glamor_egl_pixmap_private_key, image);
+        glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+    }
+
+    bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
+    if (!bo)
+        goto failure;
+
+    pixmap->devKind = gbm_bo_get_stride(bo);
+
+    if (want_name) {
+        if (glamor_egl->has_gem)
+            glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
+    }
+    else {
+        if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) {
+            *stride = pixmap->devKind;
+            *size = pixmap->devKind * gbm_bo_get_height(bo);
+        }
+    }
+
+    gbm_bo_destroy(bo);
+ failure:
+    glamor_egl_restore_context(screen);
+    return fd;
 #else
-	return -1;
+    return -1;
 #endif
 }
 
-PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
-					  int fd,
-					  CARD16 width,
-					  CARD16 height,
-					  CARD16 stride,
-					  CARD8 depth,
-					  CARD8 bpp)
+PixmapPtr
+glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen,
+                               int fd,
+                               CARD16 width,
+                               CARD16 height,
+                               CARD16 stride, CARD8 depth, CARD8 bpp)
 {
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl;
-	struct gbm_bo* bo;
-	EGLImageKHR image;
-	PixmapPtr pixmap;
-	Bool ret = FALSE;
-	EGLint attribs[] = {
-		EGL_WIDTH, 0,
-		EGL_HEIGHT, 0,
-		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
-		EGL_DMA_BUF_PLANE0_FD_EXT, 0,
-		EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
-		EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
-		EGL_NONE
-	};
-
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-
-	if (!glamor_egl->dri3_capable)
-		return NULL;
-
-	if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
-		return NULL;
-
-	attribs[1] = width;
-	attribs[3] = height;
-	attribs[7] = fd;
-	attribs[11] = stride;
-	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
-						 EGL_NO_CONTEXT,
-						 EGL_LINUX_DMA_BUF_EXT,
-						 NULL, attribs);
-
-	if (image == EGL_NO_IMAGE_KHR)
-		return NULL;
-
-	/* EGL_EXT_image_dma_buf_import can impose restrictions on the
-	 * usage of the image. Use gbm_bo to bypass the limitations. */
-
-	bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
-	glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-
-	if (!bo)
-		return NULL;
-
-	pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
-	screen->ModifyPixmapHeader (pixmap, width, height, 0, 0, stride, NULL);
-
-	ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
-	gbm_bo_destroy(bo);
-
-	if (ret)
-		return pixmap;
-	else
-	{
-		screen->DestroyPixmap(pixmap);
-		return NULL;
-	}
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl;
+    struct gbm_bo *bo;
+    EGLImageKHR image;
+    PixmapPtr pixmap;
+    Bool ret = FALSE;
+
+    EGLint attribs[] = {
+        EGL_WIDTH, 0,
+        EGL_HEIGHT, 0,
+        EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+        EGL_DMA_BUF_PLANE0_FD_EXT, 0,
+        EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+        EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
+        EGL_NONE
+    };
+
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+
+    if (!glamor_egl->dri3_capable)
+        return NULL;
+
+    if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
+        return NULL;
+
+    attribs[1] = width;
+    attribs[3] = height;
+    attribs[7] = fd;
+    attribs[11] = stride;
+    image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+                                             EGL_NO_CONTEXT,
+                                             EGL_LINUX_DMA_BUF_EXT,
+                                             NULL, attribs);
+
+    if (image == EGL_NO_IMAGE_KHR)
+        return NULL;
+
+    /* EGL_EXT_image_dma_buf_import can impose restrictions on the
+     * usage of the image. Use gbm_bo to bypass the limitations. */
+
+    bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
+    glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+
+    if (!bo)
+        return NULL;
+
+    pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
+    screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL);
+
+    ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
+    gbm_bo_destroy(bo);
+
+    if (ret)
+        return pixmap;
+    else {
+        screen->DestroyPixmap(pixmap);
+        return NULL;
+    }
 #else
-	return NULL;
+    return NULL;
 #endif
 }
 
 static void
 _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
-	EGLImageKHR image;
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-
-	image = dixLookupPrivate(&pixmap->devPrivates,
-				 glamor_egl_pixmap_private_key);
-	if (image != EGL_NO_IMAGE_KHR && image != NULL) {
-		/* Before destroy an image which was attached to
-		 * a texture. we must call glFlush to make sure the
-		 * operation on that texture has been done.*/
-		glamor_block_handler(pixmap->drawable.pScreen);
-		glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-		dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
-	}
+    ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
+    EGLImageKHR image;
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+
+    image = dixLookupPrivate(&pixmap->devPrivates,
+                             glamor_egl_pixmap_private_key);
+    if (image != EGL_NO_IMAGE_KHR && image != NULL) {
+        /* Before destroy an image which was attached to
+         * a texture. we must call glFlush to make sure the
+         * operation on that texture has been done.*/
+        glamor_block_handler(pixmap->drawable.pScreen);
+        glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+        dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
+                      NULL);
+    }
 }
 
 _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-	EGLImageKHR old_front_image;
-	EGLImageKHR new_front_image;
-
-	glamor_pixmap_exchange_fbos(front, back);
-	new_front_image = dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
-	old_front_image = dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
-	dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, new_front_image);
-	dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, old_front_image);
-	glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
-	glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
-	glamor_egl->front_image = new_front_image;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    EGLImageKHR old_front_image;
+    EGLImageKHR new_front_image;
+
+    glamor_pixmap_exchange_fbos(front, back);
+    new_front_image =
+        dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
+    old_front_image =
+        dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
+    dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key,
+                  new_front_image);
+    dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key,
+                  old_front_image);
+    glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
+    glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
+    glamor_egl->front_image = new_front_image;
 
 }
 
 void
 glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 {
-	if (pixmap->refcnt == 1)
-		_glamor_egl_destroy_pixmap_image(pixmap);
-	glamor_destroy_textured_pixmap(pixmap);
+    if (pixmap->refcnt == 1)
+        _glamor_egl_destroy_pixmap_image(pixmap);
+    glamor_destroy_textured_pixmap(pixmap);
 }
 
 static Bool
 glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
-	ScrnInfoPtr scrn;
-	struct glamor_egl_screen_private *glamor_egl;
-	PixmapPtr screen_pixmap;
-	EGLImageKHR back_image;
-
-	scrn = xf86ScreenToScrn(screen);
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-	screen_pixmap = screen->GetScreenPixmap(screen);
-
-	glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image);
-	dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
-	glamor_egl->front_image = NULL;
-	if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
-		back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
-					       glamor_egl_pixmap_private_key);
-		if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
-			glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
-			dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
-				      glamor_egl_pixmap_private_key, NULL);
-		}
-	}
-
-	screen->CloseScreen = glamor_egl->saved_close_screen;
-
-	return screen->CloseScreen(CLOSE_SCREEN_ARGS);
+    ScrnInfoPtr scrn;
+    struct glamor_egl_screen_private *glamor_egl;
+    PixmapPtr screen_pixmap;
+    EGLImageKHR back_image;
+
+    scrn = xf86ScreenToScrn(screen);
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+    screen_pixmap = screen->GetScreenPixmap(screen);
+
+    glamor_egl->egl_destroy_image_khr(glamor_egl->display,
+                                      glamor_egl->front_image);
+    dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key,
+                  NULL);
+    glamor_egl->front_image = NULL;
+    if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
+        back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
+                                      glamor_egl_pixmap_private_key);
+        if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
+            glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
+            dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
+                          glamor_egl_pixmap_private_key, NULL);
+        }
+    }
+
+    screen->CloseScreen = glamor_egl->saved_close_screen;
+
+    return screen->CloseScreen(CLOSE_SCREEN_ARGS);
 }
 
 static Bool
 glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
-			 const char *extension)
+                         const char *extension)
 {
-	const char *pext;
-	int ext_len;
-
-	ext_len = strlen(extension);
-	pext =
-	    (const char *) eglQueryString(glamor_egl->display,
-					  EGL_EXTENSIONS);
-	if (pext == NULL || extension == NULL)
-		return FALSE;
-	while ((pext = strstr(pext, extension)) != NULL) {
-		if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
-			return TRUE;
-		pext += ext_len;
-	}
-	return FALSE;
+    const char *pext;
+    int ext_len;
+
+    ext_len = strlen(extension);
+    pext = (const char *) eglQueryString(glamor_egl->display, EGL_EXTENSIONS);
+    if (pext == NULL || extension == NULL)
+        return FALSE;
+    while ((pext = strstr(pext, extension)) != NULL) {
+        if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+            return TRUE;
+        pext += ext_len;
+    }
+    return FALSE;
 }
 
 void
 glamor_egl_screen_init(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
 
-	glamor_egl->saved_close_screen = screen->CloseScreen;
-	screen->CloseScreen = glamor_egl_close_screen;
+    glamor_egl->saved_close_screen = screen->CloseScreen;
+    screen->CloseScreen = glamor_egl_close_screen;
 }
 
 static void
 glamor_egl_free_screen(FREE_SCREEN_ARGS_DECL)
 {
-	ScrnInfoPtr scrn;
-	struct glamor_egl_screen_private *glamor_egl;
+    ScrnInfoPtr scrn;
+    struct glamor_egl_screen_private *glamor_egl;
+
 #ifndef XF86_SCRN_INTERFACE
-	scrn = xf86Screens[arg];
+    scrn = xf86Screens[arg];
 #else
-	scrn = arg;
+    scrn = arg;
 #endif
 
-	glamor_egl = glamor_egl_get_screen_private(scrn);
-	if (glamor_egl != NULL) {
+    glamor_egl = glamor_egl_get_screen_private(scrn);
+    if (glamor_egl != NULL) {
 
-		eglMakeCurrent(glamor_egl->display,
-			       EGL_NO_SURFACE, EGL_NO_SURFACE,
-			       EGL_NO_CONTEXT);
+        eglMakeCurrent(glamor_egl->display,
+                       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 #ifdef GLAMOR_HAS_GBM
-		if (glamor_egl->gbm)
-			gbm_device_destroy(glamor_egl->gbm);
+        if (glamor_egl->gbm)
+            gbm_device_destroy(glamor_egl->gbm);
 #endif
-		scrn->FreeScreen = glamor_egl->saved_free_screen;
-		free(glamor_egl);
-		scrn->FreeScreen(FREE_SCREEN_ARGS);
-	}
+        scrn->FreeScreen = glamor_egl->saved_free_screen;
+        free(glamor_egl);
+        scrn->FreeScreen(FREE_SCREEN_ARGS);
+    }
 }
 
 Bool
 glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
-	struct glamor_egl_screen_private *glamor_egl;
-	const char *version;
-	EGLint config_attribs[] = {
+    struct glamor_egl_screen_private *glamor_egl;
+    const char *version;
+
+    EGLint config_attribs[] = {
 #ifdef GLAMOR_GLES2
-		EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_CONTEXT_CLIENT_VERSION, 2,
 #endif
-		EGL_NONE
-	};
-
-	glamor_identify(0);
-	glamor_egl = calloc(sizeof(*glamor_egl), 1);
-	if (glamor_egl == NULL)
-		return FALSE;
-	if (xf86GlamorEGLPrivateIndex == -1)
-		xf86GlamorEGLPrivateIndex =
-		    xf86AllocateScrnInfoPrivateIndex();
-
-	scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
-	glamor_egl->fd = fd;
+        EGL_NONE
+    };
+
+    glamor_identify(0);
+    glamor_egl = calloc(sizeof(*glamor_egl), 1);
+    if (glamor_egl == NULL)
+        return FALSE;
+    if (xf86GlamorEGLPrivateIndex == -1)
+        xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+
+    scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
+    glamor_egl->fd = fd;
 #ifdef GLAMOR_HAS_GBM
-	glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
-	if (glamor_egl->gbm == NULL) {
-		ErrorF("couldn't get display device\n");
-		return FALSE;
-	}
-	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
+    glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
+    if (glamor_egl->gbm == NULL) {
+        ErrorF("couldn't get display device\n");
+        return FALSE;
+    }
+    glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
 #else
-	glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)(intptr_t)fd);
+    glamor_egl->display = eglGetDisplay((EGLNativeDisplayType) (intptr_t) fd);
 #endif
 
-	glamor_egl->has_gem = glamor_egl_check_has_gem(fd);
+    glamor_egl->has_gem = glamor_egl_check_has_gem(fd);
 
 #ifndef GLAMOR_GLES2
-	eglBindAPI(EGL_OPENGL_API);
+    eglBindAPI(EGL_OPENGL_API);
 #else
-	eglBindAPI(EGL_OPENGL_ES_API);
+    eglBindAPI(EGL_OPENGL_ES_API);
 #endif
-	if (!eglInitialize
-	    (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor))
-	{
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "eglInitialize() failed\n");
-		return FALSE;
-	}
+    if (!eglInitialize
+        (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n");
+        return FALSE;
+    }
 
-	version = eglQueryString(glamor_egl->display, EGL_VERSION);
-	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
+    version = eglQueryString(glamor_egl->display, EGL_VERSION);
+    xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
 
 #define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
 	if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
@@ -765,96 +760,94 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 		return FALSE;  \
 	}
 
-	GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
-	GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
+    GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
+    GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
 #ifdef GLAMOR_GLES2
-	GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_gles2);
+    GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_gles2);
 #else
-	GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_opengl);
+    GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context,
+                                KHR_surfaceless_opengl);
 #endif
 
 #ifdef GLAMOR_HAS_DRI3_SUPPORT
-	if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
-	    glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import") )
-	    glamor_egl->dri3_capable = TRUE;
+    if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
+        glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import"))
+        glamor_egl->dri3_capable = TRUE;
 #endif
-	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
-	    eglGetProcAddress("eglCreateImageKHR");
-
-	glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC)
-	    eglGetProcAddress("eglDestroyImageKHR");
-
-	glamor_egl->egl_image_target_texture2d_oes =
-	    (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
-	    eglGetProcAddress("glEGLImageTargetTexture2DOES");
-
-	if (!glamor_egl->egl_create_image_khr
-	    || !glamor_egl->egl_image_target_texture2d_oes) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "eglGetProcAddress() failed\n");
-		return FALSE;
-	}
-
-	glamor_egl->context = eglCreateContext(glamor_egl->display,
-					       NULL, EGL_NO_CONTEXT,
-					       config_attribs);
-	if (glamor_egl->context == EGL_NO_CONTEXT) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to create EGL context\n");
-		return FALSE;
-	}
-
-	if (!eglMakeCurrent(glamor_egl->display,
-			    EGL_NO_SURFACE, EGL_NO_SURFACE,
-			    glamor_egl->context)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to make EGL context current\n");
-		return FALSE;
-	}
+    glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
+        eglGetProcAddress("eglCreateImageKHR");
+
+    glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC)
+        eglGetProcAddress("eglDestroyImageKHR");
+
+    glamor_egl->egl_image_target_texture2d_oes =
+        (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
+        eglGetProcAddress("glEGLImageTargetTexture2DOES");
+
+    if (!glamor_egl->egl_create_image_khr
+        || !glamor_egl->egl_image_target_texture2d_oes) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglGetProcAddress() failed\n");
+        return FALSE;
+    }
+
+    glamor_egl->context = eglCreateContext(glamor_egl->display,
+                                           NULL, EGL_NO_CONTEXT,
+                                           config_attribs);
+    if (glamor_egl->context == EGL_NO_CONTEXT) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n");
+        return FALSE;
+    }
+
+    if (!eglMakeCurrent(glamor_egl->display,
+                        EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                   "Failed to make EGL context current\n");
+        return FALSE;
+    }
 #ifdef GLX_USE_SHARED_DISPATCH
-	GET_CURRENT_CONTEXT(glamor_egl->glamor_context);
+    GET_CURRENT_CONTEXT(glamor_egl->glamor_context);
 #endif
-	glamor_egl->saved_free_screen = scrn->FreeScreen;
-	scrn->FreeScreen = glamor_egl_free_screen;
+    glamor_egl->saved_free_screen = scrn->FreeScreen;
+    scrn->FreeScreen = glamor_egl_free_screen;
 #ifdef GLAMOR_GLES2
-	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n");
+    xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n");
 #ifdef GLX_USE_SHARED_DISPATCH
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Glamor is using GLES2 but GLX needs GL. "
-					       "Indirect GLX may not work correctly.\n");
+    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+               "Glamor is using GLES2 but GLX needs GL. "
+               "Indirect GLX may not work correctly.\n");
 #endif
 #endif
-	return TRUE;
+    return TRUE;
 }
 
 Bool
 glamor_egl_init_textured_pixmap(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-	if (!dixRegisterPrivateKey
-	    (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate egl pixmap private\n",
-			   screen->myNum);
-		return FALSE;
-	}
-	if (glamor_egl->dri3_capable)
-		glamor_enable_dri3(screen);
-	return TRUE;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    if (!dixRegisterPrivateKey
+        (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to allocate egl pixmap private\n",
+                   screen->myNum);
+        return FALSE;
+    }
+    if (glamor_egl->dri3_capable)
+        glamor_enable_dri3(screen);
+    return TRUE;
 }
 
 Bool
 glamor_gl_dispatch_init(ScreenPtr screen,
-			struct glamor_gl_dispatch *dispatch,
-			int gl_version)
+                        struct glamor_gl_dispatch *dispatch, int gl_version)
 {
-	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-	if (!glamor_gl_dispatch_init_impl
-	    (dispatch, gl_version, (get_proc_address_t)eglGetProcAddress))
-		return FALSE;
-	glamor_egl->dispatch = dispatch;
-	return TRUE;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    struct glamor_egl_screen_private *glamor_egl =
+        glamor_egl_get_screen_private(scrn);
+    if (!glamor_gl_dispatch_init_impl
+        (dispatch, gl_version, (get_proc_address_t) eglGetProcAddress))
+        return FALSE;
+    glamor_egl->dispatch = dispatch;
+    return TRUE;
 }
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 9a0dec9..e7c8eda 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -37,16 +37,16 @@
 #include "glamor.h"
 
 static XF86ModuleVersionInfo VersRec = {
-	GLAMOR_EGL_MODULE_NAME,
-	MODULEVENDORSTRING,
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XORG_VERSION_CURRENT,
-	PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
-	ABI_CLASS_ANSIC,	/* Only need the ansic layer */
-	ABI_ANSIC_VERSION,
-	MOD_CLASS_NONE,
-	{0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
+    GLAMOR_EGL_MODULE_NAME,
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+    ABI_CLASS_ANSIC,            /* Only need the ansic layer */
+    ABI_ANSIC_VERSION,
+    MOD_CLASS_NONE,
+    {0, 0, 0, 0}                /* signature, to be patched into the file by a tool */
 };
 
 _X_EXPORT XF86ModuleData glamoreglModuleData = { &VersRec, NULL, NULL };
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d1b087e..76d5ddf 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -44,547 +44,552 @@
          &pos->member != (head);                                        \
          pos = __container_of(pos->member.prev, pos, member))
 
-
 #define xorg_list_for_each_entry_safe_reverse(pos, tmp, head, member)   \
     for (pos = __container_of((head)->prev, pos, member),               \
          tmp = __container_of(pos->member.prev, pos, member);           \
          &pos->member != (head);                                        \
          pos = tmp, tmp = __container_of(pos->member.prev, tmp, member))
 
-inline static int cache_wbucket(int size)
+inline static int
+cache_wbucket(int size)
 {
-	int order = __fls(size / 32);
-	if (order >= CACHE_BUCKET_WCOUNT)
-		order = CACHE_BUCKET_WCOUNT - 1;
-	return order;
+    int order = __fls(size / 32);
+
+    if (order >= CACHE_BUCKET_WCOUNT)
+        order = CACHE_BUCKET_WCOUNT - 1;
+    return order;
 }
 
-inline static int cache_hbucket(int size)
+inline static int
+cache_hbucket(int size)
 {
-	int order = __fls(size / 32);
-	if (order >= CACHE_BUCKET_HCOUNT)
-		order = CACHE_BUCKET_HCOUNT - 1;
-	return order;
+    int order = __fls(size / 32);
+
+    if (order >= CACHE_BUCKET_HCOUNT)
+        order = CACHE_BUCKET_HCOUNT - 1;
+    return order;
 }
 
 static glamor_pixmap_fbo *
-glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
-			    int w, int h, GLenum format, int flag)
+glamor_pixmap_fbo_cache_get(glamor_screen_private * glamor_priv,
+                            int w, int h, GLenum format, int flag)
 {
-	struct xorg_list *cache;
-	glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
-	int n_format;
+    struct xorg_list *cache;
+    glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
+    int n_format;
+
 #ifdef NO_FBO_CACHE
-	return NULL;
+    return NULL;
 #else
-	n_format = cache_format(format);
-	if (n_format == -1)
-		return NULL;
-	cache = &glamor_priv->fbo_cache[n_format]
-				       [cache_wbucket(w)]
-				       [cache_hbucket(h)];
-	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
-		xorg_list_for_each_entry(fbo_entry, cache, list) {
-			if (fbo_entry->width >= w && fbo_entry->height >= h) {
-
-				DEBUGF("Request w %d h %d format %x \n", w, h, format);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
-					fbo_entry, fbo_entry->width, fbo_entry->height,
-					fbo_entry->fb, fbo_entry->tex);
-				xorg_list_del(&fbo_entry->list);
-				ret_fbo = fbo_entry;
-				break;
-			}
-		}
-	}
-	else {
-		xorg_list_for_each_entry(fbo_entry, cache, list) {
-			if (fbo_entry->width == w && fbo_entry->height == h) {
-
-				DEBUGF("Request w %d h %d format %x \n", w, h, format);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
-					fbo_entry, fbo_entry->width, fbo_entry->height,
-					fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
-				assert(format == fbo_entry->format);
-				xorg_list_del(&fbo_entry->list);
-				ret_fbo = fbo_entry;
-				break;
-			}
-		}
-	}
-
-	if (ret_fbo)
-		glamor_priv->fbo_cache_watermark -= ret_fbo->width * ret_fbo->height;
-
-	assert(glamor_priv->fbo_cache_watermark >= 0);
-
-	return ret_fbo;
+    n_format = cache_format(format);
+    if (n_format == -1)
+        return NULL;
+    cache = &glamor_priv->fbo_cache[n_format]
+        [cache_wbucket(w)]
+        [cache_hbucket(h)];
+    if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
+        xorg_list_for_each_entry(fbo_entry, cache, list) {
+            if (fbo_entry->width >= w && fbo_entry->height >= h) {
+
+                DEBUGF("Request w %d h %d format %x \n", w, h, format);
+                DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
+                       fbo_entry, fbo_entry->width, fbo_entry->height,
+                       fbo_entry->fb, fbo_entry->tex);
+                xorg_list_del(&fbo_entry->list);
+                ret_fbo = fbo_entry;
+                break;
+            }
+        }
+    }
+    else {
+        xorg_list_for_each_entry(fbo_entry, cache, list) {
+            if (fbo_entry->width == w && fbo_entry->height == h) {
+
+                DEBUGF("Request w %d h %d format %x \n", w, h, format);
+                DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
+                       fbo_entry, fbo_entry->width, fbo_entry->height,
+                       fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+                assert(format == fbo_entry->format);
+                xorg_list_del(&fbo_entry->list);
+                ret_fbo = fbo_entry;
+                break;
+            }
+        }
+    }
+
+    if (ret_fbo)
+        glamor_priv->fbo_cache_watermark -= ret_fbo->width * ret_fbo->height;
+
+    assert(glamor_priv->fbo_cache_watermark >= 0);
+
+    return ret_fbo;
 #endif
 }
 
 void
-glamor_purge_fbo(glamor_pixmap_fbo *fbo)
+glamor_purge_fbo(glamor_pixmap_fbo * fbo)
 {
-	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
-	if (fbo->fb)
-		dispatch->glDeleteFramebuffers(1, &fbo->fb);
-	if (fbo->tex)
-		dispatch->glDeleteTextures(1, &fbo->tex);
-	if (fbo->pbo)
-		dispatch->glDeleteBuffers(1, &fbo->pbo);
-	glamor_put_dispatch(fbo->glamor_priv);
-
-	free(fbo);
+    glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+
+    if (fbo->fb)
+        dispatch->glDeleteFramebuffers(1, &fbo->fb);
+    if (fbo->tex)
+        dispatch->glDeleteTextures(1, &fbo->tex);
+    if (fbo->pbo)
+        dispatch->glDeleteBuffers(1, &fbo->pbo);
+    glamor_put_dispatch(fbo->glamor_priv);
+
+    free(fbo);
 }
 
 static void
-glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
+glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo * fbo)
 {
-	struct xorg_list *cache;
-	int n_format;
+    struct xorg_list *cache;
+    int n_format;
 
 #ifdef NO_FBO_CACHE
-	glamor_purge_fbo(fbo);
-	return;
+    glamor_purge_fbo(fbo);
+    return;
 #else
-	n_format = cache_format(fbo->format);
-
-	if (fbo->fb == 0 || n_format == -1
-	   || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
-		fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
-		glamor_fbo_expire(fbo->glamor_priv);
-		glamor_purge_fbo(fbo);
-		return;
-	}
-
-	cache = &fbo->glamor_priv->fbo_cache[n_format]
-					    [cache_wbucket(fbo->width)]
-					    [cache_hbucket(fbo->height)];
-	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
-		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
-
-	fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
-	xorg_list_add(&fbo->list, cache);
-	fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+    n_format = cache_format(fbo->format);
+
+    if (fbo->fb == 0 || n_format == -1
+        || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
+        fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
+        glamor_fbo_expire(fbo->glamor_priv);
+        glamor_purge_fbo(fbo);
+        return;
+    }
+
+    cache = &fbo->glamor_priv->fbo_cache[n_format]
+        [cache_wbucket(fbo->width)]
+        [cache_hbucket(fbo->height)];
+    DEBUGF
+        ("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
+         fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
+
+    fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
+    xorg_list_add(&fbo->list, cache);
+    fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
 #endif
 }
 
 static void
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
+glamor_pixmap_ensure_fb(glamor_pixmap_fbo * fbo)
 {
-	glamor_gl_dispatch *dispatch;
-	int status;
-
-	dispatch = glamor_get_dispatch(fbo->glamor_priv);
-
-	if (fbo->fb == 0)
-		dispatch->glGenFramebuffers(1, &fbo->fb);
-	assert(fbo->tex != 0);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
-	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
-					 GL_COLOR_ATTACHMENT0,
-					 GL_TEXTURE_2D, fbo->tex,
-					 0);
-	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	if (status != GL_FRAMEBUFFER_COMPLETE) {
-		const char *str;
-		switch (status) {
-		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-			str = "incomplete attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-			str = "incomplete/missing attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-			str = "incomplete draw buffer";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-			str = "incomplete read buffer";
-			break;
-		case GL_FRAMEBUFFER_UNSUPPORTED:
-			str = "unsupported";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-			str = "incomplete multiple";
-			break;
-		default:
-			str = "unknown error";
-			break;
-		}
-
-		FatalError("destination is framebuffer incomplete: %s [%x]\n",
-			   str, status);
-	}
-	glamor_put_dispatch(fbo->glamor_priv);
+    glamor_gl_dispatch *dispatch;
+    int status;
+
+    dispatch = glamor_get_dispatch(fbo->glamor_priv);
+
+    if (fbo->fb == 0)
+        dispatch->glGenFramebuffers(1, &fbo->fb);
+    assert(fbo->tex != 0);
+    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+    dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
+                                     GL_COLOR_ATTACHMENT0,
+                                     GL_TEXTURE_2D, fbo->tex, 0);
+    status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (status != GL_FRAMEBUFFER_COMPLETE) {
+        const char *str;
+
+        switch (status) {
+        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+            str = "incomplete attachment";
+            break;
+        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+            str = "incomplete/missing attachment";
+            break;
+        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+            str = "incomplete draw buffer";
+            break;
+        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+            str = "incomplete read buffer";
+            break;
+        case GL_FRAMEBUFFER_UNSUPPORTED:
+            str = "unsupported";
+            break;
+        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+            str = "incomplete multiple";
+            break;
+        default:
+            str = "unknown error";
+            break;
+        }
+
+        FatalError("destination is framebuffer incomplete: %s [%x]\n",
+                   str, status);
+    }
+    glamor_put_dispatch(fbo->glamor_priv);
 }
 
 glamor_pixmap_fbo *
-glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
-		  int w, int h, GLenum format, GLint tex, int flag)
+glamor_create_fbo_from_tex(glamor_screen_private * glamor_priv,
+                           int w, int h, GLenum format, GLint tex, int flag)
 {
-	glamor_pixmap_fbo *fbo;
+    glamor_pixmap_fbo *fbo;
 
-	fbo = calloc(1, sizeof(*fbo));
-	if (fbo == NULL)
-		return NULL;
+    fbo = calloc(1, sizeof(*fbo));
+    if (fbo == NULL)
+        return NULL;
 
-	xorg_list_init(&fbo->list);
+    xorg_list_init(&fbo->list);
 
-	fbo->tex = tex;
-	fbo->width = w;
-	fbo->height = h;
-	fbo->format = format;
-	fbo->glamor_priv = glamor_priv;
+    fbo->tex = tex;
+    fbo->width = w;
+    fbo->height = h;
+    fbo->format = format;
+    fbo->glamor_priv = glamor_priv;
 
-	if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
-		glamor_gl_dispatch *dispatch;
-		dispatch = glamor_get_dispatch(glamor_priv);
-		dispatch->glGenBuffers(1, &fbo->pbo);
-		glamor_put_dispatch(glamor_priv);
-		goto done;
-	}
+    if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
+        glamor_gl_dispatch *dispatch;
 
-	if (flag != GLAMOR_CREATE_FBO_NO_FBO)
-		glamor_pixmap_ensure_fb(fbo);
+        dispatch = glamor_get_dispatch(glamor_priv);
+        dispatch->glGenBuffers(1, &fbo->pbo);
+        glamor_put_dispatch(glamor_priv);
+        goto done;
+    }
 
-done:
-	return fbo;
-}
+    if (flag != GLAMOR_CREATE_FBO_NO_FBO)
+        glamor_pixmap_ensure_fb(fbo);
 
+ done:
+    return fbo;
+}
 
 void
-glamor_fbo_expire(glamor_screen_private *glamor_priv)
+glamor_fbo_expire(glamor_screen_private * glamor_priv)
 {
-	struct xorg_list *cache;
-	glamor_pixmap_fbo *fbo_entry, *tmp;
-	int i,j,k;
-
-	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
-		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
-			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
-				cache = &glamor_priv->fbo_cache[i][j][k];
-				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
-						break;
-					}
-
-					glamor_priv->fbo_cache_watermark -= fbo_entry->width * fbo_entry->height;
-					xorg_list_del(&fbo_entry->list);
-					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
-						fbo_entry->expire, glamor_priv->tick);
-					glamor_purge_fbo(fbo_entry);
-				}
-			}
+    struct xorg_list *cache;
+    glamor_pixmap_fbo *fbo_entry, *tmp;
+    int i, j, k;
+
+    for (i = 0; i < CACHE_FORMAT_COUNT; i++)
+        for (j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+            for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
+                cache = &glamor_priv->fbo_cache[i][j][k];
+                xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache,
+                                                      list) {
+                    if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
+                        break;
+                    }
+
+                    glamor_priv->fbo_cache_watermark -=
+                        fbo_entry->width * fbo_entry->height;
+                    xorg_list_del(&fbo_entry->list);
+                    DEBUGF("cache %p fbo %p expired %d current %d \n", cache,
+                           fbo_entry, fbo_entry->expire, glamor_priv->tick);
+                    glamor_purge_fbo(fbo_entry);
+                }
+            }
 
 }
 
 void
 glamor_init_pixmap_fbo(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	int i,j,k;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
-		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
-			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
-			{
-				xorg_list_init(&glamor_priv->fbo_cache[i][j][k]);
-			}
-	glamor_priv->fbo_cache_watermark = 0;
+    glamor_screen_private *glamor_priv;
+    int i, j, k;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    for (i = 0; i < CACHE_FORMAT_COUNT; i++)
+        for (j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+            for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
+                xorg_list_init(&glamor_priv->fbo_cache[i][j][k]);
+            }
+    glamor_priv->fbo_cache_watermark = 0;
 }
 
 void
 glamor_fini_pixmap_fbo(ScreenPtr screen)
 {
-	struct xorg_list *cache;
-	glamor_screen_private *glamor_priv;
-	glamor_pixmap_fbo *fbo_entry, *tmp;
-	int i,j,k;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
-		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
-			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
-			{
-				cache = &glamor_priv->fbo_cache[i][j][k];
-				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					xorg_list_del(&fbo_entry->list);
-					glamor_purge_fbo(fbo_entry);
-				}
-			}
+    struct xorg_list *cache;
+    glamor_screen_private *glamor_priv;
+    glamor_pixmap_fbo *fbo_entry, *tmp;
+    int i, j, k;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    for (i = 0; i < CACHE_FORMAT_COUNT; i++)
+        for (j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+            for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
+                cache = &glamor_priv->fbo_cache[i][j][k];
+                xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache,
+                                                      list) {
+                    xorg_list_del(&fbo_entry->list);
+                    glamor_purge_fbo(fbo_entry);
+                }
+            }
 }
 
 void
-glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+glamor_destroy_fbo(glamor_pixmap_fbo * fbo)
 {
-	xorg_list_del(&fbo->list);
-	glamor_pixmap_fbo_cache_put(fbo);
+    xorg_list_del(&fbo->list);
+    glamor_pixmap_fbo_cache_put(fbo);
 
 }
 
 static int
-_glamor_create_tex(glamor_screen_private *glamor_priv,
-		   int w, int h, GLenum format)
+_glamor_create_tex(glamor_screen_private * glamor_priv,
+                   int w, int h, GLenum format)
 {
-	glamor_gl_dispatch *dispatch;
-	unsigned int tex = 0;
-
-	/* With dri3, we want to allocate ARGB8888 pixmaps only.
-	 * Depending on the implementation, GL_RGBA might not
-	 * give us ARGB8888. We ask glamor_egl to use get
-	 * an ARGB8888 based texture for us. */
-	if (glamor_priv->dri3_enabled && format == GL_RGBA)
-	{
-		tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
-								w, h);
-	}
-	if (!tex)
-	{
-		dispatch = glamor_get_dispatch(glamor_priv);
-		dispatch->glGenTextures(1, &tex);
-		dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-				       format, GL_UNSIGNED_BYTE, NULL);
-		glamor_put_dispatch(glamor_priv);
-	}
-	return tex;
+    glamor_gl_dispatch *dispatch;
+    unsigned int tex = 0;
+
+    /* With dri3, we want to allocate ARGB8888 pixmaps only.
+     * Depending on the implementation, GL_RGBA might not
+     * give us ARGB8888. We ask glamor_egl to use get
+     * an ARGB8888 based texture for us. */
+    if (glamor_priv->dri3_enabled && format == GL_RGBA) {
+        tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
+                                                       w, h);
+    }
+    if (!tex) {
+        dispatch = glamor_get_dispatch(glamor_priv);
+        dispatch->glGenTextures(1, &tex);
+        dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                                  GL_NEAREST);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+                                  GL_NEAREST);
+        dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+                               format, GL_UNSIGNED_BYTE, NULL);
+        glamor_put_dispatch(glamor_priv);
+    }
+    return tex;
 }
 
 glamor_pixmap_fbo *
-glamor_create_fbo(glamor_screen_private *glamor_priv,
-		  int w, int h,
-		  GLenum format,
-		  int flag)
+glamor_create_fbo(glamor_screen_private * glamor_priv,
+                  int w, int h, GLenum format, int flag)
 {
-	glamor_pixmap_fbo *fbo;
-	GLint tex = 0;
-	int cache_flag;
-
-	if (!glamor_check_fbo_size(glamor_priv, w, h))
-		return NULL;
-
-	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
-		goto new_fbo;
-
-	if (flag == GLAMOR_CREATE_PIXMAP_MAP)
-		goto no_tex;
-
-	if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
-		cache_flag = GLAMOR_CACHE_EXACT_SIZE;
-	else
-		cache_flag = 0;
-
-	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
-					  format, cache_flag);
-	if (fbo)
-		return fbo;
-new_fbo:
-	tex = _glamor_create_tex(glamor_priv, w, h, format);
-no_tex:
-	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
-
-	return fbo;
+    glamor_pixmap_fbo *fbo;
+    GLint tex = 0;
+    int cache_flag;
+
+    if (!glamor_check_fbo_size(glamor_priv, w, h))
+        return NULL;
+
+    if (flag == GLAMOR_CREATE_FBO_NO_FBO)
+        goto new_fbo;
+
+    if (flag == GLAMOR_CREATE_PIXMAP_MAP)
+        goto no_tex;
+
+    if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
+        cache_flag = GLAMOR_CACHE_EXACT_SIZE;
+    else
+        cache_flag = 0;
+
+    fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format, cache_flag);
+    if (fbo)
+        return fbo;
+ new_fbo:
+    tex = _glamor_create_tex(glamor_priv, w, h, format);
+ no_tex:
+    fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
+
+    return fbo;
 }
 
 static glamor_pixmap_fbo *
-_glamor_create_fbo_array(glamor_screen_private *glamor_priv,
-			 int w, int h, GLenum format, int flag,
-			 int block_w, int block_h,
-			 glamor_pixmap_private *pixmap_priv,
-			 int has_fbo)
+_glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+                         int w, int h, GLenum format, int flag,
+                         int block_w, int block_h,
+                         glamor_pixmap_private * pixmap_priv, int has_fbo)
 {
-	int block_wcnt;
-	int block_hcnt;
-	glamor_pixmap_fbo **fbo_array;
-	BoxPtr box_array;
-	int i,j;
-	glamor_pixmap_private_large_t *priv;
-
-	priv = &pixmap_priv->large;
-
-	block_wcnt = (w + block_w - 1) / block_w;
-	block_hcnt = (h + block_h - 1) / block_h;
-
-	box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0]));
-	if (box_array == NULL)
-		return NULL;
-
-	fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo*));
-	if (fbo_array == NULL) {
-		free(box_array);
-		return FALSE;
-	}
-	for(i = 0; i < block_hcnt; i++)
-	{
-		int block_y1, block_y2;
-		int fbo_w, fbo_h;
-
-		block_y1 = i * block_h;
-		block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h);
-		fbo_h = block_y2 - block_y1;
-
-		for (j = 0; j < block_wcnt; j++)
-		{
-			box_array[i * block_wcnt + j].x1 = j * block_w;
-			box_array[i * block_wcnt + j].y1 = block_y1;
-			box_array[i * block_wcnt + j].x2 = (j + 1) * block_w > w ? w : (j + 1) * block_w;
-			box_array[i * block_wcnt + j].y2 = block_y2;
-			fbo_w = box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + j].x1;
-			if (!has_fbo)
-				fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
-										  fbo_w, fbo_h, format,
-										  GLAMOR_CREATE_PIXMAP_FIXUP);
-			else
-				fbo_array[i * block_wcnt + j] = priv->base.fbo;
-			if (fbo_array[i * block_wcnt + j] == NULL)
-				goto cleanup;
-		}
-	}
-
-	priv->box = box_array[0];
-	priv->box_array = box_array;
-	priv->fbo_array = fbo_array;
-	priv->block_wcnt = block_wcnt;
-	priv->block_hcnt = block_hcnt;
-	return fbo_array[0];
-
-cleanup:
-	for(i = 0; i < block_wcnt * block_hcnt; i++)
-		if ((fbo_array)[i])
-			glamor_destroy_fbo((fbo_array)[i]);
-	free(box_array);
-	free(fbo_array);
-	return NULL;
+    int block_wcnt;
+    int block_hcnt;
+    glamor_pixmap_fbo **fbo_array;
+    BoxPtr box_array;
+    int i, j;
+    glamor_pixmap_private_large_t *priv;
+
+    priv = &pixmap_priv->large;
+
+    block_wcnt = (w + block_w - 1) / block_w;
+    block_hcnt = (h + block_h - 1) / block_h;
+
+    box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0]));
+    if (box_array == NULL)
+        return NULL;
+
+    fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo *));
+    if (fbo_array == NULL) {
+        free(box_array);
+        return FALSE;
+    }
+    for (i = 0; i < block_hcnt; i++) {
+        int block_y1, block_y2;
+        int fbo_w, fbo_h;
+
+        block_y1 = i * block_h;
+        block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h);
+        fbo_h = block_y2 - block_y1;
+
+        for (j = 0; j < block_wcnt; j++) {
+            box_array[i * block_wcnt + j].x1 = j * block_w;
+            box_array[i * block_wcnt + j].y1 = block_y1;
+            box_array[i * block_wcnt + j].x2 =
+                (j + 1) * block_w > w ? w : (j + 1) * block_w;
+            box_array[i * block_wcnt + j].y2 = block_y2;
+            fbo_w =
+                box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt +
+                                                             j].x1;
+            if (!has_fbo)
+                fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
+                                                                  fbo_w, fbo_h,
+                                                                  format,
+                                                                  GLAMOR_CREATE_PIXMAP_FIXUP);
+            else
+                fbo_array[i * block_wcnt + j] = priv->base.fbo;
+            if (fbo_array[i * block_wcnt + j] == NULL)
+                goto cleanup;
+        }
+    }
+
+    priv->box = box_array[0];
+    priv->box_array = box_array;
+    priv->fbo_array = fbo_array;
+    priv->block_wcnt = block_wcnt;
+    priv->block_hcnt = block_hcnt;
+    return fbo_array[0];
+
+ cleanup:
+    for (i = 0; i < block_wcnt * block_hcnt; i++)
+        if ((fbo_array)[i])
+            glamor_destroy_fbo((fbo_array)[i]);
+    free(box_array);
+    free(fbo_array);
+    return NULL;
 }
 
-
 /* Create a fbo array to cover the w*h region, by using block_w*block_h
  * block.*/
 glamor_pixmap_fbo *
-glamor_create_fbo_array(glamor_screen_private *glamor_priv,
-			int w, int h, GLenum format, int flag,
-			int block_w, int block_h,
-			glamor_pixmap_private *pixmap_priv)
+glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+                        int w, int h, GLenum format, int flag,
+                        int block_w, int block_h,
+                        glamor_pixmap_private * pixmap_priv)
 {
-	pixmap_priv->large.block_w = block_w;
-	pixmap_priv->large.block_h = block_h;
-	return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
-					block_w, block_h, pixmap_priv, 0);
+    pixmap_priv->large.block_w = block_w;
+    pixmap_priv->large.block_h = block_h;
+    return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
+                                    block_w, block_h, pixmap_priv, 0);
 }
 
 glamor_pixmap_fbo *
-glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
+glamor_pixmap_detach_fbo(glamor_pixmap_private * pixmap_priv)
 {
-	glamor_pixmap_fbo *fbo;
+    glamor_pixmap_fbo *fbo;
 
-	if (pixmap_priv == NULL)
-		return NULL;
+    if (pixmap_priv == NULL)
+        return NULL;
 
-	fbo = pixmap_priv->base.fbo;
-	if (fbo == NULL)
-		return NULL;
+    fbo = pixmap_priv->base.fbo;
+    if (fbo == NULL)
+        return NULL;
 
-	pixmap_priv->base.fbo = NULL;
-	return fbo;
+    pixmap_priv->base.fbo = NULL;
+    return fbo;
 }
 
 /* The pixmap must not be attached to another fbo. */
 void
-glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
+glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo)
 {
-	glamor_pixmap_private *pixmap_priv;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (pixmap_priv->base.fbo)
-		return;
-
-	pixmap_priv->base.fbo = fbo;
-
-	switch (pixmap_priv->type) {
-	case GLAMOR_TEXTURE_LARGE:
-	case GLAMOR_TEXTURE_ONLY:
-	case GLAMOR_TEXTURE_DRM:
-		pixmap_priv->base.gl_fbo = 1;
-		if (fbo->tex != 0)
-			pixmap_priv->base.gl_tex = 1;
-		else {
-			/* XXX For the Xephyr only, may be broken now.*/
-			pixmap_priv->base.gl_tex = 0;
-		}
-	case GLAMOR_MEMORY_MAP:
-		pixmap->devPrivate.ptr = NULL;
-		break;
-	default:
-		break;
-	}
+    glamor_pixmap_private *pixmap_priv;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (pixmap_priv->base.fbo)
+        return;
+
+    pixmap_priv->base.fbo = fbo;
+
+    switch (pixmap_priv->type) {
+    case GLAMOR_TEXTURE_LARGE:
+    case GLAMOR_TEXTURE_ONLY:
+    case GLAMOR_TEXTURE_DRM:
+        pixmap_priv->base.gl_fbo = 1;
+        if (fbo->tex != 0)
+            pixmap_priv->base.gl_tex = 1;
+        else {
+            /* XXX For the Xephyr only, may be broken now. */
+            pixmap_priv->base.gl_tex = 0;
+        }
+    case GLAMOR_MEMORY_MAP:
+        pixmap->devPrivate.ptr = NULL;
+        break;
+    default:
+        break;
+    }
 }
 
 void
-glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
+glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv)
 {
-	glamor_pixmap_fbo *fbo;
-	if (priv->type == GLAMOR_TEXTURE_LARGE) {
-		int i;
-		glamor_pixmap_private_large_t *large = &priv->large;
-		for(i = 0; i < large->block_wcnt * large->block_hcnt; i++)
-			glamor_destroy_fbo(large->fbo_array[i]);
-		free(large->fbo_array);
-	} else {
-		fbo = glamor_pixmap_detach_fbo(priv);
-		if (fbo)
-			glamor_destroy_fbo(fbo);
-	}
-
-	free(priv);
+    glamor_pixmap_fbo *fbo;
+
+    if (priv->type == GLAMOR_TEXTURE_LARGE) {
+        int i;
+        glamor_pixmap_private_large_t *large = &priv->large;
+
+        for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
+            glamor_destroy_fbo(large->fbo_array[i]);
+        free(large->fbo_array);
+    }
+    else {
+        fbo = glamor_pixmap_detach_fbo(priv);
+        if (fbo)
+            glamor_destroy_fbo(fbo);
+    }
+
+    free(priv);
 }
 
 Bool
 glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_pixmap_private *pixmap_priv;
-	glamor_pixmap_fbo *fbo;
-
-	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv->base.fbo == NULL) {
-
-		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
-					pixmap->drawable.height,
-					format,
-					flag);
-		if (fbo == NULL)
-			return FALSE;
-
-		glamor_pixmap_attach_fbo(pixmap, fbo);
-	} else {
-		/* We do have a fbo, but it may lack of fb or tex. */
-		if (!pixmap_priv->base.fbo->tex)
-			pixmap_priv->base.fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
-								   pixmap->drawable.height, format);
-
-		if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
-			glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
-	}
-
-	return TRUE;
+    glamor_screen_private *glamor_priv;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_pixmap_fbo *fbo;
+
+    glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (pixmap_priv->base.fbo == NULL) {
+
+        fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
+                                pixmap->drawable.height, format, flag);
+        if (fbo == NULL)
+            return FALSE;
+
+        glamor_pixmap_attach_fbo(pixmap, fbo);
+    }
+    else {
+        /* We do have a fbo, but it may lack of fb or tex. */
+        if (!pixmap_priv->base.fbo->tex)
+            pixmap_priv->base.fbo->tex =
+                _glamor_create_tex(glamor_priv, pixmap->drawable.width,
+                                   pixmap->drawable.height, format);
+
+        if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
+            glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
+    }
+
+    return TRUE;
 }
 
 _X_EXPORT void
 glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
 {
-	glamor_pixmap_private *front_priv, *back_priv;
-	glamor_pixmap_fbo *temp_fbo;
-
-	front_priv = glamor_get_pixmap_private(front);
-	back_priv = glamor_get_pixmap_private(back);
-	temp_fbo = front_priv->base.fbo;
-	front_priv->base.fbo = back_priv->base.fbo;
-	back_priv->base.fbo = temp_fbo;
+    glamor_pixmap_private *front_priv, *back_priv;
+    glamor_pixmap_fbo *temp_fbo;
+
+    front_priv = glamor_get_pixmap_private(front);
+    back_priv = glamor_get_pixmap_private(back);
+    temp_fbo = front_priv->base.fbo;
+    front_priv->base.fbo = back_priv->base.fbo;
+    back_priv->base.fbo = temp_fbo;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index fbc8739..47d27bc 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -33,332 +33,318 @@
  */
 Bool
 glamor_fill(DrawablePtr drawable,
-	    GCPtr gc, int x, int y, int width, int height, Bool fallback)
+            GCPtr gc, int x, int y, int width, int height, Bool fallback)
 {
-	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
-	int off_x, off_y;
-	PixmapPtr sub_pixmap = NULL;
-	glamor_access_t sub_pixmap_access;
-	DrawablePtr saved_drawable = NULL;
-	int saved_x = x, saved_y = y;
-
-	glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
-
-	switch (gc->fillStyle) {
-	case FillSolid:
-		if (!glamor_solid(dst_pixmap,
-				  x + off_x,
-				  y + off_y,
-				  width, height, gc->alu, gc->planemask,
-				  gc->fgPixel))
-			goto fail;
-		break;
-	case FillStippled:
-	case FillOpaqueStippled:
-		if (!glamor_stipple(dst_pixmap,
-				    gc->stipple,
-				    x + off_x,
-				    y + off_y,
-				    width,
-				    height,
-				    gc->alu,
-				    gc->planemask,
-				    gc->fgPixel,
-				    gc->bgPixel, gc->patOrg.x,
-				    gc->patOrg.y))
-			goto fail;
-		break;
-	case FillTiled:
-		if (!glamor_tile(dst_pixmap,
-				 gc->tile.pixmap,
-				 x + off_x,
-				 y + off_y,
-				 width,
-				 height,
-				 gc->alu,
-				 gc->planemask,
-				 x - drawable->x - gc->patOrg.x,
-				 y - drawable->y - gc->patOrg.y))
-			goto fail;
-		break;
-	}
-	return TRUE;
-
-      fail:
-	if (!fallback) {
-		if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
-		   && glamor_ddx_fallback_check_gc(gc))
-		return FALSE;
-	}
-	/* Is it possible to set the access as WO? */
-
-	sub_pixmap_access = GLAMOR_ACCESS_RW;
-
-	sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
-					   y + off_y, width, height,
-					   sub_pixmap_access);
-
-	if (sub_pixmap != NULL) {
-		if (gc->fillStyle != FillSolid) {
-			gc->patOrg.x += (drawable->x - x);
-			gc->patOrg.y += (drawable->y - y);
-		}
-		saved_drawable = drawable;
-		drawable = &sub_pixmap->drawable;
-		saved_x = x;
-		saved_y = y;
-		x = 0;
-		y = 0;
-	}
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		if (glamor_prepare_access_gc(gc)) {
-			fbFill(drawable, gc, x, y, width, height);
-			glamor_finish_access_gc(gc);
-		}
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-	}
-
-	if (sub_pixmap != NULL) {
-		if (gc->fillStyle != FillSolid) {
-			gc->patOrg.x -= (saved_drawable->x - saved_x);
-			gc->patOrg.y -= (saved_drawable->y - saved_y);
-		}
-
-		x = saved_x;
-		y = saved_y;
-
-		glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
-				      x + off_x, y + off_y,
-				      width, height, sub_pixmap_access);
-	}
-
-	return TRUE;
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
+    int off_x, off_y;
+    PixmapPtr sub_pixmap = NULL;
+    glamor_access_t sub_pixmap_access;
+    DrawablePtr saved_drawable = NULL;
+    int saved_x = x, saved_y = y;
+
+    glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
+
+    switch (gc->fillStyle) {
+    case FillSolid:
+        if (!glamor_solid(dst_pixmap,
+                          x + off_x,
+                          y + off_y,
+                          width, height, gc->alu, gc->planemask, gc->fgPixel))
+            goto fail;
+        break;
+    case FillStippled:
+    case FillOpaqueStippled:
+        if (!glamor_stipple(dst_pixmap,
+                            gc->stipple,
+                            x + off_x,
+                            y + off_y,
+                            width,
+                            height,
+                            gc->alu,
+                            gc->planemask,
+                            gc->fgPixel,
+                            gc->bgPixel, gc->patOrg.x, gc->patOrg.y))
+            goto fail;
+        break;
+    case FillTiled:
+        if (!glamor_tile(dst_pixmap,
+                         gc->tile.pixmap,
+                         x + off_x,
+                         y + off_y,
+                         width,
+                         height,
+                         gc->alu,
+                         gc->planemask,
+                         x - drawable->x - gc->patOrg.x,
+                         y - drawable->y - gc->patOrg.y))
+            goto fail;
+        break;
+    }
+    return TRUE;
+
+ fail:
+    if (!fallback) {
+        if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
+            && glamor_ddx_fallback_check_gc(gc))
+            return FALSE;
+    }
+    /* Is it possible to set the access as WO? */
+
+    sub_pixmap_access = GLAMOR_ACCESS_RW;
+
+    sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
+                                       y + off_y, width, height,
+                                       sub_pixmap_access);
+
+    if (sub_pixmap != NULL) {
+        if (gc->fillStyle != FillSolid) {
+            gc->patOrg.x += (drawable->x - x);
+            gc->patOrg.y += (drawable->y - y);
+        }
+        saved_drawable = drawable;
+        drawable = &sub_pixmap->drawable;
+        saved_x = x;
+        saved_y = y;
+        x = 0;
+        y = 0;
+    }
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+        if (glamor_prepare_access_gc(gc)) {
+            fbFill(drawable, gc, x, y, width, height);
+            glamor_finish_access_gc(gc);
+        }
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+    }
+
+    if (sub_pixmap != NULL) {
+        if (gc->fillStyle != FillSolid) {
+            gc->patOrg.x -= (saved_drawable->x - saved_x);
+            gc->patOrg.y -= (saved_drawable->y - saved_y);
+        }
+
+        x = saved_x;
+        y = saved_y;
+
+        glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
+                              x + off_x, y + off_y,
+                              width, height, sub_pixmap_access);
+    }
+
+    return TRUE;
 }
 
 void
 glamor_init_solid_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	const char *solid_vs =
-	    "attribute vec4 v_position;"
-	    "void main()\n" "{\n" "       gl_Position = v_position;\n"
-	    "}\n";
-	const char *solid_fs =
-	    GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
-	    "void main()\n" "{\n" "	gl_FragColor = color;\n" "}\n";
-	GLint fs_prog, vs_prog;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  glamor_get_dispatch(glamor_priv);
-	glamor_priv->solid_prog = dispatch->glCreateProgram();
-	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
-	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-					   solid_fs);
-	dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
-	dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
-
-	dispatch->glBindAttribLocation(glamor_priv->solid_prog,
-				       GLAMOR_VERTEX_POS, "v_position");
-	glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
-
-	glamor_priv->solid_color_uniform_location =
-	    dispatch->glGetUniformLocation(glamor_priv->solid_prog,
-					   "color");
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    const char *solid_vs =
+        "attribute vec4 v_position;"
+        "void main()\n" "{\n" "       gl_Position = v_position;\n" "}\n";
+    const char *solid_fs =
+        GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
+        "void main()\n" "{\n" "	gl_FragColor = color;\n" "}\n";
+    GLint fs_prog, vs_prog;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_priv->solid_prog = dispatch->glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs);
+    dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
+
+    dispatch->glBindAttribLocation(glamor_priv->solid_prog,
+                                   GLAMOR_VERTEX_POS, "v_position");
+    glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
+
+    glamor_priv->solid_color_uniform_location =
+        dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color");
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_solid_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
 
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glDeleteProgram(glamor_priv->solid_prog);
-	glamor_put_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glDeleteProgram(glamor_priv->solid_prog);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
 _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch;
-	GLfloat xscale, yscale;
-	float vertices[32];
-	float *pvertices = vertices;
-	int valid_nbox = ARRAY_SIZE(vertices);
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glUseProgram(glamor_priv->solid_prog);
-
-	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
-			       1, color);
-
-	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
-
-	if (unlikely(nbox*4*2 > ARRAY_SIZE(vertices))) {
-		int allocated_box;
-
-		if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) {
-			allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
-		} else
-			allocated_box = nbox;
-		pvertices = malloc(allocated_box * 4 * 2 * sizeof(float));
-		if (pvertices)
-			valid_nbox = allocated_box;
-		else {
-			pvertices = vertices;
-			valid_nbox = ARRAY_SIZE(vertices) / (4*2);
-		}
-	}
-
-	if (unlikely(nbox > 1))
-		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					pvertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	while(nbox) {
-		int box_cnt, i;
-		float *valid_vertices;
-		valid_vertices = pvertices;
-		box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
-		for (i = 0; i < box_cnt; i++) {
-			glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
-						     box[i].x1, box[i].y1,
-						     box[i].x2, box[i].y2,
-						     glamor_priv->yInverted,
-						     valid_vertices);
-			valid_vertices += 4*2;
-		}
-		if (box_cnt == 1)
-			dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
-		else
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_gl_dispatch *dispatch;
+    GLfloat xscale, yscale;
+    float vertices[32];
+    float *pvertices = vertices;
+    int valid_nbox = ARRAY_SIZE(vertices);
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glUseProgram(glamor_priv->solid_prog);
+
+    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
+
+    pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+
+    if (unlikely(nbox * 4 * 2 > ARRAY_SIZE(vertices))) {
+        int allocated_box;
+
+        if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) {
+            allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
+        }
+        else
+            allocated_box = nbox;
+        pvertices = malloc(allocated_box * 4 * 2 * sizeof(float));
+        if (pvertices)
+            valid_nbox = allocated_box;
+        else {
+            pvertices = vertices;
+            valid_nbox = ARRAY_SIZE(vertices) / (4 * 2);
+        }
+    }
+
+    if (unlikely(nbox > 1))
+        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), pvertices);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+    while (nbox) {
+        int box_cnt, i;
+        float *valid_vertices;
+
+        valid_vertices = pvertices;
+        box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
+        for (i = 0; i < box_cnt; i++) {
+            glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
+                                         box[i].x1, box[i].y1,
+                                         box[i].x2, box[i].y2,
+                                         glamor_priv->yInverted,
+                                         valid_vertices);
+            valid_vertices += 4 * 2;
+        }
+        if (box_cnt == 1)
+            dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
+        else
 #ifndef GLAMOR_GLES2
-			dispatch->glDrawRangeElements(GL_TRIANGLES,
-						      0,
-						      box_cnt * 4,
-						      box_cnt * 6,
-						      GL_UNSIGNED_SHORT,
-						      NULL);
+            dispatch->glDrawRangeElements(GL_TRIANGLES,
+                                          0,
+                                          box_cnt * 4,
+                                          box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
 #else
-			dispatch->glDrawElements(GL_TRIANGLES,
-						 box_cnt * 6,
-						 GL_UNSIGNED_SHORT,
-						 NULL);
+            dispatch->glDrawElements(GL_TRIANGLES,
+                                     box_cnt * 6, GL_UNSIGNED_SHORT, NULL);
 #endif
-		nbox -= box_cnt;
-		box += box_cnt;
-	}
-
-	if (pvertices != vertices)
-		free(pvertices);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	glamor_priv->state = RENDER_STATE;
-	glamor_priv->render_idle_cnt = 0;
+        nbox -= box_cnt;
+        box += box_cnt;
+    }
+
+    if (pvertices != vertices)
+        free(pvertices);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    glamor_priv->state = RENDER_STATE;
+    glamor_priv->render_idle_cnt = 0;
 }
 
 Bool
 glamor_solid_boxes(PixmapPtr pixmap,
-		   BoxPtr box, int nbox,
-		   unsigned long fg_pixel)
+                   BoxPtr box, int nbox, unsigned long fg_pixel)
 {
-	glamor_pixmap_private *pixmap_priv;
-	GLfloat color[4];
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return FALSE;
-
-	glamor_get_rgba_from_pixel(fg_pixel,
-				   &color[0],
-				   &color[1],
-				   &color[2],
-				   &color[3], format_for_pixmap(pixmap));
-
-	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		RegionRec region;
-		int n_region;
-		glamor_pixmap_clipped_regions *clipped_regions;
-		int i;
-
-		RegionInitBoxes(&region, box, nbox);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
-		for(i = 0; i < n_region; i++)
-		{
-			BoxPtr inner_box;
-			int inner_nbox;
-			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
-
-			inner_box = RegionRects(clipped_regions[i].region);
-			inner_nbox = RegionNumRects(clipped_regions[i].region);
-			_glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
-			RegionDestroy(clipped_regions[i].region);
-		}
-		free(clipped_regions);
-		RegionUninit(&region);
-	} else
-		_glamor_solid_boxes(pixmap, box, nbox, color);
-
-	return TRUE;
+    glamor_pixmap_private *pixmap_priv;
+    GLfloat color[4];
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return FALSE;
+
+    glamor_get_rgba_from_pixel(fg_pixel,
+                               &color[0],
+                               &color[1],
+                               &color[2], &color[3], format_for_pixmap(pixmap));
+
+    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        RegionRec region;
+        int n_region;
+        glamor_pixmap_clipped_regions *clipped_regions;
+        int i;
+
+        RegionInitBoxes(&region, box, nbox);
+        clipped_regions =
+            glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0,
+                                           0, 0);
+        for (i = 0; i < n_region; i++) {
+            BoxPtr inner_box;
+            int inner_nbox;
+
+            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+            inner_box = RegionRects(clipped_regions[i].region);
+            inner_nbox = RegionNumRects(clipped_regions[i].region);
+            _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
+            RegionDestroy(clipped_regions[i].region);
+        }
+        free(clipped_regions);
+        RegionUninit(&region);
+    }
+    else
+        _glamor_solid_boxes(pixmap, box, nbox, color);
+
+    return TRUE;
 }
 
 Bool
 glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	     unsigned char alu, unsigned long planemask,
-	     unsigned long fg_pixel)
+             unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_pixmap_private *pixmap_priv;
-	glamor_gl_dispatch *dispatch;
-	BoxRec box;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return FALSE;
-
-	if (!glamor_set_planemask(pixmap, planemask)) {
-		glamor_fallback
-		    ("Failedto set planemask  in glamor_solid.\n");
-		return FALSE;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, alu)) {
-		if (alu == GXclear)
-			fg_pixel = 0;
-		else {
-			glamor_fallback("unsupported alu %x\n", alu);
-			glamor_put_dispatch(glamor_priv);
-			return FALSE;
-		}
-	}
-	box.x1 = x;
-	box.y1 = y;
-	box.x2 = x + width;
-	box.y2 = y + height;
-	glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
-
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_put_dispatch(glamor_priv);
-
-	return TRUE;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *pixmap_priv;
+    glamor_gl_dispatch *dispatch;
+    BoxRec box;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return FALSE;
+
+    if (!glamor_set_planemask(pixmap, planemask)) {
+        glamor_fallback("Failedto set planemask  in glamor_solid.\n");
+        return FALSE;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (!glamor_set_alu(dispatch, alu)) {
+        if (alu == GXclear)
+            fg_pixel = 0;
+        else {
+            glamor_fallback("unsupported alu %x\n", alu);
+            glamor_put_dispatch(glamor_priv);
+            return FALSE;
+        }
+    }
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + width;
+    box.y2 = y + height;
+    glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
+
+    glamor_set_alu(dispatch, GXcopy);
+    glamor_put_dispatch(glamor_priv);
+
+    return TRUE;
 }
-
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 35e881f..7261d28 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -28,86 +28,81 @@
 
 static Bool
 _glamor_fill_spans(DrawablePtr drawable,
-		  GCPtr gc,
-		  int n, DDXPointPtr points, int *widths, int sorted, Bool fallback)
+                   GCPtr gc,
+                   int n, DDXPointPtr points, int *widths, int sorted,
+                   Bool fallback)
 {
-	DDXPointPtr ppt;
-	int nbox;
-	BoxPtr pbox;
-	int x1, x2, y;
-	RegionPtr pClip = fbGetCompositeClip(gc);
-	Bool ret = FALSE;
+    DDXPointPtr ppt;
+    int nbox;
+    BoxPtr pbox;
+    int x1, x2, y;
+    RegionPtr pClip = fbGetCompositeClip(gc);
+    Bool ret = FALSE;
 
-	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
-		goto fail;
+    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
+        goto fail;
 
-	ppt = points;
-	while (n--) {
-		x1 = ppt->x;
-		y = ppt->y;
-		x2 = x1 + (int) *widths;
-		ppt++;
-		widths++;
+    ppt = points;
+    while (n--) {
+        x1 = ppt->x;
+        y = ppt->y;
+        x2 = x1 + (int) *widths;
+        ppt++;
+        widths++;
 
-		nbox = REGION_NUM_RECTS(pClip);
-		pbox = REGION_RECTS(pClip);
-		while (nbox--) {
-			int real_x1 = x1, real_x2 = x2;
+        nbox = REGION_NUM_RECTS(pClip);
+        pbox = REGION_RECTS(pClip);
+        while (nbox--) {
+            int real_x1 = x1, real_x2 = x2;
 
-			if (real_x1 < pbox->x1)
-				real_x1 = pbox->x1;
+            if (real_x1 < pbox->x1)
+                real_x1 = pbox->x1;
 
-			if (real_x2 > pbox->x2)
-				real_x2 = pbox->x2;
+            if (real_x2 > pbox->x2)
+                real_x2 = pbox->x2;
 
-			if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) {
-				if (!glamor_fill(drawable, gc, real_x1, y, 
-						 real_x2 - real_x1, 1, fallback))
-					goto fail;
-			}
-			pbox++;
-		}
-	}
-	ret = TRUE;
-	goto done;
+            if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) {
+                if (!glamor_fill(drawable, gc, real_x1, y,
+                                 real_x2 - real_x1, 1, fallback))
+                    goto fail;
+            }
+            pbox++;
+        }
+    }
+    ret = TRUE;
+    goto done;
 
-fail:
-	if (!fallback 
-	    && glamor_ddx_fallback_check_pixmap(drawable)
-	    && glamor_ddx_fallback_check_gc(gc)) {
-		goto done;
-	}
-	glamor_fallback("to %p (%c)\n", drawable,
-			glamor_get_drawable_location(drawable));
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		if (glamor_prepare_access_gc(gc)) {
-			fbFillSpans(drawable, gc, n, points, widths,
-				    sorted);
-			glamor_finish_access_gc(gc);
-		}
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-	}
-	ret = TRUE;
+ fail:
+    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
+        && glamor_ddx_fallback_check_gc(gc)) {
+        goto done;
+    }
+    glamor_fallback("to %p (%c)\n", drawable,
+                    glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+        if (glamor_prepare_access_gc(gc)) {
+            fbFillSpans(drawable, gc, n, points, widths, sorted);
+            glamor_finish_access_gc(gc);
+        }
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+    }
+    ret = TRUE;
 
-done:
-	return ret;
+ done:
+    return ret;
 }
 
-
 void
 glamor_fill_spans(DrawablePtr drawable,
-		  GCPtr gc,
-		  int n, DDXPointPtr points, int *widths, int sorted)
+                  GCPtr gc, int n, DDXPointPtr points, int *widths, int sorted)
 {
-	_glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE);
+    _glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE);
 }
 
 Bool
 glamor_fill_spans_nf(DrawablePtr drawable,
-		     GCPtr gc,
-		     int n, DDXPointPtr points, int *widths, int sorted)
+                     GCPtr gc,
+                     int n, DDXPointPtr points, int *widths, int sorted)
 {
-	return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE);
+    return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE);
 }
-
-
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 5df576c..5609e70 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -28,74 +28,71 @@
 
 #include "glamor_priv.h"
 
-
 static Bool
 _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
-		  unsigned int format, unsigned long planeMask, char *d,
-		  Bool fallback)
+                  unsigned int format, unsigned long planeMask, char *d,
+                  Bool fallback)
 {
-	PixmapPtr pixmap, sub_pixmap;
-	struct glamor_pixmap_private *pixmap_priv;
-	int x_off, y_off;
-	int stride;
-	void *data;
-
-	pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+    PixmapPtr pixmap, sub_pixmap;
+    struct glamor_pixmap_private *pixmap_priv;
+    int x_off, y_off;
+    int stride;
+    void *data;
 
-	if (format != ZPixmap)
-		goto fall_back;
-	pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+    pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
-	if (!glamor_set_planemask(pixmap, planeMask)) {
-		glamor_fallback
-		    ("Failedto set planemask  in glamor_solid.\n");
-		goto fall_back;
-	}
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (format != ZPixmap)
+        goto fall_back;
+    pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
+    if (!glamor_set_planemask(pixmap, planeMask)) {
+        glamor_fallback("Failedto set planemask  in glamor_solid.\n");
+        goto fall_back;
+    }
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		goto fall_back;
-	stride = PixmapBytePad(w, drawable->depth);
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        goto fall_back;
+    stride = PixmapBytePad(w, drawable->depth);
 
-	x += drawable->x + x_off;
-	y += drawable->y + y_off;
+    x += drawable->x + x_off;
+    y += drawable->y + y_off;
 
-	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride,
-						 d, 0, GLAMOR_ACCESS_RO);
-	if (data != NULL) {
-		assert(data == d);
-		return TRUE;
-	}
-fall_back:
-	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
-					   y + y_off + drawable->y, w, h,
-					   GLAMOR_ACCESS_RO);
-	if (sub_pixmap) {
-		fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d);
-		glamor_put_sub_pixmap(sub_pixmap, pixmap,
-				      x + x_off + drawable->x,
-				      y + y_off + drawable->y,
-				      w, h, GLAMOR_ACCESS_RO);
-	} else
-		miGetImage(drawable, x, y, w, h, format, planeMask, d);
+    data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride,
+                                             d, 0, GLAMOR_ACCESS_RO);
+    if (data != NULL) {
+        assert(data == d);
+        return TRUE;
+    }
+ fall_back:
+    sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
+                                       y + y_off + drawable->y, w, h,
+                                       GLAMOR_ACCESS_RO);
+    if (sub_pixmap) {
+        fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d);
+        glamor_put_sub_pixmap(sub_pixmap, pixmap,
+                              x + x_off + drawable->x,
+                              y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RO);
+    }
+    else
+        miGetImage(drawable, x, y, w, h, format, planeMask, d);
 
-	return TRUE;
+    return TRUE;
 }
 
 void
 glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
-		 unsigned int format, unsigned long planeMask, char *d)
+                 unsigned int format, unsigned long planeMask, char *d)
 {
-	_glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE);
+    _glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE);
 }
 
 Bool
 glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h,
-		    unsigned int format, unsigned long planeMask, char *d)
+                    unsigned int format, unsigned long planeMask, char *d)
 {
-	return _glamor_get_image(pDrawable, x, y, w, 
-				 h, format, planeMask, d, FALSE);
+    return _glamor_get_image(pDrawable, x, y, w,
+                             h, format, planeMask, d, FALSE);
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 6d6c8e9..afb76f6 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -28,68 +28,64 @@
 
 #include "glamor_priv.h"
 
-static Bool 
+static Bool
 _glamor_get_spans(DrawablePtr drawable,
-		  int wmax,
-		  DDXPointPtr points, int *widths, int count, char *dst,
-		  Bool fallback)
+                  int wmax,
+                  DDXPointPtr points, int *widths, int count, char *dst,
+                  Bool fallback)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	int i;
-	uint8_t *readpixels_dst = (uint8_t *) dst;
-	void *data;
-	int x_off, y_off;
-	Bool ret = FALSE;
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    int i;
+    uint8_t *readpixels_dst = (uint8_t *) dst;
+    void *data;
+    int x_off, y_off;
+    Bool ret = FALSE;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		goto fail;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        goto fail;
 
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-	for (i = 0; i < count; i++) {
-		data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off,
-							 points[i].y + y_off, widths[i], 1,
-							 PixmapBytePad(widths[i], drawable->depth),
-							 readpixels_dst, 0, GLAMOR_ACCESS_RO);
-		assert(data == readpixels_dst);
-		readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
-	}
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+    for (i = 0; i < count; i++) {
+        data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off,
+                                                 points[i].y + y_off, widths[i],
+                                                 1, PixmapBytePad(widths[i],
+                                                                  drawable->
+                                                                  depth),
+                                                 readpixels_dst, 0,
+                                                 GLAMOR_ACCESS_RO);
+        assert(data == readpixels_dst);
+        readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
+    }
 
-	ret = TRUE;
-	goto done;
-fail:
+    ret = TRUE;
+    goto done;
+ fail:
 
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(drawable))
-		goto done;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
+        goto done;
 
-	ret = TRUE;
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
-		fbGetSpans(drawable, wmax, points, widths, count, dst);
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
-	}
-done:
-	return ret;
+    ret = TRUE;
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
+        fbGetSpans(drawable, wmax, points, widths, count, dst);
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
+    }
+ done:
+    return ret;
 }
 
 void
 glamor_get_spans(DrawablePtr drawable,
-		 int wmax,
-		 DDXPointPtr points, int *widths, int count, char *dst)
+                 int wmax,
+                 DDXPointPtr points, int *widths, int count, char *dst)
 {
-	_glamor_get_spans(drawable, wmax, points, 
-			  widths, count, dst, TRUE);
+    _glamor_get_spans(drawable, wmax, points, widths, count, dst, TRUE);
 }
 
 Bool
 glamor_get_spans_nf(DrawablePtr drawable,
-		    int wmax,
-		    DDXPointPtr points, int *widths, int count, char *dst)
+                    int wmax,
+                    DDXPointPtr points, int *widths, int count, char *dst)
 {
-	return _glamor_get_spans(drawable, wmax, points, 
-				 widths, count, dst, FALSE);
+    return _glamor_get_spans(drawable, wmax, points, widths, count, dst, FALSE);
 }
-
-
-
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index da99e26..0bdda9c 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -41,78 +41,78 @@
 
 _X_EXPORT Bool
 glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-			     int gl_version,
-			     void *(*get_proc_address) (const char *))
+                             int gl_version,
+                             void *(*get_proc_address) (const char *))
 {
 #ifndef GLAMOR_GLES2
-	INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
-	INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
-	INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
-	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
-	INIT_FUNC(dispatch, glLogicOp, get_proc_address);
-	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
-	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
-	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
-	INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
-	INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address);
+    INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
+    INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
+    INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
+    INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
+    INIT_FUNC(dispatch, glLogicOp, get_proc_address);
+    INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+    INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
+    INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
+    INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
+    INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address);
 #endif
-	INIT_FUNC(dispatch, glViewport, get_proc_address);
-	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
-	INIT_FUNC(dispatch, glDrawElements, get_proc_address);
-	INIT_FUNC(dispatch, glReadPixels, get_proc_address);
-	INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
-	INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
-	INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
-	INIT_FUNC(dispatch, glGenTextures, get_proc_address);
-	INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
-	INIT_FUNC(dispatch, glBindTexture, get_proc_address);
-	INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
-	INIT_FUNC(dispatch, glFlush, get_proc_address);
-	INIT_FUNC(dispatch, glFinish, get_proc_address);
-	INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
-	INIT_FUNC(dispatch, glGetString, get_proc_address);
-	INIT_FUNC(dispatch, glScissor, get_proc_address);
-	INIT_FUNC(dispatch, glEnable, get_proc_address);
-	INIT_FUNC(dispatch, glDisable, get_proc_address);
-	INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
-	INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
-	INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
-	INIT_FUNC(dispatch, glBufferData, get_proc_address);
-	INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
-	INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
-	INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
-	INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
-	INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
-	INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
-	INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
-	INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
-	INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
-	INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
-	INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
-	INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
-	INIT_FUNC(dispatch, glShaderSource, get_proc_address);
+    INIT_FUNC(dispatch, glViewport, get_proc_address);
+    INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
+    INIT_FUNC(dispatch, glDrawElements, get_proc_address);
+    INIT_FUNC(dispatch, glReadPixels, get_proc_address);
+    INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
+    INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
+    INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
+    INIT_FUNC(dispatch, glGenTextures, get_proc_address);
+    INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
+    INIT_FUNC(dispatch, glBindTexture, get_proc_address);
+    INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
+    INIT_FUNC(dispatch, glFlush, get_proc_address);
+    INIT_FUNC(dispatch, glFinish, get_proc_address);
+    INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
+    INIT_FUNC(dispatch, glGetString, get_proc_address);
+    INIT_FUNC(dispatch, glScissor, get_proc_address);
+    INIT_FUNC(dispatch, glEnable, get_proc_address);
+    INIT_FUNC(dispatch, glDisable, get_proc_address);
+    INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
+    INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
+    INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
+    INIT_FUNC(dispatch, glBufferData, get_proc_address);
+    INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
+    INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
+    INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
+    INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
+    INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
+    INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
+    INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
+    INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
+    INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
+    INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
+    INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
+    INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
+    INIT_FUNC(dispatch, glShaderSource, get_proc_address);
 
-	INIT_FUNC(dispatch, glUseProgram, get_proc_address);
-	INIT_FUNC(dispatch, glUniform1i, get_proc_address);
-	INIT_FUNC(dispatch, glUniform1f, get_proc_address);
-	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
-	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
-	INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
-	INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
-	INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address);
-	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
-	INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
-	INIT_FUNC(dispatch, glCreateShader, get_proc_address);
-	INIT_FUNC(dispatch, glCompileShader, get_proc_address);
-	INIT_FUNC(dispatch, glAttachShader, get_proc_address);
-	INIT_FUNC(dispatch, glDeleteShader, get_proc_address);
-	INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
-	INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
-	INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
-	INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
-	INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
+    INIT_FUNC(dispatch, glUseProgram, get_proc_address);
+    INIT_FUNC(dispatch, glUniform1i, get_proc_address);
+    INIT_FUNC(dispatch, glUniform1f, get_proc_address);
+    INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+    INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
+    INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
+    INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
+    INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address);
+    INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
+    INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
+    INIT_FUNC(dispatch, glCreateShader, get_proc_address);
+    INIT_FUNC(dispatch, glCompileShader, get_proc_address);
+    INIT_FUNC(dispatch, glAttachShader, get_proc_address);
+    INIT_FUNC(dispatch, glDeleteShader, get_proc_address);
+    INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
+    INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
+    INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
+    INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
+    INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
 
-	return TRUE;
-      fail:
-	return FALSE;
+    return TRUE;
+ fail:
+    return FALSE;
 }
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index 76dadd4..63790b4 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -1,138 +1,128 @@
 typedef struct glamor_gl_dispatch {
-	/* Transformation functions */
-	void (*glMatrixMode) (GLenum mode);
-	void (*glLoadIdentity) (void);
-	void (*glViewport) (GLint x, GLint y, GLsizei width,
-			    GLsizei height);
-	/* Drawing functions */
-	void (*glRasterPos2i) (GLint x, GLint y);
-
-	/* Vertex Array */
-	void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
-
-	/* Elements Array*/
-	void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices);
-	void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices);
-
-	/* Raster functions */
-	void (*glReadPixels) (GLint x, GLint y,
-			      GLsizei width, GLsizei height,
-			      GLenum format, GLenum type, GLvoid * pixels);
-
-	void (*glDrawPixels) (GLsizei width, GLsizei height,
-			      GLenum format, GLenum type,
-			      const GLvoid * pixels);
-	void (*glPixelStorei) (GLenum pname, GLint param);
-	/* Texture Mapping */
-
-	void (*glTexParameteri) (GLenum target, GLenum pname, GLint param);
-	void (*glTexImage2D) (GLenum target, GLint level,
-			      GLint internalFormat,
-			      GLsizei width, GLsizei height,
-			      GLint border, GLenum format, GLenum type,
-			      const GLvoid * pixels);
-	/* 1.1 */
-	void (*glGenTextures) (GLsizei n, GLuint * textures);
-	void (*glDeleteTextures) (GLsizei n, const GLuint * textures);
-	void (*glBindTexture) (GLenum target, GLuint texture);
-	void (*glTexSubImage2D) (GLenum target, GLint level,
-				 GLint xoffset, GLint yoffset,
-				 GLsizei width, GLsizei height,
-				 GLenum format, GLenum type,
-				 const GLvoid * pixels);
-	/* MISC */
-	void (*glFlush) (void);
-	void (*glFinish) (void);
-	void (*glGetIntegerv) (GLenum pname, GLint * params);
-	const GLubyte *(*glGetString) (GLenum name);
-	void (*glScissor) (GLint x, GLint y, GLsizei width,
-			   GLsizei height);
-	void (*glEnable) (GLenum cap);
-	void (*glDisable) (GLenum cap);
-	void (*glBlendFunc) (GLenum sfactor, GLenum dfactor);
-	void (*glLogicOp) (GLenum opcode);
-
-	/* 1.3 */
-	void (*glActiveTexture) (GLenum texture);
-
-	/* GL Extentions */
-	void (*glGenBuffers) (GLsizei n, GLuint * buffers);
-	void (*glBufferData) (GLenum target, GLsizeiptr size,
-			      const GLvoid * data, GLenum usage);
-	GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
-	GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
-	GLboolean (*glUnmapBuffer) (GLenum target);
-	void (*glBindBuffer) (GLenum target, GLuint buffer);
-	void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
-
-	void (*glFramebufferTexture2D) (GLenum target, GLenum attachment,
-					GLenum textarget, GLuint texture,
-					GLint level);
-	void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
-	void (*glDeleteFramebuffers) (GLsizei n,
-				      const GLuint * framebuffers);
-	void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers);
-	GLenum (*glCheckFramebufferStatus) (GLenum target);
-	void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1,
-				   GLint srcY1, GLint dstX0, GLint dstY0,
-				   GLint dstX1, GLint dstY1,
-				   GLbitfield mask, GLenum filter);
-
-	void (*glVertexAttribPointer) (GLuint index, GLint size,
-				       GLenum type, GLboolean normalized,
-				       GLsizei stride,
-				       const GLvoid * pointer);
-	void (*glDisableVertexAttribArray) (GLuint index);
-	void (*glEnableVertexAttribArray) (GLuint index);
-	void (*glBindAttribLocation) (GLuint program, GLuint index,
-				      const GLchar * name);
-
-	void (*glLinkProgram) (GLuint program);
-	void (*glShaderSource) (GLuint shader, GLsizei count,
-				const GLchar * *string,
-				const GLint * length);
-	void (*glUseProgram) (GLuint program);
-	void (*glUniform1i) (GLint location, GLint v0);
-	void (*glUniform1f) (GLint location, GLfloat v0);
-	void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
-			     GLfloat v2, GLfloat v3);
-	void (*glUniform1fv) (GLint location, GLsizei count,
-			      const GLfloat * value);
-	void (*glUniform2fv) (GLint location, GLsizei count,
-			      const GLfloat * value);
-	void (*glUniform4fv) (GLint location, GLsizei count,
-			      const GLfloat * value);
-	void (*glUniformMatrix3fv) (GLint location, GLsizei count,
-		           GLboolean transpose, const GLfloat* value);
-	GLuint (*glCreateProgram) (void);
-	GLuint (*glDeleteProgram) (GLuint);
-	GLuint (*glCreateShader) (GLenum type);
-	void (*glCompileShader) (GLuint shader);
-	void (*glAttachShader) (GLuint program, GLuint shader);
-	void (*glDeleteShader) (GLuint shader);
-	void (*glGetShaderiv) (GLuint shader, GLenum pname,
-			       GLint * params);
-	void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
-				    GLsizei * length, GLchar * infoLog);
-	void (*glGetProgramiv) (GLuint program, GLenum pname,
-				GLint * params);
-	void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize,
-				     GLsizei * length, GLchar * infoLog);
-	GLint (*glGetUniformLocation) (GLuint program,
-				       const GLchar * name);
+    /* Transformation functions */
+    void (*glMatrixMode) (GLenum mode);
+    void (*glLoadIdentity) (void);
+    void (*glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
+    /* Drawing functions */
+    void (*glRasterPos2i) (GLint x, GLint y);
+
+    /* Vertex Array */
+    void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
+
+    /* Elements Array */
+    void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type,
+                            const GLvoid * indices);
+    void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end,
+                                 GLsizei count, GLenum type,
+                                 const GLvoid * indices);
+
+    /* Raster functions */
+    void (*glReadPixels) (GLint x, GLint y,
+                          GLsizei width, GLsizei height,
+                          GLenum format, GLenum type, GLvoid * pixels);
+
+    void (*glDrawPixels) (GLsizei width, GLsizei height,
+                          GLenum format, GLenum type, const GLvoid * pixels);
+    void (*glPixelStorei) (GLenum pname, GLint param);
+    /* Texture Mapping */
+
+    void (*glTexParameteri) (GLenum target, GLenum pname, GLint param);
+    void (*glTexImage2D) (GLenum target, GLint level,
+                          GLint internalFormat,
+                          GLsizei width, GLsizei height,
+                          GLint border, GLenum format, GLenum type,
+                          const GLvoid * pixels);
+    /* 1.1 */
+    void (*glGenTextures) (GLsizei n, GLuint * textures);
+    void (*glDeleteTextures) (GLsizei n, const GLuint * textures);
+    void (*glBindTexture) (GLenum target, GLuint texture);
+    void (*glTexSubImage2D) (GLenum target, GLint level,
+                             GLint xoffset, GLint yoffset,
+                             GLsizei width, GLsizei height,
+                             GLenum format, GLenum type, const GLvoid * pixels);
+    /* MISC */
+    void (*glFlush) (void);
+    void (*glFinish) (void);
+    void (*glGetIntegerv) (GLenum pname, GLint * params);
+    const GLubyte *(*glGetString) (GLenum name);
+    void (*glScissor) (GLint x, GLint y, GLsizei width, GLsizei height);
+    void (*glEnable) (GLenum cap);
+    void (*glDisable) (GLenum cap);
+    void (*glBlendFunc) (GLenum sfactor, GLenum dfactor);
+    void (*glLogicOp) (GLenum opcode);
+
+    /* 1.3 */
+    void (*glActiveTexture) (GLenum texture);
+
+    /* GL Extentions */
+    void (*glGenBuffers) (GLsizei n, GLuint * buffers);
+    void (*glBufferData) (GLenum target, GLsizeiptr size,
+                          const GLvoid * data, GLenum usage);
+    GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
+    GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset,
+                                 GLsizeiptr length, GLbitfield access);
+     GLboolean(*glUnmapBuffer) (GLenum target);
+    void (*glBindBuffer) (GLenum target, GLuint buffer);
+    void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
+
+    void (*glFramebufferTexture2D) (GLenum target, GLenum attachment,
+                                    GLenum textarget, GLuint texture,
+                                    GLint level);
+    void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
+    void (*glDeleteFramebuffers) (GLsizei n, const GLuint * framebuffers);
+    void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers);
+     GLenum(*glCheckFramebufferStatus) (GLenum target);
+    void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1,
+                               GLint srcY1, GLint dstX0, GLint dstY0,
+                               GLint dstX1, GLint dstY1,
+                               GLbitfield mask, GLenum filter);
+
+    void (*glVertexAttribPointer) (GLuint index, GLint size,
+                                   GLenum type, GLboolean normalized,
+                                   GLsizei stride, const GLvoid * pointer);
+    void (*glDisableVertexAttribArray) (GLuint index);
+    void (*glEnableVertexAttribArray) (GLuint index);
+    void (*glBindAttribLocation) (GLuint program, GLuint index,
+                                  const GLchar * name);
+
+    void (*glLinkProgram) (GLuint program);
+    void (*glShaderSource) (GLuint shader, GLsizei count,
+                            const GLchar * *string, const GLint * length);
+    void (*glUseProgram) (GLuint program);
+    void (*glUniform1i) (GLint location, GLint v0);
+    void (*glUniform1f) (GLint location, GLfloat v0);
+    void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
+                         GLfloat v2, GLfloat v3);
+    void (*glUniform1fv) (GLint location, GLsizei count, const GLfloat * value);
+    void (*glUniform2fv) (GLint location, GLsizei count, const GLfloat * value);
+    void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat * value);
+    void (*glUniformMatrix3fv) (GLint location, GLsizei count,
+                                GLboolean transpose, const GLfloat * value);
+     GLuint(*glCreateProgram) (void);
+     GLuint(*glDeleteProgram) (GLuint);
+     GLuint(*glCreateShader) (GLenum type);
+    void (*glCompileShader) (GLuint shader);
+    void (*glAttachShader) (GLuint program, GLuint shader);
+    void (*glDeleteShader) (GLuint shader);
+    void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint * params);
+    void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
+                                GLsizei * length, GLchar * infoLog);
+    void (*glGetProgramiv) (GLuint program, GLenum pname, GLint * params);
+    void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize,
+                                 GLsizei * length, GLchar * infoLog);
+     GLint(*glGetUniformLocation) (GLuint program, const GLchar * name);
 
 } glamor_gl_dispatch;
 
-
 typedef void *(*get_proc_address_t) (const char *);
 
 _X_EXPORT Bool
-glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-			     int gl_version,
-			     get_proc_address_t get_proc_address);
 
+glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
+                             int gl_version,
+                             get_proc_address_t get_proc_address);
 
 _X_EXPORT Bool
+
 glamor_gl_dispatch_init(ScreenPtr screen,
-			struct glamor_gl_dispatch *dispatch,
-			int gl_version);
+                        struct glamor_gl_dispatch *dispatch, int gl_version);
diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h
index 1f7206b..2a220c3 100644
--- a/glamor/glamor_glext.h
+++ b/glamor/glamor_glext.h
@@ -26,7 +26,6 @@
  *
  */
 
-
 #ifdef GLAMOR_GLES2
 
 #define GL_BGRA                                 GL_BGRA_EXT
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index b55327c..ac97157 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -30,89 +30,90 @@
 
 static Bool
 _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+                        int x, int y, unsigned int nglyph,
+                        CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	if (!fallback 
-	    && glamor_ddx_fallback_check_pixmap(pDrawable)
-	    && glamor_ddx_fallback_check_gc(pGC))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
+        && glamor_ddx_fallback_check_gc(pGC))
+        return FALSE;
 
-	miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-	return TRUE;
+    miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+    return TRUE;
 }
 
 void
 glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase)
+                       int x, int y, unsigned int nglyph,
+                       CharInfoPtr * ppci, pointer pglyphBase)
 {
-	_glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE);
+    _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
+                            TRUE);
 }
 
 Bool
 glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase)
+                          int x, int y, unsigned int nglyph,
+                          CharInfoPtr * ppci, pointer pglyphBase)
 {
-	return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE);
+    return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
+                                   pglyphBase, FALSE);
 }
 
 static Bool
 _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+                       int x, int y, unsigned int nglyph,
+                       CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(pDrawable)
-	    && glamor_ddx_fallback_check_gc(pGC))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
+        && glamor_ddx_fallback_check_gc(pGC))
+        return FALSE;
 
-	miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-	return TRUE;
+    miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+    return TRUE;
 }
 
 void
 glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase)
+                      int x, int y, unsigned int nglyph,
+                      CharInfoPtr * ppci, pointer pglyphBase)
 {
-	_glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE);
+    _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,
+                           TRUE);
 }
 
 Bool
 glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase)
+                         int x, int y, unsigned int nglyph,
+                         CharInfoPtr * ppci, pointer pglyphBase)
 {
-	return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE);
+    return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci,
+                                  pglyphBase, FALSE);
 }
 
 static Bool
 _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
-		    DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback)
+                    DrawablePtr pDrawable, int w, int h, int x, int y,
+                    Bool fallback)
 {
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(pDrawable)
-	    && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
-	    && glamor_ddx_fallback_check_gc(pGC))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
+        && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
+        && glamor_ddx_fallback_check_gc(pGC))
+        return FALSE;
 
-	miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
-	return TRUE;
+    miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
+    return TRUE;
 }
 
 void
 glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
-		   DrawablePtr pDrawable, int w, int h, int x, int y)
+                   DrawablePtr pDrawable, int w, int h, int x, int y)
 {
-	_glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE);
+    _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE);
 }
 
 Bool
 glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
-		      DrawablePtr pDrawable, int w, int h, int x, int y)
+                      DrawablePtr pDrawable, int w, int h, int x, int y)
 {
-	return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE);
+    return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE);
 }
-
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index fc361df..ed7cfc2 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -71,25 +71,25 @@
 #define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1)
 
 typedef struct {
-	PicturePtr source;
-	glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4];
-	int count;
+    PicturePtr source;
+    glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4];
+    int count;
 } glamor_glyph_buffer_t;
 
 struct glamor_glyph {
-	glamor_glyph_cache_t *cache;
-	uint16_t x, y;
-	uint16_t size, pos;
-	unsigned long long left_x1_map, left_x2_map;
-	unsigned long long right_x1_map, right_x2_map;  /* Use to check real intersect or not. */
-	Bool has_edge_map;
-	Bool cached;
+    glamor_glyph_cache_t *cache;
+    uint16_t x, y;
+    uint16_t size, pos;
+    unsigned long long left_x1_map, left_x2_map;
+    unsigned long long right_x1_map, right_x2_map;      /* Use to check real intersect or not. */
+    Bool has_edge_map;
+    Bool cached;
 };
 
 typedef enum {
-	GLAMOR_GLYPH_SUCCESS,	/* Glyph added to render buffer */
-	GLAMOR_GLYPH_FAIL,	/* out of memory, etc */
-	GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
+    GLAMOR_GLYPH_SUCCESS,       /* Glyph added to render buffer */
+    GLAMOR_GLYPH_FAIL,          /* out of memory, etc */
+    GLAMOR_GLYPH_NEED_FLUSH,    /* would evict a glyph already in the buffer */
 } glamor_glyph_cache_result_t;
 
 #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
@@ -98,7 +98,7 @@ static DevPrivateKeyRec glamor_glyph_key;
 static inline struct glamor_glyph *
 glamor_glyph_get_private(GlyphPtr glyph)
 {
-	return (struct glamor_glyph*)glyph->devPrivates;
+    return (struct glamor_glyph *) glyph->devPrivates;
 }
 
 /*
@@ -122,170 +122,175 @@ glamor_glyph_get_private(GlyphPtr glyph)
  */
 
 struct glamor_glyph_mask_cache_entry {
-	int idx;
-	int width;
-	int height;
-	int x;
-	int y;
+    int idx;
+    int width;
+    int height;
+    int x;
+    int y;
 };
 
 static struct glamor_glyph_mask_cache {
-	PixmapPtr pixmap;
-	struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
-	unsigned int free_bitmap;
-	unsigned int cleared_bitmap;
-}*mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS] = {NULL};
+    PixmapPtr pixmap;
+    struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
+    unsigned int free_bitmap;
+    unsigned int cleared_bitmap;
+} *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS] = {
+NULL};
 
 static void
 clear_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache,
-		     unsigned int clear_mask_bits)
+                        unsigned int clear_mask_bits)
 {
-	unsigned int i = 0;
-	BoxRec box[MASK_CACHE_WIDTH];
-	int box_cnt = 0;
-
-	assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0);
-	for(i = 0; i < MASK_CACHE_WIDTH;i++)
-	{
-		if (clear_mask_bits & (1 << i)) {
-			box[box_cnt].x1 = maskcache->mcache[i].x;
-			box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE;
-			box[box_cnt].y1 = maskcache->mcache[i].y;
-			box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE;
-			box_cnt++;
-		}
-	}
-	glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0);
-	maskcache->cleared_bitmap |= clear_mask_bits;
+    unsigned int i = 0;
+    BoxRec box[MASK_CACHE_WIDTH];
+    int box_cnt = 0;
+
+    assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0);
+    for (i = 0; i < MASK_CACHE_WIDTH; i++) {
+        if (clear_mask_bits & (1 << i)) {
+            box[box_cnt].x1 = maskcache->mcache[i].x;
+            box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE;
+            box[box_cnt].y1 = maskcache->mcache[i].y;
+            box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE;
+            box_cnt++;
+        }
+    }
+    glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0);
+    maskcache->cleared_bitmap |= clear_mask_bits;
 }
 
 static void
 clear_mask_cache(struct glamor_glyph_mask_cache *maskcache)
 {
-	int x = 0;
-	int cnt = MASK_CACHE_WIDTH;
-	unsigned int i = 0;
-	struct glamor_glyph_mask_cache_entry *mce;
-	glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
-		     MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0);
-	mce = &maskcache->mcache[0];
-	while(cnt--) {
-		mce->width = 0;
-		mce->height = 0;
-		mce->x = x;
-		mce->y = CACHE_PICTURE_SIZE;
-		mce->idx = i++;
-		x += MASK_CACHE_MAX_SIZE;
-		mce++;
-	}
-	maskcache->free_bitmap = MASK_CACHE_MASK;
-	maskcache->cleared_bitmap = MASK_CACHE_MASK;
+    int x = 0;
+    int cnt = MASK_CACHE_WIDTH;
+    unsigned int i = 0;
+    struct glamor_glyph_mask_cache_entry *mce;
+
+    glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
+                 MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0);
+    mce = &maskcache->mcache[0];
+    while (cnt--) {
+        mce->width = 0;
+        mce->height = 0;
+        mce->x = x;
+        mce->y = CACHE_PICTURE_SIZE;
+        mce->idx = i++;
+        x += MASK_CACHE_MAX_SIZE;
+        mce++;
+    }
+    maskcache->free_bitmap = MASK_CACHE_MASK;
+    maskcache->cleared_bitmap = MASK_CACHE_MASK;
 }
 
 static int
 find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask)
 {
-	int idx = 0;
-	unsigned int bits_mask;
-	bits_mask = ((1LL << bits_cnt) - 1);
-
-	if (unlikely(bits_cnt > 56)) {
-		while(bits) {
-			if ((bits & bits_mask) == bits_mask) {
-				*pbits_mask = bits_mask << idx;
-				return idx;
-			}
-			bits >>= 1;
-			idx++;
-		}
-	} else {
-		idx = __fls(bits);
-		while(bits) {
-			unsigned int temp_bits;
-			temp_bits = bits_mask << (idx - bits_cnt + 1);
-			if ((bits & temp_bits) == temp_bits) {
-				*pbits_mask = temp_bits;
-				return (idx - bits_cnt + 1);
-			}
-			/* Find first zero. And clear the tested bit.*/
-			bits &= ~(1LL<<idx);
-			idx = __fls(~bits);
-			bits &= ~((1LL << idx) - 1);
-			idx--;
-		}
-	}
-	return -1;
+    int idx = 0;
+    unsigned int bits_mask;
+
+    bits_mask = ((1LL << bits_cnt) - 1);
+
+    if (unlikely(bits_cnt > 56)) {
+        while (bits) {
+            if ((bits & bits_mask) == bits_mask) {
+                *pbits_mask = bits_mask << idx;
+                return idx;
+            }
+            bits >>= 1;
+            idx++;
+        }
+    }
+    else {
+        idx = __fls(bits);
+        while (bits) {
+            unsigned int temp_bits;
+
+            temp_bits = bits_mask << (idx - bits_cnt + 1);
+            if ((bits & temp_bits) == temp_bits) {
+                *pbits_mask = temp_bits;
+                return (idx - bits_cnt + 1);
+            }
+            /* Find first zero. And clear the tested bit. */
+            bits &= ~(1LL << idx);
+            idx = __fls(~bits);
+            bits &= ~((1LL << idx) - 1);
+            idx--;
+        }
+    }
+    return -1;
 }
 
 static struct glamor_glyph_mask_cache_entry *
 get_mask_cache(struct glamor_glyph_mask_cache *maskcache, int blocks)
 {
-	int free_cleared_bit, idx = -1;
-	int retry_cnt = 0;
-	unsigned int bits_mask = 0;
-
-	if (maskcache->free_bitmap == 0)
-		return NULL;
-retry:
-	free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap;
-	if (free_cleared_bit && blocks == 1) {
-		idx = __fls(free_cleared_bit);
-		bits_mask = 1 << idx;
-	} else if (free_cleared_bit && blocks > 1) {
-		idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask);
-	}
-
-	if (idx < 0) {
-		clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap);
-		if (retry_cnt++ > 2)
-			return NULL;
-		goto retry;
-	}
-
-	maskcache->cleared_bitmap &= ~bits_mask;
-	maskcache->free_bitmap &= ~bits_mask;
-	DEBUGF("get idx %d free %x clear %x \n",
-		idx, maskcache->free_bitmap, maskcache->cleared_bitmap);
-	return &maskcache->mcache[idx];
+    int free_cleared_bit, idx = -1;
+    int retry_cnt = 0;
+    unsigned int bits_mask = 0;
+
+    if (maskcache->free_bitmap == 0)
+        return NULL;
+ retry:
+    free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap;
+    if (free_cleared_bit && blocks == 1) {
+        idx = __fls(free_cleared_bit);
+        bits_mask = 1 << idx;
+    }
+    else if (free_cleared_bit && blocks > 1) {
+        idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask);
+    }
+
+    if (idx < 0) {
+        clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap);
+        if (retry_cnt++ > 2)
+            return NULL;
+        goto retry;
+    }
+
+    maskcache->cleared_bitmap &= ~bits_mask;
+    maskcache->free_bitmap &= ~bits_mask;
+    DEBUGF("get idx %d free %x clear %x \n",
+           idx, maskcache->free_bitmap, maskcache->cleared_bitmap);
+    return &maskcache->mcache[idx];
 }
 
 static void
 put_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache,
-		       unsigned int bitmap)
+                      unsigned int bitmap)
 {
-	maskcache->free_bitmap |= bitmap;
-	DEBUGF("put bitmap %x free %x clear %x \n",
-		bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap);
+    maskcache->free_bitmap |= bitmap;
+    DEBUGF("put bitmap %x free %x clear %x \n",
+           bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap);
 }
 
 static void
 glamor_unrealize_glyph_caches(ScreenPtr pScreen)
 {
-	glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
-	int i;
+    glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
+    int i;
 
-	if (!glamor->glyph_cache_initialized)
-		return;
+    if (!glamor->glyph_cache_initialized)
+        return;
 
-	for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) {
-		glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) {
+        glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
 
-		if (cache->picture)
-			FreePicture(cache->picture, 0);
+        if (cache->picture)
+            FreePicture(cache->picture, 0);
 
-		if (cache->glyphs)
-			free(cache->glyphs);
+        if (cache->glyphs)
+            free(cache->glyphs);
 
-		if (mask_cache[i])
-			free(mask_cache[i]);
-	}
-	glamor->glyph_cache_initialized = FALSE;
+        if (mask_cache[i])
+            free(mask_cache[i]);
+    }
+    glamor->glyph_cache_initialized = FALSE;
 }
 
 void
 glamor_glyphs_fini(ScreenPtr pScreen)
 {
-	glamor_unrealize_glyph_caches(pScreen);
+    glamor_unrealize_glyph_caches(pScreen);
 }
 
 /* All caches for a single format share a single pixmap for glyph storage,
@@ -301,80 +306,80 @@ glamor_glyphs_fini(ScreenPtr pScreen)
 static Bool
 glamor_realize_glyph_caches(ScreenPtr pScreen)
 {
-	glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
-	unsigned int formats[] = {
-		PIXMAN_a8,
-		PIXMAN_a8r8g8b8,
-	};
-	int i;
-
-	if (glamor->glyph_cache_initialized)
-		return TRUE;
-
-	glamor->glyph_cache_initialized = TRUE;
-	memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
-
-	for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
-		glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
-		PixmapPtr pixmap;
-		PicturePtr picture;
-		XID component_alpha;
-		int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
-		int error;
-		PictFormatPtr pPictFormat =
-		    PictureMatchFormat(pScreen, depth, formats[i]);
-		if (!pPictFormat)
-			goto bail;
-
-		/* Now allocate the pixmap and picture */
-		pixmap = pScreen->CreatePixmap(pScreen,
-					      CACHE_PICTURE_SIZE,
-					      CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, depth,
-					      0);
-		if (!pixmap)
-			goto bail;
-
-		component_alpha = NeedsComponent(pPictFormat->format);
-		picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
-					CPComponentAlpha, &component_alpha,
-					serverClient, &error);
-
-		pScreen->DestroyPixmap(pixmap);
-		if (!picture)
-			goto bail;
-
-		ValidatePicture(picture);
-
-		cache->picture = picture;
-		cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
-		if (!cache->glyphs)
-			goto bail;
-
-		cache->evict = rand() % GLYPH_CACHE_SIZE;
-		mask_cache[i] = calloc(1, sizeof(*mask_cache[i]));
-		mask_cache[i]->pixmap = pixmap;
-		clear_mask_cache(mask_cache[i]);
-	}
-	assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
-
-	return TRUE;
-
-      bail:
-	glamor_unrealize_glyph_caches(pScreen);
-	return FALSE;
+    glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
+
+    unsigned int formats[] = {
+        PIXMAN_a8,
+        PIXMAN_a8r8g8b8,
+    };
+    int i;
+
+    if (glamor->glyph_cache_initialized)
+        return TRUE;
+
+    glamor->glyph_cache_initialized = TRUE;
+    memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
+
+    for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+        glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
+        PixmapPtr pixmap;
+        PicturePtr picture;
+        XID component_alpha;
+        int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
+        int error;
+        PictFormatPtr pPictFormat =
+            PictureMatchFormat(pScreen, depth, formats[i]);
+        if (!pPictFormat)
+            goto bail;
+
+        /* Now allocate the pixmap and picture */
+        pixmap = pScreen->CreatePixmap(pScreen,
+                                       CACHE_PICTURE_SIZE,
+                                       CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE,
+                                       depth, 0);
+        if (!pixmap)
+            goto bail;
+
+        component_alpha = NeedsComponent(pPictFormat->format);
+        picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
+                                CPComponentAlpha, &component_alpha,
+                                serverClient, &error);
+
+        pScreen->DestroyPixmap(pixmap);
+        if (!picture)
+            goto bail;
+
+        ValidatePicture(picture);
+
+        cache->picture = picture;
+        cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
+        if (!cache->glyphs)
+            goto bail;
+
+        cache->evict = rand() % GLYPH_CACHE_SIZE;
+        mask_cache[i] = calloc(1, sizeof(*mask_cache[i]));
+        mask_cache[i]->pixmap = pixmap;
+        clear_mask_cache(mask_cache[i]);
+    }
+    assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
+
+    return TRUE;
+
+ bail:
+    glamor_unrealize_glyph_caches(pScreen);
+    return FALSE;
 }
 
-
 Bool
 glamor_glyphs_init(ScreenPtr pScreen)
 {
-	if (!dixRegisterPrivateKey(&glamor_glyph_key,
-		PRIVATE_GLYPH, sizeof(struct glamor_glyph)))
-		return FALSE;
+    if (!dixRegisterPrivateKey(&glamor_glyph_key,
+                               PRIVATE_GLYPH, sizeof(struct glamor_glyph)))
+        return FALSE;
 
-	/* Skip pixmap creation if we don't intend to use it. */
+    /* Skip pixmap creation if we don't intend to use it. */
 
-	return glamor_realize_glyph_caches(pScreen);
+    return glamor_realize_glyph_caches(pScreen);
 }
 
 /* The most efficient thing to way to upload the glyph to the screen
@@ -382,209 +387,209 @@ glamor_glyphs_init(ScreenPtr pScreen)
  */
 static void
 glamor_glyph_cache_upload_glyph(ScreenPtr screen,
-				glamor_glyph_cache_t * cache,
-				GlyphPtr glyph, int x, int y)
+                                glamor_glyph_cache_t * cache,
+                                GlyphPtr glyph, int x, int y)
 {
-	PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
-	PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
-	PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
-	PixmapPtr scratch;
-	BoxRec box;
-	GCPtr gc;
-
-	gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
-	if (!gc)
-		return;
-
-	ValidateGC(&pCachePixmap->drawable, gc);
-
-	scratch = pGlyphPixmap;
-	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
-
-		scratch = glamor_create_pixmap(screen,
-					       glyph->info.width,
-					       glyph->info.height,
-					       pCachePixmap->
-					       drawable.depth, 0);
-		if (scratch) {
-			PicturePtr picture;
-			int error;
-
-			picture =
-			    CreatePicture(0,
-					  &scratch->drawable,
-					  PictureMatchFormat
-					  (screen,
-					   pCachePixmap->
-					   drawable.depth,
-					   cache->picture->format),
-					  0, NULL, serverClient,
-				  &error);
-			if (picture) {
-				ValidatePicture(picture);
-				glamor_composite(PictOpSrc,
-					      pGlyphPicture,
-					      NULL, picture,
-					      0, 0, 0, 0, 0,
-					      0,
-					      glyph->info.width,
-					      glyph->info.height);
-				FreePicture(picture, 0);
-			}
-		} else {
-			scratch = pGlyphPixmap;
-		}
-	}
-
-	box.x1 = x;
-	box.y1 = y;
-	box.x2 = x + glyph->info.width;
-	box.y2 = y + glyph->info.height;
-	glamor_copy_n_to_n_nf(&scratch->drawable,
-			    &pCachePixmap->drawable, NULL,
-			    &box, 1,
-			    -x, -y,
-			    FALSE, FALSE, 0, NULL);
-	if (scratch != pGlyphPixmap)
-		screen->DestroyPixmap(scratch);
-
-	FreeScratchGC(gc);
+    PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
+    PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
+    PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
+    PixmapPtr scratch;
+    BoxRec box;
+    GCPtr gc;
+
+    gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
+    if (!gc)
+        return;
+
+    ValidateGC(&pCachePixmap->drawable, gc);
+
+    scratch = pGlyphPixmap;
+    if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
+
+        scratch = glamor_create_pixmap(screen,
+                                       glyph->info.width,
+                                       glyph->info.height,
+                                       pCachePixmap->drawable.depth, 0);
+        if (scratch) {
+            PicturePtr picture;
+            int error;
+
+            picture =
+                CreatePicture(0,
+                              &scratch->drawable,
+                              PictureMatchFormat
+                              (screen,
+                               pCachePixmap->drawable.depth,
+                               cache->picture->format),
+                              0, NULL, serverClient, &error);
+            if (picture) {
+                ValidatePicture(picture);
+                glamor_composite(PictOpSrc,
+                                 pGlyphPicture,
+                                 NULL, picture,
+                                 0, 0, 0, 0, 0,
+                                 0, glyph->info.width, glyph->info.height);
+                FreePicture(picture, 0);
+            }
+        }
+        else {
+            scratch = pGlyphPixmap;
+        }
+    }
+
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + glyph->info.width;
+    box.y2 = y + glyph->info.height;
+    glamor_copy_n_to_n_nf(&scratch->drawable,
+                          &pCachePixmap->drawable, NULL,
+                          &box, 1, -x, -y, FALSE, FALSE, 0, NULL);
+    if (scratch != pGlyphPixmap)
+        screen->DestroyPixmap(scratch);
+
+    FreeScratchGC(gc);
 }
 
-
 void
 glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 {
-	struct glamor_glyph *priv;
+    struct glamor_glyph *priv;
 
-	/* Use Lookup in case we have not attached to this glyph. */
-	priv = glamor_glyph_get_private(glyph);
+    /* Use Lookup in case we have not attached to this glyph. */
+    priv = glamor_glyph_get_private(glyph);
 
-	if (priv->cached)
-		priv->cache->glyphs[priv->pos] = NULL;
+    if (priv->cached)
+        priv->cache->glyphs[priv->pos] = NULL;
 }
 
 /* Cut and paste from render/glyph.c - probably should export it instead */
 static void
 glamor_glyph_extents(int nlist,
-		     GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
+                     GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
 {
-	int x1, x2, y1, y2;
-	int x, y, n;
-
-	x1 = y1 = MAXSHORT;
-	x2 = y2 = MINSHORT;
-	x = y = 0;
-	while (nlist--) {
-		x += list->xOff;
-		y += list->yOff;
-		n = list->len;
-		list++;
-		while (n--) {
-			GlyphPtr glyph = *glyphs++;
-			int v;
-
-			v = x - glyph->info.x;
-			if (v < x1)
-				x1 = v;
-			v += glyph->info.width;
-			if (v > x2)
-				x2 = v;
-
-			v = y - glyph->info.y;
-			if (v < y1)
-				y1 = v;
-			v += glyph->info.height;
-			if (v > y2)
-				y2 = v;
-
-			x += glyph->info.xOff;
-			y += glyph->info.yOff;
-		}
-	}
-
-	extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
-	extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
-	extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
-	extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
+    int x1, x2, y1, y2;
+    int x, y, n;
+
+    x1 = y1 = MAXSHORT;
+    x2 = y2 = MINSHORT;
+    x = y = 0;
+    while (nlist--) {
+        x += list->xOff;
+        y += list->yOff;
+        n = list->len;
+        list++;
+        while (n--) {
+            GlyphPtr glyph = *glyphs++;
+            int v;
+
+            v = x - glyph->info.x;
+            if (v < x1)
+                x1 = v;
+            v += glyph->info.width;
+            if (v > x2)
+                x2 = v;
+
+            v = y - glyph->info.y;
+            if (v < y1)
+                y1 = v;
+            v += glyph->info.height;
+            if (v > y2)
+                y2 = v;
+
+            x += glyph->info.xOff;
+            y += glyph->info.yOff;
+        }
+    }
+
+    extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
+    extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
+    extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
+    extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
 }
 
 static void
 glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
-			     PicturePtr glyph_picture)
+                               PicturePtr glyph_picture)
 {
-	PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
-	int j;
-	unsigned long long left_x1_map = 0, left_x2_map = 0;
-	unsigned long long right_x1_map = 0, right_x2_map = 0;
-	int bitsPerPixel;
-	int stride;
-	void *bits;
-	int width;
-	unsigned int left_x1_data = 0, left_x2_data = 0;
-	unsigned int right_x1_data = 0, right_x2_data = 0;
-
-	bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
-	stride = glyph_pixmap->devKind;
-	bits = glyph_pixmap->devPrivate.ptr;
-	width = glyph->info.width;
-
-	if (glyph_pixmap->drawable.width < 2
-	    || !(glyph_pixmap->drawable.depth == 8
-		|| glyph_pixmap->drawable.depth == 1
-		|| glyph_pixmap->drawable.depth == 32)) {
-		priv->has_edge_map = FALSE;
-		return;
-	}
-
-	left_x1_map = left_x2_map = 0;
-	right_x1_map = right_x2_map = 0;
-
-	for(j = 0; j < glyph_pixmap->drawable.height; j++)
-	{
-		if (bitsPerPixel == 8) {
-			unsigned char *data;
-			data =	(unsigned char*)((unsigned char*)bits + stride * j);
-			left_x1_data = *data++;
-			left_x2_data = *data;
-			data =	(unsigned char*)((unsigned char*)bits + stride * j + width - 2);
-			right_x1_data = *data++;
-			right_x2_data = *data;
-		} else if (bitsPerPixel == 32) {
-			left_x1_data = *((unsigned int*)bits + stride/4 * j);
-			left_x2_data = *((unsigned int*)bits + stride/4 * j + 1);
-			right_x1_data = *((unsigned int*)bits + stride/4 * j + width - 2);
-			right_x2_data = *((unsigned int*)bits + stride/4 * j + width - 1);
-		} else if (bitsPerPixel == 1) {
-			unsigned char temp;
-			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
-				+ glyph_pixmap->devKind * j) & 0x3;
-			left_x1_data = temp & 0x1;
-			left_x2_data = temp & 0x2;
-
-			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
-				+ glyph_pixmap->devKind * j
-				+ (glyph_pixmap->drawable.width - 2)/8);
-			right_x1_data = temp
-				    & (1 << ((glyph_pixmap->drawable.width - 2) % 8));
-			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
-				+ glyph_pixmap->devKind * j
-				+ (glyph_pixmap->drawable.width - 1)/8);
-			right_x2_data = temp
-				   & (1 << ((glyph_pixmap->drawable.width - 1) % 8));
-		}
-		left_x1_map |= (left_x1_data !=0) << j;
-		left_x2_map |= (left_x2_data !=0) << j;
-		right_x1_map |= (right_x1_data !=0) << j;
-		right_x2_map |= (right_x2_data !=0) << j;
-	}
-
-	priv->left_x1_map = left_x1_map;
-	priv->left_x2_map = left_x2_map;
-	priv->right_x1_map = right_x1_map;
-	priv->right_x2_map = right_x2_map;
-	priv->has_edge_map = TRUE;
-	return;
+    PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
+    int j;
+    unsigned long long left_x1_map = 0, left_x2_map = 0;
+    unsigned long long right_x1_map = 0, right_x2_map = 0;
+    int bitsPerPixel;
+    int stride;
+    void *bits;
+    int width;
+    unsigned int left_x1_data = 0, left_x2_data = 0;
+    unsigned int right_x1_data = 0, right_x2_data = 0;
+
+    bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
+    stride = glyph_pixmap->devKind;
+    bits = glyph_pixmap->devPrivate.ptr;
+    width = glyph->info.width;
+
+    if (glyph_pixmap->drawable.width < 2
+        || !(glyph_pixmap->drawable.depth == 8
+             || glyph_pixmap->drawable.depth == 1
+             || glyph_pixmap->drawable.depth == 32)) {
+        priv->has_edge_map = FALSE;
+        return;
+    }
+
+    left_x1_map = left_x2_map = 0;
+    right_x1_map = right_x2_map = 0;
+
+    for (j = 0; j < glyph_pixmap->drawable.height; j++) {
+        if (bitsPerPixel == 8) {
+            unsigned char *data;
+
+            data = (unsigned char *) ((unsigned char *) bits + stride * j);
+            left_x1_data = *data++;
+            left_x2_data = *data;
+            data =
+                (unsigned char *) ((unsigned char *) bits + stride * j + width -
+                                   2);
+            right_x1_data = *data++;
+            right_x2_data = *data;
+        }
+        else if (bitsPerPixel == 32) {
+            left_x1_data = *((unsigned int *) bits + stride / 4 * j);
+            left_x2_data = *((unsigned int *) bits + stride / 4 * j + 1);
+            right_x1_data =
+                *((unsigned int *) bits + stride / 4 * j + width - 2);
+            right_x2_data =
+                *((unsigned int *) bits + stride / 4 * j + width - 1);
+        }
+        else if (bitsPerPixel == 1) {
+            unsigned char temp;
+
+            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
+                     + glyph_pixmap->devKind * j) & 0x3;
+            left_x1_data = temp & 0x1;
+            left_x2_data = temp & 0x2;
+
+            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
+                     + glyph_pixmap->devKind * j
+                     + (glyph_pixmap->drawable.width - 2) / 8);
+            right_x1_data = temp
+                & (1 << ((glyph_pixmap->drawable.width - 2) % 8));
+            temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
+                     + glyph_pixmap->devKind * j
+                     + (glyph_pixmap->drawable.width - 1) / 8);
+            right_x2_data = temp
+                & (1 << ((glyph_pixmap->drawable.width - 1) % 8));
+        }
+        left_x1_map |= (left_x1_data != 0) << j;
+        left_x2_map |= (left_x2_data != 0) << j;
+        right_x1_map |= (right_x1_data != 0) << j;
+        right_x2_map |= (right_x2_data != 0) << j;
+    }
+
+    priv->left_x1_map = left_x1_map;
+    priv->left_x2_map = left_x2_map;
+    priv->right_x1_map = right_x1_map;
+    priv->right_x2_map = right_x2_map;
+    priv->has_edge_map = TRUE;
+    return;
 }
 
 /**
@@ -597,82 +602,80 @@ glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
 #define INTERSECTED 1
 
 struct glamor_glyph_list {
-	int nlist;
-	GlyphListPtr list;
-	GlyphPtr *glyphs;
-	int type;
+    int nlist;
+    GlyphListPtr list;
+    GlyphPtr *glyphs;
+    int type;
 };
 
 static Bool
 glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
-		     GlyphPtr *cur_glyphs,
-		     GlyphPtr **head_glyphs,
-		     GlyphListPtr cur_list,
-		     int cur_pos, int cur_x, int cur_y,
-		     int x1, int y1, int x2, int y2,
-		     GlyphListPtr *head_list,
-		     int *head_pos,
-		     int *head_x,
-		     int *head_y,
-		     int *fixed_cnt,
-		     int type,
-		     BoxPtr prev_extents
-		     )
+                     GlyphPtr * cur_glyphs,
+                     GlyphPtr ** head_glyphs,
+                     GlyphListPtr cur_list,
+                     int cur_pos, int cur_x, int cur_y,
+                     int x1, int y1, int x2, int y2,
+                     GlyphListPtr * head_list,
+                     int *head_pos,
+                     int *head_x,
+                     int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents)
 {
-	int x_off = 0;
-	int y_off = 0;
-	int n_off = 0;
-	int list_cnt;
-	if (type == NON_INTERSECTED) {
-		if (x1 < prev_extents->x2 && x2 > prev_extents->x1
-		    && y1 < prev_extents->y2 && y2 > prev_extents->y1)
-			return FALSE;
-		x_off = (*(cur_glyphs-1))->info.xOff;
-		y_off = (*(cur_glyphs-1))->info.yOff;
-		n_off = 1;
-	}
-
-	list_cnt = cur_list - *head_list + 1;
-	if (cur_pos <= n_off) {
-		DEBUGF("break at %d n_off %d\n", cur_pos, n_off);
-		list_cnt--;
-		if (cur_pos < n_off) {
-		/* we overlap with previous list's last glyph. */
-			x_off += cur_list->xOff;
-			y_off += cur_list->yOff;
-			cur_list--;
-			cur_pos = cur_list->len;
-			if (cur_pos <= n_off) {
-				list_cnt--;
-			}
-		}
-	}
-	DEBUGF("got %d lists\n", list_cnt);
-	if (list_cnt != 0) {
-		fixed_list->list = malloc(list_cnt * sizeof(*cur_list));
-		memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
-		fixed_list->list[0].xOff = *head_x;
-		fixed_list->list[0].yOff = *head_y;
-		fixed_list->glyphs = *head_glyphs;
-		fixed_list->type = type & INTERSECTED_TYPE_MASK;
-		fixed_list->nlist = list_cnt;
-		if (cur_list != *head_list) {
-			fixed_list->list[0].len = (*head_list)->len - *head_pos;
-			if (cur_pos != n_off)
-			fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
-		} else
-			fixed_list->list[0].len = cur_pos - *head_pos - n_off;
-		(*fixed_cnt)++;
-	}
-
-	if (type <= INTERSECTED) {
-		*head_list = cur_list;
-		*head_pos = cur_pos - n_off;
-		*head_x = cur_x - x_off;
-		*head_y = cur_y - y_off;
-		*head_glyphs = cur_glyphs - n_off;
-	}
-	return TRUE;
+    int x_off = 0;
+    int y_off = 0;
+    int n_off = 0;
+    int list_cnt;
+
+    if (type == NON_INTERSECTED) {
+        if (x1 < prev_extents->x2 && x2 > prev_extents->x1
+            && y1 < prev_extents->y2 && y2 > prev_extents->y1)
+            return FALSE;
+        x_off = (*(cur_glyphs - 1))->info.xOff;
+        y_off = (*(cur_glyphs - 1))->info.yOff;
+        n_off = 1;
+    }
+
+    list_cnt = cur_list - *head_list + 1;
+    if (cur_pos <= n_off) {
+        DEBUGF("break at %d n_off %d\n", cur_pos, n_off);
+        list_cnt--;
+        if (cur_pos < n_off) {
+            /* we overlap with previous list's last glyph. */
+            x_off += cur_list->xOff;
+            y_off += cur_list->yOff;
+            cur_list--;
+            cur_pos = cur_list->len;
+            if (cur_pos <= n_off) {
+                list_cnt--;
+            }
+        }
+    }
+    DEBUGF("got %d lists\n", list_cnt);
+    if (list_cnt != 0) {
+        fixed_list->list = malloc(list_cnt * sizeof(*cur_list));
+        memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
+        fixed_list->list[0].xOff = *head_x;
+        fixed_list->list[0].yOff = *head_y;
+        fixed_list->glyphs = *head_glyphs;
+        fixed_list->type = type & INTERSECTED_TYPE_MASK;
+        fixed_list->nlist = list_cnt;
+        if (cur_list != *head_list) {
+            fixed_list->list[0].len = (*head_list)->len - *head_pos;
+            if (cur_pos != n_off)
+                fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
+        }
+        else
+            fixed_list->list[0].len = cur_pos - *head_pos - n_off;
+        (*fixed_cnt)++;
+    }
+
+    if (type <= INTERSECTED) {
+        *head_list = cur_list;
+        *head_pos = cur_pos - n_off;
+        *head_x = cur_x - x_off;
+        *head_y = cur_y - y_off;
+        *head_glyphs = cur_glyphs - n_off;
+    }
+    return TRUE;
 }
 
 /*
@@ -693,462 +696,468 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
 
 static int
 glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
-			PictFormatShort mask_format,
-			ScreenPtr screen, Bool check_fake_overlap,
-			struct glamor_glyph_list * fixed_list,
-			int fixed_size)
+                        PictFormatShort mask_format,
+                        ScreenPtr screen, Bool check_fake_overlap,
+                        struct glamor_glyph_list *fixed_list, int fixed_size)
 {
-	int x1, x2, y1, y2;
-	int n;
-	int x, y;
-	BoxPtr extents;
-	BoxRec prev_extents;
-	Bool first = TRUE, first_list = TRUE;
-	Bool need_free_list_region = FALSE;
-	Bool need_free_fixed_list = FALSE;
-	struct glamor_glyph *priv = NULL;
-	Bool in_non_intersected_list = -1;
-	GlyphListPtr head_list;
-	int head_x, head_y, head_pos;
-	int fixed_cnt = 0;
-	GlyphPtr *head_glyphs;
-	GlyphListPtr cur_list = list;
-	RegionRec list_region;
-	RegionRec current_region;
-	BoxRec current_box;
-
-	if (nlist > 1) {
-		pixman_region_init(&list_region);
-		need_free_list_region = TRUE;
-	}
-
-	pixman_region_init(&current_region);
-
-	extents = pixman_region_extents(&current_region);
-
-	x = 0;
-	y = 0;
-	x1 = x2 = y1 = y2 = 0;
-	n = 0;
-	extents->x1 = 0;
-	extents->y1 = 0;
-	extents->x2 = 0;
-	extents->y2 = 0;
-
-	head_list = list;
-	DEBUGF("has %d lists.\n", nlist);
-	while (nlist--) {
-		BoxRec left_box, right_box = {0};
-		Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
-		Bool left_to_right;
-		struct glamor_glyph *left_priv = NULL, *right_priv = NULL;
-
-		x += list->xOff;
-		y += list->yOff;
-		n = list->len;
-		left_to_right = TRUE;
-		cur_list = list++;
-
-		if (unlikely(!first_list)) {
-			pixman_region_init_with_extents(&current_region, extents);
-			pixman_region_union(&list_region, &list_region, &current_region);
-			first = TRUE;
-		} else {
-			head_list = cur_list;
-			head_pos = cur_list->len - n;
-			head_x = x;
-			head_y = y;
-			head_glyphs = glyphs;
-		}
-
-		DEBUGF("current list %p has %d glyphs\n", cur_list, n);
-		while (n--) {
-			GlyphPtr glyph = *glyphs++;
-
-			DEBUGF("the %dth glyph\n", cur_list->len - n - 1);
-			if (glyph->info.width == 0
-			    || glyph->info.height == 0) {
-				x += glyph->info.xOff;
-				y += glyph->info.yOff;
-				continue;
-			}
-			if (mask_format
-			    && mask_format != GlyphPicture(glyph)[screen->myNum]->format) {
-				need_free_fixed_list = TRUE;
-				goto done;
-			}
-
-			x1 = x - glyph->info.x;
-			if (x1 < MINSHORT)
-				x1 = MINSHORT;
-			y1 = y - glyph->info.y;
-			if (y1 < MINSHORT)
-				y1 = MINSHORT;
-			if (check_fake_overlap)
-				priv = glamor_glyph_get_private(glyph);
-
-			x2 = x1 + glyph->info.width;
-			y2 = y1 + glyph->info.height;
-
-			if (x2 > MAXSHORT)
-				x2 = MAXSHORT;
-			if (y2 > MAXSHORT)
-				y2 = MAXSHORT;
-
-			if (first) {
-				extents->x1 = x1;
-				extents->y1 = y1;
-				extents->x2 = x2;
-				extents->y2 = y2;
-
-				prev_extents = *extents;
-
-				first = FALSE;
-				if (check_fake_overlap && priv
-				    && priv->has_edge_map && glyph->info.yOff == 0) {
-					left_box.x1 = x1;
-					left_box.x2 = x1 + 1;
-					left_box.y1 = y1;
-
-					right_box.x1 = x2 - 2;
-					right_box.x2 = x2 - 1;
-					right_box.y1 = y1;
-					left_priv = right_priv = priv;
-					has_left_edge_box = TRUE;
-					has_right_edge_box = TRUE;
-				}
-			} else {
-				if (unlikely(!first_list)) {
-					current_box.x1 = x1;
-					current_box.y1 = y1;
-					current_box.x2 = x2;
-					current_box.y2 = y2;
-					if (pixman_region_contains_rectangle(&list_region, &current_box) != PIXMAN_REGION_OUT) {
-						need_free_fixed_list = TRUE;
-						goto done;
-					}
-				}
-
-				if (x1 < extents->x2 && x2 > extents->x1
-				    && y1 < extents->y2
-				    && y2 > extents->y1) {
-
-					if (check_fake_overlap && (has_left_edge_box || has_right_edge_box)
-					    && priv->has_edge_map && glyph->info.yOff == 0) {
-						int left_dx, right_dx;
-						unsigned long long intersected;
-
-						left_dx = has_left_edge_box ? 1 : 0;
-						right_dx = has_right_edge_box ? 1 : 0;
-						if (x1 + 1 < extents->x2 - right_dx && x2 - 1 > extents->x1 + left_dx)
-							goto real_intersected;
-
-						if (left_to_right && has_right_edge_box) {
-							if (x1 == right_box.x1) {
-								intersected = ((priv->left_x1_map & right_priv->right_x1_map)
-										| (priv->left_x2_map & right_priv->right_x2_map));
-								if (intersected)
-									goto real_intersected;
-							} else if (x1 == right_box.x2) {
-								intersected = (priv->left_x1_map & right_priv->right_x2_map);
-								if (intersected) {
-								#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
-								/* tolerate with two pixels overlap. */
-									intersected &= ~(1<<__fls(intersected));
-									if ((intersected & (intersected - 1)))
-								#endif
-										goto real_intersected;
-								}
-							}
-						} else if (!left_to_right && has_left_edge_box) {
-							if (x2 - 1 == left_box.x1) {
-								intersected = (priv->right_x2_map & left_priv->left_x1_map);
-								if (intersected) {
-								#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
-								/* tolerate with two pixels overlap. */
-									intersected &= ~(1<<__fls(intersected));
-									if ((intersected & (intersected - 1)))
-								#endif
-										goto real_intersected;
-								}
-							} else if (x2 - 1 == right_box.x2) {
-								if ((priv->right_x1_map & left_priv->left_x1_map)
-								   || (priv->right_x2_map & left_priv->left_x2_map))
-									goto real_intersected;
-							}
-						} else {
-							if (x1 < extents->x2 && x1 + 2 > extents->x1)
-								goto real_intersected;
-						}
-						goto non_intersected;
-					} else {
-real_intersected:
-						DEBUGF("overlap with previous glyph.\n");
-						if (in_non_intersected_list == 1) {
-							if (fixed_cnt >= fixed_size) {
-								need_free_fixed_list = TRUE;
-								goto done;
-							}
-							if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-									     glyphs - 1,
-									     &head_glyphs,
-									     cur_list,
-									     cur_list->len - (n + 1), x, y,
-									     x1, y1, x2, y2,
-									     &head_list,
-									     &head_pos,
-									     &head_x,
-									     &head_y, &fixed_cnt,
-									     NON_INTERSECTED,
-									     &prev_extents
-									     )){
-								need_free_fixed_list = TRUE;
-								goto done;
-							}
-						}
-
-						in_non_intersected_list = 0;
-
-					}
-				} else {
-non_intersected:
-					DEBUGF("doesn't overlap with previous glyph.\n");
-					if (in_non_intersected_list == 0) {
-						if (fixed_cnt >= fixed_size) {
-							need_free_fixed_list = TRUE;
-							goto done;
-						}
-						if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-								     glyphs - 1,
-								     &head_glyphs,
-								     cur_list,
-								     cur_list->len - (n + 1), x, y,
-								     x1, y1, x2, y2,
-								     &head_list,
-								     &head_pos,
-								     &head_x,
-								     &head_y, &fixed_cnt,
-								     INTERSECTED,
-								     &prev_extents
-								     )) {
-							need_free_fixed_list = TRUE;
-							goto done;
-						}
-					}
-					in_non_intersected_list = 1;
-				}
-				prev_extents = *extents;
-			}
-
-			if (check_fake_overlap && priv
-			    && priv->has_edge_map && glyph->info.yOff == 0) {
-				if (!has_left_edge_box || x1 < extents->x1) {
-					left_box.x1 = x1;
-					left_box.x2 = x1 + 1;
-					left_box.y1 = y1;
-					has_left_edge_box = TRUE;
-					left_priv = priv;
-				}
-
-				if (!has_right_edge_box || x2 > extents->x2) {
-					right_box.x1 = x2 - 2;
-					right_box.x2 = x2 - 1;
-					right_box.y1 = y1;
-					has_right_edge_box = TRUE;
-					right_priv = priv;
-				}
-			}
-
-			if (x1 < extents->x1)
-				extents->x1 = x1;
-			if (x2 > extents->x2)
-				extents->x2 = x2;
-
-			if (y1 < extents->y1)
-				extents->y1 = y1;
-			if (y2 > extents->y2)
-				extents->y2 = y2;
-
-			x += glyph->info.xOff;
-			y += glyph->info.yOff;
-		}
-		first_list = FALSE;
-	}
-
-	if (in_non_intersected_list == 0 && fixed_cnt == 0) {
-		fixed_cnt = -1;
-		goto done;
-	}
-
-	if ((in_non_intersected_list != -1
-		|| head_pos != n) && (fixed_cnt > 0)) {
-		if (fixed_cnt >= fixed_size) {
-			need_free_fixed_list = TRUE;
-			goto done;
-		}
-		if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
-				     glyphs - 1,
-				     &head_glyphs,
-				     cur_list,
-				     cur_list->len - (n + 1), x, y,
-				     x1, y1, x2, y2,
-				     &head_list,
-				     &head_pos,
-				     &head_x,
-				     &head_y, &fixed_cnt,
-				     (!in_non_intersected_list) | 0x80,
-				     &prev_extents
-				     )) {
-			need_free_fixed_list = TRUE;
-			goto done;
-		}
-	}
-
-done:
-	if (need_free_list_region)
-		pixman_region_fini(&list_region);
-	pixman_region_fini(&current_region);
-
-	if (need_free_fixed_list && fixed_cnt >= 0) {
-		while(fixed_cnt--) {
-			free(fixed_list[fixed_cnt].list);
-		}
-	}
-
-	DEBUGF("Got %d fixed list \n", fixed_cnt);
-	return fixed_cnt;
+    int x1, x2, y1, y2;
+    int n;
+    int x, y;
+    BoxPtr extents;
+    BoxRec prev_extents;
+    Bool first = TRUE, first_list = TRUE;
+    Bool need_free_list_region = FALSE;
+    Bool need_free_fixed_list = FALSE;
+    struct glamor_glyph *priv = NULL;
+    Bool in_non_intersected_list = -1;
+    GlyphListPtr head_list;
+    int head_x, head_y, head_pos;
+    int fixed_cnt = 0;
+    GlyphPtr *head_glyphs;
+    GlyphListPtr cur_list = list;
+    RegionRec list_region;
+    RegionRec current_region;
+    BoxRec current_box;
+
+    if (nlist > 1) {
+        pixman_region_init(&list_region);
+        need_free_list_region = TRUE;
+    }
+
+    pixman_region_init(&current_region);
+
+    extents = pixman_region_extents(&current_region);
+
+    x = 0;
+    y = 0;
+    x1 = x2 = y1 = y2 = 0;
+    n = 0;
+    extents->x1 = 0;
+    extents->y1 = 0;
+    extents->x2 = 0;
+    extents->y2 = 0;
+
+    head_list = list;
+    DEBUGF("has %d lists.\n", nlist);
+    while (nlist--) {
+        BoxRec left_box, right_box = { 0 };
+        Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
+        Bool left_to_right;
+        struct glamor_glyph *left_priv = NULL, *right_priv = NULL;
+
+        x += list->xOff;
+        y += list->yOff;
+        n = list->len;
+        left_to_right = TRUE;
+        cur_list = list++;
+
+        if (unlikely(!first_list)) {
+            pixman_region_init_with_extents(&current_region, extents);
+            pixman_region_union(&list_region, &list_region, &current_region);
+            first = TRUE;
+        }
+        else {
+            head_list = cur_list;
+            head_pos = cur_list->len - n;
+            head_x = x;
+            head_y = y;
+            head_glyphs = glyphs;
+        }
+
+        DEBUGF("current list %p has %d glyphs\n", cur_list, n);
+        while (n--) {
+            GlyphPtr glyph = *glyphs++;
+
+            DEBUGF("the %dth glyph\n", cur_list->len - n - 1);
+            if (glyph->info.width == 0 || glyph->info.height == 0) {
+                x += glyph->info.xOff;
+                y += glyph->info.yOff;
+                continue;
+            }
+            if (mask_format
+                && mask_format != GlyphPicture(glyph)[screen->myNum]->format) {
+                need_free_fixed_list = TRUE;
+                goto done;
+            }
+
+            x1 = x - glyph->info.x;
+            if (x1 < MINSHORT)
+                x1 = MINSHORT;
+            y1 = y - glyph->info.y;
+            if (y1 < MINSHORT)
+                y1 = MINSHORT;
+            if (check_fake_overlap)
+                priv = glamor_glyph_get_private(glyph);
+
+            x2 = x1 + glyph->info.width;
+            y2 = y1 + glyph->info.height;
+
+            if (x2 > MAXSHORT)
+                x2 = MAXSHORT;
+            if (y2 > MAXSHORT)
+                y2 = MAXSHORT;
+
+            if (first) {
+                extents->x1 = x1;
+                extents->y1 = y1;
+                extents->x2 = x2;
+                extents->y2 = y2;
+
+                prev_extents = *extents;
+
+                first = FALSE;
+                if (check_fake_overlap && priv
+                    && priv->has_edge_map && glyph->info.yOff == 0) {
+                    left_box.x1 = x1;
+                    left_box.x2 = x1 + 1;
+                    left_box.y1 = y1;
+
+                    right_box.x1 = x2 - 2;
+                    right_box.x2 = x2 - 1;
+                    right_box.y1 = y1;
+                    left_priv = right_priv = priv;
+                    has_left_edge_box = TRUE;
+                    has_right_edge_box = TRUE;
+                }
+            }
+            else {
+                if (unlikely(!first_list)) {
+                    current_box.x1 = x1;
+                    current_box.y1 = y1;
+                    current_box.x2 = x2;
+                    current_box.y2 = y2;
+                    if (pixman_region_contains_rectangle
+                        (&list_region, &current_box) != PIXMAN_REGION_OUT) {
+                        need_free_fixed_list = TRUE;
+                        goto done;
+                    }
+                }
+
+                if (x1 < extents->x2 && x2 > extents->x1
+                    && y1 < extents->y2 && y2 > extents->y1) {
+
+                    if (check_fake_overlap &&
+                        (has_left_edge_box || has_right_edge_box)
+                        && priv->has_edge_map && glyph->info.yOff == 0) {
+                        int left_dx, right_dx;
+                        unsigned long long intersected;
+
+                        left_dx = has_left_edge_box ? 1 : 0;
+                        right_dx = has_right_edge_box ? 1 : 0;
+                        if (x1 + 1 < extents->x2 - right_dx &&
+                            x2 - 1 > extents->x1 + left_dx)
+                            goto real_intersected;
+
+                        if (left_to_right && has_right_edge_box) {
+                            if (x1 == right_box.x1) {
+                                intersected =
+                                    ((priv->left_x1_map & right_priv->
+                                      right_x1_map)
+                                     | (priv->left_x2_map & right_priv->
+                                        right_x2_map));
+                                if (intersected)
+                                    goto real_intersected;
+                            }
+                            else if (x1 == right_box.x2) {
+                                intersected =
+                                    (priv->left_x1_map & right_priv->
+                                     right_x2_map);
+                                if (intersected) {
+#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
+                                    /* tolerate with two pixels overlap. */
+                                    intersected &= ~(1 << __fls(intersected));
+                                    if ((intersected & (intersected - 1)))
+#endif
+                                        goto real_intersected;
+                                }
+                            }
+                        }
+                        else if (!left_to_right && has_left_edge_box) {
+                            if (x2 - 1 == left_box.x1) {
+                                intersected =
+                                    (priv->right_x2_map & left_priv->
+                                     left_x1_map);
+                                if (intersected) {
+#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
+                                    /* tolerate with two pixels overlap. */
+                                    intersected &= ~(1 << __fls(intersected));
+                                    if ((intersected & (intersected - 1)))
+#endif
+                                        goto real_intersected;
+                                }
+                            }
+                            else if (x2 - 1 == right_box.x2) {
+                                if ((priv->right_x1_map & left_priv->
+                                     left_x1_map)
+                                    || (priv->right_x2_map & left_priv->
+                                        left_x2_map))
+                                    goto real_intersected;
+                            }
+                        }
+                        else {
+                            if (x1 < extents->x2 && x1 + 2 > extents->x1)
+                                goto real_intersected;
+                        }
+                        goto non_intersected;
+                    }
+                    else {
+ real_intersected:
+                        DEBUGF("overlap with previous glyph.\n");
+                        if (in_non_intersected_list == 1) {
+                            if (fixed_cnt >= fixed_size) {
+                                need_free_fixed_list = TRUE;
+                                goto done;
+                            }
+                            if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+                                                      glyphs - 1,
+                                                      &head_glyphs,
+                                                      cur_list,
+                                                      cur_list->len - (n + 1),
+                                                      x, y, x1, y1, x2, y2,
+                                                      &head_list, &head_pos,
+                                                      &head_x, &head_y,
+                                                      &fixed_cnt,
+                                                      NON_INTERSECTED,
+                                                      &prev_extents)) {
+                                need_free_fixed_list = TRUE;
+                                goto done;
+                            }
+                        }
+
+                        in_non_intersected_list = 0;
+
+                    }
+                }
+                else {
+ non_intersected:
+                    DEBUGF("doesn't overlap with previous glyph.\n");
+                    if (in_non_intersected_list == 0) {
+                        if (fixed_cnt >= fixed_size) {
+                            need_free_fixed_list = TRUE;
+                            goto done;
+                        }
+                        if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+                                                  glyphs - 1,
+                                                  &head_glyphs,
+                                                  cur_list,
+                                                  cur_list->len - (n + 1), x, y,
+                                                  x1, y1, x2, y2,
+                                                  &head_list,
+                                                  &head_pos,
+                                                  &head_x,
+                                                  &head_y, &fixed_cnt,
+                                                  INTERSECTED, &prev_extents)) {
+                            need_free_fixed_list = TRUE;
+                            goto done;
+                        }
+                    }
+                    in_non_intersected_list = 1;
+                }
+                prev_extents = *extents;
+            }
+
+            if (check_fake_overlap && priv
+                && priv->has_edge_map && glyph->info.yOff == 0) {
+                if (!has_left_edge_box || x1 < extents->x1) {
+                    left_box.x1 = x1;
+                    left_box.x2 = x1 + 1;
+                    left_box.y1 = y1;
+                    has_left_edge_box = TRUE;
+                    left_priv = priv;
+                }
+
+                if (!has_right_edge_box || x2 > extents->x2) {
+                    right_box.x1 = x2 - 2;
+                    right_box.x2 = x2 - 1;
+                    right_box.y1 = y1;
+                    has_right_edge_box = TRUE;
+                    right_priv = priv;
+                }
+            }
+
+            if (x1 < extents->x1)
+                extents->x1 = x1;
+            if (x2 > extents->x2)
+                extents->x2 = x2;
+
+            if (y1 < extents->y1)
+                extents->y1 = y1;
+            if (y2 > extents->y2)
+                extents->y2 = y2;
+
+            x += glyph->info.xOff;
+            y += glyph->info.yOff;
+        }
+        first_list = FALSE;
+    }
+
+    if (in_non_intersected_list == 0 && fixed_cnt == 0) {
+        fixed_cnt = -1;
+        goto done;
+    }
+
+    if ((in_non_intersected_list != -1 || head_pos != n) && (fixed_cnt > 0)) {
+        if (fixed_cnt >= fixed_size) {
+            need_free_fixed_list = TRUE;
+            goto done;
+        }
+        if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+                                  glyphs - 1,
+                                  &head_glyphs,
+                                  cur_list,
+                                  cur_list->len - (n + 1), x, y,
+                                  x1, y1, x2, y2,
+                                  &head_list,
+                                  &head_pos,
+                                  &head_x,
+                                  &head_y, &fixed_cnt,
+                                  (!in_non_intersected_list) | 0x80,
+                                  &prev_extents)) {
+            need_free_fixed_list = TRUE;
+            goto done;
+        }
+    }
+
+ done:
+    if (need_free_list_region)
+        pixman_region_fini(&list_region);
+    pixman_region_fini(&current_region);
+
+    if (need_free_fixed_list && fixed_cnt >= 0) {
+        while (fixed_cnt--) {
+            free(fixed_list[fixed_cnt].list);
+        }
+    }
+
+    DEBUGF("Got %d fixed list \n", fixed_cnt);
+    return fixed_cnt;
 }
 
 static inline unsigned int
 glamor_glyph_size_to_count(int size)
 {
-	size /= GLYPH_MIN_SIZE;
-	return size * size;
+    size /= GLYPH_MIN_SIZE;
+    return size * size;
 }
 
 static inline unsigned int
 glamor_glyph_count_to_mask(int count)
 {
-	return ~(count - 1);
+    return ~(count - 1);
 }
 
 static inline unsigned int
 glamor_glyph_size_to_mask(int size)
 {
-	return
-	    glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size));
+    return glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size));
 }
 
 static PicturePtr
-glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
-		   int *out_y)
+glamor_glyph_cache(glamor_screen_private * glamor, GlyphPtr glyph, int *out_x,
+                   int *out_y)
 {
-	ScreenPtr screen = glamor->screen;
-	PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
-	glamor_glyph_cache_t *cache =
-	    &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) !=
-				 0];
-	struct glamor_glyph *priv = NULL, *evicted_priv = NULL;
-	int size, mask, pos, s;
-
-	if (glyph->info.width > GLYPH_MAX_SIZE
-	    || glyph->info.height > GLYPH_MAX_SIZE)
-		return NULL;
-
-	for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
-		if (glyph->info.width <= size
-		    && glyph->info.height <= size)
-			break;
-
-	s = glamor_glyph_size_to_count(size);
-	mask = glamor_glyph_count_to_mask(s);
-	pos = (cache->count + s - 1) & mask;
-
-	priv = glamor_glyph_get_private(glyph);
-	if (pos < GLYPH_CACHE_SIZE) {
-		cache->count = pos + s;
-	} else {
-		for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) {
-			int i =
-			    cache->evict & glamor_glyph_size_to_mask(s);
-			GlyphPtr evicted = cache->glyphs[i];
-			if (evicted == NULL)
-				continue;
-
-			evicted_priv = glamor_glyph_get_private(evicted);
-			assert(evicted_priv->pos == i);
-			if (evicted_priv->size >= s) {
-				cache->glyphs[i] = NULL;
-				evicted_priv->cached = FALSE;
-				pos = cache->evict &
-				    glamor_glyph_size_to_mask(size);
-			} else
-				evicted_priv = NULL;
-			break;
-		}
-		if (evicted_priv == NULL) {
-			int count = glamor_glyph_size_to_count(size);
-			mask = glamor_glyph_count_to_mask(count);
-			pos = cache->evict & mask;
-			for (s = 0; s < count; s++) {
-				GlyphPtr evicted = cache->glyphs[pos + s];
-				if (evicted != NULL) {
-
-					evicted_priv =
-					    glamor_glyph_get_private
-					    (evicted);
-
-					assert(evicted_priv->pos == pos + s);
-					evicted_priv->cached = FALSE;
-					cache->glyphs[pos + s] = NULL;
-				}
-			}
-
-		}
-		/* And pick a new eviction position */
-		cache->evict = rand() % GLYPH_CACHE_SIZE;
-	}
-
-
-	cache->glyphs[pos] = glyph;
-
-	priv->cache = cache;
-	priv->size = size;
-	priv->pos = pos;
-	s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
-		   (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
-	priv->x =
-	    s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
-	priv->y =
-	    (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
-	for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) {
-		if (pos & 1)
-			priv->x += s;
-		if (pos & 2)
-			priv->y += s;
-		pos >>= 2;
-	}
-
-	glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x,
-					priv->y);
+    ScreenPtr screen = glamor->screen;
+    PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
+    glamor_glyph_cache_t *cache =
+        &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0];
+    struct glamor_glyph *priv = NULL, *evicted_priv = NULL;
+    int size, mask, pos, s;
+
+    if (glyph->info.width > GLYPH_MAX_SIZE
+        || glyph->info.height > GLYPH_MAX_SIZE)
+        return NULL;
+
+    for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
+        if (glyph->info.width <= size && glyph->info.height <= size)
+            break;
+
+    s = glamor_glyph_size_to_count(size);
+    mask = glamor_glyph_count_to_mask(s);
+    pos = (cache->count + s - 1) & mask;
+
+    priv = glamor_glyph_get_private(glyph);
+    if (pos < GLYPH_CACHE_SIZE) {
+        cache->count = pos + s;
+    }
+    else {
+        for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) {
+            int i = cache->evict & glamor_glyph_size_to_mask(s);
+            GlyphPtr evicted = cache->glyphs[i];
+
+            if (evicted == NULL)
+                continue;
+
+            evicted_priv = glamor_glyph_get_private(evicted);
+            assert(evicted_priv->pos == i);
+            if (evicted_priv->size >= s) {
+                cache->glyphs[i] = NULL;
+                evicted_priv->cached = FALSE;
+                pos = cache->evict & glamor_glyph_size_to_mask(size);
+            }
+            else
+                evicted_priv = NULL;
+            break;
+        }
+        if (evicted_priv == NULL) {
+            int count = glamor_glyph_size_to_count(size);
+
+            mask = glamor_glyph_count_to_mask(count);
+            pos = cache->evict & mask;
+            for (s = 0; s < count; s++) {
+                GlyphPtr evicted = cache->glyphs[pos + s];
+
+                if (evicted != NULL) {
+
+                    evicted_priv = glamor_glyph_get_private(evicted);
+
+                    assert(evicted_priv->pos == pos + s);
+                    evicted_priv->cached = FALSE;
+                    cache->glyphs[pos + s] = NULL;
+                }
+            }
+
+        }
+        /* And pick a new eviction position */
+        cache->evict = rand() % GLYPH_CACHE_SIZE;
+    }
+
+    cache->glyphs[pos] = glyph;
+
+    priv->cache = cache;
+    priv->size = size;
+    priv->pos = pos;
+    s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
+               (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
+    priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
+    priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
+    for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) {
+        if (pos & 1)
+            priv->x += s;
+        if (pos & 2)
+            priv->y += s;
+        pos >>= 2;
+    }
+
+    glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y);
 #ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-	if (priv->has_edge_map == FALSE && glyph->info.width >= 2)
-		glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture);
+    if (priv->has_edge_map == FALSE && glyph->info.width >= 2)
+        glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture);
 #endif
-	priv->cached = TRUE;
+    priv->cached = TRUE;
 
-	*out_x = priv->x;
-	*out_y = priv->y;
-	return cache->picture;
+    *out_x = priv->x;
+    *out_y = priv->y;
+    return cache->picture;
 }
-typedef void (*glyphs_flush_func)(void * arg);
+
+typedef void (*glyphs_flush_func) (void *arg);
 struct glyphs_flush_dst_arg {
-	CARD8 op;
-	PicturePtr src;
-	PicturePtr dst;
-	glamor_glyph_buffer_t * buffer;
-	int x_src,y_src;
-	int x_dst, y_dst;
+    CARD8 op;
+    PicturePtr src;
+    PicturePtr dst;
+    glamor_glyph_buffer_t *buffer;
+    int x_src, y_src;
+    int x_dst, y_dst;
 };
 
 static struct glyphs_flush_dst_arg dst_arg;
@@ -1157,650 +1166,638 @@ static glamor_glyph_buffer_t dst_buffer;
 static glamor_glyph_buffer_t mask_buffer;
 unsigned long long mask_glyphs_cnt = 0;
 unsigned long long dst_glyphs_cnt = 0;
+
 #define GLYPHS_DST_MODE_VIA_MASK		0
 #define GLYPHS_DST_MODE_VIA_MASK_CACHE		1
 #define GLYPHS_DST_MODE_TO_DST			2
 #define GLYPHS_DST_MODE_MASK_TO_DST		3
 
 struct glyphs_flush_mask_arg {
-	PicturePtr mask;
-	glamor_glyph_buffer_t *buffer;
-	struct glamor_glyph_mask_cache *maskcache;
-	unsigned int used_bitmap;
+    PicturePtr mask;
+    glamor_glyph_buffer_t *buffer;
+    struct glamor_glyph_mask_cache *maskcache;
+    unsigned int used_bitmap;
 };
 
 static void
 glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
 {
-	if (arg->buffer->count>0) {
+    if (arg->buffer->count > 0) {
 #ifdef RENDER
-	glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
-				     NULL, arg->mask,
-				     arg->buffer->count,
-				     arg->buffer->rects);
+        glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
+                                     NULL, arg->mask,
+                                     arg->buffer->count, arg->buffer->rects);
 #endif
-	}
-	arg->buffer->count = 0;
-	arg->buffer->source = NULL;
+    }
+    arg->buffer->count = 0;
+    arg->buffer->source = NULL;
 
 }
 
 static void
-glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg)
+glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg)
 {
-	if (!arg->buffer)
-		return;
-
-	if (mask_buffer.count > 0) {
-		glamor_glyphs_flush_mask(&mask_arg);
-	}
-	if (mask_arg.used_bitmap) {
-		put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap);
-		mask_arg.used_bitmap = 0;
-	}
-
-	if (arg->buffer->count > 0) {
-		glamor_composite_glyph_rects(arg->op, arg->src,
-					arg->buffer->source, arg->dst,
-					arg->buffer->count,
-					&arg->buffer->rects[0]);
-		arg->buffer->count = 0;
-		arg->buffer->source = NULL;
-	}
+    if (!arg->buffer)
+        return;
+
+    if (mask_buffer.count > 0) {
+        glamor_glyphs_flush_mask(&mask_arg);
+    }
+    if (mask_arg.used_bitmap) {
+        put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap);
+        mask_arg.used_bitmap = 0;
+    }
+
+    if (arg->buffer->count > 0) {
+        glamor_composite_glyph_rects(arg->op, arg->src,
+                                     arg->buffer->source, arg->dst,
+                                     arg->buffer->count,
+                                     &arg->buffer->rects[0]);
+        arg->buffer->count = 0;
+        arg->buffer->source = NULL;
+    }
 }
 
-
 static glamor_glyph_cache_result_t
-glamor_buffer_glyph(glamor_screen_private *glamor_priv,
-		    glamor_glyph_buffer_t * buffer,
-		    PictFormatShort format,
-		    GlyphPtr glyph, struct glamor_glyph *priv,
-		    int x_glyph, int y_glyph,
-		    int dx, int dy, int w, int h,
-		    int glyphs_dst_mode,
-		    glyphs_flush_func glyphs_flush, void *flush_arg)
+glamor_buffer_glyph(glamor_screen_private * glamor_priv,
+                    glamor_glyph_buffer_t * buffer,
+                    PictFormatShort format,
+                    GlyphPtr glyph, struct glamor_glyph *priv,
+                    int x_glyph, int y_glyph,
+                    int dx, int dy, int w, int h,
+                    int glyphs_dst_mode,
+                    glyphs_flush_func glyphs_flush, void *flush_arg)
 {
-	ScreenPtr screen = glamor_priv->screen;
-	glamor_composite_rect_t *rect;
-	PicturePtr source;
-	int x, y;
-	glamor_glyph_cache_t *cache;
-
-	if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST)
-		priv = glamor_glyph_get_private(glyph);
-
-	if (PICT_FORMAT_BPP(format) == 1)
-		format = PICT_a8;
-
-	cache =
-	    &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0];
-
-	if (buffer->source
-	    && buffer->source != cache->picture
-	    && glyphs_flush) {
-		(*glyphs_flush)(flush_arg);
-		glyphs_flush = NULL;
-	}
-
-	if (buffer->count == GLYPH_BUFFER_SIZE
-	    && glyphs_flush) {
-		(*glyphs_flush)(flush_arg);
-		glyphs_flush = NULL;
-	}
-
-	if (priv && priv->cached) {
-		rect = &buffer->rects[buffer->count++];
-		rect->x_src = priv->x + dx;
-		rect->y_src = priv->y + dy;
-		if (buffer->source == NULL)
-			buffer->source = priv->cache->picture;
-		if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE)
-			assert(priv->cache->glyphs[priv->pos] == glyph);
-	} else {
-		assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST);
-		if (glyphs_flush)
-			(*glyphs_flush)(flush_arg);
-		source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
-
-		if (source != NULL) {
-			rect = &buffer->rects[buffer->count++];
-			rect->x_src = x + dx;
-			rect->y_src = y + dy;
-			if (buffer->source == NULL)
-				buffer->source = source;
-			if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
-				glamor_gl_dispatch *dispatch;
-				/* mode 1 means we are using global mask cache,
-				 * thus we have to composite from the cache picture
-				 * to the cache picture, we need a flush here to make
-				 * sure latter we get the corret glyphs data.*/
-				dispatch = glamor_get_dispatch(glamor_priv);
-				dispatch->glFlush();
-				glamor_put_dispatch(glamor_priv);
-			}
-		} else {
-	/* Couldn't find the glyph in the cache, use the glyph picture directly */
-			source = GlyphPicture(glyph)[screen->myNum];
-			if (buffer->source
-			    && buffer->source != source
-			    && glyphs_flush)
-				(*glyphs_flush)(flush_arg);
-			buffer->source = source;
-
-			rect = &buffer->rects[buffer->count++];
-			rect->x_src = 0 + dx;
-			rect->y_src = 0 + dy;
-		}
-		priv = glamor_glyph_get_private(glyph);
-	}
-
-	rect->x_dst = x_glyph;
-	rect->y_dst = y_glyph;
-	if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) {
-		rect->x_dst -= glyph->info.x;
-		rect->y_dst -= glyph->info.y;
-	}
-	rect->width = w;
-	rect->height = h;
-	if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) {
-		rect->x_mask = rect->x_src;
-		rect->y_mask = rect->y_src;
-		rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst;
-		rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst;
-	}
-
-	return GLAMOR_GLYPH_SUCCESS;
+    ScreenPtr screen = glamor_priv->screen;
+    glamor_composite_rect_t *rect;
+    PicturePtr source;
+    int x, y;
+    glamor_glyph_cache_t *cache;
+
+    if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST)
+        priv = glamor_glyph_get_private(glyph);
+
+    if (PICT_FORMAT_BPP(format) == 1)
+        format = PICT_a8;
+
+    cache = &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0];
+
+    if (buffer->source && buffer->source != cache->picture && glyphs_flush) {
+        (*glyphs_flush) (flush_arg);
+        glyphs_flush = NULL;
+    }
+
+    if (buffer->count == GLYPH_BUFFER_SIZE && glyphs_flush) {
+        (*glyphs_flush) (flush_arg);
+        glyphs_flush = NULL;
+    }
+
+    if (priv && priv->cached) {
+        rect = &buffer->rects[buffer->count++];
+        rect->x_src = priv->x + dx;
+        rect->y_src = priv->y + dy;
+        if (buffer->source == NULL)
+            buffer->source = priv->cache->picture;
+        if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE)
+            assert(priv->cache->glyphs[priv->pos] == glyph);
+    }
+    else {
+        assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST);
+        if (glyphs_flush)
+            (*glyphs_flush) (flush_arg);
+        source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
+
+        if (source != NULL) {
+            rect = &buffer->rects[buffer->count++];
+            rect->x_src = x + dx;
+            rect->y_src = y + dy;
+            if (buffer->source == NULL)
+                buffer->source = source;
+            if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
+                glamor_gl_dispatch *dispatch;
+
+                /* mode 1 means we are using global mask cache,
+                 * thus we have to composite from the cache picture
+                 * to the cache picture, we need a flush here to make
+                 * sure latter we get the corret glyphs data.*/
+                dispatch = glamor_get_dispatch(glamor_priv);
+                dispatch->glFlush();
+                glamor_put_dispatch(glamor_priv);
+            }
+        }
+        else {
+            /* Couldn't find the glyph in the cache, use the glyph picture directly */
+            source = GlyphPicture(glyph)[screen->myNum];
+            if (buffer->source && buffer->source != source && glyphs_flush)
+                (*glyphs_flush) (flush_arg);
+            buffer->source = source;
+
+            rect = &buffer->rects[buffer->count++];
+            rect->x_src = 0 + dx;
+            rect->y_src = 0 + dy;
+        }
+        priv = glamor_glyph_get_private(glyph);
+    }
+
+    rect->x_dst = x_glyph;
+    rect->y_dst = y_glyph;
+    if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) {
+        rect->x_dst -= glyph->info.x;
+        rect->y_dst -= glyph->info.y;
+    }
+    rect->width = w;
+    rect->height = h;
+    if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) {
+        rect->x_mask = rect->x_src;
+        rect->y_mask = rect->y_src;
+        rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst;
+        rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst;
+    }
+
+    return GLAMOR_GLYPH_SUCCESS;
 }
 
-
 static void
-glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
-			 BoxPtr rects,
-			 int nrect, PictFormatShort format,
-			 GlyphPtr glyph, struct glamor_glyph *priv,
-			 int glyph_x, int glyph_y,
-			 int glyph_dx, int glyph_dy,
-			 int width, int height,
-			 int glyphs_mode,
-			 glyphs_flush_func flush_func,
-			 void *arg
-			 )
+glamor_buffer_glyph_clip(glamor_screen_private * glamor_priv,
+                         BoxPtr rects,
+                         int nrect, PictFormatShort format,
+                         GlyphPtr glyph, struct glamor_glyph *priv,
+                         int glyph_x, int glyph_y,
+                         int glyph_dx, int glyph_dy,
+                         int width, int height,
+                         int glyphs_mode,
+                         glyphs_flush_func flush_func, void *arg)
 {
-	int i;
-	for (i = 0; i < nrect; i++) {
-		int dst_x, dst_y;
-		int dx, dy;
-		int x2, y2;
-
-		dst_x = glyph_x - glyph_dx;
-		dst_y = glyph_y - glyph_dy;
-		x2 = dst_x + width;
-		y2 = dst_y + height;
-		dx = dy = 0;
-		if (rects[i].y1 >= y2)
-			break;
-
-		if (dst_x < rects[i].x1)
-			dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
-		if (x2 > rects[i].x2)
-			x2 = rects[i].x2;
-		if (dst_y < rects[i].y1)
-			dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
-		if (y2 > rects[i].y2)
-			y2 = rects[i].y2;
-		if (dst_x < x2 && dst_y < y2) {
-
-			glamor_buffer_glyph(glamor_priv,
-					    &dst_buffer,
-					    format,
-					    glyph, priv,
-					    dst_x + glyph_dx,
-					    dst_y + glyph_dy,
-					    dx, dy,
-					    x2 - dst_x, y2 - dst_y,
-			    		    glyphs_mode,
-					    flush_func,
-					    arg);
-		}
-	}
+    int i;
+
+    for (i = 0; i < nrect; i++) {
+        int dst_x, dst_y;
+        int dx, dy;
+        int x2, y2;
+
+        dst_x = glyph_x - glyph_dx;
+        dst_y = glyph_y - glyph_dy;
+        x2 = dst_x + width;
+        y2 = dst_y + height;
+        dx = dy = 0;
+        if (rects[i].y1 >= y2)
+            break;
+
+        if (dst_x < rects[i].x1)
+            dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
+        if (x2 > rects[i].x2)
+            x2 = rects[i].x2;
+        if (dst_y < rects[i].y1)
+            dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
+        if (y2 > rects[i].y2)
+            y2 = rects[i].y2;
+        if (dst_x < x2 && dst_y < y2) {
+
+            glamor_buffer_glyph(glamor_priv,
+                                &dst_buffer,
+                                format,
+                                glyph, priv,
+                                dst_x + glyph_dx,
+                                dst_y + glyph_dy,
+                                dx, dy,
+                                x2 - dst_x, y2 - dst_y,
+                                glyphs_mode, flush_func, arg);
+        }
+    }
 }
 
-
 static void
 glamor_glyphs_via_mask(CARD8 op,
-		       PicturePtr src,
-		       PicturePtr dst,
-		       PictFormatPtr mask_format,
-		       INT16 x_src,
-		       INT16 y_src,
-		       int nlist, GlyphListPtr list, GlyphPtr * glyphs,
-		       Bool use_mask_cache)
+                       PicturePtr src,
+                       PicturePtr dst,
+                       PictFormatPtr mask_format,
+                       INT16 x_src,
+                       INT16 y_src,
+                       int nlist, GlyphListPtr list, GlyphPtr * glyphs,
+                       Bool use_mask_cache)
 {
-	PixmapPtr mask_pixmap = 0;
-	PicturePtr mask;
-	ScreenPtr screen = dst->pDrawable->pScreen;
-	int width = 0, height = 0;
-	int x, y;
-	int x_dst = list->xOff, y_dst = list->yOff;
-	int n;
-	GlyphPtr glyph;
-	int error;
-	BoxRec extents = { 0, 0, 0, 0 };
-	XID component_alpha;
-	glamor_screen_private *glamor_priv;
-	int need_free_mask = FALSE;
-	glamor_glyph_buffer_t buffer;
-	struct glyphs_flush_mask_arg arg;
-	glamor_glyph_buffer_t *pmask_buffer;
-	struct glyphs_flush_mask_arg *pmask_arg;
-	struct glamor_glyph_mask_cache_entry *mce = NULL;
-	struct glamor_glyph_mask_cache *maskcache;
-	glamor_glyph_cache_t *cache;
-	int glyphs_dst_mode;
-
-	glamor_glyph_extents(nlist, list, glyphs, &extents);
-
-	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
-		return;
-	glamor_priv = glamor_get_screen_private(screen);
-	width = extents.x2 - extents.x1;
-	height = extents.y2 - extents.y1;
-
-	if (mask_format->depth == 1) {
-		PictFormatPtr a8Format =
-		    PictureMatchFormat(screen, 8, PICT_a8);
-
-		if (a8Format)
-			mask_format = a8Format;
-	}
-
-	cache = &glamor_priv->glyphCaches
-			[PICT_FORMAT_RGB(mask_format->format) != 0];
-	maskcache = mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0];
-
-	x = -extents.x1;
-	y = -extents.y1;
-	if (!use_mask_cache
-	    || width > (CACHE_PICTURE_SIZE/4)
-	    || height > MASK_CACHE_MAX_SIZE) {
-new_mask_pixmap:
-		mask_pixmap = glamor_create_pixmap(screen, width, height,
-						   mask_format->depth,
-						   CREATE_PIXMAP_USAGE_SCRATCH);
-		if (!mask_pixmap) {
-			glamor_destroy_pixmap(mask_pixmap);
-			return;
-		}
-		glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0);
-		component_alpha = NeedsComponent(mask_format->format);
-		mask = CreatePicture(0, &mask_pixmap->drawable,
-				     mask_format, CPComponentAlpha,
-				     &component_alpha, serverClient, &error);
-		if (!mask)
-			return;
-		need_free_mask = TRUE;
-		pmask_arg = &arg;
-		pmask_buffer = &buffer;
-		pmask_buffer->count = 0;
-		pmask_buffer->source = NULL;
-		pmask_arg->used_bitmap = 0;
-		glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK;
-	} else {
-		int retry_cnt = 0;
-retry:
-	   	mce = get_mask_cache(maskcache,
-				     (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE);
-
-		if (mce == NULL) {
-			glamor_glyphs_flush_dst(&dst_arg);
-			retry_cnt++;
-			if (retry_cnt > 2) {
-				assert(0);
-				goto new_mask_pixmap;
-			}
-			goto retry;
-		}
-
-		mask = cache->picture;
-		x += mce->x;
-		y += mce->y;
-		mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE;
-		mce->height = 1;
-		if (mask_arg.mask && mask_arg.mask != mask
-			&& mask_buffer.count != 0)
-			glamor_glyphs_flush_dst(&dst_arg);
-		pmask_arg = &mask_arg;
-		pmask_buffer = &mask_buffer;
-		pmask_arg->maskcache = maskcache;
-		glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE;
-	}
-	pmask_arg->mask = mask;
-	pmask_arg->buffer = pmask_buffer;
-	while (nlist--) {
-		x += list->xOff;
-		y += list->yOff;
-		n = list->len;
-		mask_glyphs_cnt += n;
-		while (n--) {
-			glyph = *glyphs++;
-			if (glyph->info.width > 0
-			    && glyph->info.height > 0) {
-				glyphs_flush_func flush_func;
-				void *temp_arg;
-				if (need_free_mask) {
-					if (pmask_buffer->count)
-						flush_func = (glyphs_flush_func)glamor_glyphs_flush_mask;
-					else
-						flush_func = NULL;
-					temp_arg = pmask_arg;
-				} else {
-					/* If we are using global mask cache, then we need to
-					 * flush dst instead of mask. As some dst depends on the
-					 * previous mask result. Just flush mask can't get all previous's
-					 * overlapped glyphs.*/
-					if (dst_buffer.count || mask_buffer.count)
-						flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
-					else
-						flush_func = NULL;
-					temp_arg = &dst_arg;
-				}
-				glamor_buffer_glyph(glamor_priv, pmask_buffer,
-						    mask_format->format,
-						    glyph, NULL, x, y,
-						    0, 0,
-						    glyph->info.width, glyph->info.height,
-						    glyphs_dst_mode,
-						    flush_func,
-						    (void*)temp_arg);
-			}
-			x += glyph->info.xOff;
-			y += glyph->info.yOff;
-		}
-		list++;
-	}
-
-	x = extents.x1;
-	y = extents.y1;
-	if (need_free_mask) {
-		glamor_glyphs_flush_mask(pmask_arg);
-		CompositePicture(op,
-				 src,
-				 mask,
-				 dst,
-				 x_src + x - x_dst,
-				 y_src + y - y_dst, 0, 0, x, y, width, height);
-		FreePicture(mask, 0);
-		glamor_destroy_pixmap(mask_pixmap);
-	} else {
-		struct glamor_glyph priv;
-		glyphs_flush_func flush_func;
-		BoxPtr rects;
-		int nrect;
-
-		priv.cache = cache;
-		priv.x = mce->x;
-		priv.y = mce->y;
-		priv.cached = TRUE;
-		rects = REGION_RECTS(dst->pCompositeClip);
-		nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
-		pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx;
-		dst_arg.op = op;
-		dst_arg.src = src;
-		dst_arg.dst = dst;
-		dst_arg.buffer = &dst_buffer;
-		dst_arg.x_src = x_src;
-		dst_arg.y_src = y_src;
-		dst_arg.x_dst = x_dst;
-		dst_arg.y_dst = y_dst;
-
-		if (dst_buffer.source == NULL) {
-			dst_buffer.source = cache->picture;
-		} else if (dst_buffer.source != cache->picture) {
-			glamor_glyphs_flush_dst(&dst_arg);
-			dst_buffer.source = cache->picture;
-		}
-
-		x += dst->pDrawable->x;
-		y += dst->pDrawable->y;
-
-		if (dst_buffer.count || mask_buffer.count)
-			flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
-		else
-			flush_func = NULL;
-
-		glamor_buffer_glyph_clip(glamor_priv,
-					 rects, nrect,
-					 mask_format->format,
-					 NULL, &priv,
-					 x, y,
-					 0, 0,
-					 width, height,
-					 GLYPHS_DST_MODE_MASK_TO_DST,
-					 flush_func,
-					 (void *)&dst_arg
-					 );
-	}
+    PixmapPtr mask_pixmap = 0;
+    PicturePtr mask;
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    int width = 0, height = 0;
+    int x, y;
+    int x_dst = list->xOff, y_dst = list->yOff;
+    int n;
+    GlyphPtr glyph;
+    int error;
+    BoxRec extents = { 0, 0, 0, 0 };
+    XID component_alpha;
+    glamor_screen_private *glamor_priv;
+    int need_free_mask = FALSE;
+    glamor_glyph_buffer_t buffer;
+    struct glyphs_flush_mask_arg arg;
+    glamor_glyph_buffer_t *pmask_buffer;
+    struct glyphs_flush_mask_arg *pmask_arg;
+    struct glamor_glyph_mask_cache_entry *mce = NULL;
+    struct glamor_glyph_mask_cache *maskcache;
+    glamor_glyph_cache_t *cache;
+    int glyphs_dst_mode;
+
+    glamor_glyph_extents(nlist, list, glyphs, &extents);
+
+    if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+        return;
+    glamor_priv = glamor_get_screen_private(screen);
+    width = extents.x2 - extents.x1;
+    height = extents.y2 - extents.y1;
+
+    if (mask_format->depth == 1) {
+        PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8);
+
+        if (a8Format)
+            mask_format = a8Format;
+    }
+
+    cache = &glamor_priv->glyphCaches
+        [PICT_FORMAT_RGB(mask_format->format) != 0];
+    maskcache = mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0];
+
+    x = -extents.x1;
+    y = -extents.y1;
+    if (!use_mask_cache || width > (CACHE_PICTURE_SIZE / 4)
+        || height > MASK_CACHE_MAX_SIZE) {
+ new_mask_pixmap:
+        mask_pixmap = glamor_create_pixmap(screen, width, height,
+                                           mask_format->depth,
+                                           CREATE_PIXMAP_USAGE_SCRATCH);
+        if (!mask_pixmap) {
+            glamor_destroy_pixmap(mask_pixmap);
+            return;
+        }
+        glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0);
+        component_alpha = NeedsComponent(mask_format->format);
+        mask = CreatePicture(0, &mask_pixmap->drawable,
+                             mask_format, CPComponentAlpha,
+                             &component_alpha, serverClient, &error);
+        if (!mask)
+            return;
+        need_free_mask = TRUE;
+        pmask_arg = &arg;
+        pmask_buffer = &buffer;
+        pmask_buffer->count = 0;
+        pmask_buffer->source = NULL;
+        pmask_arg->used_bitmap = 0;
+        glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK;
+    }
+    else {
+        int retry_cnt = 0;
+
+ retry:
+        mce = get_mask_cache(maskcache,
+                             (width + MASK_CACHE_MAX_SIZE -
+                              1) / MASK_CACHE_MAX_SIZE);
+
+        if (mce == NULL) {
+            glamor_glyphs_flush_dst(&dst_arg);
+            retry_cnt++;
+            if (retry_cnt > 2) {
+                assert(0);
+                goto new_mask_pixmap;
+            }
+            goto retry;
+        }
+
+        mask = cache->picture;
+        x += mce->x;
+        y += mce->y;
+        mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE;
+        mce->height = 1;
+        if (mask_arg.mask && mask_arg.mask != mask && mask_buffer.count != 0)
+            glamor_glyphs_flush_dst(&dst_arg);
+        pmask_arg = &mask_arg;
+        pmask_buffer = &mask_buffer;
+        pmask_arg->maskcache = maskcache;
+        glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE;
+    }
+    pmask_arg->mask = mask;
+    pmask_arg->buffer = pmask_buffer;
+    while (nlist--) {
+        x += list->xOff;
+        y += list->yOff;
+        n = list->len;
+        mask_glyphs_cnt += n;
+        while (n--) {
+            glyph = *glyphs++;
+            if (glyph->info.width > 0 && glyph->info.height > 0) {
+                glyphs_flush_func flush_func;
+                void *temp_arg;
+
+                if (need_free_mask) {
+                    if (pmask_buffer->count)
+                        flush_func =
+                            (glyphs_flush_func) glamor_glyphs_flush_mask;
+                    else
+                        flush_func = NULL;
+                    temp_arg = pmask_arg;
+                }
+                else {
+                    /* If we are using global mask cache, then we need to
+                     * flush dst instead of mask. As some dst depends on the
+                     * previous mask result. Just flush mask can't get all previous's
+                     * overlapped glyphs.*/
+                    if (dst_buffer.count || mask_buffer.count)
+                        flush_func =
+                            (glyphs_flush_func) glamor_glyphs_flush_dst;
+                    else
+                        flush_func = NULL;
+                    temp_arg = &dst_arg;
+                }
+                glamor_buffer_glyph(glamor_priv, pmask_buffer,
+                                    mask_format->format,
+                                    glyph, NULL, x, y,
+                                    0, 0,
+                                    glyph->info.width, glyph->info.height,
+                                    glyphs_dst_mode,
+                                    flush_func, (void *) temp_arg);
+            }
+            x += glyph->info.xOff;
+            y += glyph->info.yOff;
+        }
+        list++;
+    }
+
+    x = extents.x1;
+    y = extents.y1;
+    if (need_free_mask) {
+        glamor_glyphs_flush_mask(pmask_arg);
+        CompositePicture(op,
+                         src,
+                         mask,
+                         dst,
+                         x_src + x - x_dst,
+                         y_src + y - y_dst, 0, 0, x, y, width, height);
+        FreePicture(mask, 0);
+        glamor_destroy_pixmap(mask_pixmap);
+    }
+    else {
+        struct glamor_glyph priv;
+        glyphs_flush_func flush_func;
+        BoxPtr rects;
+        int nrect;
+
+        priv.cache = cache;
+        priv.x = mce->x;
+        priv.y = mce->y;
+        priv.cached = TRUE;
+        rects = REGION_RECTS(dst->pCompositeClip);
+        nrect = REGION_NUM_RECTS(dst->pCompositeClip);
+
+        pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx;
+        dst_arg.op = op;
+        dst_arg.src = src;
+        dst_arg.dst = dst;
+        dst_arg.buffer = &dst_buffer;
+        dst_arg.x_src = x_src;
+        dst_arg.y_src = y_src;
+        dst_arg.x_dst = x_dst;
+        dst_arg.y_dst = y_dst;
+
+        if (dst_buffer.source == NULL) {
+            dst_buffer.source = cache->picture;
+        }
+        else if (dst_buffer.source != cache->picture) {
+            glamor_glyphs_flush_dst(&dst_arg);
+            dst_buffer.source = cache->picture;
+        }
+
+        x += dst->pDrawable->x;
+        y += dst->pDrawable->y;
+
+        if (dst_buffer.count || mask_buffer.count)
+            flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
+        else
+            flush_func = NULL;
+
+        glamor_buffer_glyph_clip(glamor_priv,
+                                 rects, nrect,
+                                 mask_format->format,
+                                 NULL, &priv,
+                                 x, y,
+                                 0, 0,
+                                 width, height,
+                                 GLYPHS_DST_MODE_MASK_TO_DST,
+                                 flush_func, (void *) &dst_arg);
+    }
 }
 
 static void
 glamor_glyphs_to_dst(CARD8 op,
-		     PicturePtr src,
-		     PicturePtr dst,
-		     INT16 x_src,
-		     INT16 y_src,
-		     int nlist, GlyphListPtr list,
-		     GlyphPtr * glyphs)
+                     PicturePtr src,
+                     PicturePtr dst,
+                     INT16 x_src,
+                     INT16 y_src,
+                     int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-	ScreenPtr screen = dst->pDrawable->pScreen;
-	int x = 0, y = 0;
-	int x_dst = list->xOff, y_dst = list->yOff;
-	int n;
-	GlyphPtr glyph;
-	BoxPtr rects;
-	int nrect;
-	glamor_screen_private *glamor_priv;
-
-	rects = REGION_RECTS(dst->pCompositeClip);
-	nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
-	glamor_priv = glamor_get_screen_private(screen);
-
-	dst_arg.op = op;
-	dst_arg.src = src;
-	dst_arg.dst = dst;
-	dst_arg.buffer = &dst_buffer;
-	dst_arg.x_src = x_src;
-	dst_arg.y_src = y_src;
-	dst_arg.x_dst = x_dst;
-	dst_arg.y_dst = y_dst;
-
-	x = dst->pDrawable->x;
-	y = dst->pDrawable->y;
-
-	while (nlist--) {
-		x += list->xOff;
-		y += list->yOff;
-		n = list->len;
-		dst_glyphs_cnt += n;
-		while (n--) {
-			glyph = *glyphs++;
-
-			if (glyph->info.width > 0
-			    && glyph->info.height > 0) {
-				glyphs_flush_func flush_func;
-
-				if (dst_buffer.count || mask_buffer.count)
-					flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
-				else
-					flush_func = NULL;
-				glamor_buffer_glyph_clip(glamor_priv,
-							 rects, nrect,
-							 (GlyphPicture(glyph)[screen->myNum])->format,
-							 glyph, NULL,
-							 x, y,
-							 glyph->info.x, glyph->info.y,
-							 glyph->info.width, glyph->info.height,
-							 GLYPHS_DST_MODE_TO_DST,
-							 flush_func,
-							 (void *)&dst_arg
-							 );
-			}
-
-			x += glyph->info.xOff;
-			y += glyph->info.yOff;
-		}
-		list++;
-	}
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    int x = 0, y = 0;
+    int x_dst = list->xOff, y_dst = list->yOff;
+    int n;
+    GlyphPtr glyph;
+    BoxPtr rects;
+    int nrect;
+    glamor_screen_private *glamor_priv;
+
+    rects = REGION_RECTS(dst->pCompositeClip);
+    nrect = REGION_NUM_RECTS(dst->pCompositeClip);
+
+    glamor_priv = glamor_get_screen_private(screen);
+
+    dst_arg.op = op;
+    dst_arg.src = src;
+    dst_arg.dst = dst;
+    dst_arg.buffer = &dst_buffer;
+    dst_arg.x_src = x_src;
+    dst_arg.y_src = y_src;
+    dst_arg.x_dst = x_dst;
+    dst_arg.y_dst = y_dst;
+
+    x = dst->pDrawable->x;
+    y = dst->pDrawable->y;
+
+    while (nlist--) {
+        x += list->xOff;
+        y += list->yOff;
+        n = list->len;
+        dst_glyphs_cnt += n;
+        while (n--) {
+            glyph = *glyphs++;
+
+            if (glyph->info.width > 0 && glyph->info.height > 0) {
+                glyphs_flush_func flush_func;
+
+                if (dst_buffer.count || mask_buffer.count)
+                    flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
+                else
+                    flush_func = NULL;
+                glamor_buffer_glyph_clip(glamor_priv,
+                                         rects, nrect,
+                                         (GlyphPicture(glyph)[screen->myNum])->
+                                         format, glyph, NULL, x, y,
+                                         glyph->info.x, glyph->info.y,
+                                         glyph->info.width, glyph->info.height,
+                                         GLYPHS_DST_MODE_TO_DST, flush_func,
+                                         (void *) &dst_arg);
+            }
+
+            x += glyph->info.xOff;
+            y += glyph->info.yOff;
+        }
+        list++;
+    }
 }
+
 #define MAX_FIXED_SIZE
 static void
-glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer)
+glamor_glyphs_reset_buffer(glamor_glyph_buffer_t * buffer)
 {
-	buffer->count = 0;
-	buffer->source = NULL;
+    buffer->count = 0;
+    buffer->source = NULL;
 }
 
 static Bool
 _glamor_glyphs(CARD8 op,
-	       PicturePtr src,
-	       PicturePtr dst,
-	       PictFormatPtr mask_format,
-	       INT16 x_src,
-	       INT16 y_src, int nlist, GlyphListPtr list,
-	       GlyphPtr * glyphs, Bool fallback)
+               PicturePtr src,
+               PicturePtr dst,
+               PictFormatPtr mask_format,
+               INT16 x_src,
+               INT16 y_src, int nlist, GlyphListPtr list,
+               GlyphPtr * glyphs, Bool fallback)
 {
-	PictFormatShort format;
-	int fixed_size, fixed_cnt = 0;
-	struct glamor_glyph_list *fixed_list = NULL;
-	Bool need_free_list = FALSE;
+    PictFormatShort format;
+    int fixed_size, fixed_cnt = 0;
+    struct glamor_glyph_list *fixed_list = NULL;
+    Bool need_free_list = FALSE;
+
 #ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-	Bool check_fake_overlap = TRUE;
-	if (!(op == PictOpOver
-	    || op == PictOpAdd
-	    || op == PictOpXor)) {
-	/* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)).
-	 * For those op, (A IN (C ADD D)) OP B !=  (A IN D) OP ((A IN C) OP B)
-	 *		or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B)
-	 * We need to split the faked regions to three or two, and composite the disoverlapped small
-	 * boxes one by one. For other Ops, it's safe to composite the whole box.  */
-		check_fake_overlap = FALSE;
-	}
+    Bool check_fake_overlap = TRUE;
+
+    if (!(op == PictOpOver || op == PictOpAdd || op == PictOpXor)) {
+        /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)).
+         * For those op, (A IN (C ADD D)) OP B !=  (A IN D) OP ((A IN C) OP B)
+         *              or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B)
+         * We need to split the faked regions to three or two, and composite the disoverlapped small
+         * boxes one by one. For other Ops, it's safe to composite the whole box.  */
+        check_fake_overlap = FALSE;
+    }
 #else
-	Bool check_fake_overlap = FALSE;
+    Bool check_fake_overlap = FALSE;
 #endif
-	if (mask_format)
-		format = mask_format->depth << 24 | mask_format->format;
-	else
-		format = 0;
-
-	fixed_size = 32;
-	glamor_glyphs_reset_buffer(&dst_buffer);
-
-	if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
-	    && (dst->format == ((mask_format->depth << 24) | mask_format->format)))) {
-		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
-				     list, glyphs);
-		goto last_flush;
-	}
-
-	glamor_glyphs_reset_buffer(&mask_buffer);
-
-	/* We have mask_format. Need to check the real overlap or not.*/
-	format = mask_format->depth << 24 | mask_format->format;
-
-	fixed_list = calloc(fixed_size, sizeof(*fixed_list));
-	if (unlikely(fixed_list == NULL))
-		fixed_size = 0;
-	fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
-				format, dst->pDrawable->pScreen,
-				check_fake_overlap,
-				fixed_list, fixed_size);
-	if (fixed_cnt == 0)
-		mask_format = NULL;
-	need_free_list = TRUE;
-
-	if (fixed_cnt <= 0) {
-		if (mask_format == NULL) {
-			glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
-					     list, glyphs);
-			goto last_flush;
-		} else {
-			glamor_glyphs_via_mask(op, src, dst, mask_format,
-					       x_src, y_src, nlist, list, glyphs,
-					       FALSE);
-			goto free_fixed_list;
-		}
-	} else {
-
-		/* We have splitted the original list to serval list, some are overlapped
-		 * and some are non-overlapped. For the non-overlapped, we render it to
-		 * dst directly. For the overlapped, we render it to mask picture firstly,
-		 * then render the mask to dst. If we can use mask cache which is in the
-		 * glyphs cache's last row, we can accumulate the rendering of mask to dst
-		 * with the other dst_buffer's rendering operations thus can reduce the call
-		 * of glDrawElements.
-		 *
-		 * */
-		struct glamor_glyph_list *saved_list;
-
-		saved_list = fixed_list;
-		mask_arg.used_bitmap = 0;
-		while(fixed_cnt--) {
-			if (fixed_list->type == NON_INTERSECTED) {
-				glamor_glyphs_to_dst(op, src, dst,
-						     x_src, y_src,
-						     fixed_list->nlist,
-						     fixed_list->list,
-						     fixed_list->glyphs);
-			}
-			else
-				glamor_glyphs_via_mask(op, src, dst,
-						       mask_format, x_src, y_src,
-						       fixed_list->nlist,
-						       fixed_list->list,
-						       fixed_list->glyphs, TRUE);
-
-			free(fixed_list->list);
-			fixed_list++;
-		}
-		free(saved_list);
-		need_free_list = FALSE;
-	}
-
-last_flush:
-	if (dst_buffer.count || mask_buffer.count)
-		glamor_glyphs_flush_dst(&dst_arg);
-free_fixed_list:
-	if(need_free_list) {
-		assert(fixed_cnt <= 0);
-		free(fixed_list);
-	}
-	return TRUE;
+    if (mask_format)
+        format = mask_format->depth << 24 | mask_format->format;
+    else
+        format = 0;
+
+    fixed_size = 32;
+    glamor_glyphs_reset_buffer(&dst_buffer);
+
+    if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
+                         && (dst->format ==
+                             ((mask_format->depth << 24) | mask_format->
+                              format)))) {
+        glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs);
+        goto last_flush;
+    }
+
+    glamor_glyphs_reset_buffer(&mask_buffer);
+
+    /* We have mask_format. Need to check the real overlap or not. */
+    format = mask_format->depth << 24 | mask_format->format;
+
+    fixed_list = calloc(fixed_size, sizeof(*fixed_list));
+    if (unlikely(fixed_list == NULL))
+        fixed_size = 0;
+    fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
+                                        format, dst->pDrawable->pScreen,
+                                        check_fake_overlap,
+                                        fixed_list, fixed_size);
+    if (fixed_cnt == 0)
+        mask_format = NULL;
+    need_free_list = TRUE;
+
+    if (fixed_cnt <= 0) {
+        if (mask_format == NULL) {
+            glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
+                                 list, glyphs);
+            goto last_flush;
+        }
+        else {
+            glamor_glyphs_via_mask(op, src, dst, mask_format,
+                                   x_src, y_src, nlist, list, glyphs, FALSE);
+            goto free_fixed_list;
+        }
+    }
+    else {
+
+        /* We have splitted the original list to serval list, some are overlapped
+         * and some are non-overlapped. For the non-overlapped, we render it to
+         * dst directly. For the overlapped, we render it to mask picture firstly,
+         * then render the mask to dst. If we can use mask cache which is in the
+         * glyphs cache's last row, we can accumulate the rendering of mask to dst
+         * with the other dst_buffer's rendering operations thus can reduce the call
+         * of glDrawElements.
+         *
+         * */
+        struct glamor_glyph_list *saved_list;
+
+        saved_list = fixed_list;
+        mask_arg.used_bitmap = 0;
+        while (fixed_cnt--) {
+            if (fixed_list->type == NON_INTERSECTED) {
+                glamor_glyphs_to_dst(op, src, dst,
+                                     x_src, y_src,
+                                     fixed_list->nlist,
+                                     fixed_list->list, fixed_list->glyphs);
+            }
+            else
+                glamor_glyphs_via_mask(op, src, dst,
+                                       mask_format, x_src, y_src,
+                                       fixed_list->nlist,
+                                       fixed_list->list,
+                                       fixed_list->glyphs, TRUE);
+
+            free(fixed_list->list);
+            fixed_list++;
+        }
+        free(saved_list);
+        need_free_list = FALSE;
+    }
+
+ last_flush:
+    if (dst_buffer.count || mask_buffer.count)
+        glamor_glyphs_flush_dst(&dst_arg);
+ free_fixed_list:
+    if (need_free_list) {
+        assert(fixed_cnt <= 0);
+        free(fixed_list);
+    }
+    return TRUE;
 }
 
 void
 glamor_glyphs(CARD8 op,
-	      PicturePtr src,
-	      PicturePtr dst,
-	      PictFormatPtr mask_format,
-	      INT16 x_src,
-	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+              PicturePtr src,
+              PicturePtr dst,
+              PictFormatPtr mask_format,
+              INT16 x_src,
+              INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-	_glamor_glyphs(op, src, dst, mask_format, x_src,
-		       y_src, nlist, list, glyphs, TRUE);
+    _glamor_glyphs(op, src, dst, mask_format, x_src,
+                   y_src, nlist, list, glyphs, TRUE);
 }
 
 Bool
 glamor_glyphs_nf(CARD8 op,
-		 PicturePtr src,
-		 PicturePtr dst,
-		 PictFormatPtr mask_format,
-		 INT16 x_src,
-		 INT16 y_src, int nlist,
-		 GlyphListPtr list, GlyphPtr * glyphs)
+                 PicturePtr src,
+                 PicturePtr dst,
+                 PictFormatPtr mask_format,
+                 INT16 x_src,
+                 INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-	return _glamor_glyphs(op, src, dst, mask_format, x_src,
-			      y_src, nlist, list, glyphs, FALSE);
+    return _glamor_glyphs(op, src, dst, mask_format, x_src,
+                          y_src, nlist, list, glyphs, FALSE);
 }
-
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 4abc82d..df6c3bb 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -43,15 +43,16 @@
 #ifdef GLAMOR_GRADIENT_SHADER
 
 static GLint
-_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array)
+_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count,
+                                   int use_array)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
 
-	char *gradient_fs = NULL;
-	GLint fs_getcolor_prog;
+    char *gradient_fs = NULL;
+    GLint fs_getcolor_prog;
 
-	#define gradient_fs_getcolor\
+#define gradient_fs_getcolor\
 	    GLAMOR_DEFAULT_PRECISION\
 	    "uniform int n_stop;\n"\
 	    "uniform float stops[%d];\n"\
@@ -82,163 +83,86 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	    "    return gradient_color;\n"\
 	    "}\n"
 
-	/* Because the array access for shader is very slow, the performance is very low
-	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
-	const char *gradient_fs_getcolor_no_array =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform int n_stop;\n"
-	    "uniform float stop0;\n"
-	    "uniform float stop1;\n"
-	    "uniform float stop2;\n"
-	    "uniform float stop3;\n"
-	    "uniform float stop4;\n"
-	    "uniform float stop5;\n"
-	    "uniform float stop6;\n"
-	    "uniform float stop7;\n"
-	    "uniform vec4 stop_color0;\n"
-	    "uniform vec4 stop_color1;\n"
-	    "uniform vec4 stop_color2;\n"
-	    "uniform vec4 stop_color3;\n"
-	    "uniform vec4 stop_color4;\n"
-	    "uniform vec4 stop_color5;\n"
-	    "uniform vec4 stop_color6;\n"
-	    "uniform vec4 stop_color7;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len)\n"
-	    "{\n"
-	    "    float stop_after;\n"
-	    "    float stop_before;\n"
-	    "    vec4 stop_color_before;\n"
-	    "    vec4 stop_color_after;\n"
-	    "    float new_alpha; \n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    \n"
-	    "    if((stop_len < stop0) && (n_stop >= 1)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color0;\n"
-	    "        stop_after = stop0;\n"
-	    "        stop_before = stop0;\n"
-	    "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color1;\n"
-	    "        stop_after = stop1;\n"
-	    "        stop_before = stop0;\n"
-	    "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
-	    "        stop_color_before = stop_color1;\n"
-	    "        stop_color_after = stop_color2;\n"
-	    "        stop_after = stop2;\n"
-	    "        stop_before = stop1;\n"
-	    "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
-	    "        stop_color_before = stop_color2;\n"
-	    "        stop_color_after = stop_color3;\n"
-	    "        stop_after = stop3;\n"
-	    "        stop_before = stop2;\n"
-	    "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
-	    "        stop_color_before = stop_color3;\n"
-	    "        stop_color_after = stop_color4;\n"
-	    "        stop_after = stop4;\n"
-	    "        stop_before = stop3;\n"
-	    "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
-	    "        stop_color_before = stop_color4;\n"
-	    "        stop_color_after = stop_color5;\n"
-	    "        stop_after = stop5;\n"
-	    "        stop_before = stop4;\n"
-	    "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
-	    "        stop_color_before = stop_color5;\n"
-	    "        stop_color_after = stop_color6;\n"
-	    "        stop_after = stop6;\n"
-	    "        stop_before = stop5;\n"
-	    "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
-	    "        stop_color_before = stop_color6;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop6;\n"
-	    "    } else {\n"
-	    "        stop_color_before = stop_color7;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop7;\n"
-	    "    }\n"
-	    "    if(stop_after - stop_before > 2.0)\n"
-	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
-	    "    else if(stop_after - stop_before < 0.000001)\n"
-	    "        percentage = 0.0;\n"
-	    "    else \n"
-	    "        percentage = (stop_len - stop_before)/(stop_after - stop_before);\n"
-	    "    new_alpha = percentage * stop_color_after.a + \n"
-	    "                       (1.0-percentage) * stop_color_before.a; \n"
-	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
-	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
-	    "    \n"
-	    "    return gradient_color;\n"
-	    "}\n";
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	if(use_array) {
-		XNFasprintf(&gradient_fs,
-		    gradient_fs_getcolor, stops_count, stops_count);
-		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-		                                            gradient_fs);
-		free(gradient_fs);
-	} else {
-		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-		                                            gradient_fs_getcolor_no_array);
-	}
-
-	return fs_getcolor_prog;
+    /* Because the array access for shader is very slow, the performance is very low
+       if use array. So use global uniform to replace for it if the number of n_stops is small. */
+    const char *gradient_fs_getcolor_no_array = GLAMOR_DEFAULT_PRECISION "uniform int n_stop;\n" "uniform float stop0;\n" "uniform float stop1;\n" "uniform float stop2;\n" "uniform float stop3;\n" "uniform float stop4;\n" "uniform float stop5;\n" "uniform float stop6;\n" "uniform float stop7;\n" "uniform vec4 stop_color0;\n" "uniform vec4 stop_color1;\n" "uniform vec4 stop_color2;\n" "uniform vec4 stop_color3;\n" "uniform vec4 stop_color4;\n" "uniform vec4 stop_color5;\n" "uniform vec4 stop_color6;\n" "uniform vec4 stop_color7;\n" "\n" "vec4 get_color(float stop_len)\n" "{\n" "    float stop_after;\n" "    float stop_before;\n" "    vec4 stop_color_before;\n" "    vec4 stop_color_after;\n" "    float new_alpha; \n" "    vec4 gradient_color;\n" "    float percentage; \n" "    \n" "    if((stop_len < stop0) && (n_stop >= 1)) {\n" "        stop_color_before = stop_color0;\n" "        stop_color_after = stop_color0;\n" "        stop_after = stop0;\n" "        stop_before = stop0;\n" "  
   } else if((stop_len < stop1) && (n_stop >= 2)) {\n" "        stop_color_before = stop_color0;\n" "        stop_color_after = stop_color1;\n" "        stop_after = stop1;\n" "        stop_before = stop0;\n" "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n" "        stop_color_before = stop_color1;\n" "        stop_color_after = stop_color2;\n" "        stop_after = stop2;\n" "        stop_before = stop1;\n" "    } else if((stop_len < stop3) && (n_stop >= 4)){\n" "        stop_color_before = stop_color2;\n" "        stop_color_after = stop_color3;\n" "        stop_after = stop3;\n" "        stop_before = stop2;\n" "    } else if((stop_len < stop4) && (n_stop >= 5)){\n" "        stop_color_before = stop_color3;\n" "        stop_color_after = stop_color4;\n" "        stop_after = stop4;\n" "        stop_before = stop3;\n" "    } else if((stop_len < stop5) && (n_stop >= 6)){\n" "        stop_color_before = stop_color4;\n" "        stop_color_after = stop_color5;\n" "        stop
 _after = stop5;\n" "        stop_before = stop4;\n" "    } else if((stop_len < stop6) && (n_stop >= 7)){\n" "        stop_color_before = stop_color5;\n" "        stop_color_after = stop_color6;\n" "        stop_after = stop6;\n" "        stop_before = stop5;\n" "    } else if((stop_len < stop7) && (n_stop >= 8)){\n" "        stop_color_before = stop_color6;\n" "        stop_color_after = stop_color7;\n" "        stop_after = stop7;\n" "        stop_before = stop6;\n" "    } else {\n" "        stop_color_before = stop_color7;\n" "        stop_color_after = stop_color7;\n" "        stop_after = stop7;\n" "        stop_before = stop7;\n" "    }\n" "    if(stop_after - stop_before > 2.0)\n" "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+        "    else if(stop_after - stop_before < 0.000001)\n"
+        "        percentage = 0.0;\n"
+        "    else \n"
+        "        percentage = (stop_len - stop_before)/(stop_after - stop_before);\n"
+        "    new_alpha = percentage * stop_color_after.a + \n"
+        "                       (1.0-percentage) * stop_color_before.a; \n"
+        "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
+        "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
+        "                          new_alpha);\n"
+        "    \n" "    return gradient_color;\n" "}\n";
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    if (use_array) {
+        XNFasprintf(&gradient_fs,
+                    gradient_fs_getcolor, stops_count, stops_count);
+        fs_getcolor_prog =
+            glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, gradient_fs);
+        free(gradient_fs);
+    }
+    else {
+        fs_getcolor_prog =
+            glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+                                     gradient_fs_getcolor_no_array);
+    }
+
+    return fs_getcolor_prog;
 }
 
 static void
-_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
+_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
+                                       int dyn_gen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	int index;
-
-	GLint gradient_prog = 0;
-	char *gradient_fs = NULL;
-	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
-
-	const char *gradient_vs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_Position = v_position;\n"
-	    "    source_texture = v_texcoord.xy;\n"
-	    "}\n";
-
-	/*
-	 *     Refer to pixman radial gradient.
-	 *
-	 *     The problem is given the two circles of c1 and c2 with the radius of r1 and
-	 *     r1, we need to caculate the t, which is used to do interpolate with stops,
-	 *     using the fomula:
-	 *     length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2
-	 *     expand the fomula with xy coond, get the following:
-	 *     sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y))
-	 *           = (1-t)r1 + t*r2
-	 *     <====> At*t- 2Bt + C = 0
-	 *     where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1)
-	 *           B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1)
-	 *           C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1
-	 *
-	 *     solve the fomula and we get the result of
-	 *     t = (B + sqrt(B*B - A*C)) / A  or
-	 *     t = (B - sqrt(B*B - A*C)) / A  (quadratic equation have two solutions)
-	 *
-	 *     The solution we are going to prefer is the bigger one, unless the
-	 *     radius associated to it is negative (or it falls outside the valid t range)
-	 */
-
-	#define gradient_radial_fs_template\
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    int index;
+
+    GLint gradient_prog = 0;
+    char *gradient_fs = NULL;
+    GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+
+    const char *gradient_vs =
+        GLAMOR_DEFAULT_PRECISION
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord;\n"
+        "varying vec2 source_texture;\n"
+        "\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = v_position;\n"
+        "    source_texture = v_texcoord.xy;\n" "}\n";
+
+    /*
+     *     Refer to pixman radial gradient.
+     *
+     *     The problem is given the two circles of c1 and c2 with the radius of r1 and
+     *     r1, we need to caculate the t, which is used to do interpolate with stops,
+     *     using the fomula:
+     *     length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2
+     *     expand the fomula with xy coond, get the following:
+     *     sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y))
+     *           = (1-t)r1 + t*r2
+     *     <====> At*t- 2Bt + C = 0
+     *     where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1)
+     *           B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1)
+     *           C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1
+     *
+     *     solve the fomula and we get the result of
+     *     t = (B + sqrt(B*B - A*C)) / A  or
+     *     t = (B - sqrt(B*B - A*C)) / A  (quadratic equation have two solutions)
+     *
+     *     The solution we are going to prefer is the bigger one, unless the
+     *     radius associated to it is negative (or it falls outside the valid t range)
+     */
+
+#define gradient_radial_fs_template\
 	    GLAMOR_DEFAULT_PRECISION\
 	    "uniform mat3 transform_mat;\n"\
 	    "uniform int repeat_type;\n"\
@@ -344,149 +268,164 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy
 	    "    }\n"\
 	    "}\n"
 
-	glamor_priv = glamor_get_screen_private(screen);
-
-	if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
-		/* Very Good, not to generate again. */
-		return;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
-		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
-		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
-	}
-
-	gradient_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch,
-	                                   GL_VERTEX_SHADER, gradient_vs);
-
-	XNFasprintf(&gradient_fs,
-	            gradient_radial_fs_template,
-	            PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-
-	fs_main_prog = glamor_compile_glsl_prog(dispatch,
-	                                        GL_FRAGMENT_SHADER, gradient_fs);
-
-	free(gradient_fs);
-
-	fs_getcolor_prog =
-	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
-
-	dispatch->glAttachShader(gradient_prog, vs_prog);
-	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-	dispatch->glAttachShader(gradient_prog, fs_main_prog);
-
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
-
-	glamor_link_glsl_prog(dispatch, gradient_prog);
-
-	dispatch->glUseProgram(0);
-
-	if (dyn_gen) {
-		index = 2;
-		glamor_priv->radial_max_nstops = stops_count;
-	} else if (stops_count) {
-		index = 1;
-	} else {
-		index = 0;
-	}
-
-	glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+
+    if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
+        /* Very Good, not to generate again. */
+        return;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
+        dispatch->glDeleteShader(glamor_priv->
+                                 radial_gradient_shaders
+                                 [SHADER_GRADIENT_VS_PROG][2]);
+        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+        dispatch->glDeleteShader(glamor_priv->
+                                 radial_gradient_shaders
+                                 [SHADER_GRADIENT_FS_MAIN_PROG][2]);
+        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
+            0;
+
+        dispatch->glDeleteShader(glamor_priv->
+                                 radial_gradient_shaders
+                                 [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+        glamor_priv->
+            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+        dispatch->glDeleteProgram(glamor_priv->
+                                  gradient_prog[SHADER_GRADIENT_RADIAL][2]);
+        glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
+    }
+
+    gradient_prog = dispatch->glCreateProgram();
+
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs);
+
+    XNFasprintf(&gradient_fs,
+                gradient_radial_fs_template,
+                PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL,
+                PIXMAN_REPEAT_REFLECT);
+
+    fs_main_prog = glamor_compile_glsl_prog(dispatch,
+                                            GL_FRAGMENT_SHADER, gradient_fs);
+
+    free(gradient_fs);
+
+    fs_getcolor_prog =
+        _glamor_create_getcolor_fs_program(screen, stops_count,
+                                           (stops_count > 0));
+
+    dispatch->glAttachShader(gradient_prog, vs_prog);
+    dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+    dispatch->glAttachShader(gradient_prog, fs_main_prog);
+
+    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS,
+                                   "v_positionsition");
+    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE,
+                                   "v_texcoord");
+
+    glamor_link_glsl_prog(dispatch, gradient_prog);
+
+    dispatch->glUseProgram(0);
+
+    if (dyn_gen) {
+        index = 2;
+        glamor_priv->radial_max_nstops = stops_count;
+    }
+    else if (stops_count) {
+        index = 1;
+    }
+    else {
+        index = 0;
+    }
+
+    glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
+    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] =
+        vs_prog;
+    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] =
+        fs_main_prog;
+    glamor_priv->
+        radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
+        fs_getcolor_prog;
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
-_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
+_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
+                                       int dyn_gen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-
-	int index = 0;
-	GLint gradient_prog = 0;
-	char *gradient_fs = NULL;
-	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
-
-	const char *gradient_vs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_Position = v_position;\n"
-	    "    source_texture = v_texcoord.xy;\n"
-	    "}\n";
-
-	/*
-	 *                                      |
-	 *                                      |\
-	 *                                      | \
-	 *                                      |  \
-	 *                                      |   \
-	 *                                      |\   \
-	 *                                      | \   \
-	 *     cos_val =                        |\ p1d \   /
-	 *      sqrt(1/(slope*slope+1.0))  ------>\ \   \ /
-	 *                                      |  \ \   \
-	 *                                      |   \ \ / \
-	 *                                      |    \ *Pt1\
-	 *         *p1                          |     \     \     *P
-	 *          \                           |    / \     \   /
-	 *           \                          |   /   \     \ /
-	 *            \                         |       pd     \
-	 *             \                        |         \   / \
-	 *            p2*                       |          \ /   \       /
-	 *        slope = (p2.y - p1.y) /       |           /     p2d   /
-	 *                    (p2.x - p1.x)     |          /       \   /
-	 *                                      |         /         \ /
-	 *                                      |        /           /
-	 *                                      |       /           /
-	 *                                      |      /           *Pt2
-	 *                                      |                 /
-	 *                                      |                /
-	 *                                      |               /
-	 *                                      |              /
-	 *                                      |             /
-	 *                               -------+---------------------------------
-	 *                                     O|
-	 *                                      |
-	 *                                      |
-	 *
-	 *	step 1: compute the distance of p, pt1 and pt2 in the slope direction.
-	 *		Caculate the distance on Y axis first and multiply cos_val to
-	 *		get the value on slope direction(pd, p1d and p2d represent the
-	 *		distance of p, pt1, and pt2 respectively).
-	 *
-	 *	step 2: caculate the percentage of (pd - p1d)/(p2d - p1d).
-	 *		If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d)
-	 *		to make it in the range of [0, (p2d - p1d)].
-	 *
-	 *	step 3: compare the percentage to every stop and find the stpos just
-	 *		before and after it. Use the interpolation fomula to compute RGBA.
-	 */
-
-	#define gradient_fs_template	\
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+
+    int index = 0;
+    GLint gradient_prog = 0;
+    char *gradient_fs = NULL;
+    GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+
+    const char *gradient_vs =
+        GLAMOR_DEFAULT_PRECISION
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord;\n"
+        "varying vec2 source_texture;\n"
+        "\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = v_position;\n"
+        "    source_texture = v_texcoord.xy;\n" "}\n";
+
+    /*
+     *                                      |
+     *                                      |\
+     *                                      | \
+     *                                      |  \
+     *                                      |   \
+     *                                      |\   \
+     *                                      | \   \
+     *     cos_val =                        |\ p1d \   /
+     *      sqrt(1/(slope*slope+1.0))  ------>\ \   \ /
+     *                                      |  \ \   \
+     *                                      |   \ \ / \
+     *                                      |    \ *Pt1\
+     *         *p1                          |     \     \     *P
+     *          \                           |    / \     \   /
+     *           \                          |   /   \     \ /
+     *            \                         |       pd     \
+     *             \                        |         \   / \
+     *            p2*                       |          \ /   \       /
+     *        slope = (p2.y - p1.y) /       |           /     p2d   /
+     *                    (p2.x - p1.x)     |          /       \   /
+     *                                      |         /         \ /
+     *                                      |        /           /
+     *                                      |       /           /
+     *                                      |      /           *Pt2
+     *                                      |                 /
+     *                                      |                /
+     *                                      |               /
+     *                                      |              /
+     *                                      |             /
+     *                               -------+---------------------------------
+     *                                     O|
+     *                                      |
+     *                                      |
+     *
+     *      step 1: compute the distance of p, pt1 and pt2 in the slope direction.
+     *              Caculate the distance on Y axis first and multiply cos_val to
+     *              get the value on slope direction(pd, p1d and p2d represent the
+     *              distance of p, pt1, and pt2 respectively).
+     *
+     *      step 2: caculate the percentage of (pd - p1d)/(p2d - p1d).
+     *              If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d)
+     *              to make it in the range of [0, (p2d - p1d)].
+     *
+     *      step 3: compare the percentage to every stop and find the stpos just
+     *              before and after it. Use the interpolation fomula to compute RGBA.
+     */
+
+#define gradient_fs_template	\
 	    GLAMOR_DEFAULT_PRECISION\
 	    "uniform mat3 transform_mat;\n"\
 	    "uniform int repeat_type;\n"\
@@ -569,1016 +508,1086 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 	    "    gl_FragColor = get_color(stop_len);\n"\
 	    "}\n"
 
-	glamor_priv = glamor_get_screen_private(screen);
-
-	if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
-		/* Very Good, not to generate again. */
-		return;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
-		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
-		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
-	}
-
-	gradient_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch,
-	                                   GL_VERTEX_SHADER, gradient_vs);
-
-	XNFasprintf(&gradient_fs,
-	            gradient_fs_template,
-	            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-
-	fs_main_prog = glamor_compile_glsl_prog(dispatch,
-	                                        GL_FRAGMENT_SHADER, gradient_fs);
-	free(gradient_fs);
-
-	fs_getcolor_prog =
-	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
-
-	dispatch->glAttachShader(gradient_prog, vs_prog);
-	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-	dispatch->glAttachShader(gradient_prog, fs_main_prog);
-
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
-
-	glamor_link_glsl_prog(dispatch, gradient_prog);
-
-	dispatch->glUseProgram(0);
-
-	if (dyn_gen) {
-		index = 2;
-		glamor_priv->linear_max_nstops = stops_count;
-	} else if (stops_count) {
-		index = 1;
-	} else {
-		index = 0;
-	}
-
-	glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+
+    if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
+        /* Very Good, not to generate again. */
+        return;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
+        dispatch->glDeleteShader(glamor_priv->
+                                 linear_gradient_shaders
+                                 [SHADER_GRADIENT_VS_PROG][2]);
+        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+        dispatch->glDeleteShader(glamor_priv->
+                                 linear_gradient_shaders
+                                 [SHADER_GRADIENT_FS_MAIN_PROG][2]);
+        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] =
+            0;
+
+        dispatch->glDeleteShader(glamor_priv->
+                                 linear_gradient_shaders
+                                 [SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+        glamor_priv->
+            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+        dispatch->glDeleteProgram(glamor_priv->
+                                  gradient_prog[SHADER_GRADIENT_LINEAR][2]);
+        glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
+    }
+
+    gradient_prog = dispatch->glCreateProgram();
+
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, gradient_vs);
+
+    XNFasprintf(&gradient_fs,
+                gradient_fs_template,
+                PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+
+    fs_main_prog = glamor_compile_glsl_prog(dispatch,
+                                            GL_FRAGMENT_SHADER, gradient_fs);
+    free(gradient_fs);
+
+    fs_getcolor_prog =
+        _glamor_create_getcolor_fs_program(screen, stops_count,
+                                           (stops_count > 0));
+
+    dispatch->glAttachShader(gradient_prog, vs_prog);
+    dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+    dispatch->glAttachShader(gradient_prog, fs_main_prog);
+
+    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS,
+                                   "v_position");
+    dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE,
+                                   "v_texcoord");
+
+    glamor_link_glsl_prog(dispatch, gradient_prog);
+
+    dispatch->glUseProgram(0);
+
+    if (dyn_gen) {
+        index = 2;
+        glamor_priv->linear_max_nstops = stops_count;
+    }
+    else if (stops_count) {
+        index = 1;
+    }
+    else {
+        index = 0;
+    }
+
+    glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
+    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] =
+        vs_prog;
+    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] =
+        fs_main_prog;
+    glamor_priv->
+        linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] =
+        fs_getcolor_prog;
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_init_gradient_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	int i;
-
-	glamor_priv = glamor_get_screen_private(screen);
-
-	for (i = 0; i < 3; i++) {
-		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
-
-		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
-	}
-	glamor_priv->linear_max_nstops = 0;
-	glamor_priv->radial_max_nstops = 0;
-
-	_glamor_create_linear_gradient_program(screen, 0, 0);
-	_glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
-
-	_glamor_create_radial_gradient_program(screen, 0, 0);
-	_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
+    glamor_screen_private *glamor_priv;
+    int i;
+
+    glamor_priv = glamor_get_screen_private(screen);
+
+    for (i = 0; i < 3; i++) {
+        glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
+        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+        glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] =
+            0;
+        glamor_priv->
+            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+
+        glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
+        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+        glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] =
+            0;
+        glamor_priv->
+            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+    }
+    glamor_priv->linear_max_nstops = 0;
+    glamor_priv->radial_max_nstops = 0;
+
+    _glamor_create_linear_gradient_program(screen, 0, 0);
+    _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
+
+    _glamor_create_radial_gradient_program(screen, 0, 0);
+    _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
 }
 
 void
 glamor_fini_gradient_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	int i = 0;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	for (i = 0; i < 3; i++) {
-		/* Linear Gradient */
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
-
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
-		if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
-			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]);
-
-		/* Radial Gradient */
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
-
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
-		if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
-			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]);
-	}
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    int i = 0;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    for (i = 0; i < 3; i++) {
+        /* Linear Gradient */
+        if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     linear_gradient_shaders
+                                     [SHADER_GRADIENT_VS_PROG][i]);
+
+        if (glamor_priv->
+            linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     linear_gradient_shaders
+                                     [SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+        if (glamor_priv->
+            linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     linear_gradient_shaders
+                                     [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+        if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
+            dispatch->glDeleteProgram(glamor_priv->
+                                      gradient_prog[SHADER_GRADIENT_LINEAR][i]);
+
+        /* Radial Gradient */
+        if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     radial_gradient_shaders
+                                     [SHADER_GRADIENT_VS_PROG][i]);
+
+        if (glamor_priv->
+            radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     radial_gradient_shaders
+                                     [SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+        if (glamor_priv->
+            radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+            dispatch->glDeleteShader(glamor_priv->
+                                     radial_gradient_shaders
+                                     [SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+        if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
+            dispatch->glDeleteProgram(glamor_priv->
+                                      gradient_prog[SHADER_GRADIENT_RADIAL][i]);
+    }
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
-_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
-				      int width, int height, int normalize)
+_glamor_gradient_convert_trans_matrix(PictTransform * from, float to[3][3],
+                                      int width, int height, int normalize)
 {
-	/*
-	 * Because in the shader program, we normalize all the pixel cood to [0, 1],
-	 * so with the transform matrix, the correct logic should be:
-	 * v_s = A*T*v
-	 * v_s: point vector in shader after normalized.
-	 * A: The transition matrix from   width X height --> 1.0 X 1.0
-	 * T: The transform matrix.
-	 * v: point vector in width X height space.
-	 *
-	 * result is OK if we use this fomula. But for every point in width X height space,
-	 * we can just use their normalized point vector in shader, namely we can just
-	 * use the result of A*v in shader. So we have no chance to insert T in A*v.
-	 * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the
-	 * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v)
-	 * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and
-	 * we name this matrix T_s.
-	 *
-	 * Firstly, because A is for the scale convertion, we find
-	 *      --         --
-	 *      |1/w  0   0 |
-	 * A =  | 0  1/h  0 |
-	 *      | 0   0  1.0|
-	 *      --         --
-	 * so T_s = A*T*inv(a) and result
-	 *
-	 *       --                      --
-	 *       | t11      h*t12/w  t13/w|
-	 * T_s = | w*t21/h  t22      t23/h|
-	 *       | w*t31    h*t32    t33  |
-	 *       --                      --
-	 */
-
-	to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]);
-	to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1])
-	                        * (normalize ? (((float)height) / ((float)width)) : 1.0);
-	to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2])
-	                        / (normalize ? ((float)width) : 1.0);
-
-	to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0])
-	                        * (normalize ? (((float)width) / ((float)height)) : 1.0);
-	to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]);
-	to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2])
-	                        / (normalize ? ((float)height) : 1.0);
-
-	to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0])
-	                        * (normalize ? ((float)width) : 1.0);
-	to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1])
-	                        * (normalize ? ((float)height) : 1.0);
-	to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]);
-
-	DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
-	       to[0][0], to[0][1], to[0][2],
-	       to[1][0], to[1][1], to[1][2],
-	       to[2][0], to[2][1], to[2][2]);
+    /*
+     * Because in the shader program, we normalize all the pixel cood to [0, 1],
+     * so with the transform matrix, the correct logic should be:
+     * v_s = A*T*v
+     * v_s: point vector in shader after normalized.
+     * A: The transition matrix from   width X height --> 1.0 X 1.0
+     * T: The transform matrix.
+     * v: point vector in width X height space.
+     *
+     * result is OK if we use this fomula. But for every point in width X height space,
+     * we can just use their normalized point vector in shader, namely we can just
+     * use the result of A*v in shader. So we have no chance to insert T in A*v.
+     * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the
+     * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v)
+     * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and
+     * we name this matrix T_s.
+     *
+     * Firstly, because A is for the scale convertion, we find
+     *      --         --
+     *      |1/w  0   0 |
+     * A =  | 0  1/h  0 |
+     *      | 0   0  1.0|
+     *      --         --
+     * so T_s = A*T*inv(a) and result
+     *
+     *       --                      --
+     *       | t11      h*t12/w  t13/w|
+     * T_s = | w*t21/h  t22      t23/h|
+     *       | w*t31    h*t32    t33  |
+     *       --                      --
+     */
+
+    to[0][0] = (float) pixman_fixed_to_double(from->matrix[0][0]);
+    to[0][1] = (float) pixman_fixed_to_double(from->matrix[0][1])
+        * (normalize ? (((float) height) / ((float) width)) : 1.0);
+    to[0][2] = (float) pixman_fixed_to_double(from->matrix[0][2])
+        / (normalize ? ((float) width) : 1.0);
+
+    to[1][0] = (float) pixman_fixed_to_double(from->matrix[1][0])
+        * (normalize ? (((float) width) / ((float) height)) : 1.0);
+    to[1][1] = (float) pixman_fixed_to_double(from->matrix[1][1]);
+    to[1][2] = (float) pixman_fixed_to_double(from->matrix[1][2])
+        / (normalize ? ((float) height) : 1.0);
+
+    to[2][0] = (float) pixman_fixed_to_double(from->matrix[2][0])
+        * (normalize ? ((float) width) : 1.0);
+    to[2][1] = (float) pixman_fixed_to_double(from->matrix[2][1])
+        * (normalize ? ((float) height) : 1.0);
+    to[2][2] = (float) pixman_fixed_to_double(from->matrix[2][2]);
+
+    DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
+           to[0][0], to[0][1], to[0][2],
+           to[1][0], to[1][1], to[1][2], to[2][0], to[2][1], to[2][2]);
 }
 
 static int
 _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
-                                        glamor_screen_private *glamor_priv,
+                                        glamor_screen_private * glamor_priv,
                                         PicturePtr dst_picture,
-                                        GLfloat *xscale, GLfloat *yscale,
+                                        GLfloat * xscale, GLfloat * yscale,
                                         int x_source, int y_source,
                                         float vertices[8],
                                         float tex_vertices[8],
-					int tex_normalize)
+                                        int tex_normalize)
 {
-	glamor_pixmap_private *pixmap_priv;
-	PixmapPtr pixmap = NULL;
-	glamor_gl_dispatch *dispatch = NULL;
-
-	pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
-		return 0;
-	}
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
-
-	DEBUGF("xscale = %f, yscale = %f,"
-	       " x_source = %d, y_source = %d, width = %d, height = %d\n",
-	       *xscale, *yscale, x_source, y_source,
-	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
-
-	glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale,
-	                  0, 0,
-	                  (INT16)(dst_picture->pDrawable->width),
-	                  (INT16)(dst_picture->pDrawable->height),
-	                  glamor_priv->yInverted, vertices);
-
-	if (tex_normalize) {
-		glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
-		                x_source, y_source,
-		                (INT16)(dst_picture->pDrawable->width + x_source),
-		                (INT16)(dst_picture->pDrawable->height + y_source),
-		                glamor_priv->yInverted, tex_vertices);
-	} else {
-		glamor_set_tcoords_tri_strip((INT16)(dst_picture->pDrawable->width),
-		                 (INT16)(dst_picture->pDrawable->height),
-		                 x_source, y_source,
-		                 (INT16)(dst_picture->pDrawable->width) + x_source,
-		                 (INT16)(dst_picture->pDrawable->height) + y_source,
-		                 glamor_priv->yInverted, tex_vertices);
-	}
-
-	DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
-	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-	       vertices[0], vertices[1], vertices[2], vertices[3],
-	       vertices[4], vertices[5], vertices[6], vertices[7]);
-	DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
-	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-	       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
-	       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 0, vertices);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 0, tex_vertices);
-
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	glamor_put_dispatch(glamor_priv);
-
-	return 1;
+    glamor_pixmap_private *pixmap_priv;
+    PixmapPtr pixmap = NULL;
+    glamor_gl_dispatch *dispatch = NULL;
+
+    pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {     /* should always have here. */
+        return 0;
+    }
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+    pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+
+    DEBUGF("xscale = %f, yscale = %f,"
+           " x_source = %d, y_source = %d, width = %d, height = %d\n",
+           *xscale, *yscale, x_source, y_source,
+           dst_picture->pDrawable->width, dst_picture->pDrawable->height);
+
+    glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale,
+                                           0, 0,
+                                           (INT16) (dst_picture->pDrawable->
+                                                    width),
+                                           (INT16) (dst_picture->pDrawable->
+                                                    height),
+                                           glamor_priv->yInverted, vertices);
+
+    if (tex_normalize) {
+        glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
+                                                x_source, y_source,
+                                                (INT16) (dst_picture->
+                                                         pDrawable->width +
+                                                         x_source),
+                                                (INT16) (dst_picture->
+                                                         pDrawable->height +
+                                                         y_source),
+                                                glamor_priv->yInverted,
+                                                tex_vertices);
+    }
+    else {
+        glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width),
+                                     (INT16) (dst_picture->pDrawable->height),
+                                     x_source, y_source,
+                                     (INT16) (dst_picture->pDrawable->width) +
+                                     x_source,
+                                     (INT16) (dst_picture->pDrawable->height) +
+                                     y_source, glamor_priv->yInverted,
+                                     tex_vertices);
+    }
+
+    DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+           "rightbottom: %f X %f, leftbottom : %f X %f\n",
+           vertices[0], vertices[1], vertices[2], vertices[3],
+           vertices[4], vertices[5], vertices[6], vertices[7]);
+    DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+           "rightbottom: %f X %f, leftbottom : %f X %f\n",
+           tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
+           tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 0, vertices);
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                                    GL_FALSE, 0, tex_vertices);
+
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    glamor_put_dispatch(glamor_priv);
+
+    return 1;
 }
 
 static int
 _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
-        GLfloat *stop_colors, GLfloat *n_stops)
+                           GLfloat * stop_colors, GLfloat * n_stops)
 {
-	int i;
-	int count = 1;
-
-	for (i = 0; i < pgradient->nstops; i++) {
-		stop_colors[count*4] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.red);
-		stop_colors[count*4+1] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.green);
-		stop_colors[count*4+2] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.blue);
-		stop_colors[count*4+3] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.alpha);
-
-		n_stops[count] = (GLfloat)pixman_fixed_to_double(
-		                                pgradient->stops[i].x);
-		count++;
-	}
-
-	/* for the end stop. */
-	count++;
-
-	switch (src_picture->repeatType) {
+    int i;
+    int count = 1;
+
+    for (i = 0; i < pgradient->nstops; i++) {
+        stop_colors[count * 4] =
+            pixman_fixed_to_double(pgradient->stops[i].color.red);
+        stop_colors[count * 4 + 1] =
+            pixman_fixed_to_double(pgradient->stops[i].color.green);
+        stop_colors[count * 4 + 2] =
+            pixman_fixed_to_double(pgradient->stops[i].color.blue);
+        stop_colors[count * 4 + 3] =
+            pixman_fixed_to_double(pgradient->stops[i].color.alpha);
+
+        n_stops[count] =
+            (GLfloat) pixman_fixed_to_double(pgradient->stops[i].x);
+        count++;
+    }
+
+    /* for the end stop. */
+    count++;
+
+    switch (src_picture->repeatType) {
 #define REPEAT_FILL_STOPS(m, n) \
 			stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \
 			stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \
 			stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \
 			stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3];
 
-		default:
-		case PIXMAN_REPEAT_NONE:
-			stop_colors[0] = 0.0;	   //R
-			stop_colors[1] = 0.0;	   //G
-			stop_colors[2] = 0.0;	   //B
-			stop_colors[3] = 0.0;	   //Alpha
-			n_stops[0] = -(float)INT_MAX;  //should be small enough.
-
-			stop_colors[0 + (count-1)*4] = 0.0;	 //R
-			stop_colors[1 + (count-1)*4] = 0.0;	 //G
-			stop_colors[2 + (count-1)*4] = 0.0;	 //B
-			stop_colors[3 + (count-1)*4] = 0.0;	 //Alpha
-			n_stops[count-1] = (float)INT_MAX;  //should be large enough.
-			break;
-		case PIXMAN_REPEAT_NORMAL:
-			REPEAT_FILL_STOPS(0, count - 2);
-			n_stops[0] = n_stops[count-2] - 1.0;
-
-			REPEAT_FILL_STOPS(count - 1, 1);
-			n_stops[count-1] = n_stops[1] + 1.0;
-			break;
-		case PIXMAN_REPEAT_REFLECT:
-			REPEAT_FILL_STOPS(0, 1);
-			n_stops[0] = -n_stops[1];
-
-			REPEAT_FILL_STOPS(count - 1, count - 2);
-			n_stops[count-1] = 1.0 + 1.0 - n_stops[count-2];
-			break;
-		case PIXMAN_REPEAT_PAD:
-			REPEAT_FILL_STOPS(0, 1);
-			n_stops[0] = -(float)INT_MAX;
-
-			REPEAT_FILL_STOPS(count - 1, count - 2);
-			n_stops[count-1] = (float)INT_MAX;
-			break;
+    default:
+    case PIXMAN_REPEAT_NONE:
+        stop_colors[0] = 0.0;   //R
+        stop_colors[1] = 0.0;   //G
+        stop_colors[2] = 0.0;   //B
+        stop_colors[3] = 0.0;   //Alpha
+        n_stops[0] = -(float) INT_MAX;  //should be small enough.
+
+        stop_colors[0 + (count - 1) * 4] = 0.0; //R
+        stop_colors[1 + (count - 1) * 4] = 0.0; //G
+        stop_colors[2 + (count - 1) * 4] = 0.0; //B
+        stop_colors[3 + (count - 1) * 4] = 0.0; //Alpha
+        n_stops[count - 1] = (float) INT_MAX;   //should be large enough.
+        break;
+    case PIXMAN_REPEAT_NORMAL:
+        REPEAT_FILL_STOPS(0, count - 2);
+        n_stops[0] = n_stops[count - 2] - 1.0;
+
+        REPEAT_FILL_STOPS(count - 1, 1);
+        n_stops[count - 1] = n_stops[1] + 1.0;
+        break;
+    case PIXMAN_REPEAT_REFLECT:
+        REPEAT_FILL_STOPS(0, 1);
+        n_stops[0] = -n_stops[1];
+
+        REPEAT_FILL_STOPS(count - 1, count - 2);
+        n_stops[count - 1] = 1.0 + 1.0 - n_stops[count - 2];
+        break;
+    case PIXMAN_REPEAT_PAD:
+        REPEAT_FILL_STOPS(0, 1);
+        n_stops[0] = -(float) INT_MAX;
+
+        REPEAT_FILL_STOPS(count - 1, count - 2);
+        n_stops[count - 1] = (float) INT_MAX;
+        break;
 #undef REPEAT_FILL_STOPS
-	}
+    }
 
-	for (i = 0; i < count; i++) {
-		DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n",
-		       i, n_stops[i],
-		       stop_colors[i*4], stop_colors[i*4+1],
-		       stop_colors[i*4+2], stop_colors[i*4+3]);
-	}
+    for (i = 0; i < count; i++) {
+        DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n",
+               i, n_stops[i],
+               stop_colors[i * 4], stop_colors[i * 4 + 1],
+               stop_colors[i * 4 + 2], stop_colors[i * 4 + 3]);
+    }
 
-	return count;
+    return count;
 }
 
 PicturePtr
 glamor_generate_radial_gradient_picture(ScreenPtr screen,
-                                         PicturePtr src_picture,
-                                         int x_source, int y_source,
-                                         int width, int height,
-                                         PictFormatShort format)
+                                        PicturePtr src_picture,
+                                        int x_source, int y_source,
+                                        int width, int height,
+                                        PictFormatShort format)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	PicturePtr dst_picture = NULL;
-	PixmapPtr pixmap = NULL;
-	GLint gradient_prog = 0;
-	int error;
-	float tex_vertices[8];
-	int stops_count = 0;
-	int count = 0;
-	GLfloat *stop_colors = NULL;
-	GLfloat *n_stops = NULL;
-	GLfloat xscale, yscale;
-	float vertices[8];
-	float transform_mat[3][3];
-	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
-	                                         {0.0, 1.0, 0.0},
-	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4];
-	GLfloat n_stops_st[RADIAL_SMALL_STOPS];
-	GLfloat A_value;
-	GLfloat cxy[4];
-	float c1x, c1y, c2x, c2y, r1, r2;
-
-	GLint transform_mat_uniform_location = 0;
-	GLint repeat_type_uniform_location = 0;
-	GLint n_stop_uniform_location = 0;
-	GLint stops_uniform_location = 0;
-	GLint stop_colors_uniform_location = 0;
-	GLint stop0_uniform_location = 0;
-	GLint stop1_uniform_location = 0;
-	GLint stop2_uniform_location = 0;
-	GLint stop3_uniform_location = 0;
-	GLint stop4_uniform_location = 0;
-	GLint stop5_uniform_location = 0;
-	GLint stop6_uniform_location = 0;
-	GLint stop7_uniform_location = 0;
-	GLint stop_color0_uniform_location = 0;
-	GLint stop_color1_uniform_location = 0;
-	GLint stop_color2_uniform_location = 0;
-	GLint stop_color3_uniform_location = 0;
-	GLint stop_color4_uniform_location = 0;
-	GLint stop_color5_uniform_location = 0;
-	GLint stop_color6_uniform_location = 0;
-	GLint stop_color7_uniform_location = 0;
-	GLint A_value_uniform_location = 0;
-	GLint c1_uniform_location = 0;
-	GLint r1_uniform_location = 0;
-	GLint c2_uniform_location = 0;
-	GLint r2_uniform_location = 0;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	/* Create a pixmap with VBO. */
-	pixmap = glamor_create_pixmap(screen,
-	                              width, height,
-	                              PIXMAN_FORMAT_DEPTH(format),
-	                              0);
-	if (!pixmap)
-		goto GRADIENT_FAIL;
-
-	dst_picture = CreatePicture(0, &pixmap->drawable,
-	                            PictureMatchFormat(screen,
-	                                 PIXMAN_FORMAT_DEPTH(format), format),
-	                            0, 0, serverClient, &error);
-
-	/* Release the reference, picture will hold the last one. */
-	glamor_destroy_pixmap(pixmap);
-
-	if (!dst_picture)
-		goto GRADIENT_FAIL;
-
-	ValidatePicture(dst_picture);
-
-	stops_count = src_picture->pSourcePict->radial.nstops + 2;
-
-	/* Because the max value of nstops is unkown, so create a program
-	   when nstops > LINEAR_LARGE_STOPS.*/
-	if (stops_count <= RADIAL_SMALL_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
-	} else if (stops_count <= RADIAL_LARGE_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
-	} else {
-		_glamor_create_radial_gradient_program(screen,
-						       src_picture->pSourcePict->linear.nstops + 2,
-						       1);
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
-	}
-
-	/* Bind all the uniform vars .*/
-	transform_mat_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	n_stop_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
-	A_value_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "A_value");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	c1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "c1");
-	r1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "r1");
-	c2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "c2");
-	r2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "r2");
-
-	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
-		stop0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
-		stop1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
-		stop2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
-		stop3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
-		stop4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
-		stop5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
-		stop6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
-		stop7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
-
-		stop_color0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
-		stop_color1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
-		stop_color2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
-		stop_color3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
-		stop_color4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
-		stop_color5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
-		stop_color6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
-		stop_color7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
-	} else {
-		stops_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stops");
-		stop_colors_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
-	}
-
-	dispatch->glUseProgram(gradient_prog);
-
-	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
-
-
-	if (src_picture->transform) {
-		_glamor_gradient_convert_trans_matrix(src_picture->transform,
-		                                      transform_mat,
-		                                      width, height, 0);
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &transform_mat[0][0]);
-	} else {
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &identity_mat[0][0]);
-	}
-
-	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
-	                                             &xscale, &yscale, x_source, y_source,
-	                                             vertices, tex_vertices, 0))
-		goto GRADIENT_FAIL;
-
-	/* Set all the stops and colors to shader. */
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		stop_colors = malloc(4 * stops_count * sizeof(float));
-		if (stop_colors == NULL) {
-			ErrorF("Failed to allocate stop_colors memory.\n");
-			goto GRADIENT_FAIL;
-		}
-
-		n_stops = malloc(stops_count * sizeof(float));
-		if (n_stops == NULL) {
-			ErrorF("Failed to allocate n_stops memory.\n");
-			goto GRADIENT_FAIL;
-		}
-	} else {
-		stop_colors = stop_colors_st;
-		n_stops = n_stops_st;
-	}
-
-	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
-	                                   stop_colors, n_stops);
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
-		int j = 0;
-		dispatch->glUniform4f(stop_color0_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color1_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color2_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color3_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color4_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color5_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color6_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color7_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-
-		j = 0;
-		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	} else {
-		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
-		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	}
-
-	c1x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
-	c1y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y);
-	c2x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x);
-	c2y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y);
-
-	r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius);
-	r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius);
-
-	glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, cxy);
-	dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
-	dispatch->glUniform1f(r1_uniform_location, r1);
-
-	glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, cxy);
-	dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
-	dispatch->glUniform1f(r2_uniform_location, r2);
-
-	A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1);
-	dispatch->glUniform1f(A_value_uniform_location, A_value);
-
-	DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
-	       c1x, c1y, r1, c2x, c2y, r2, A_value);
-
-	/* Now rendering. */
-	dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-	/* Do the clear logic.*/
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		free(n_stops);
-		free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-
-	glamor_put_dispatch(glamor_priv);
-	return dst_picture;
-
-GRADIENT_FAIL:
-	if (dst_picture) {
-		FreePicture(dst_picture, 0);
-	}
-
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		if (n_stops)
-			free(n_stops);
-		if (stop_colors)
-			free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return NULL;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    PicturePtr dst_picture = NULL;
+    PixmapPtr pixmap = NULL;
+    GLint gradient_prog = 0;
+    int error;
+    float tex_vertices[8];
+    int stops_count = 0;
+    int count = 0;
+    GLfloat *stop_colors = NULL;
+    GLfloat *n_stops = NULL;
+    GLfloat xscale, yscale;
+    float vertices[8];
+    float transform_mat[3][3];
+    static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
+    {0.0, 1.0, 0.0},
+    {0.0, 0.0, 1.0}
+    };
+    GLfloat stop_colors_st[RADIAL_SMALL_STOPS * 4];
+    GLfloat n_stops_st[RADIAL_SMALL_STOPS];
+    GLfloat A_value;
+    GLfloat cxy[4];
+    float c1x, c1y, c2x, c2y, r1, r2;
+
+    GLint transform_mat_uniform_location = 0;
+    GLint repeat_type_uniform_location = 0;
+    GLint n_stop_uniform_location = 0;
+    GLint stops_uniform_location = 0;
+    GLint stop_colors_uniform_location = 0;
+    GLint stop0_uniform_location = 0;
+    GLint stop1_uniform_location = 0;
+    GLint stop2_uniform_location = 0;
+    GLint stop3_uniform_location = 0;
+    GLint stop4_uniform_location = 0;
+    GLint stop5_uniform_location = 0;
+    GLint stop6_uniform_location = 0;
+    GLint stop7_uniform_location = 0;
+    GLint stop_color0_uniform_location = 0;
+    GLint stop_color1_uniform_location = 0;
+    GLint stop_color2_uniform_location = 0;
+    GLint stop_color3_uniform_location = 0;
+    GLint stop_color4_uniform_location = 0;
+    GLint stop_color5_uniform_location = 0;
+    GLint stop_color6_uniform_location = 0;
+    GLint stop_color7_uniform_location = 0;
+    GLint A_value_uniform_location = 0;
+    GLint c1_uniform_location = 0;
+    GLint r1_uniform_location = 0;
+    GLint c2_uniform_location = 0;
+    GLint r2_uniform_location = 0;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    /* Create a pixmap with VBO. */
+    pixmap = glamor_create_pixmap(screen,
+                                  width, height,
+                                  PIXMAN_FORMAT_DEPTH(format), 0);
+    if (!pixmap)
+        goto GRADIENT_FAIL;
+
+    dst_picture = CreatePicture(0, &pixmap->drawable,
+                                PictureMatchFormat(screen,
+                                                   PIXMAN_FORMAT_DEPTH(format),
+                                                   format), 0, 0, serverClient,
+                                &error);
+
+    /* Release the reference, picture will hold the last one. */
+    glamor_destroy_pixmap(pixmap);
+
+    if (!dst_picture)
+        goto GRADIENT_FAIL;
+
+    ValidatePicture(dst_picture);
+
+    stops_count = src_picture->pSourcePict->radial.nstops + 2;
+
+    /* Because the max value of nstops is unkown, so create a program
+       when nstops > LINEAR_LARGE_STOPS. */
+    if (stops_count <= RADIAL_SMALL_STOPS) {
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
+    }
+    else if (stops_count <= RADIAL_LARGE_STOPS) {
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
+    }
+    else {
+        _glamor_create_radial_gradient_program(screen,
+                                               src_picture->pSourcePict->linear.
+                                               nstops + 2, 1);
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
+    }
+
+    /* Bind all the uniform vars . */
+    transform_mat_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+    repeat_type_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+    n_stop_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+    A_value_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "A_value");
+    repeat_type_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+    c1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c1");
+    r1_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r1");
+    c2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "c2");
+    r2_uniform_location = dispatch->glGetUniformLocation(gradient_prog, "r2");
+
+    if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
+        stop0_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop0");
+        stop1_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop1");
+        stop2_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop2");
+        stop3_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop3");
+        stop4_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop4");
+        stop5_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop5");
+        stop6_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop6");
+        stop7_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+        stop_color0_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+        stop_color1_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+        stop_color2_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+        stop_color3_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+        stop_color4_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+        stop_color5_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+        stop_color6_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+        stop_color7_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+    }
+    else {
+        stops_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stops");
+        stop_colors_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+    }
+
+    dispatch->glUseProgram(gradient_prog);
+
+    dispatch->glUniform1i(repeat_type_uniform_location,
+                          src_picture->repeatType);
+
+    if (src_picture->transform) {
+        _glamor_gradient_convert_trans_matrix(src_picture->transform,
+                                              transform_mat, width, height, 0);
+        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+                                     1, 1, &transform_mat[0][0]);
+    }
+    else {
+        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+                                     1, 1, &identity_mat[0][0]);
+    }
+
+    if (!_glamor_gradient_set_pixmap_destination
+        (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
+         vertices, tex_vertices, 0))
+        goto GRADIENT_FAIL;
+
+    /* Set all the stops and colors to shader. */
+    if (stops_count > RADIAL_SMALL_STOPS) {
+        stop_colors = malloc(4 * stops_count * sizeof(float));
+        if (stop_colors == NULL) {
+            ErrorF("Failed to allocate stop_colors memory.\n");
+            goto GRADIENT_FAIL;
+        }
+
+        n_stops = malloc(stops_count * sizeof(float));
+        if (n_stops == NULL) {
+            ErrorF("Failed to allocate n_stops memory.\n");
+            goto GRADIENT_FAIL;
+        }
+    }
+    else {
+        stop_colors = stop_colors_st;
+        n_stops = n_stops_st;
+    }
+
+    count =
+        _glamor_gradient_set_stops(src_picture,
+                                   &src_picture->pSourcePict->gradient,
+                                   stop_colors, n_stops);
+
+    if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
+        int j = 0;
+
+        dispatch->glUniform4f(stop_color0_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color1_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color2_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color3_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color4_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color5_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color6_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color7_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+
+        j = 0;
+        dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+        dispatch->glUniform1i(n_stop_uniform_location, count);
+    }
+    else {
+        dispatch->glUniform4fv(stop_colors_uniform_location, count,
+                               stop_colors);
+        dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+        dispatch->glUniform1i(n_stop_uniform_location, count);
+    }
+
+    c1x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
+    c1y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y);
+    c2x = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x);
+    c2y = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y);
+
+    r1 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.
+                                        radius);
+    r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.
+                                        radius);
+
+    glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted,
+                             cxy);
+    dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
+    dispatch->glUniform1f(r1_uniform_location, r1);
+
+    glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted,
+                             cxy);
+    dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
+    dispatch->glUniform1f(r2_uniform_location, r2);
+
+    A_value =
+        (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 -
+                                                                 r1) * (r2 -
+                                                                        r1);
+    dispatch->glUniform1f(A_value_uniform_location, A_value);
+
+    DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
+           c1x, c1y, r1, c2x, c2y, r2, A_value);
+
+    /* Now rendering. */
+    dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+    /* Do the clear logic. */
+    if (stops_count > RADIAL_SMALL_STOPS) {
+        free(n_stops);
+        free(stop_colors);
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
+
+    glamor_put_dispatch(glamor_priv);
+    return dst_picture;
+
+ GRADIENT_FAIL:
+    if (dst_picture) {
+        FreePicture(dst_picture, 0);
+    }
+
+    if (stops_count > RADIAL_SMALL_STOPS) {
+        if (n_stops)
+            free(n_stops);
+        if (stop_colors)
+            free(stop_colors);
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    return NULL;
 }
 
 PicturePtr
 glamor_generate_linear_gradient_picture(ScreenPtr screen,
-                                         PicturePtr src_picture,
-                                         int x_source, int y_source,
-                                         int width, int height,
-                                         PictFormatShort format)
+                                        PicturePtr src_picture,
+                                        int x_source, int y_source,
+                                        int width, int height,
+                                        PictFormatShort format)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	PicturePtr dst_picture = NULL;
-	PixmapPtr pixmap = NULL;
-	GLint gradient_prog = 0;
-	int error;
-	float pt_distance;
-	float p1_distance;
-	GLfloat cos_val;
-	float tex_vertices[8];
-	int stops_count = 0;
-	GLfloat *stop_colors = NULL;
-	GLfloat *n_stops = NULL;
-	int count = 0;
-	float slope;
-	GLfloat xscale, yscale;
-	GLfloat pt1[2], pt2[2];
-	float vertices[8];
-	float transform_mat[3][3];
-	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
-	                                         {0.0, 1.0, 0.0},
-	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4];
-	GLfloat n_stops_st[LINEAR_SMALL_STOPS];
-
-	GLint transform_mat_uniform_location = 0;
-	GLint n_stop_uniform_location = 0;
-	GLint stops_uniform_location = 0;
-	GLint stop0_uniform_location = 0;
-	GLint stop1_uniform_location = 0;
-	GLint stop2_uniform_location = 0;
-	GLint stop3_uniform_location = 0;
-	GLint stop4_uniform_location = 0;
-	GLint stop5_uniform_location = 0;
-	GLint stop6_uniform_location = 0;
-	GLint stop7_uniform_location = 0;
-	GLint stop_colors_uniform_location = 0;
-	GLint stop_color0_uniform_location = 0;
-	GLint stop_color1_uniform_location = 0;
-	GLint stop_color2_uniform_location = 0;
-	GLint stop_color3_uniform_location = 0;
-	GLint stop_color4_uniform_location = 0;
-	GLint stop_color5_uniform_location = 0;
-	GLint stop_color6_uniform_location = 0;
-	GLint stop_color7_uniform_location = 0;
-	GLint pt_slope_uniform_location = 0;
-	GLint repeat_type_uniform_location = 0;
-	GLint hor_ver_uniform_location = 0;
-	GLint cos_val_uniform_location = 0;
-	GLint p1_distance_uniform_location = 0;
-	GLint pt_distance_uniform_location = 0;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	/* Create a pixmap with VBO. */
-	pixmap = glamor_create_pixmap(screen,
-	                              width, height,
-	                              PIXMAN_FORMAT_DEPTH(format),
-	                              0);
-
-	if (!pixmap)
-		goto GRADIENT_FAIL;
-
-	dst_picture = CreatePicture(0, &pixmap->drawable,
-	                            PictureMatchFormat(screen,
-	                                    PIXMAN_FORMAT_DEPTH(format), format),
-	                            0, 0, serverClient, &error);
-
-	/* Release the reference, picture will hold the last one. */
-	glamor_destroy_pixmap(pixmap);
-
-	if (!dst_picture)
-		goto GRADIENT_FAIL;
-
-	ValidatePicture(dst_picture);
-
-	stops_count = src_picture->pSourcePict->linear.nstops + 2;
-
-	/* Because the max value of nstops is unkown, so create a program
-	   when nstops > LINEAR_LARGE_STOPS.*/
-	if (stops_count <= LINEAR_SMALL_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
-	} else if (stops_count <= LINEAR_LARGE_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
-	} else {
-		_glamor_create_linear_gradient_program(screen,
-		        src_picture->pSourcePict->linear.nstops + 2, 1);
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
-	}
-
-	/* Bind all the uniform vars .*/
-	n_stop_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
-	pt_slope_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	hor_ver_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
-	transform_mat_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
-	cos_val_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "cos_val");
-	p1_distance_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
-	pt_distance_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
-		stop0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
-		stop1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
-		stop2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
-		stop3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
-		stop4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
-		stop5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
-		stop6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
-		stop7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
-
-		stop_color0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
-		stop_color1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
-		stop_color2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
-		stop_color3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
-		stop_color4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
-		stop_color5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
-		stop_color6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
-		stop_color7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
-	} else {
-		stops_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stops");
-		stop_colors_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
-	}
-
-	dispatch->glUseProgram(gradient_prog);
-
-	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
-
-	/* set the transform matrix. */
-	if (src_picture->transform) {
-		_glamor_gradient_convert_trans_matrix(src_picture->transform,
-		                                      transform_mat,
-		                                      width, height, 1);
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &transform_mat[0][0]);
-	} else {
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &identity_mat[0][0]);
-	}
-
-	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
-	                                             &xscale, &yscale, x_source, y_source,
-	                                             vertices, tex_vertices, 1))
-		goto GRADIENT_FAIL;
-
-	/* Normalize the PTs. */
-	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
-	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
-	                        glamor_priv->yInverted,
-	                        pt1);
-	DEBUGF("pt1:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
-	       pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), pt1[0], pt1[1]);
-
-	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
-	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
-	                        glamor_priv->yInverted,
-	                        pt2);
-	DEBUGF("pt2:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
-	       pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), pt2[0], pt2[1]);
-
-	/* Set all the stops and colors to shader. */
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		stop_colors = malloc(4 * stops_count * sizeof(float));
-		if (stop_colors == NULL) {
-			ErrorF("Failed to allocate stop_colors memory.\n");
-			goto GRADIENT_FAIL;
-		}
-
-		n_stops = malloc(stops_count * sizeof(float));
-		if (n_stops == NULL) {
-			ErrorF("Failed to allocate n_stops memory.\n");
-			goto GRADIENT_FAIL;
-		}
-	} else {
-		stop_colors = stop_colors_st;
-		n_stops = n_stops_st;
-	}
-
-	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
-	                                   stop_colors, n_stops);
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
-		int j = 0;
-		dispatch->glUniform4f(stop_color0_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color1_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color2_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color3_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color4_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color5_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color6_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color7_uniform_location,
-		                      stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-
-		j = 0;
-		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	} else {
-		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
-		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	}
-
-	if (src_picture->pSourcePict->linear.p2.y ==
-	              src_picture->pSourcePict->linear.p1.y) { // The horizontal case.
-		dispatch->glUniform1i(hor_ver_uniform_location, 1);
-		DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n",
-		       pt1[1], pt2[1]);
-
-		p1_distance = pt1[0];
-		pt_distance = (pt2[0] - p1_distance);
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	} else {
-		/* The slope need to compute here. In shader, the viewport set will change
-		   the orginal slope and the slope which is vertical to it will not be correct.*/
-		slope = - (float)(src_picture->pSourcePict->linear.p2.x
-				  - src_picture->pSourcePict->linear.p1.x) /
-		          (float)(src_picture->pSourcePict->linear.p2.y
-				  - src_picture->pSourcePict->linear.p1.y);
-		slope = slope * yscale / xscale;
-		dispatch->glUniform1f(pt_slope_uniform_location, slope);
-		dispatch->glUniform1i(hor_ver_uniform_location, 0);
-
-		cos_val = sqrt(1.0 / (slope * slope + 1.0));
-		dispatch->glUniform1f(cos_val_uniform_location, cos_val);
-
-		p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
-		pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	}
-
-	/* Now rendering. */
-	dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-	/* Do the clear logic.*/
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		free(n_stops);
-		free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-
-	glamor_put_dispatch(glamor_priv);
-	return dst_picture;
-
-GRADIENT_FAIL:
-	if (dst_picture) {
-		FreePicture(dst_picture, 0);
-	}
-
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		if (n_stops)
-			free(n_stops);
-		if (stop_colors)
-			free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return NULL;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    PicturePtr dst_picture = NULL;
+    PixmapPtr pixmap = NULL;
+    GLint gradient_prog = 0;
+    int error;
+    float pt_distance;
+    float p1_distance;
+    GLfloat cos_val;
+    float tex_vertices[8];
+    int stops_count = 0;
+    GLfloat *stop_colors = NULL;
+    GLfloat *n_stops = NULL;
+    int count = 0;
+    float slope;
+    GLfloat xscale, yscale;
+    GLfloat pt1[2], pt2[2];
+    float vertices[8];
+    float transform_mat[3][3];
+    static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
+    {0.0, 1.0, 0.0},
+    {0.0, 0.0, 1.0}
+    };
+    GLfloat stop_colors_st[LINEAR_SMALL_STOPS * 4];
+    GLfloat n_stops_st[LINEAR_SMALL_STOPS];
+
+    GLint transform_mat_uniform_location = 0;
+    GLint n_stop_uniform_location = 0;
+    GLint stops_uniform_location = 0;
+    GLint stop0_uniform_location = 0;
+    GLint stop1_uniform_location = 0;
+    GLint stop2_uniform_location = 0;
+    GLint stop3_uniform_location = 0;
+    GLint stop4_uniform_location = 0;
+    GLint stop5_uniform_location = 0;
+    GLint stop6_uniform_location = 0;
+    GLint stop7_uniform_location = 0;
+    GLint stop_colors_uniform_location = 0;
+    GLint stop_color0_uniform_location = 0;
+    GLint stop_color1_uniform_location = 0;
+    GLint stop_color2_uniform_location = 0;
+    GLint stop_color3_uniform_location = 0;
+    GLint stop_color4_uniform_location = 0;
+    GLint stop_color5_uniform_location = 0;
+    GLint stop_color6_uniform_location = 0;
+    GLint stop_color7_uniform_location = 0;
+    GLint pt_slope_uniform_location = 0;
+    GLint repeat_type_uniform_location = 0;
+    GLint hor_ver_uniform_location = 0;
+    GLint cos_val_uniform_location = 0;
+    GLint p1_distance_uniform_location = 0;
+    GLint pt_distance_uniform_location = 0;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    /* Create a pixmap with VBO. */
+    pixmap = glamor_create_pixmap(screen,
+                                  width, height,
+                                  PIXMAN_FORMAT_DEPTH(format), 0);
+
+    if (!pixmap)
+        goto GRADIENT_FAIL;
+
+    dst_picture = CreatePicture(0, &pixmap->drawable,
+                                PictureMatchFormat(screen,
+                                                   PIXMAN_FORMAT_DEPTH(format),
+                                                   format), 0, 0, serverClient,
+                                &error);
+
+    /* Release the reference, picture will hold the last one. */
+    glamor_destroy_pixmap(pixmap);
+
+    if (!dst_picture)
+        goto GRADIENT_FAIL;
+
+    ValidatePicture(dst_picture);
+
+    stops_count = src_picture->pSourcePict->linear.nstops + 2;
+
+    /* Because the max value of nstops is unkown, so create a program
+       when nstops > LINEAR_LARGE_STOPS. */
+    if (stops_count <= LINEAR_SMALL_STOPS) {
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
+    }
+    else if (stops_count <= LINEAR_LARGE_STOPS) {
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
+    }
+    else {
+        _glamor_create_linear_gradient_program(screen,
+                                               src_picture->pSourcePict->linear.
+                                               nstops + 2, 1);
+        gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
+    }
+
+    /* Bind all the uniform vars . */
+    n_stop_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+    pt_slope_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
+    repeat_type_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+    hor_ver_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
+    transform_mat_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+    cos_val_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "cos_val");
+    p1_distance_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
+    pt_distance_uniform_location =
+        dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
+
+    if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
+        stop0_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop0");
+        stop1_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop1");
+        stop2_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop2");
+        stop3_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop3");
+        stop4_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop4");
+        stop5_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop5");
+        stop6_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop6");
+        stop7_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+        stop_color0_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+        stop_color1_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+        stop_color2_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+        stop_color3_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+        stop_color4_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+        stop_color5_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+        stop_color6_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+        stop_color7_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+    }
+    else {
+        stops_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stops");
+        stop_colors_uniform_location =
+            dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+    }
+
+    dispatch->glUseProgram(gradient_prog);
+
+    dispatch->glUniform1i(repeat_type_uniform_location,
+                          src_picture->repeatType);
+
+    /* set the transform matrix. */
+    if (src_picture->transform) {
+        _glamor_gradient_convert_trans_matrix(src_picture->transform,
+                                              transform_mat, width, height, 1);
+        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+                                     1, 1, &transform_mat[0][0]);
+    }
+    else {
+        dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+                                     1, 1, &identity_mat[0][0]);
+    }
+
+    if (!_glamor_gradient_set_pixmap_destination
+        (screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
+         vertices, tex_vertices, 1))
+        goto GRADIENT_FAIL;
+
+    /* Normalize the PTs. */
+    glamor_set_normalize_pt(xscale, yscale,
+                            pixman_fixed_to_double(src_picture->pSourcePict->
+                                                   linear.p1.x),
+                            pixman_fixed_to_double(src_picture->pSourcePict->
+                                                   linear.p1.y),
+                            glamor_priv->yInverted, pt1);
+    DEBUGF("pt1:(%f, %f) ---> (%f %f)\n",
+           pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
+           pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
+           pt1[0], pt1[1]);
+
+    glamor_set_normalize_pt(xscale, yscale,
+                            pixman_fixed_to_double(src_picture->pSourcePict->
+                                                   linear.p2.x),
+                            pixman_fixed_to_double(src_picture->pSourcePict->
+                                                   linear.p2.y),
+                            glamor_priv->yInverted, pt2);
+    DEBUGF("pt2:(%f, %f) ---> (%f %f)\n",
+           pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
+           pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
+           pt2[0], pt2[1]);
+
+    /* Set all the stops and colors to shader. */
+    if (stops_count > LINEAR_SMALL_STOPS) {
+        stop_colors = malloc(4 * stops_count * sizeof(float));
+        if (stop_colors == NULL) {
+            ErrorF("Failed to allocate stop_colors memory.\n");
+            goto GRADIENT_FAIL;
+        }
+
+        n_stops = malloc(stops_count * sizeof(float));
+        if (n_stops == NULL) {
+            ErrorF("Failed to allocate n_stops memory.\n");
+            goto GRADIENT_FAIL;
+        }
+    }
+    else {
+        stop_colors = stop_colors_st;
+        n_stops = n_stops_st;
+    }
+
+    count =
+        _glamor_gradient_set_stops(src_picture,
+                                   &src_picture->pSourcePict->gradient,
+                                   stop_colors, n_stops);
+
+    if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
+        int j = 0;
+
+        dispatch->glUniform4f(stop_color0_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color1_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color2_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color3_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color4_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color5_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color6_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+        j++;
+        dispatch->glUniform4f(stop_color7_uniform_location,
+                              stop_colors[4 * j + 0], stop_colors[4 * j + 1],
+                              stop_colors[4 * j + 2], stop_colors[4 * j + 3]);
+
+        j = 0;
+        dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+        dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+
+        dispatch->glUniform1i(n_stop_uniform_location, count);
+    }
+    else {
+        dispatch->glUniform4fv(stop_colors_uniform_location, count,
+                               stop_colors);
+        dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+        dispatch->glUniform1i(n_stop_uniform_location, count);
+    }
+
+    if (src_picture->pSourcePict->linear.p2.y == src_picture->pSourcePict->linear.p1.y) {       // The horizontal case.
+        dispatch->glUniform1i(hor_ver_uniform_location, 1);
+        DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n",
+               pt1[1], pt2[1]);
+
+        p1_distance = pt1[0];
+        pt_distance = (pt2[0] - p1_distance);
+        dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+        dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+    }
+    else {
+        /* The slope need to compute here. In shader, the viewport set will change
+           the orginal slope and the slope which is vertical to it will not be correct. */
+        slope = -(float) (src_picture->pSourcePict->linear.p2.x
+                          - src_picture->pSourcePict->linear.p1.x) /
+            (float) (src_picture->pSourcePict->linear.p2.y
+                     - src_picture->pSourcePict->linear.p1.y);
+        slope = slope * yscale / xscale;
+        dispatch->glUniform1f(pt_slope_uniform_location, slope);
+        dispatch->glUniform1i(hor_ver_uniform_location, 0);
+
+        cos_val = sqrt(1.0 / (slope * slope + 1.0));
+        dispatch->glUniform1f(cos_val_uniform_location, cos_val);
+
+        p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
+        pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
+        dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+        dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+    }
+
+    /* Now rendering. */
+    dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+    /* Do the clear logic. */
+    if (stops_count > LINEAR_SMALL_STOPS) {
+        free(n_stops);
+        free(stop_colors);
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
+
+    glamor_put_dispatch(glamor_priv);
+    return dst_picture;
+
+ GRADIENT_FAIL:
+    if (dst_picture) {
+        FreePicture(dst_picture, 0);
+    }
+
+    if (stops_count > LINEAR_SMALL_STOPS) {
+        if (n_stops)
+            free(n_stops);
+        if (stop_colors)
+            free(stop_colors);
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    return NULL;
 }
 
-#endif /* End of GLAMOR_GRADIENT_SHADER */
+#endif                          /* End of GLAMOR_GRADIENT_SHADER */
 
-#endif /* End of RENDER */
+#endif                          /* End of RENDER */
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 91ee8f2..b9c140b 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -17,117 +17,117 @@
 
 static glamor_pixmap_clipped_regions *
 __glamor_compute_clipped_regions(int block_w,
-			       int block_h,
-			       int block_stride,
-			       int x, int y,
-			       int w, int h,
-                               RegionPtr region,
-                               int *n_region,
-			       int reverse,
-			       int upsidedown)
+                                 int block_h,
+                                 int block_stride,
+                                 int x, int y,
+                                 int w, int h,
+                                 RegionPtr region,
+                                 int *n_region, int reverse, int upsidedown)
 {
-	glamor_pixmap_clipped_regions * clipped_regions;
-	BoxPtr extent;
-	int start_x, start_y, end_x, end_y;
-	int start_block_x, start_block_y;
-	int end_block_x, end_block_y;
-	int loop_start_block_x, loop_start_block_y;
-	int loop_end_block_x, loop_end_block_y;
-	int loop_block_stride;
-	int i, j, delta_i, delta_j;
-	RegionRec temp_region;
-	RegionPtr current_region;
-	int block_idx;
-	int k = 0;
-	int temp_block_idx;
-
-	extent = RegionExtents(region);
-	start_x = MAX(x, extent->x1);
-	start_y = MAX(y, extent->y1);
-	end_x = MIN(x + w, extent->x2);
-	end_y = MIN(y + h, extent->y2);
-
-	DEBUGF("start compute clipped regions:\n");
-	DEBUGF("block w %d h %d  x %d y %d w %d h %d, block_stride %d \n",
-		block_w, block_h, x, y, w, h, block_stride);
-	DEBUGRegionPrint(region);
-
-	DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, end_x, end_y);
-
-	if (start_x >= end_x || start_y >= end_y) {
-		*n_region = 0;
-		return NULL;
-	}
-
-	start_block_x = (start_x  - x)/ block_w;
-	start_block_y = (start_y - y)/ block_h;
-	end_block_x = (end_x - x)/ block_w;
-	end_block_y = (end_y - y)/ block_h;
-
-	clipped_regions = calloc((end_block_x - start_block_x + 1)
-				 * (end_block_y - start_block_y + 1),
-				 sizeof(*clipped_regions));
-
-
-	DEBUGF("startx %d starty %d endx %d endy %d \n",
-		start_x, start_y, end_x, end_y);
-	DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x);
-	DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y);
-
-	if (!reverse) {
-		loop_start_block_x = start_block_x;
-		loop_end_block_x = end_block_x + 1;
-		delta_i = 1;
-	} else {
-		loop_start_block_x = end_block_x;
-		loop_end_block_x = start_block_x - 1;
-		delta_i = -1;
-	}
-
-	if (!upsidedown) {
-		loop_start_block_y = start_block_y;
-		loop_end_block_y = end_block_y + 1;
-		delta_j = 1;
-	} else {
-		loop_start_block_y = end_block_y;
-		loop_end_block_y = start_block_y - 1;
-		delta_j = -1;
-	}
-
-	loop_block_stride = delta_j * block_stride;
-	block_idx = (loop_start_block_y - delta_j) * block_stride;
-
-	for(j = loop_start_block_y; j != loop_end_block_y; j += delta_j)
-	{
-		block_idx += loop_block_stride;
-		temp_block_idx = block_idx + loop_start_block_x;
-		for(i = loop_start_block_x;
-		    i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i)
-		{
-			BoxRec temp_box;
-			temp_box.x1 = x + i * block_w;
-			temp_box.y1 = y + j * block_h;
-			temp_box.x2 = MIN(temp_box.x1 + block_w, end_x);
-			temp_box.y2 = MIN(temp_box.y1 + block_h, end_y);
-			RegionInitBoxes(&temp_region, &temp_box, 1);
-			DEBUGF("block idx %d \n",temp_block_idx);
-			DEBUGRegionPrint(&temp_region);
-			current_region = RegionCreate(NULL, 4);
-			RegionIntersect(current_region, &temp_region, region);
-			DEBUGF("i %d j %d  region: \n",i ,j);
-			DEBUGRegionPrint(current_region);
-			if (RegionNumRects(current_region)) {
-				clipped_regions[k].region = current_region;
-				clipped_regions[k].block_idx = temp_block_idx;
-				k++;
-			} else
-				RegionDestroy(current_region);
-			RegionUninit(&temp_region);
-		}
-	}
-
-	*n_region = k;
-	return clipped_regions;
+    glamor_pixmap_clipped_regions *clipped_regions;
+    BoxPtr extent;
+    int start_x, start_y, end_x, end_y;
+    int start_block_x, start_block_y;
+    int end_block_x, end_block_y;
+    int loop_start_block_x, loop_start_block_y;
+    int loop_end_block_x, loop_end_block_y;
+    int loop_block_stride;
+    int i, j, delta_i, delta_j;
+    RegionRec temp_region;
+    RegionPtr current_region;
+    int block_idx;
+    int k = 0;
+    int temp_block_idx;
+
+    extent = RegionExtents(region);
+    start_x = MAX(x, extent->x1);
+    start_y = MAX(y, extent->y1);
+    end_x = MIN(x + w, extent->x2);
+    end_y = MIN(y + h, extent->y2);
+
+    DEBUGF("start compute clipped regions:\n");
+    DEBUGF("block w %d h %d  x %d y %d w %d h %d, block_stride %d \n",
+           block_w, block_h, x, y, w, h, block_stride);
+    DEBUGRegionPrint(region);
+
+    DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y,
+           end_x, end_y);
+
+    if (start_x >= end_x || start_y >= end_y) {
+        *n_region = 0;
+        return NULL;
+    }
+
+    start_block_x = (start_x - x) / block_w;
+    start_block_y = (start_y - y) / block_h;
+    end_block_x = (end_x - x) / block_w;
+    end_block_y = (end_y - y) / block_h;
+
+    clipped_regions = calloc((end_block_x - start_block_x + 1)
+                             * (end_block_y - start_block_y + 1),
+                             sizeof(*clipped_regions));
+
+    DEBUGF("startx %d starty %d endx %d endy %d \n",
+           start_x, start_y, end_x, end_y);
+    DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x);
+    DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y);
+
+    if (!reverse) {
+        loop_start_block_x = start_block_x;
+        loop_end_block_x = end_block_x + 1;
+        delta_i = 1;
+    }
+    else {
+        loop_start_block_x = end_block_x;
+        loop_end_block_x = start_block_x - 1;
+        delta_i = -1;
+    }
+
+    if (!upsidedown) {
+        loop_start_block_y = start_block_y;
+        loop_end_block_y = end_block_y + 1;
+        delta_j = 1;
+    }
+    else {
+        loop_start_block_y = end_block_y;
+        loop_end_block_y = start_block_y - 1;
+        delta_j = -1;
+    }
+
+    loop_block_stride = delta_j * block_stride;
+    block_idx = (loop_start_block_y - delta_j) * block_stride;
+
+    for (j = loop_start_block_y; j != loop_end_block_y; j += delta_j) {
+        block_idx += loop_block_stride;
+        temp_block_idx = block_idx + loop_start_block_x;
+        for (i = loop_start_block_x;
+             i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i) {
+            BoxRec temp_box;
+
+            temp_box.x1 = x + i * block_w;
+            temp_box.y1 = y + j * block_h;
+            temp_box.x2 = MIN(temp_box.x1 + block_w, end_x);
+            temp_box.y2 = MIN(temp_box.y1 + block_h, end_y);
+            RegionInitBoxes(&temp_region, &temp_box, 1);
+            DEBUGF("block idx %d \n", temp_block_idx);
+            DEBUGRegionPrint(&temp_region);
+            current_region = RegionCreate(NULL, 4);
+            RegionIntersect(current_region, &temp_region, region);
+            DEBUGF("i %d j %d  region: \n", i, j);
+            DEBUGRegionPrint(current_region);
+            if (RegionNumRects(current_region)) {
+                clipped_regions[k].region = current_region;
+                clipped_regions[k].block_idx = temp_block_idx;
+                k++;
+            }
+            else
+                RegionDestroy(current_region);
+            RegionUninit(&temp_region);
+        }
+    }
+
+    *n_region = k;
+    return clipped_regions;
 }
 
 /**
@@ -144,83 +144,88 @@ __glamor_compute_clipped_regions(int block_w,
  */
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
-				   RegionPtr region,
-				   int *n_region,
-				   int inner_block_w, int inner_block_h,
-				   int reverse, int upsidedown)
+glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv,
+                                   RegionPtr region,
+                                   int *n_region,
+                                   int inner_block_w, int inner_block_h,
+                                   int reverse, int upsidedown)
 {
-	glamor_pixmap_clipped_regions * clipped_regions, *inner_regions, *result_regions;
-	int i, j, x, y, k, inner_n_regions;
-	int width, height;
-	glamor_pixmap_private_large_t *priv;
-	priv = &pixmap_priv->large;
-
-	DEBUGF("ext called \n");
-
-	if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-		clipped_regions = calloc(1, sizeof(*clipped_regions));
-		if (clipped_regions == NULL) {
-			*n_region = 0;
-			return NULL;
-		}
-		clipped_regions[0].region = RegionCreate(NULL, 1);
-		clipped_regions[0].block_idx = 0;
-		RegionCopy(clipped_regions[0].region, region);
-		*n_region = 1;
-		priv->block_w = priv->base.pixmap->drawable.width;
-		priv->block_h = priv->base.pixmap->drawable.height;
-		priv->box_array = &priv->box;
-		priv->box.x1 = priv->box.y1 = 0;
-		priv->box.x2 = priv->block_w;
-		priv->box.y2 = priv->block_h;
-	} else {
-		clipped_regions =  __glamor_compute_clipped_regions(priv->block_w,
-					priv->block_h,
-					priv->block_wcnt,
-					0, 0,
-					priv->base.pixmap->drawable.width,
-					priv->base.pixmap->drawable.height,
-					region, n_region, reverse, upsidedown
-					);
-
-		if (clipped_regions == NULL) {
-			*n_region = 0;
-			return NULL;
-		}
-	}
-	if (inner_block_w >= priv->block_w
-	    && inner_block_h >= priv->block_h)
-		return clipped_regions;
-	result_regions = calloc(*n_region
-				* ((priv->block_w + inner_block_w - 1)/inner_block_w)
-				* ((priv->block_h + inner_block_h - 1)/ inner_block_h),
-				sizeof(*result_regions));
-	k = 0;
-	for(i = 0; i < *n_region; i++)
-	{
-		x = priv->box_array[clipped_regions[i].block_idx].x1;
-		y = priv->box_array[clipped_regions[i].block_idx].y1;
-		width = priv->box_array[clipped_regions[i].block_idx].x2 - x;
-		height = priv->box_array[clipped_regions[i].block_idx].y2 - y;
-		inner_regions = __glamor_compute_clipped_regions(inner_block_w,
-					inner_block_h,
-					0, x, y,
-					width,
-					height,
-					clipped_regions[i].region,
-					&inner_n_regions, reverse, upsidedown);
-		for(j = 0; j < inner_n_regions; j++)
-		{
-			result_regions[k].region = inner_regions[j].region;
-			result_regions[k].block_idx = clipped_regions[i].block_idx;
-			k++;
-		}
-		free(inner_regions);
-	}
-	*n_region = k;
-	free(clipped_regions);
-	return result_regions;
+    glamor_pixmap_clipped_regions *clipped_regions, *inner_regions,
+        *result_regions;
+    int i, j, x, y, k, inner_n_regions;
+    int width, height;
+    glamor_pixmap_private_large_t *priv;
+
+    priv = &pixmap_priv->large;
+
+    DEBUGF("ext called \n");
+
+    if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+        clipped_regions = calloc(1, sizeof(*clipped_regions));
+        if (clipped_regions == NULL) {
+            *n_region = 0;
+            return NULL;
+        }
+        clipped_regions[0].region = RegionCreate(NULL, 1);
+        clipped_regions[0].block_idx = 0;
+        RegionCopy(clipped_regions[0].region, region);
+        *n_region = 1;
+        priv->block_w = priv->base.pixmap->drawable.width;
+        priv->block_h = priv->base.pixmap->drawable.height;
+        priv->box_array = &priv->box;
+        priv->box.x1 = priv->box.y1 = 0;
+        priv->box.x2 = priv->block_w;
+        priv->box.y2 = priv->block_h;
+    }
+    else {
+        clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
+                                                           priv->block_h,
+                                                           priv->block_wcnt,
+                                                           0, 0,
+                                                           priv->base.pixmap->
+                                                           drawable.width,
+                                                           priv->base.pixmap->
+                                                           drawable.height,
+                                                           region, n_region,
+                                                           reverse, upsidedown);
+
+        if (clipped_regions == NULL) {
+            *n_region = 0;
+            return NULL;
+        }
+    }
+    if (inner_block_w >= priv->block_w && inner_block_h >= priv->block_h)
+        return clipped_regions;
+    result_regions = calloc(*n_region
+                            * ((priv->block_w + inner_block_w - 1) /
+                               inner_block_w)
+                            * ((priv->block_h + inner_block_h - 1) /
+                               inner_block_h), sizeof(*result_regions));
+    k = 0;
+    for (i = 0; i < *n_region; i++) {
+        x = priv->box_array[clipped_regions[i].block_idx].x1;
+        y = priv->box_array[clipped_regions[i].block_idx].y1;
+        width = priv->box_array[clipped_regions[i].block_idx].x2 - x;
+        height = priv->box_array[clipped_regions[i].block_idx].y2 - y;
+        inner_regions = __glamor_compute_clipped_regions(inner_block_w,
+                                                         inner_block_h,
+                                                         0, x, y,
+                                                         width,
+                                                         height,
+                                                         clipped_regions[i].
+                                                         region,
+                                                         &inner_n_regions,
+                                                         reverse, upsidedown);
+        for (j = 0; j < inner_n_regions; j++) {
+            result_regions[k].region = inner_regions[j].region;
+            result_regions[k].block_idx = clipped_regions[i].block_idx;
+            k++;
+        }
+        free(inner_regions);
+    }
+    *n_region = k;
+    free(clipped_regions);
+    return result_regions;
 }
 
 /*
@@ -232,35 +237,36 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 static RegionPtr
 _glamor_convert_pad_region(RegionPtr region, int w, int h)
 {
-	RegionPtr pad_region;
-	int nrect;
-	BoxPtr box;
-	int overlap;
-
-	nrect = RegionNumRects(region);
-	box = RegionRects(region);
-	pad_region = RegionCreate(NULL, 4);
-	if (pad_region == NULL)
-		return NULL;
-	while(nrect--) {
-		BoxRec pad_box;
-		RegionRec temp_region;
-		pad_box = *box;
-		if (pad_box.x1 < 0 && pad_box.x2 <= 0)
-			pad_box.x2 = 1;
-		else if (pad_box.x1 >= w && pad_box.x2 > w)
-			pad_box.x1 = w - 1;
-		if (pad_box.y1 < 0 && pad_box.y2 <=0)
-			pad_box.y2 = 1;
-		else if (pad_box.y1 >= h && pad_box.y2 > h)
-			pad_box.y1 = h - 1;
-		RegionInitBoxes(&temp_region, &pad_box, 1);
-		RegionAppend(pad_region, &temp_region);
-		RegionUninit(&temp_region);
-		box++;
-	}
-	RegionValidate(pad_region, &overlap);
-	return pad_region;
+    RegionPtr pad_region;
+    int nrect;
+    BoxPtr box;
+    int overlap;
+
+    nrect = RegionNumRects(region);
+    box = RegionRects(region);
+    pad_region = RegionCreate(NULL, 4);
+    if (pad_region == NULL)
+        return NULL;
+    while (nrect--) {
+        BoxRec pad_box;
+        RegionRec temp_region;
+
+        pad_box = *box;
+        if (pad_box.x1 < 0 && pad_box.x2 <= 0)
+            pad_box.x2 = 1;
+        else if (pad_box.x1 >= w && pad_box.x2 > w)
+            pad_box.x1 = w - 1;
+        if (pad_box.y1 < 0 && pad_box.y2 <= 0)
+            pad_box.y2 = 1;
+        else if (pad_box.y1 >= h && pad_box.y2 > h)
+            pad_box.y1 = h - 1;
+        RegionInitBoxes(&temp_region, &pad_box, 1);
+        RegionAppend(pad_region, &temp_region);
+        RegionUninit(&temp_region);
+        box++;
+    }
+    RegionValidate(pad_region, &overlap);
+    return pad_region;
 }
 
 /*
@@ -278,32 +284,35 @@ _glamor_convert_pad_region(RegionPtr region, int w, int h)
 static void
 _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
 {
-	int odd1, odd2;
-	int c1, c2;
-
-	if (*xy2 - *xy1 > wh) {
-		*xy1 = 0;
-		*xy2 = wh;
-		return;
-	}
-	modulus(*xy1, wh, c1);
-	odd1 = ((*xy1 - c1) / wh) & 0x1;
-	modulus(*xy2, wh, c2);
-	odd2 = ((*xy2 - c2) / wh) & 0x1;
-
-	if (odd1 && odd2) {
-		*xy1 = wh - c2;
-		*xy2 = wh - c1;
-	} else if (odd1 && !odd2) {
-		*xy1 = 0;
-		*xy2 = MAX(c2, wh - c1);
-	} else if (!odd1 && odd2) {
-		*xy2 = wh;
-		*xy1 = MIN(c1, wh - c2);
-	} else {
-		*xy1 = c1;
-		*xy2 = c2;
-	}
+    int odd1, odd2;
+    int c1, c2;
+
+    if (*xy2 - *xy1 > wh) {
+        *xy1 = 0;
+        *xy2 = wh;
+        return;
+    }
+    modulus(*xy1, wh, c1);
+    odd1 = ((*xy1 - c1) / wh) & 0x1;
+    modulus(*xy2, wh, c2);
+    odd2 = ((*xy2 - c2) / wh) & 0x1;
+
+    if (odd1 && odd2) {
+        *xy1 = wh - c2;
+        *xy2 = wh - c1;
+    }
+    else if (odd1 && !odd2) {
+        *xy1 = 0;
+        *xy2 = MAX(c2, wh - c1);
+    }
+    else if (!odd1 && odd2) {
+        *xy2 = wh;
+        *xy1 = MIN(c1, wh - c2);
+    }
+    else {
+        *xy1 = c1;
+        *xy2 = c2;
+    }
 }
 
 /**
@@ -316,367 +325,405 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
  *
  */
 static glamor_pixmap_clipped_regions *
-_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
-				RegionPtr region, int *n_region,
-				int repeat_type, int is_transform,
-				int reverse, int upsidedown)
+_glamor_compute_clipped_regions(glamor_pixmap_private * pixmap_priv,
+                                RegionPtr region, int *n_region,
+                                int repeat_type, int is_transform,
+                                int reverse, int upsidedown)
 {
-	glamor_pixmap_clipped_regions * clipped_regions;
-	BoxPtr extent;
-	int i, j;
-	RegionPtr current_region;
-	int pixmap_width, pixmap_height;
-	int m;
-	BoxRec repeat_box;
-	RegionRec repeat_region;
-	int right_shift = 0;
-	int down_shift = 0;
-	int x_center_shift = 0, y_center_shift = 0;
-	glamor_pixmap_private_large_t *priv;
-	priv = &pixmap_priv->large;
-
-	DEBUGRegionPrint(region);
-	if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-		clipped_regions = calloc(1, sizeof(*clipped_regions));
-		clipped_regions[0].region = RegionCreate(NULL, 1);
-		clipped_regions[0].block_idx = 0;
-		RegionCopy(clipped_regions[0].region, region);
-		*n_region = 1;
-		return clipped_regions;
-	}
-
-	pixmap_width = priv->base.pixmap->drawable.width;
-	pixmap_height = priv->base.pixmap->drawable.height;
-	if (repeat_type == 0 || repeat_type == RepeatPad) {
-		RegionPtr saved_region = NULL;
-		if (repeat_type == RepeatPad) {
-			saved_region = region;
-			region = _glamor_convert_pad_region(saved_region, pixmap_width, pixmap_height);
-			if (region == NULL) {
-				*n_region = 0;
-				return NULL;
-			}
-		}
-		clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
-							priv->block_h,
-							priv->block_wcnt,
-							0, 0,
-							priv->base.pixmap->drawable.width,
-							priv->base.pixmap->drawable.height,
-							region, n_region, reverse, upsidedown
-							);
-		if (saved_region)
-			RegionDestroy(region);
-		return clipped_regions;
-	}
-	extent = RegionExtents(region);
-
-	x_center_shift = extent->x1 / pixmap_width;
-	if (x_center_shift < 0)
-		x_center_shift--;
-	if (abs(x_center_shift) & 1)
-		x_center_shift++;
-	y_center_shift = extent->y1 / pixmap_height;
-	if (y_center_shift < 0)
-		y_center_shift--;
-	if (abs(y_center_shift) & 1)
-		y_center_shift++;
-
-	if (extent->x1 < 0)
-		right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width );
-	if (extent->y1 < 0)
-		down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height );
-
-	if (right_shift != 0 || down_shift != 0) {
-		if (repeat_type == RepeatReflect) {
-			right_shift = (right_shift + 1)&~1;
-			down_shift = (down_shift + 1)&~1;
-		}
-		RegionTranslate(region, right_shift * pixmap_width, down_shift * pixmap_height);
-	}
-
-	extent = RegionExtents(region);
-	/* Tile a large pixmap to another large pixmap.
-	 * We can't use the target large pixmap as the
-	 * loop variable, instead we need to loop for all
-	 * the blocks in the tile pixmap.
-	 *
-	 * simulate repeat each single block to cover the
-	 * target's blocks. Two special case:
-	 * a block_wcnt == 1 or block_hcnt ==1, then we
-	 * only need to loop one direction as the other
-	 * direction is fully included in the first block.
-	 *
-	 * For the other cases, just need to start
-	 * from a proper shiftx/shifty, and then increase
-	 * y by tile_height each time to walk trhough the
-	 * target block and then walk trhough the target
-	 * at x direction by increate tile_width each time.
-	 *
-	 * This way, we can consolidate all the sub blocks
-	 * of the target boxes into one tile source's block.
-	 *
-	 * */
-	m = 0;
-	clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt,
-				 sizeof(*clipped_regions));
-	if (clipped_regions == NULL) {
-		*n_region = 0;
-		return NULL;
-	}
-	if (right_shift != 0 || down_shift != 0) {
-		DEBUGF("region to be repeated shifted \n");
-		DEBUGRegionPrint(region);
-	}
-	DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height);
-	DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, extent->x2, extent->y2);
-	for(j = 0; j < priv->block_hcnt; j++)
-	{
-		for(i = 0; i < priv->block_wcnt; i++)
-		{
-			int dx = pixmap_width;
-			int dy = pixmap_height;
-			int idx;
-			int shift_x;
-			int shift_y;
-			int saved_y1, saved_y2;
-			int x_idx = 0, y_idx = 0, saved_y_idx = 0;
-			RegionRec temp_region;
-			BoxRec reflect_repeat_box;
-			BoxPtr valid_repeat_box;
-
-			shift_x = (extent->x1 / pixmap_width) * pixmap_width;
-			shift_y = (extent->y1 / pixmap_height) * pixmap_height;
-			idx = j * priv->block_wcnt + i;
-			if (repeat_type == RepeatReflect) {
-				x_idx = (extent->x1 / pixmap_width);
-				y_idx = (extent->y1 / pixmap_height);
-			}
-
-			/* Construct a rect to clip the target region. */
-			repeat_box.x1 = shift_x + priv->box_array[idx].x1;
-			repeat_box.y1 = shift_y + priv->box_array[idx].y1;
-			if (priv->block_wcnt == 1) {
-				repeat_box.x2 = extent->x2;
-				dx = extent->x2 - repeat_box.x1;
-			} else
-				repeat_box.x2 = shift_x + priv->box_array[idx].x2;
-			if (priv->block_hcnt == 1) {
-				repeat_box.y2 = extent->y2;
-				dy = extent->y2 - repeat_box.y1;
-			} else
-				repeat_box.y2 = shift_y + priv->box_array[idx].y2;
-
-			current_region = RegionCreate(NULL, 4);
-			RegionInit(&temp_region, NULL, 4);
-			DEBUGF("init repeat box %d %d %d %d \n",
-				repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
-
-			if (repeat_type == RepeatNormal) {
-				saved_y1 = repeat_box.y1;
-				saved_y2 = repeat_box.y2;
-				for(; repeat_box.x1 < extent->x2;
-				      repeat_box.x1 += dx, repeat_box.x2 += dx)
-				{
-					repeat_box.y1 = saved_y1;
-					repeat_box.y2 = saved_y2;
-					for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
-					     repeat_box.y1 < extent->y2;
-					     repeat_box.y1 += dy, repeat_box.y2 += dy)
-					{
-
-						RegionInitBoxes(&repeat_region, &repeat_box, 1);
-						DEBUGF("Start to clip repeat region: \n");
-						DEBUGRegionPrint(&repeat_region);
-						RegionIntersect(&temp_region, &repeat_region, region);
-						DEBUGF("clip result:\n");
-						DEBUGRegionPrint(&temp_region);
-						RegionAppend(current_region, &temp_region);
-						RegionUninit(&repeat_region);
-					}
-				}
-			} else if (repeat_type == RepeatReflect) {
-				saved_y1 = repeat_box.y1;
-				saved_y2 = repeat_box.y2;
-				saved_y_idx = y_idx;
-				for(; ; repeat_box.x1 += dx, repeat_box.x2 += dx)
-				{
-					repeat_box.y1 = saved_y1;
-					repeat_box.y2 = saved_y2;
-					y_idx = saved_y_idx;
-					reflect_repeat_box.x1 = (x_idx & 1) ?
-								((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1;
-					reflect_repeat_box.x2 = (x_idx & 1) ?
-								((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2;
-					valid_repeat_box = &reflect_repeat_box;
-
-					if (valid_repeat_box->x1 >= extent->x2)
-						break;
-					for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
-					     ;
-					     repeat_box.y1 += dy, repeat_box.y2 += dy)
-					{
-
-						DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, dx, dy);
-						DEBUGF("repeat box %d %d %d %d \n",
-							repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
-
-						if (priv->block_hcnt > 1) {
-						reflect_repeat_box.y1 = (y_idx & 1) ?
-							((2 * y_idx + 1) * dy - repeat_box.y2) : repeat_box.y1;
-						reflect_repeat_box.y2 = (y_idx & 1) ?
-							((2 * y_idx + 1) * dy - repeat_box.y1) : repeat_box.y2;
-						} else {
-						reflect_repeat_box.y1 = repeat_box.y1;
-						reflect_repeat_box.y2 = repeat_box.y2;
-						}
-
-						DEBUGF("valid_repeat_box x1 %d y1 %d \n",
-							valid_repeat_box->x1, valid_repeat_box->y1);
-						if (valid_repeat_box->y1 >= extent->y2)
-							break;
-						RegionInitBoxes(&repeat_region, valid_repeat_box, 1);
-						DEBUGF("start to clip repeat[reflect] region: \n");
-						DEBUGRegionPrint(&repeat_region);
-						RegionIntersect(&temp_region, &repeat_region, region);
-						DEBUGF("result:\n");
-						DEBUGRegionPrint(&temp_region);
-						if (is_transform && RegionNumRects(&temp_region)) {
-							BoxRec temp_box;
-							BoxPtr temp_extent;
-							temp_extent = RegionExtents(&temp_region);
-							if (priv->block_wcnt > 1) {
-								if (x_idx & 1) {
-									temp_box.x1 = ((2 * x_idx + 1)*dx - temp_extent->x2);
-									temp_box.x2 = ((2 * x_idx + 1)*dx - temp_extent->x1);
-								} else {
-									temp_box.x1 = temp_extent->x1;
-									temp_box.x2 = temp_extent->x2;
-								}
-								modulus(temp_box.x1, pixmap_width, temp_box.x1);
-								modulus(temp_box.x2, pixmap_width, temp_box.x2);
-								if (temp_box.x2 == 0) temp_box.x2 = pixmap_width;
-							} else {
-								temp_box.x1 = temp_extent->x1;
-								temp_box.x2 = temp_extent->x2;
-								_glamor_largepixmap_reflect_fixup(&temp_box.x1, &temp_box.x2, pixmap_width);
-							}
-
-							if (priv->block_hcnt > 1) {
-								if (y_idx & 1) {
-									temp_box.y1 = ((2 * y_idx + 1)*dy - temp_extent->y2);
-									temp_box.y2 = ((2 * y_idx + 1)*dy - temp_extent->y1);
-								} else {
-									temp_box.y1 = temp_extent->y1;
-									temp_box.y2 = temp_extent->y2;
-								}
-
-								modulus(temp_box.y1, pixmap_height, temp_box.y1);
-								modulus(temp_box.y2, pixmap_height, temp_box.y2);
-								if (temp_box.y2 == 0) temp_box.y2 = pixmap_height;
-							} else {
-								temp_box.y1 = temp_extent->y1;
-								temp_box.y2 = temp_extent->y2;
-								_glamor_largepixmap_reflect_fixup(&temp_box.y1, &temp_box.y2, pixmap_height);
-							}
-
-							RegionInitBoxes(&temp_region, &temp_box, 1);
-							RegionTranslate(&temp_region, x_center_shift * pixmap_width, y_center_shift * pixmap_height);
-							DEBUGF("for transform result:\n");
-							DEBUGRegionPrint(&temp_region);
-						}
-						RegionAppend(current_region, &temp_region);
-						RegionUninit(&repeat_region);
-						y_idx++;
-					}
-					x_idx++;
-				}
-			}
-			DEBUGF("dx %d dy %d \n", dx, dy);
-
-			if (RegionNumRects(current_region)) {
-
-				if ((right_shift != 0 || down_shift != 0) && !(is_transform && repeat_type == RepeatReflect))
-					RegionTranslate(current_region,
-							-right_shift * pixmap_width,
-							-down_shift * pixmap_height);
-				clipped_regions[m].region = current_region;
-				clipped_regions[m].block_idx = idx;
-				m++;
-			} else
-				RegionDestroy(current_region);
-			RegionUninit(&temp_region);
-		}
-	}
-
-	if (right_shift != 0 || down_shift != 0)
-		RegionTranslate(region, -right_shift * pixmap_width, -down_shift * pixmap_height);
-	*n_region = m;
-
-	return clipped_regions;
+    glamor_pixmap_clipped_regions *clipped_regions;
+    BoxPtr extent;
+    int i, j;
+    RegionPtr current_region;
+    int pixmap_width, pixmap_height;
+    int m;
+    BoxRec repeat_box;
+    RegionRec repeat_region;
+    int right_shift = 0;
+    int down_shift = 0;
+    int x_center_shift = 0, y_center_shift = 0;
+    glamor_pixmap_private_large_t *priv;
+
+    priv = &pixmap_priv->large;
+
+    DEBUGRegionPrint(region);
+    if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+        clipped_regions = calloc(1, sizeof(*clipped_regions));
+        clipped_regions[0].region = RegionCreate(NULL, 1);
+        clipped_regions[0].block_idx = 0;
+        RegionCopy(clipped_regions[0].region, region);
+        *n_region = 1;
+        return clipped_regions;
+    }
+
+    pixmap_width = priv->base.pixmap->drawable.width;
+    pixmap_height = priv->base.pixmap->drawable.height;
+    if (repeat_type == 0 || repeat_type == RepeatPad) {
+        RegionPtr saved_region = NULL;
+
+        if (repeat_type == RepeatPad) {
+            saved_region = region;
+            region =
+                _glamor_convert_pad_region(saved_region, pixmap_width,
+                                           pixmap_height);
+            if (region == NULL) {
+                *n_region = 0;
+                return NULL;
+            }
+        }
+        clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
+                                                           priv->block_h,
+                                                           priv->block_wcnt,
+                                                           0, 0,
+                                                           priv->base.pixmap->
+                                                           drawable.width,
+                                                           priv->base.pixmap->
+                                                           drawable.height,
+                                                           region, n_region,
+                                                           reverse, upsidedown);
+        if (saved_region)
+            RegionDestroy(region);
+        return clipped_regions;
+    }
+    extent = RegionExtents(region);
+
+    x_center_shift = extent->x1 / pixmap_width;
+    if (x_center_shift < 0)
+        x_center_shift--;
+    if (abs(x_center_shift) & 1)
+        x_center_shift++;
+    y_center_shift = extent->y1 / pixmap_height;
+    if (y_center_shift < 0)
+        y_center_shift--;
+    if (abs(y_center_shift) & 1)
+        y_center_shift++;
+
+    if (extent->x1 < 0)
+        right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width);
+    if (extent->y1 < 0)
+        down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height);
+
+    if (right_shift != 0 || down_shift != 0) {
+        if (repeat_type == RepeatReflect) {
+            right_shift = (right_shift + 1) & ~1;
+            down_shift = (down_shift + 1) & ~1;
+        }
+        RegionTranslate(region, right_shift * pixmap_width,
+                        down_shift * pixmap_height);
+    }
+
+    extent = RegionExtents(region);
+    /* Tile a large pixmap to another large pixmap.
+     * We can't use the target large pixmap as the
+     * loop variable, instead we need to loop for all
+     * the blocks in the tile pixmap.
+     *
+     * simulate repeat each single block to cover the
+     * target's blocks. Two special case:
+     * a block_wcnt == 1 or block_hcnt ==1, then we
+     * only need to loop one direction as the other
+     * direction is fully included in the first block.
+     *
+     * For the other cases, just need to start
+     * from a proper shiftx/shifty, and then increase
+     * y by tile_height each time to walk trhough the
+     * target block and then walk trhough the target
+     * at x direction by increate tile_width each time.
+     *
+     * This way, we can consolidate all the sub blocks
+     * of the target boxes into one tile source's block.
+     *
+     * */
+    m = 0;
+    clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt,
+                             sizeof(*clipped_regions));
+    if (clipped_regions == NULL) {
+        *n_region = 0;
+        return NULL;
+    }
+    if (right_shift != 0 || down_shift != 0) {
+        DEBUGF("region to be repeated shifted \n");
+        DEBUGRegionPrint(region);
+    }
+    DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height);
+    DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1,
+           extent->x2, extent->y2);
+    for (j = 0; j < priv->block_hcnt; j++) {
+        for (i = 0; i < priv->block_wcnt; i++) {
+            int dx = pixmap_width;
+            int dy = pixmap_height;
+            int idx;
+            int shift_x;
+            int shift_y;
+            int saved_y1, saved_y2;
+            int x_idx = 0, y_idx = 0, saved_y_idx = 0;
+            RegionRec temp_region;
+            BoxRec reflect_repeat_box;
+            BoxPtr valid_repeat_box;
+
+            shift_x = (extent->x1 / pixmap_width) * pixmap_width;
+            shift_y = (extent->y1 / pixmap_height) * pixmap_height;
+            idx = j * priv->block_wcnt + i;
+            if (repeat_type == RepeatReflect) {
+                x_idx = (extent->x1 / pixmap_width);
+                y_idx = (extent->y1 / pixmap_height);
+            }
+
+            /* Construct a rect to clip the target region. */
+            repeat_box.x1 = shift_x + priv->box_array[idx].x1;
+            repeat_box.y1 = shift_y + priv->box_array[idx].y1;
+            if (priv->block_wcnt == 1) {
+                repeat_box.x2 = extent->x2;
+                dx = extent->x2 - repeat_box.x1;
+            }
+            else
+                repeat_box.x2 = shift_x + priv->box_array[idx].x2;
+            if (priv->block_hcnt == 1) {
+                repeat_box.y2 = extent->y2;
+                dy = extent->y2 - repeat_box.y1;
+            }
+            else
+                repeat_box.y2 = shift_y + priv->box_array[idx].y2;
+
+            current_region = RegionCreate(NULL, 4);
+            RegionInit(&temp_region, NULL, 4);
+            DEBUGF("init repeat box %d %d %d %d \n",
+                   repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
+
+            if (repeat_type == RepeatNormal) {
+                saved_y1 = repeat_box.y1;
+                saved_y2 = repeat_box.y2;
+                for (; repeat_box.x1 < extent->x2;
+                     repeat_box.x1 += dx, repeat_box.x2 += dx) {
+                    repeat_box.y1 = saved_y1;
+                    repeat_box.y2 = saved_y2;
+                    for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
+                         repeat_box.y1 < extent->y2;
+                         repeat_box.y1 += dy, repeat_box.y2 += dy) {
+
+                        RegionInitBoxes(&repeat_region, &repeat_box, 1);
+                        DEBUGF("Start to clip repeat region: \n");
+                        DEBUGRegionPrint(&repeat_region);
+                        RegionIntersect(&temp_region, &repeat_region, region);
+                        DEBUGF("clip result:\n");
+                        DEBUGRegionPrint(&temp_region);
+                        RegionAppend(current_region, &temp_region);
+                        RegionUninit(&repeat_region);
+                    }
+                }
+            }
+            else if (repeat_type == RepeatReflect) {
+                saved_y1 = repeat_box.y1;
+                saved_y2 = repeat_box.y2;
+                saved_y_idx = y_idx;
+                for (;; repeat_box.x1 += dx, repeat_box.x2 += dx) {
+                    repeat_box.y1 = saved_y1;
+                    repeat_box.y2 = saved_y2;
+                    y_idx = saved_y_idx;
+                    reflect_repeat_box.x1 = (x_idx & 1) ?
+                        ((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1;
+                    reflect_repeat_box.x2 = (x_idx & 1) ?
+                        ((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2;
+                    valid_repeat_box = &reflect_repeat_box;
+
+                    if (valid_repeat_box->x1 >= extent->x2)
+                        break;
+                    for (repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;;
+                         repeat_box.y1 += dy, repeat_box.y2 += dy) {
+
+                        DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx,
+                               dx, dy);
+                        DEBUGF("repeat box %d %d %d %d \n", repeat_box.x1,
+                               repeat_box.y1, repeat_box.x2, repeat_box.y2);
+
+                        if (priv->block_hcnt > 1) {
+                            reflect_repeat_box.y1 = (y_idx & 1) ?
+                                ((2 * y_idx + 1) * dy -
+                                 repeat_box.y2) : repeat_box.y1;
+                            reflect_repeat_box.y2 =
+                                (y_idx & 1) ? ((2 * y_idx + 1) * dy -
+                                               repeat_box.y1) : repeat_box.y2;
+                        }
+                        else {
+                            reflect_repeat_box.y1 = repeat_box.y1;
+                            reflect_repeat_box.y2 = repeat_box.y2;
+                        }
+
+                        DEBUGF("valid_repeat_box x1 %d y1 %d \n",
+                               valid_repeat_box->x1, valid_repeat_box->y1);
+                        if (valid_repeat_box->y1 >= extent->y2)
+                            break;
+                        RegionInitBoxes(&repeat_region, valid_repeat_box, 1);
+                        DEBUGF("start to clip repeat[reflect] region: \n");
+                        DEBUGRegionPrint(&repeat_region);
+                        RegionIntersect(&temp_region, &repeat_region, region);
+                        DEBUGF("result:\n");
+                        DEBUGRegionPrint(&temp_region);
+                        if (is_transform && RegionNumRects(&temp_region)) {
+                            BoxRec temp_box;
+                            BoxPtr temp_extent;
+
+                            temp_extent = RegionExtents(&temp_region);
+                            if (priv->block_wcnt > 1) {
+                                if (x_idx & 1) {
+                                    temp_box.x1 =
+                                        ((2 * x_idx + 1) * dx -
+                                         temp_extent->x2);
+                                    temp_box.x2 =
+                                        ((2 * x_idx + 1) * dx -
+                                         temp_extent->x1);
+                                }
+                                else {
+                                    temp_box.x1 = temp_extent->x1;
+                                    temp_box.x2 = temp_extent->x2;
+                                }
+                                modulus(temp_box.x1, pixmap_width, temp_box.x1);
+                                modulus(temp_box.x2, pixmap_width, temp_box.x2);
+                                if (temp_box.x2 == 0)
+                                    temp_box.x2 = pixmap_width;
+                            }
+                            else {
+                                temp_box.x1 = temp_extent->x1;
+                                temp_box.x2 = temp_extent->x2;
+                                _glamor_largepixmap_reflect_fixup(&temp_box.x1,
+                                                                  &temp_box.x2,
+                                                                  pixmap_width);
+                            }
+
+                            if (priv->block_hcnt > 1) {
+                                if (y_idx & 1) {
+                                    temp_box.y1 =
+                                        ((2 * y_idx + 1) * dy -
+                                         temp_extent->y2);
+                                    temp_box.y2 =
+                                        ((2 * y_idx + 1) * dy -
+                                         temp_extent->y1);
+                                }
+                                else {
+                                    temp_box.y1 = temp_extent->y1;
+                                    temp_box.y2 = temp_extent->y2;
+                                }
+
+                                modulus(temp_box.y1, pixmap_height,
+                                        temp_box.y1);
+                                modulus(temp_box.y2, pixmap_height,
+                                        temp_box.y2);
+                                if (temp_box.y2 == 0)
+                                    temp_box.y2 = pixmap_height;
+                            }
+                            else {
+                                temp_box.y1 = temp_extent->y1;
+                                temp_box.y2 = temp_extent->y2;
+                                _glamor_largepixmap_reflect_fixup(&temp_box.y1,
+                                                                  &temp_box.y2,
+                                                                  pixmap_height);
+                            }
+
+                            RegionInitBoxes(&temp_region, &temp_box, 1);
+                            RegionTranslate(&temp_region,
+                                            x_center_shift * pixmap_width,
+                                            y_center_shift * pixmap_height);
+                            DEBUGF("for transform result:\n");
+                            DEBUGRegionPrint(&temp_region);
+                        }
+                        RegionAppend(current_region, &temp_region);
+                        RegionUninit(&repeat_region);
+                        y_idx++;
+                    }
+                    x_idx++;
+                }
+            }
+            DEBUGF("dx %d dy %d \n", dx, dy);
+
+            if (RegionNumRects(current_region)) {
+
+                if ((right_shift != 0 || down_shift != 0) &&
+                    !(is_transform && repeat_type == RepeatReflect))
+                    RegionTranslate(current_region, -right_shift * pixmap_width,
+                                    -down_shift * pixmap_height);
+                clipped_regions[m].region = current_region;
+                clipped_regions[m].block_idx = idx;
+                m++;
+            }
+            else
+                RegionDestroy(current_region);
+            RegionUninit(&temp_region);
+        }
+    }
+
+    if (right_shift != 0 || down_shift != 0)
+        RegionTranslate(region, -right_shift * pixmap_width,
+                        -down_shift * pixmap_height);
+    *n_region = m;
+
+    return clipped_regions;
 }
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
-			       int *n_region, int repeat_type,
-			       int reverse, int upsidedown)
+glamor_compute_clipped_regions(glamor_pixmap_private * priv, RegionPtr region,
+                               int *n_region, int repeat_type,
+                               int reverse, int upsidedown)
 {
-	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0, reverse, upsidedown);
+    return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type,
+                                           0, reverse, upsidedown);
 }
 
 /* XXX overflow still exist. maybe we need to change to use region32.
  * by default. Or just use region32 for repeat cases?
  **/
 glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
-					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type,
-					 int reverse, int upsidedown)
+glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv,
+                                         struct pixman_transform * transform,
+                                         RegionPtr region, int *n_region,
+                                         int dx, int dy, int repeat_type,
+                                         int reverse, int upsidedown)
 {
-	BoxPtr temp_extent;
-	struct pixman_box32 temp_box;
-	struct pixman_box16 short_box;
-	RegionPtr temp_region;
-	glamor_pixmap_clipped_regions *ret;
-
-	temp_region = RegionCreate(NULL, 4);
-	temp_extent = RegionExtents(region);
-	DEBUGF("dest region \n");
-	DEBUGRegionPrint(region);
-	/* dx/dy may exceed MAX SHORT. we have to use
-	 * a box32 to represent it.*/
-	temp_box.x1 = temp_extent->x1 + dx;
-	temp_box.x2 = temp_extent->x2 + dx;
-	temp_box.y1 = temp_extent->y1 + dy;
-	temp_box.y2 = temp_extent->y2 + dy;
-
-	DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
-	if (transform)
-		glamor_get_transform_extent_from_box(&temp_box, transform);
-	if (repeat_type == RepeatNone) {
-		if (temp_box.x1 < 0) temp_box.x1 = 0;
-		if (temp_box.y1 < 0) temp_box.y1 = 0;
-		temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
-		temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
-	}
-	/* Now copy back the box32 to a box16 box. */
-	short_box.x1 = temp_box.x1;
-	short_box.y1 = temp_box.y1;
-	short_box.x2 = temp_box.x2;
-	short_box.y2 = temp_box.y2;
-	RegionInitBoxes(temp_region, &short_box, 1);
-	DEBUGF("copy to temp source region \n");
-	DEBUGRegionPrint(temp_region);
-	ret = _glamor_compute_clipped_regions(priv,
-					      temp_region,
-					      n_region,
-					      repeat_type,
-					      1, reverse,
-					      upsidedown);
-	DEBUGF("n_regions = %d \n", *n_region);
-	RegionDestroy(temp_region);
-
-	return ret;
+    BoxPtr temp_extent;
+    struct pixman_box32 temp_box;
+    struct pixman_box16 short_box;
+    RegionPtr temp_region;
+    glamor_pixmap_clipped_regions *ret;
+
+    temp_region = RegionCreate(NULL, 4);
+    temp_extent = RegionExtents(region);
+    DEBUGF("dest region \n");
+    DEBUGRegionPrint(region);
+    /* dx/dy may exceed MAX SHORT. we have to use
+     * a box32 to represent it.*/
+    temp_box.x1 = temp_extent->x1 + dx;
+    temp_box.x2 = temp_extent->x2 + dx;
+    temp_box.y1 = temp_extent->y1 + dy;
+    temp_box.y2 = temp_extent->y2 + dy;
+
+    DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2,
+           temp_box.y2);
+    if (transform)
+        glamor_get_transform_extent_from_box(&temp_box, transform);
+    if (repeat_type == RepeatNone) {
+        if (temp_box.x1 < 0)
+            temp_box.x1 = 0;
+        if (temp_box.y1 < 0)
+            temp_box.y1 = 0;
+        temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
+        temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
+    }
+    /* Now copy back the box32 to a box16 box. */
+    short_box.x1 = temp_box.x1;
+    short_box.y1 = temp_box.y1;
+    short_box.x2 = temp_box.x2;
+    short_box.y2 = temp_box.y2;
+    RegionInitBoxes(temp_region, &short_box, 1);
+    DEBUGF("copy to temp source region \n");
+    DEBUGRegionPrint(temp_region);
+    ret = _glamor_compute_clipped_regions(priv,
+                                          temp_region,
+                                          n_region,
+                                          repeat_type, 1, reverse, upsidedown);
+    DEBUGF("n_regions = %d \n", *n_region);
+    RegionDestroy(temp_region);
+
+    return ret;
 }
+
 /*
  * As transform and repeatpad mode.
  * We may get a clipped result which in multipe regions.
@@ -689,120 +736,121 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pix
  * if the clipped result cross the region boundary.
  */
 static void
-glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type,
-			     glamor_pixmap_clipped_regions *clipped_regions,
-			     int *n_regions, int *need_clean_fbo)
+glamor_merge_clipped_regions(glamor_pixmap_private * pixmap_priv,
+                             int repeat_type,
+                             glamor_pixmap_clipped_regions * clipped_regions,
+                             int *n_regions, int *need_clean_fbo)
 {
-	BoxPtr temp_extent;
-	BoxRec temp_box, copy_box;
-	RegionPtr temp_region;
-	glamor_pixmap_private *temp_priv;
-	PixmapPtr temp_pixmap;
-	int overlap;
-	int i;
-	int pixmap_width, pixmap_height;
-	glamor_pixmap_private_large_t *priv;
-
-	priv = &pixmap_priv->large;
-	pixmap_width = priv->base.pixmap->drawable.width;
-	pixmap_height = priv->base.pixmap->drawable.height;
-
-	temp_region = RegionCreate(NULL, 4);
-	for(i = 0; i < *n_regions; i++)
-	{
-		DEBUGF("Region %d:\n", i);
-		DEBUGRegionPrint(clipped_regions[i].region);
-		RegionAppend(temp_region, clipped_regions[i].region);
-	}
-
-	RegionValidate(temp_region, &overlap);
-	DEBUGF("temp region: \n");
-	DEBUGRegionPrint(temp_region);
-	temp_extent = RegionExtents(temp_region);
-
-	temp_box = *temp_extent;
-
-	DEBUGF("need copy region: \n");
-	DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
-	temp_pixmap = glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
-					  temp_box.x2 - temp_box.x1,
-					  temp_box.y2 - temp_box.y1,
-					  priv->base.pixmap->drawable.depth,
-					  GLAMOR_CREATE_PIXMAP_FIXUP);
-	if (temp_pixmap == NULL) {
-		assert(0);
-		return;
-	}
-
-	temp_priv = glamor_get_pixmap_private(temp_pixmap);
-	assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
-
-	priv->box = temp_box;
-	if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
-	    && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) {
-		int dx, dy;
-		copy_box.x1 = 0;
-		copy_box.y1 = 0;
-		copy_box.x2 = temp_extent->x2 - temp_extent->x1;
-		copy_box.y2 = temp_extent->y2 - temp_extent->y1;
-		dx = temp_extent->x1;
-		dy = temp_extent->y1;
-		glamor_copy_n_to_n(&priv->base.pixmap->drawable,
-				   &temp_pixmap->drawable,
-				   NULL, &copy_box, 1, dx,
-				   dy, 0, 0, 0, NULL);
-//		glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
-//			       temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
-	} else {
-		for (i = 0; i < *n_regions; i++)
-		{
-			BoxPtr box;
-			int nbox;
-			box = REGION_RECTS(clipped_regions[i].region);
-			nbox = REGION_NUM_RECTS(clipped_regions[i].region);
-			while(nbox--) {
-				int dx, dy, c, d;
-				DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n",
-					box->x1, box->y1, box->x2, box->y2);
-				modulus(box->x1, pixmap_width, c);
-				dx = c - (box->x1 - temp_box.x1);
-				copy_box.x1 = box->x1 - temp_box.x1;
-				copy_box.x2 = box->x2 - temp_box.x1;
-
-				modulus(box->y1, pixmap_height, d);
-				dy = d - (box->y1 - temp_box.y1);
-				copy_box.y1 = box->y1 - temp_box.y1;
-				copy_box.y2 = box->y2 - temp_box.y1;
-
-				DEBUGF("copying box %d %d %d %d, dx %d dy %d\n",
-					copy_box.x1, copy_box.y1, copy_box.x2,
-					copy_box.y2, dx, dy);
-
-				glamor_copy_n_to_n(&priv->base.pixmap->drawable,
-						   &temp_pixmap->drawable,
-						   NULL, &copy_box, 1, dx,
-						   dy, 0, 0, 0, NULL);
-				box++;
-			}
-		}
-		//glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
-		//	       temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff);
-	}
-	/* The first region will be released at caller side. */
-	for(i = 1; i < *n_regions; i++)
-		RegionDestroy(clipped_regions[i].region);
-	RegionDestroy(temp_region);
-	priv->box = temp_box;
-	priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
-	DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
-		priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
-	glamor_destroy_pixmap(temp_pixmap);
-	*need_clean_fbo = 1;
-	*n_regions = 1;
+    BoxPtr temp_extent;
+    BoxRec temp_box, copy_box;
+    RegionPtr temp_region;
+    glamor_pixmap_private *temp_priv;
+    PixmapPtr temp_pixmap;
+    int overlap;
+    int i;
+    int pixmap_width, pixmap_height;
+    glamor_pixmap_private_large_t *priv;
+
+    priv = &pixmap_priv->large;
+    pixmap_width = priv->base.pixmap->drawable.width;
+    pixmap_height = priv->base.pixmap->drawable.height;
+
+    temp_region = RegionCreate(NULL, 4);
+    for (i = 0; i < *n_regions; i++) {
+        DEBUGF("Region %d:\n", i);
+        DEBUGRegionPrint(clipped_regions[i].region);
+        RegionAppend(temp_region, clipped_regions[i].region);
+    }
+
+    RegionValidate(temp_region, &overlap);
+    DEBUGF("temp region: \n");
+    DEBUGRegionPrint(temp_region);
+    temp_extent = RegionExtents(temp_region);
+
+    temp_box = *temp_extent;
+
+    DEBUGF("need copy region: \n");
+    DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2,
+           temp_box.y2);
+    temp_pixmap =
+        glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
+                             temp_box.x2 - temp_box.x1,
+                             temp_box.y2 - temp_box.y1,
+                             priv->base.pixmap->drawable.depth,
+                             GLAMOR_CREATE_PIXMAP_FIXUP);
+    if (temp_pixmap == NULL) {
+        assert(0);
+        return;
+    }
+
+    temp_priv = glamor_get_pixmap_private(temp_pixmap);
+    assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
+
+    priv->box = temp_box;
+    if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
+        && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) {
+        int dx, dy;
+
+        copy_box.x1 = 0;
+        copy_box.y1 = 0;
+        copy_box.x2 = temp_extent->x2 - temp_extent->x1;
+        copy_box.y2 = temp_extent->y2 - temp_extent->y1;
+        dx = temp_extent->x1;
+        dy = temp_extent->y1;
+        glamor_copy_n_to_n(&priv->base.pixmap->drawable,
+                           &temp_pixmap->drawable,
+                           NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+//              glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
+//                             temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
+    }
+    else {
+        for (i = 0; i < *n_regions; i++) {
+            BoxPtr box;
+            int nbox;
+
+            box = REGION_RECTS(clipped_regions[i].region);
+            nbox = REGION_NUM_RECTS(clipped_regions[i].region);
+            while (nbox--) {
+                int dx, dy, c, d;
+
+                DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n",
+                       box->x1, box->y1, box->x2, box->y2);
+                modulus(box->x1, pixmap_width, c);
+                dx = c - (box->x1 - temp_box.x1);
+                copy_box.x1 = box->x1 - temp_box.x1;
+                copy_box.x2 = box->x2 - temp_box.x1;
+
+                modulus(box->y1, pixmap_height, d);
+                dy = d - (box->y1 - temp_box.y1);
+                copy_box.y1 = box->y1 - temp_box.y1;
+                copy_box.y2 = box->y2 - temp_box.y1;
+
+                DEBUGF("copying box %d %d %d %d, dx %d dy %d\n",
+                       copy_box.x1, copy_box.y1, copy_box.x2,
+                       copy_box.y2, dx, dy);
+
+                glamor_copy_n_to_n(&priv->base.pixmap->drawable,
+                                   &temp_pixmap->drawable,
+                                   NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+                box++;
+            }
+        }
+        //glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
+        //             temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff);
+    }
+    /* The first region will be released at caller side. */
+    for (i = 1; i < *n_regions; i++)
+        RegionDestroy(clipped_regions[i].region);
+    RegionDestroy(temp_region);
+    priv->box = temp_box;
+    priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
+    DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
+           priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
+    glamor_destroy_pixmap(temp_pixmap);
+    *need_clean_fbo = 1;
+    *n_regions = 1;
 }
 
-
-
 /**
  * Given an expected transformed block width and block height,
  *
@@ -817,45 +865,47 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type
  **/
 Bool
 glamor_get_transform_block_size(struct pixman_transform *transform,
-			   int block_w, int block_h,
-			   int *transformed_block_w,
-			   int *transformed_block_h)
+                                int block_w, int block_h,
+                                int *transformed_block_w,
+                                int *transformed_block_h)
 {
-	double a,b,c,d,e,f,g,h;
-	double scale;
-	int width, height;
-	a = pixman_fixed_to_double(transform->matrix[0][0]);
-	b = pixman_fixed_to_double(transform->matrix[0][1]);
-	c = pixman_fixed_to_double(transform->matrix[1][0]);
-	d = pixman_fixed_to_double(transform->matrix[1][1]);
-	scale = pixman_fixed_to_double(transform->matrix[2][2]);
-	if (block_w > 2048) {
-	/* For large block size, we shrink it to smaller box,
-	 * thus latter we may get less cross boundary regions and
-	 * thus can avoid some extra copy.
-	 *
-	 **/
-		width = block_w  / 4;
-		height = block_h / 4;
-	} else {
-		width = block_w - 2;
-		height = block_h - 2;
-	}
-	e = a + b;
-	f = c + d;
-
-	g = a - b;
-	h = c - d;
-
-	e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g)));
-	f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h)));
-	*transformed_block_w = MIN(e, f) - 1;
-	*transformed_block_h = *transformed_block_w;
-	if (*transformed_block_w <= 0 || *transformed_block_h <= 0)
-		return FALSE;
-	DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h,
-		*transformed_block_w, *transformed_block_h);
-	return TRUE;
+    double a, b, c, d, e, f, g, h;
+    double scale;
+    int width, height;
+
+    a = pixman_fixed_to_double(transform->matrix[0][0]);
+    b = pixman_fixed_to_double(transform->matrix[0][1]);
+    c = pixman_fixed_to_double(transform->matrix[1][0]);
+    d = pixman_fixed_to_double(transform->matrix[1][1]);
+    scale = pixman_fixed_to_double(transform->matrix[2][2]);
+    if (block_w > 2048) {
+        /* For large block size, we shrink it to smaller box,
+         * thus latter we may get less cross boundary regions and
+         * thus can avoid some extra copy.
+         *
+         **/
+        width = block_w / 4;
+        height = block_h / 4;
+    }
+    else {
+        width = block_w - 2;
+        height = block_h - 2;
+    }
+    e = a + b;
+    f = c + d;
+
+    g = a - b;
+    h = c - d;
+
+    e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g)));
+    f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h)));
+    *transformed_block_w = MIN(e, f) - 1;
+    *transformed_block_h = *transformed_block_w;
+    if (*transformed_block_w <= 0 || *transformed_block_h <= 0)
+        return FALSE;
+    DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h,
+           *transformed_block_w, *transformed_block_h);
+    return TRUE;
 }
 
 #define VECTOR_FROM_POINT(p, x, y)	\
@@ -864,314 +914,341 @@ glamor_get_transform_block_size(struct pixman_transform *transform,
 	p.v[2] = 1.0;
 void
 glamor_get_transform_extent_from_box(struct pixman_box32 *box,
-		struct pixman_transform *transform)
+                                     struct pixman_transform *transform)
 {
-	struct pixman_f_vector p0, p1, p2, p3;
-	float min_x, min_y, max_x, max_y;
-
-	struct pixman_f_transform ftransform;
-
-	VECTOR_FROM_POINT(p0, box->x1, box->y1)
-	VECTOR_FROM_POINT(p1, box->x2, box->y1)
-	VECTOR_FROM_POINT(p2, box->x2, box->y2)
-	VECTOR_FROM_POINT(p3, box->x1, box->y2)
-
-	pixman_f_transform_from_pixman_transform(&ftransform, transform);
-	pixman_f_transform_point(&ftransform, &p0);
-	pixman_f_transform_point(&ftransform, &p1);
-	pixman_f_transform_point(&ftransform, &p2);
-	pixman_f_transform_point(&ftransform, &p3);
-
-	min_x = MIN(p0.v[0], p1.v[0]);
-	min_x = MIN(min_x, p2.v[0]);
-	min_x = MIN(min_x, p3.v[0]);
-
-	min_y = MIN(p0.v[1], p1.v[1]);
-	min_y = MIN(min_y, p2.v[1]);
-	min_y = MIN(min_y, p3.v[1]);
-
-	max_x = MAX(p0.v[0], p1.v[0]);
-	max_x = MAX(max_x, p2.v[0]);
-	max_x = MAX(max_x, p3.v[0]);
-
-	max_y = MAX(p0.v[1], p1.v[1]);
-	max_y = MAX(max_y, p2.v[1]);
-	max_y = MAX(max_y, p3.v[1]);
-	box->x1 = floor(min_x) - 1;
-	box->y1 = floor(min_y) - 1;
-	box->x2 = ceil(max_x) + 1;
-	box->y2 = ceil(max_y) + 1;
+    struct pixman_f_vector p0, p1, p2, p3;
+    float min_x, min_y, max_x, max_y;
+
+    struct pixman_f_transform ftransform;
+
+    VECTOR_FROM_POINT(p0, box->x1, box->y1)
+        VECTOR_FROM_POINT(p1, box->x2, box->y1)
+        VECTOR_FROM_POINT(p2, box->x2, box->y2)
+        VECTOR_FROM_POINT(p3, box->x1, box->y2)
+
+        pixman_f_transform_from_pixman_transform(&ftransform, transform);
+    pixman_f_transform_point(&ftransform, &p0);
+    pixman_f_transform_point(&ftransform, &p1);
+    pixman_f_transform_point(&ftransform, &p2);
+    pixman_f_transform_point(&ftransform, &p3);
+
+    min_x = MIN(p0.v[0], p1.v[0]);
+    min_x = MIN(min_x, p2.v[0]);
+    min_x = MIN(min_x, p3.v[0]);
+
+    min_y = MIN(p0.v[1], p1.v[1]);
+    min_y = MIN(min_y, p2.v[1]);
+    min_y = MIN(min_y, p3.v[1]);
+
+    max_x = MAX(p0.v[0], p1.v[0]);
+    max_x = MAX(max_x, p2.v[0]);
+    max_x = MAX(max_x, p3.v[0]);
+
+    max_y = MAX(p0.v[1], p1.v[1]);
+    max_y = MAX(max_y, p2.v[1]);
+    max_y = MAX(max_y, p3.v[1]);
+    box->x1 = floor(min_x) - 1;
+    box->y1 = floor(min_y) - 1;
+    box->x2 = ceil(max_x) + 1;
+    box->y2 = ceil(max_y) + 1;
 }
 
 static void
-_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
-					int repeat_type,
-					glamor_pixmap_clipped_regions *clipped_regions,
-					int *n_regions, int *need_clean_fbo)
+_glamor_process_transformed_clipped_region(glamor_pixmap_private * priv,
+                                           int repeat_type,
+                                           glamor_pixmap_clipped_regions *
+                                           clipped_regions, int *n_regions,
+                                           int *need_clean_fbo)
 {
-	int shift_x, shift_y;
-	if (*n_regions != 1) {
-	/* Merge all source regions into one region. */
-		glamor_merge_clipped_regions(priv, repeat_type,
-					     clipped_regions, n_regions,
-					     need_clean_fbo);
-	} else {
-		SET_PIXMAP_FBO_CURRENT(priv,
-				       clipped_regions[0].block_idx);
-		if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) {
-			/* The required source areas are in one region,
-			 * we need to shift the corresponding box's coords to proper position,
-			 * thus we can calculate the relative coords correctly.*/
-			BoxPtr temp_box;
-			int rem;
-			temp_box = RegionExtents(clipped_regions[0].region);
-			modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
-			shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
-			modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
-			shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
-
-			if (shift_x != 0) {
-				priv->large.box.x1 += shift_x * priv->base.pixmap->drawable.width;
-				priv->large.box.x2 += shift_x * priv->base.pixmap->drawable.width;
-			}
-			if (shift_y != 0) {
-				priv->large.box.y1 += shift_y * priv->base.pixmap->drawable.height;
-				priv->large.box.y2 += shift_y * priv->base.pixmap->drawable.height;
-			}
-		}
-	}
+    int shift_x, shift_y;
+
+    if (*n_regions != 1) {
+        /* Merge all source regions into one region. */
+        glamor_merge_clipped_regions(priv, repeat_type,
+                                     clipped_regions, n_regions,
+                                     need_clean_fbo);
+    }
+    else {
+        SET_PIXMAP_FBO_CURRENT(priv, clipped_regions[0].block_idx);
+        if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) {
+            /* The required source areas are in one region,
+             * we need to shift the corresponding box's coords to proper position,
+             * thus we can calculate the relative coords correctly.*/
+            BoxPtr temp_box;
+            int rem;
+
+            temp_box = RegionExtents(clipped_regions[0].region);
+            modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
+            shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
+            modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
+            shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
+
+            if (shift_x != 0) {
+                priv->large.box.x1 +=
+                    shift_x * priv->base.pixmap->drawable.width;
+                priv->large.box.x2 +=
+                    shift_x * priv->base.pixmap->drawable.width;
+            }
+            if (shift_y != 0) {
+                priv->large.box.y1 +=
+                    shift_y * priv->base.pixmap->drawable.height;
+                priv->large.box.y2 +=
+                    shift_y * priv->base.pixmap->drawable.height;
+            }
+        }
+    }
 }
 
-
 Bool
 glamor_composite_largepixmap_region(CARD8 op,
-			  PicturePtr source,
-			  PicturePtr mask,
-			  PicturePtr dest,
-			  glamor_pixmap_private * source_pixmap_priv,
-			  glamor_pixmap_private * mask_pixmap_priv,
-			  glamor_pixmap_private * dest_pixmap_priv,
-			  RegionPtr region, Bool force_clip,
-			  INT16 x_source,
-			  INT16 y_source,
-			  INT16 x_mask,
-			  INT16 y_mask,
-			  INT16 x_dest, INT16 y_dest,
-			  CARD16 width, CARD16 height)
+                                    PicturePtr source,
+                                    PicturePtr mask,
+                                    PicturePtr dest,
+                                    glamor_pixmap_private * source_pixmap_priv,
+                                    glamor_pixmap_private * mask_pixmap_priv,
+                                    glamor_pixmap_private * dest_pixmap_priv,
+                                    RegionPtr region, Bool force_clip,
+                                    INT16 x_source,
+                                    INT16 y_source,
+                                    INT16 x_mask,
+                                    INT16 y_mask,
+                                    INT16 x_dest, INT16 y_dest,
+                                    CARD16 width, CARD16 height)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_pixmap_clipped_regions *clipped_dest_regions;
-	glamor_pixmap_clipped_regions *clipped_source_regions;
-	glamor_pixmap_clipped_regions *clipped_mask_regions;
-	int n_dest_regions;
-	int n_mask_regions;
-	int n_source_regions;
-	int i,j,k;
-	int need_clean_source_fbo = 0;
-	int need_clean_mask_fbo = 0;
-	int is_normal_source_fbo = 0;
-	int is_normal_mask_fbo = 0;
-	int fixed_block_width, fixed_block_height;
-	int null_source, null_mask;
-	glamor_pixmap_private * need_free_source_pixmap_priv = NULL;
-	glamor_pixmap_private * need_free_mask_pixmap_priv = NULL;
-	int source_repeat_type = 0, mask_repeat_type = 0;
-	int ok = TRUE;
-
-	if (source->repeat)
-		source_repeat_type = source->repeatType;
-	else
-		source_repeat_type = RepeatNone;
-
-	if (mask && mask->repeat)
-		mask_repeat_type = mask->repeatType;
-	else
-		mask_repeat_type = RepeatNone;
-
-	glamor_priv = dest_pixmap_priv->base.glamor_priv;
-	fixed_block_width = glamor_priv->max_fbo_size;
-	fixed_block_height = glamor_priv->max_fbo_size;
-	/* If we got an totally out-of-box region for a source or mask
-	 * region without repeat, we need to set it as null_source and
-	 * give it a solid color (0,0,0,0). */
-	null_source = 0;
-	null_mask = 0;
-	RegionTranslate(region, -dest->pDrawable->x,
-			-dest->pDrawable->y);
-
-	/* need to transform the dest region to the correct sourcei/mask region.
-	 * it's a little complex, as one single edge of the
-	 * target region may be transformed to cross a block boundary of the
-	 * source or mask. Then it's impossible to handle it as usual way.
-	 * We may have to split the original dest region to smaller region, and
-	 * make sure each region's transformed region can fit into one texture,
-	 * and then continue this loop again, and each time when a transformed region
-	 * cross the bound, we need to copy it to a single pixmap and do the composition
-	 * with the new pixmap. If the transformed region doesn't cross a source/mask's
-	 * boundary then we don't need to copy.
-	 *
-	 */
-	if (source_pixmap_priv
-	    && source->transform
-	    && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		int source_transformed_block_width, source_transformed_block_height;
-		if (!glamor_get_transform_block_size(source->transform,
-					  source_pixmap_priv->large.block_w,
-					  source_pixmap_priv->large.block_h,
-					  &source_transformed_block_width,
-					  &source_transformed_block_height)) {
-			DEBUGF("source block size less than 1, fallback.\n");
-			RegionTranslate(region, dest->pDrawable->x,
-					dest->pDrawable->y);
-			return FALSE;
-		}
-		fixed_block_width = min(fixed_block_width , source_transformed_block_width);
-		fixed_block_height = min(fixed_block_height , source_transformed_block_height);
-		DEBUGF("new source block size %d x %d \n", fixed_block_width, fixed_block_height);
-	}
-
-	if (mask_pixmap_priv
-	    && mask->transform
-	    && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		int mask_transformed_block_width, mask_transformed_block_height;
-		if (!glamor_get_transform_block_size(mask->transform,
-					  mask_pixmap_priv->large.block_w,
-					  mask_pixmap_priv->large.block_h,
-					  &mask_transformed_block_width,
-					  &mask_transformed_block_height)) {
-			DEBUGF("mask block size less than 1, fallback.\n");
-			RegionTranslate(region, dest->pDrawable->x,
-					dest->pDrawable->y);
-			return FALSE;
-		}
-		fixed_block_width = min(fixed_block_width , mask_transformed_block_width);
-		fixed_block_height = min(fixed_block_height , mask_transformed_block_height);
-		DEBUGF("new mask block size %d x %d \n", fixed_block_width, fixed_block_height);
-	}
-
-	/*compute the correct block width and height whose transformed source/mask
-	 *region can fit into one texture.*/
-	if (force_clip || fixed_block_width < glamor_priv->max_fbo_size
-	    || fixed_block_height < glamor_priv->max_fbo_size)
-		clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv,
-									  region,
-									  &n_dest_regions,
-									  fixed_block_width,
-									  fixed_block_height,
-									  0, 0);
-	else
-		clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
-								      region,
-								      &n_dest_regions,
-								      0, 0, 0);
-	DEBUGF("dest clipped result %d region: \n", n_dest_regions);
-	if (source_pixmap_priv
-	    && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv)
-		&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		/* XXX self-copy...*/
-		need_free_source_pixmap_priv = source_pixmap_priv;
-		source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
-		*source_pixmap_priv = *need_free_source_pixmap_priv;
-		need_free_source_pixmap_priv = source_pixmap_priv;
-	}
-	assert(mask_pixmap_priv != dest_pixmap_priv);
-
-	for(i = 0; i < n_dest_regions; i++)
-	{
-		DEBUGF("dest region %d  idx %d\n", i, clipped_dest_regions[i].block_idx);
-		DEBUGRegionPrint(clipped_dest_regions[i].region);
-		SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx);
-		if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-			if (!source->transform && source_repeat_type != RepeatPad) {
-				RegionTranslate(clipped_dest_regions[i].region,
-						x_source - x_dest,
-						y_source - y_dest);
-				clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
-										        clipped_dest_regions[i].region,
-										        &n_source_regions, source_repeat_type,
-											0, 0);
-				is_normal_source_fbo = 1;
-			}
-			else {
-				clipped_source_regions = glamor_compute_transform_clipped_regions(source_pixmap_priv,
-									source->transform,
-									clipped_dest_regions[i].region,
-									&n_source_regions,
-									x_source - x_dest, y_source - y_dest,
-									source_repeat_type, 0, 0);
-				is_normal_source_fbo = 0;
-				if (n_source_regions == 0) {
-					/* Pad the out-of-box region to (0,0,0,0). */
-					null_source = 1;
-					n_source_regions = 1;
-				} else
-					_glamor_process_transformed_clipped_region(source_pixmap_priv,
-						source_repeat_type, clipped_source_regions, &n_source_regions,
-						&need_clean_source_fbo);
-			}
-			DEBUGF("source clipped result %d region: \n", n_source_regions);
-			for(j = 0; j < n_source_regions; j++)
-			{
-				if (is_normal_source_fbo)
-					SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
-							       clipped_source_regions[j].block_idx);
-
-				if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-					if (is_normal_mask_fbo && is_normal_source_fbo) {
-						/* both mask and source are normal fbo box without transform or repeatpad.
-						 * The region is clipped against source and then we clip it against mask here.*/
-						DEBUGF("source region %d  idx %d\n", j, clipped_source_regions[j].block_idx);
-						DEBUGRegionPrint(clipped_source_regions[j].region);
-						RegionTranslate(clipped_source_regions[j].region,
-								- x_source + x_mask,
-							- y_source + y_mask);
-						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
-											     clipped_source_regions[j].region,
-											     &n_mask_regions, mask_repeat_type,
-											     0, 0);
-						is_normal_mask_fbo = 1;
-					} else if (is_normal_mask_fbo && !is_normal_source_fbo) {
-						assert(n_source_regions == 1);
-						/* The source fbo is not a normal fbo box, it has transform or repeatpad.
-						 * the valid clip region should be the clip dest region rather than the
-						 * clip source region.*/
-						RegionTranslate(clipped_dest_regions[i].region,
-								- x_dest + x_mask,
-								- y_dest + y_mask);
-						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
-											     clipped_dest_regions[i].region,
-											     &n_mask_regions, mask_repeat_type,
-											     0, 0);
-						is_normal_mask_fbo = 1;
-					} else {
-						/* This mask region has transform or repeatpad, we need clip it agains the previous
-						 * valid region rather than the mask region. */
-						if (!is_normal_source_fbo)
-							clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
-												mask->transform,
-												clipped_dest_regions[i].region,
-												&n_mask_regions,
-												x_mask - x_dest,
-												y_mask - y_dest,
-												mask_repeat_type, 0, 0);
-						else
-							clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
-												mask->transform,
-												clipped_source_regions[j].region,
-												&n_mask_regions,
-												x_mask - x_source, y_mask - y_source,
-												mask_repeat_type, 0, 0);
-						is_normal_mask_fbo = 0;
-						if (n_mask_regions == 0) {
-						/* Pad the out-of-box region to (0,0,0,0). */
-							null_mask = 1;
-							n_mask_regions = 1;
-						} else
-							_glamor_process_transformed_clipped_region(mask_pixmap_priv,
-								mask_repeat_type, clipped_mask_regions, &n_mask_regions,
-								&need_clean_mask_fbo);
-					}
-					DEBUGF("mask clipped result %d region: \n", n_mask_regions);
+    glamor_screen_private *glamor_priv;
+    glamor_pixmap_clipped_regions *clipped_dest_regions;
+    glamor_pixmap_clipped_regions *clipped_source_regions;
+    glamor_pixmap_clipped_regions *clipped_mask_regions;
+    int n_dest_regions;
+    int n_mask_regions;
+    int n_source_regions;
+    int i, j, k;
+    int need_clean_source_fbo = 0;
+    int need_clean_mask_fbo = 0;
+    int is_normal_source_fbo = 0;
+    int is_normal_mask_fbo = 0;
+    int fixed_block_width, fixed_block_height;
+    int null_source, null_mask;
+    glamor_pixmap_private *need_free_source_pixmap_priv = NULL;
+    glamor_pixmap_private *need_free_mask_pixmap_priv = NULL;
+    int source_repeat_type = 0, mask_repeat_type = 0;
+    int ok = TRUE;
+
+    if (source->repeat)
+        source_repeat_type = source->repeatType;
+    else
+        source_repeat_type = RepeatNone;
+
+    if (mask && mask->repeat)
+        mask_repeat_type = mask->repeatType;
+    else
+        mask_repeat_type = RepeatNone;
+
+    glamor_priv = dest_pixmap_priv->base.glamor_priv;
+    fixed_block_width = glamor_priv->max_fbo_size;
+    fixed_block_height = glamor_priv->max_fbo_size;
+    /* If we got an totally out-of-box region for a source or mask
+     * region without repeat, we need to set it as null_source and
+     * give it a solid color (0,0,0,0). */
+    null_source = 0;
+    null_mask = 0;
+    RegionTranslate(region, -dest->pDrawable->x, -dest->pDrawable->y);
+
+    /* need to transform the dest region to the correct sourcei/mask region.
+     * it's a little complex, as one single edge of the
+     * target region may be transformed to cross a block boundary of the
+     * source or mask. Then it's impossible to handle it as usual way.
+     * We may have to split the original dest region to smaller region, and
+     * make sure each region's transformed region can fit into one texture,
+     * and then continue this loop again, and each time when a transformed region
+     * cross the bound, we need to copy it to a single pixmap and do the composition
+     * with the new pixmap. If the transformed region doesn't cross a source/mask's
+     * boundary then we don't need to copy.
+     *
+     */
+    if (source_pixmap_priv
+        && source->transform
+        && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        int source_transformed_block_width, source_transformed_block_height;
+
+        if (!glamor_get_transform_block_size(source->transform,
+                                             source_pixmap_priv->large.block_w,
+                                             source_pixmap_priv->large.block_h,
+                                             &source_transformed_block_width,
+                                             &source_transformed_block_height))
+        {
+            DEBUGF("source block size less than 1, fallback.\n");
+            RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y);
+            return FALSE;
+        }
+        fixed_block_width =
+            min(fixed_block_width, source_transformed_block_width);
+        fixed_block_height =
+            min(fixed_block_height, source_transformed_block_height);
+        DEBUGF("new source block size %d x %d \n", fixed_block_width,
+               fixed_block_height);
+    }
+
+    if (mask_pixmap_priv
+        && mask->transform && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        int mask_transformed_block_width, mask_transformed_block_height;
+
+        if (!glamor_get_transform_block_size(mask->transform,
+                                             mask_pixmap_priv->large.block_w,
+                                             mask_pixmap_priv->large.block_h,
+                                             &mask_transformed_block_width,
+                                             &mask_transformed_block_height)) {
+            DEBUGF("mask block size less than 1, fallback.\n");
+            RegionTranslate(region, dest->pDrawable->x, dest->pDrawable->y);
+            return FALSE;
+        }
+        fixed_block_width =
+            min(fixed_block_width, mask_transformed_block_width);
+        fixed_block_height =
+            min(fixed_block_height, mask_transformed_block_height);
+        DEBUGF("new mask block size %d x %d \n", fixed_block_width,
+               fixed_block_height);
+    }
+
+    /*compute the correct block width and height whose transformed source/mask
+     *region can fit into one texture.*/
+    if (force_clip || fixed_block_width < glamor_priv->max_fbo_size
+        || fixed_block_height < glamor_priv->max_fbo_size)
+        clipped_dest_regions =
+            glamor_compute_clipped_regions_ext(dest_pixmap_priv, region,
+                                               &n_dest_regions,
+                                               fixed_block_width,
+                                               fixed_block_height, 0, 0);
+    else
+        clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
+                                                              region,
+                                                              &n_dest_regions,
+                                                              0, 0, 0);
+    DEBUGF("dest clipped result %d region: \n", n_dest_regions);
+    if (source_pixmap_priv
+        && (source_pixmap_priv == dest_pixmap_priv ||
+            source_pixmap_priv == mask_pixmap_priv)
+        && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        /* XXX self-copy... */
+        need_free_source_pixmap_priv = source_pixmap_priv;
+        source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
+        *source_pixmap_priv = *need_free_source_pixmap_priv;
+        need_free_source_pixmap_priv = source_pixmap_priv;
+    }
+    assert(mask_pixmap_priv != dest_pixmap_priv);
+
+    for (i = 0; i < n_dest_regions; i++) {
+        DEBUGF("dest region %d  idx %d\n", i,
+               clipped_dest_regions[i].block_idx);
+        DEBUGRegionPrint(clipped_dest_regions[i].region);
+        SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv,
+                               clipped_dest_regions[i].block_idx);
+        if (source_pixmap_priv &&
+            source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+            if (!source->transform && source_repeat_type != RepeatPad) {
+                RegionTranslate(clipped_dest_regions[i].region,
+                                x_source - x_dest, y_source - y_dest);
+                clipped_source_regions =
+                    glamor_compute_clipped_regions(source_pixmap_priv,
+                                                   clipped_dest_regions[i].
+                                                   region, &n_source_regions,
+                                                   source_repeat_type, 0, 0);
+                is_normal_source_fbo = 1;
+            }
+            else {
+                clipped_source_regions =
+                    glamor_compute_transform_clipped_regions(source_pixmap_priv,
+                                                             source->transform,
+                                                             clipped_dest_regions
+                                                             [i].region,
+                                                             &n_source_regions,
+                                                             x_source - x_dest,
+                                                             y_source - y_dest,
+                                                             source_repeat_type,
+                                                             0, 0);
+                is_normal_source_fbo = 0;
+                if (n_source_regions == 0) {
+                    /* Pad the out-of-box region to (0,0,0,0). */
+                    null_source = 1;
+                    n_source_regions = 1;
+                }
+                else
+                    _glamor_process_transformed_clipped_region
+                        (source_pixmap_priv, source_repeat_type,
+                         clipped_source_regions, &n_source_regions,
+                         &need_clean_source_fbo);
+            }
+            DEBUGF("source clipped result %d region: \n", n_source_regions);
+            for (j = 0; j < n_source_regions; j++) {
+                if (is_normal_source_fbo)
+                    SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
+                                           clipped_source_regions[j].block_idx);
+
+                if (mask_pixmap_priv &&
+                    mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                    if (is_normal_mask_fbo && is_normal_source_fbo) {
+                        /* both mask and source are normal fbo box without transform or repeatpad.
+                         * The region is clipped against source and then we clip it against mask here.*/
+                        DEBUGF("source region %d  idx %d\n", j,
+                               clipped_source_regions[j].block_idx);
+                        DEBUGRegionPrint(clipped_source_regions[j].region);
+                        RegionTranslate(clipped_source_regions[j].region,
+                                        -x_source + x_mask, -y_source + y_mask);
+                        clipped_mask_regions =
+                            glamor_compute_clipped_regions(mask_pixmap_priv,
+                                                           clipped_source_regions
+                                                           [j].region,
+                                                           &n_mask_regions,
+                                                           mask_repeat_type, 0,
+                                                           0);
+                        is_normal_mask_fbo = 1;
+                    }
+                    else if (is_normal_mask_fbo && !is_normal_source_fbo) {
+                        assert(n_source_regions == 1);
+                        /* The source fbo is not a normal fbo box, it has transform or repeatpad.
+                         * the valid clip region should be the clip dest region rather than the
+                         * clip source region.*/
+                        RegionTranslate(clipped_dest_regions[i].region,
+                                        -x_dest + x_mask, -y_dest + y_mask);
+                        clipped_mask_regions =
+                            glamor_compute_clipped_regions(mask_pixmap_priv,
+                                                           clipped_dest_regions
+                                                           [i].region,
+                                                           &n_mask_regions,
+                                                           mask_repeat_type, 0,
+                                                           0);
+                        is_normal_mask_fbo = 1;
+                    }
+                    else {
+                        /* This mask region has transform or repeatpad, we need clip it agains the previous
+                         * valid region rather than the mask region. */
+                        if (!is_normal_source_fbo)
+                            clipped_mask_regions =
+                                glamor_compute_transform_clipped_regions
+                                (mask_pixmap_priv, mask->transform,
+                                 clipped_dest_regions[i].region,
+                                 &n_mask_regions, x_mask - x_dest,
+                                 y_mask - y_dest, mask_repeat_type, 0, 0);
+                        else
+                            clipped_mask_regions =
+                                glamor_compute_transform_clipped_regions
+                                (mask_pixmap_priv, mask->transform,
+                                 clipped_source_regions[j].region,
+                                 &n_mask_regions, x_mask - x_source,
+                                 y_mask - y_source, mask_repeat_type, 0, 0);
+                        is_normal_mask_fbo = 0;
+                        if (n_mask_regions == 0) {
+                            /* Pad the out-of-box region to (0,0,0,0). */
+                            null_mask = 1;
+                            n_mask_regions = 1;
+                        }
+                        else
+                            _glamor_process_transformed_clipped_region
+                                (mask_pixmap_priv, mask_repeat_type,
+                                 clipped_mask_regions, &n_mask_regions,
+                                 &need_clean_mask_fbo);
+                    }
+                    DEBUGF("mask clipped result %d region: \n", n_mask_regions);
 
 #define COMPOSITE_REGION(region) do {				\
 	if (!glamor_composite_clipped_region(op,		\
@@ -1186,139 +1263,157 @@ glamor_composite_largepixmap_region(CARD8 op,
 	}							\
    } while(0)
 
-					for(k = 0; k < n_mask_regions; k++)
-					{
-						DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
-						DEBUGRegionPrint(clipped_mask_regions[k].region);
-						if (is_normal_mask_fbo) {
-							SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
-								       clipped_mask_regions[k].block_idx);
-							DEBUGF("mask fbo off %d %d \n",
-								mask_pixmap_priv->large.box.x1,
-								mask_pixmap_priv->large.box.y1);
-							DEBUGF("start composite mask hasn't transform.\n");
-							RegionTranslate(clipped_mask_regions[k].region,
-									x_dest - x_mask + dest->pDrawable->x,
-									y_dest - y_mask + dest->pDrawable->y);
-							COMPOSITE_REGION(clipped_mask_regions[k].region);
-						} else if (!is_normal_mask_fbo && !is_normal_source_fbo) {
-							DEBUGF("start composite both mask and source have transform.\n");
-							RegionTranslate(clipped_dest_regions[i].region,
-									dest->pDrawable->x,
-									dest->pDrawable->y);
-							COMPOSITE_REGION(clipped_dest_regions[i].region);
-						} else {
-							DEBUGF("start composite only mask has transform.\n");
-							RegionTranslate(clipped_source_regions[j].region,
-									x_dest - x_source + dest->pDrawable->x,
-									y_dest - y_source + dest->pDrawable->y);
-							COMPOSITE_REGION(clipped_source_regions[j].region);
-						}
-						RegionDestroy(clipped_mask_regions[k].region);
-					}
-					free(clipped_mask_regions);
-					if (null_mask) null_mask = 0;
-					if (need_clean_mask_fbo) {
-						assert(is_normal_mask_fbo == 0);
-						glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
-						mask_pixmap_priv->base.fbo = NULL;
-						need_clean_mask_fbo = 0;
-					}
-				} else {
-					if (is_normal_source_fbo) {
-						RegionTranslate(clipped_source_regions[j].region,
-								-x_source + x_dest + dest->pDrawable->x,
-								-y_source + y_dest + dest->pDrawable->y);
-						COMPOSITE_REGION(clipped_source_regions[j].region);
-					} else {
-						/* Source has transform or repeatPad. dest regions is the right
-						 * region to do the composite. */
-						RegionTranslate(clipped_dest_regions[i].region,
-								dest->pDrawable->x,
-								dest->pDrawable->y);
-						COMPOSITE_REGION(clipped_dest_regions[i].region);
-					}
-				}
-				if (clipped_source_regions && clipped_source_regions[j].region)
-					RegionDestroy(clipped_source_regions[j].region);
-			}
-			free(clipped_source_regions);
-			if (null_source) null_source = 0;
-			if (need_clean_source_fbo) {
-				assert(is_normal_source_fbo == 0);
-				glamor_destroy_fbo(source_pixmap_priv->base.fbo);
-				source_pixmap_priv->base.fbo = NULL;
-				need_clean_source_fbo = 0;
-			}
-		}
-		else {
-			if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-				if (!mask->transform && mask_repeat_type != RepeatPad) {
-					RegionTranslate(clipped_dest_regions[i].region,
-							x_mask - x_dest,
-							y_mask - y_dest);
-					clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
-								        clipped_dest_regions[i].region,
-								        &n_mask_regions, mask_repeat_type, 0, 0);
-					is_normal_mask_fbo = 1;
-				}
-				else {
-					clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
-										mask->transform,
-										clipped_dest_regions[i].region,
-										&n_mask_regions,
-										x_mask - x_dest, y_mask - y_dest,
-										mask_repeat_type, 0, 0);
-					is_normal_mask_fbo = 0;
-					if (n_mask_regions == 0) {
-						/* Pad the out-of-box region to (0,0,0,0). */
-						null_mask = 1;
-						n_mask_regions = 1;
-					} else
-						_glamor_process_transformed_clipped_region(mask_pixmap_priv,
-							mask_repeat_type, clipped_mask_regions, &n_mask_regions,
-							&need_clean_mask_fbo);
-				}
-
-				for(k = 0; k < n_mask_regions; k++)
-				{
-					DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
-					DEBUGRegionPrint(clipped_mask_regions[k].region);
-					if (is_normal_mask_fbo) {
-						SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
-								       clipped_mask_regions[k].block_idx);
-						RegionTranslate(clipped_mask_regions[k].region,
-								x_dest - x_mask + dest->pDrawable->x,
-								y_dest - y_mask + dest->pDrawable->y);
-						COMPOSITE_REGION(clipped_mask_regions[k].region);
-					} else {
-						RegionTranslate(clipped_dest_regions[i].region,
-								dest->pDrawable->x,
-								dest->pDrawable->y);
-						COMPOSITE_REGION(clipped_dest_regions[i].region);
-					}
-					RegionDestroy(clipped_mask_regions[k].region);
-				}
-				free(clipped_mask_regions);
-				if (null_mask) null_mask = 0;
-				if (need_clean_mask_fbo) {
-					glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
-					mask_pixmap_priv->base.fbo = NULL;
-					need_clean_mask_fbo = 0;
-				}
-			}
-			else {
-				RegionTranslate(clipped_dest_regions[i].region,
-						dest->pDrawable->x,
-						dest->pDrawable->y);
-				COMPOSITE_REGION(clipped_dest_regions[i].region);
-			}
-		}
-		RegionDestroy(clipped_dest_regions[i].region);
-	}
-	free(clipped_dest_regions);
-	free(need_free_source_pixmap_priv);
-	free(need_free_mask_pixmap_priv);
-	ok = TRUE;
-	return ok;
+                    for (k = 0; k < n_mask_regions; k++) {
+                        DEBUGF("mask region %d  idx %d\n", k,
+                               clipped_mask_regions[k].block_idx);
+                        DEBUGRegionPrint(clipped_mask_regions[k].region);
+                        if (is_normal_mask_fbo) {
+                            SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+                                                   clipped_mask_regions[k].
+                                                   block_idx);
+                            DEBUGF("mask fbo off %d %d \n",
+                                   mask_pixmap_priv->large.box.x1,
+                                   mask_pixmap_priv->large.box.y1);
+                            DEBUGF("start composite mask hasn't transform.\n");
+                            RegionTranslate(clipped_mask_regions[k].region,
+                                            x_dest - x_mask +
+                                            dest->pDrawable->x,
+                                            y_dest - y_mask +
+                                            dest->pDrawable->y);
+                            COMPOSITE_REGION(clipped_mask_regions[k].region);
+                        }
+                        else if (!is_normal_mask_fbo && !is_normal_source_fbo) {
+                            DEBUGF
+                                ("start composite both mask and source have transform.\n");
+                            RegionTranslate(clipped_dest_regions[i].region,
+                                            dest->pDrawable->x,
+                                            dest->pDrawable->y);
+                            COMPOSITE_REGION(clipped_dest_regions[i].region);
+                        }
+                        else {
+                            DEBUGF
+                                ("start composite only mask has transform.\n");
+                            RegionTranslate(clipped_source_regions[j].region,
+                                            x_dest - x_source +
+                                            dest->pDrawable->x,
+                                            y_dest - y_source +
+                                            dest->pDrawable->y);
+                            COMPOSITE_REGION(clipped_source_regions[j].region);
+                        }
+                        RegionDestroy(clipped_mask_regions[k].region);
+                    }
+                    free(clipped_mask_regions);
+                    if (null_mask)
+                        null_mask = 0;
+                    if (need_clean_mask_fbo) {
+                        assert(is_normal_mask_fbo == 0);
+                        glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+                        mask_pixmap_priv->base.fbo = NULL;
+                        need_clean_mask_fbo = 0;
+                    }
+                }
+                else {
+                    if (is_normal_source_fbo) {
+                        RegionTranslate(clipped_source_regions[j].region,
+                                        -x_source + x_dest + dest->pDrawable->x,
+                                        -y_source + y_dest +
+                                        dest->pDrawable->y);
+                        COMPOSITE_REGION(clipped_source_regions[j].region);
+                    }
+                    else {
+                        /* Source has transform or repeatPad. dest regions is the right
+                         * region to do the composite. */
+                        RegionTranslate(clipped_dest_regions[i].region,
+                                        dest->pDrawable->x, dest->pDrawable->y);
+                        COMPOSITE_REGION(clipped_dest_regions[i].region);
+                    }
+                }
+                if (clipped_source_regions && clipped_source_regions[j].region)
+                    RegionDestroy(clipped_source_regions[j].region);
+            }
+            free(clipped_source_regions);
+            if (null_source)
+                null_source = 0;
+            if (need_clean_source_fbo) {
+                assert(is_normal_source_fbo == 0);
+                glamor_destroy_fbo(source_pixmap_priv->base.fbo);
+                source_pixmap_priv->base.fbo = NULL;
+                need_clean_source_fbo = 0;
+            }
+        }
+        else {
+            if (mask_pixmap_priv &&
+                mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                if (!mask->transform && mask_repeat_type != RepeatPad) {
+                    RegionTranslate(clipped_dest_regions[i].region,
+                                    x_mask - x_dest, y_mask - y_dest);
+                    clipped_mask_regions =
+                        glamor_compute_clipped_regions(mask_pixmap_priv,
+                                                       clipped_dest_regions[i].
+                                                       region, &n_mask_regions,
+                                                       mask_repeat_type, 0, 0);
+                    is_normal_mask_fbo = 1;
+                }
+                else {
+                    clipped_mask_regions =
+                        glamor_compute_transform_clipped_regions
+                        (mask_pixmap_priv, mask->transform,
+                         clipped_dest_regions[i].region, &n_mask_regions,
+                         x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0,
+                         0);
+                    is_normal_mask_fbo = 0;
+                    if (n_mask_regions == 0) {
+                        /* Pad the out-of-box region to (0,0,0,0). */
+                        null_mask = 1;
+                        n_mask_regions = 1;
+                    }
+                    else
+                        _glamor_process_transformed_clipped_region
+                            (mask_pixmap_priv, mask_repeat_type,
+                             clipped_mask_regions, &n_mask_regions,
+                             &need_clean_mask_fbo);
+                }
+
+                for (k = 0; k < n_mask_regions; k++) {
+                    DEBUGF("mask region %d  idx %d\n", k,
+                           clipped_mask_regions[k].block_idx);
+                    DEBUGRegionPrint(clipped_mask_regions[k].region);
+                    if (is_normal_mask_fbo) {
+                        SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+                                               clipped_mask_regions[k].
+                                               block_idx);
+                        RegionTranslate(clipped_mask_regions[k].region,
+                                        x_dest - x_mask + dest->pDrawable->x,
+                                        y_dest - y_mask + dest->pDrawable->y);
+                        COMPOSITE_REGION(clipped_mask_regions[k].region);
+                    }
+                    else {
+                        RegionTranslate(clipped_dest_regions[i].region,
+                                        dest->pDrawable->x, dest->pDrawable->y);
+                        COMPOSITE_REGION(clipped_dest_regions[i].region);
+                    }
+                    RegionDestroy(clipped_mask_regions[k].region);
+                }
+                free(clipped_mask_regions);
+                if (null_mask)
+                    null_mask = 0;
+                if (need_clean_mask_fbo) {
+                    glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+                    mask_pixmap_priv->base.fbo = NULL;
+                    need_clean_mask_fbo = 0;
+                }
+            }
+            else {
+                RegionTranslate(clipped_dest_regions[i].region,
+                                dest->pDrawable->x, dest->pDrawable->y);
+                COMPOSITE_REGION(clipped_dest_regions[i].region);
+            }
+        }
+        RegionDestroy(clipped_dest_regions[i].region);
+    }
+    free(clipped_dest_regions);
+    free(need_free_source_pixmap_priv);
+    free(need_free_mask_pixmap_priv);
+    ok = TRUE;
+    return ok;
 }
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 7d5ffbb..f2afbc3 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -37,30 +37,30 @@
 enum glamor_pixmap_status
 glamor_upload_picture_to_texture(PicturePtr picture)
 {
-	PixmapPtr pixmap;
-	assert(picture->pDrawable);
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+    PixmapPtr pixmap;
 
-	return glamor_upload_pixmap_to_texture(pixmap);
-}
+    assert(picture->pDrawable);
+    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 
+    return glamor_upload_pixmap_to_texture(pixmap);
+}
 
 Bool
 glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
 {
-	if (!picture || !picture->pDrawable)
-		return TRUE;
+    if (!picture || !picture->pDrawable)
+        return TRUE;
 
-	return glamor_prepare_access(picture->pDrawable, access);
+    return glamor_prepare_access(picture->pDrawable, access);
 }
 
 void
 glamor_finish_access_picture(PicturePtr picture, glamor_access_t access)
 {
-	if (!picture || !picture->pDrawable)
-		return;
+    if (!picture || !picture->pDrawable)
+        return;
 
-	glamor_finish_access(picture->pDrawable, access);
+    glamor_finish_access(picture->pDrawable, access);
 }
 
 /* 
@@ -71,61 +71,62 @@ glamor_finish_access_picture(PicturePtr picture, glamor_access_t access)
 int
 glamor_create_picture(PicturePtr picture)
 {
-	PixmapPtr pixmap;
-	glamor_pixmap_private *pixmap_priv;
-
-	if (!picture || !picture->pDrawable)
-		return 0;
-
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (!pixmap_priv) {
-	/* We must create a pixmap priv to track the picture format even
- 	 * if the pixmap is a pure in memory pixmap. The reason is that
- 	 * we may need to upload this pixmap to a texture on the fly. During
- 	 * the uploading, we need to know the picture format. */
-		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
-		pixmap_priv = glamor_get_pixmap_private(pixmap);
-	} else {
-		if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-			/* If the picture format is not compatible with glamor fbo format,
-			 * we have to mark this pixmap as a separated texture, and don't
-			 * fallback to DDX layer. */
-			if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-			    && !glamor_pict_format_is_compatible(picture->format,
-								 pixmap->drawable.depth))
-				glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
-		}
-	}
-
-	pixmap_priv->base.is_picture = 1;
-	pixmap_priv->base.picture = picture;
-
-	return miCreatePicture(picture);
+    PixmapPtr pixmap;
+    glamor_pixmap_private *pixmap_priv;
+
+    if (!picture || !picture->pDrawable)
+        return 0;
+
+    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (!pixmap_priv) {
+        /* We must create a pixmap priv to track the picture format even
+         * if the pixmap is a pure in memory pixmap. The reason is that
+         * we may need to upload this pixmap to a texture on the fly. During
+         * the uploading, we need to know the picture format. */
+        glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+        pixmap_priv = glamor_get_pixmap_private(pixmap);
+    }
+    else {
+        if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+            /* If the picture format is not compatible with glamor fbo format,
+             * we have to mark this pixmap as a separated texture, and don't
+             * fallback to DDX layer. */
+            if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
+                && !glamor_pict_format_is_compatible(picture->format,
+                                                     pixmap->drawable.depth))
+                glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
+        }
+    }
+
+    pixmap_priv->base.is_picture = 1;
+    pixmap_priv->base.picture = picture;
+
+    return miCreatePicture(picture);
 }
 
 void
 glamor_destroy_picture(PicturePtr picture)
 {
-	PixmapPtr pixmap;
-	glamor_pixmap_private *pixmap_priv;
+    PixmapPtr pixmap;
+    glamor_pixmap_private *pixmap_priv;
 
-	if (!picture || !picture->pDrawable)
-		return;
+    if (!picture || !picture->pDrawable)
+        return;
 
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
+    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (pixmap_priv) {
-		pixmap_priv->base.is_picture = 0;
-		pixmap_priv->base.picture = NULL;
-	}
-	miDestroyPicture(picture);
+    if (pixmap_priv) {
+        pixmap_priv->base.is_picture = 0;
+        pixmap_priv->base.picture = NULL;
+    }
+    miDestroyPicture(picture);
 }
 
 void
 glamor_picture_format_fixup(PicturePtr picture,
-			    glamor_pixmap_private * pixmap_priv)
+                            glamor_pixmap_private * pixmap_priv)
 {
-	pixmap_priv->base.picture = picture;
+    pixmap_priv->base.picture = picture;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index be7aa3d..69e581c 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -37,21 +37,20 @@
  */
 void
 glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
-			   int *x, int *y)
+                           int *x, int *y)
 {
 #ifdef COMPOSITE
-	if (drawable->type == DRAWABLE_WINDOW) {
-		*x = -pixmap->screen_x;
-		*y = -pixmap->screen_y;
-		return;
-	}
+    if (drawable->type == DRAWABLE_WINDOW) {
+        *x = -pixmap->screen_x;
+        *y = -pixmap->screen_y;
+        return;
+    }
 #endif
 
-	*x = 0;
-	*y = 0;
+    *x = 0;
+    *y = 0;
 }
 
-
 void
 glamor_pixmap_init(ScreenPtr screen)
 {
@@ -64,173 +63,168 @@ glamor_pixmap_fini(ScreenPtr screen)
 }
 
 void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int width, int height)
+glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0,
+                                  int width, int height)
 {
-	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+    glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+
+    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 #ifndef GLAMOR_GLES2
-	dispatch->glMatrixMode(GL_PROJECTION);
-	dispatch->glLoadIdentity();
-	dispatch->glMatrixMode(GL_MODELVIEW);
-	dispatch->glLoadIdentity();
+    dispatch->glMatrixMode(GL_PROJECTION);
+    dispatch->glLoadIdentity();
+    dispatch->glMatrixMode(GL_MODELVIEW);
+    dispatch->glLoadIdentity();
 #endif
-	dispatch->glViewport(x0, y0,
-			     width, height);
+    dispatch->glViewport(x0, y0, width, height);
 
-	glamor_put_dispatch(fbo->glamor_priv);
+    glamor_put_dispatch(fbo->glamor_priv);
 }
 
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
-	int w,h;
+    int w, h;
 
-	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
-	glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
-					  w, h);
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
+    glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h);
 }
 
 int
 glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
 {
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return -1;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return -1;
 
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	return 0;
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    return 0;
 }
 
 int
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
-	int err;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
+    int err;
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	err = glamor_set_destination_pixmap_priv(pixmap_priv);
-	return err;
+    err = glamor_set_destination_pixmap_priv(pixmap_priv);
+    return err;
 }
 
 Bool
 glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 {
-	if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
-		return GL_TRUE;
-	}
+    if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+        return GL_TRUE;
+    }
 
-	glamor_fallback("unsupported planemask %lx\n", planemask);
-	return GL_FALSE;
+    glamor_fallback("unsupported planemask %lx\n", planemask);
+    return GL_FALSE;
 }
 
 Bool
 glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 {
 #ifndef GLAMOR_GLES2
-	if (alu == GXcopy) {
-		dispatch->glDisable(GL_COLOR_LOGIC_OP);
-		return TRUE;
-	}
-	dispatch->glEnable(GL_COLOR_LOGIC_OP);
-	switch (alu) {
-	case GXclear:
-		dispatch->glLogicOp(GL_CLEAR);
-		break;
-	case GXand:
-		dispatch->glLogicOp(GL_AND);
-		break;
-	case GXandReverse:
-		dispatch->glLogicOp(GL_AND_REVERSE);
-		break;
-	case GXandInverted:
-		dispatch->glLogicOp(GL_AND_INVERTED);
-		break;
-	case GXnoop:
-		dispatch->glLogicOp(GL_NOOP);
-		break;
-	case GXxor:
-		dispatch->glLogicOp(GL_XOR);
-		break;
-	case GXor:
-		dispatch->glLogicOp(GL_OR);
-		break;
-	case GXnor:
-		dispatch->glLogicOp(GL_NOR);
-		break;
-	case GXequiv:
-		dispatch->glLogicOp(GL_EQUIV);
-		break;
-	case GXinvert:
-		dispatch->glLogicOp(GL_INVERT);
-		break;
-	case GXorReverse:
-		dispatch->glLogicOp(GL_OR_REVERSE);
-		break;
-	case GXcopyInverted:
-		dispatch->glLogicOp(GL_COPY_INVERTED);
-		break;
-	case GXorInverted:
-		dispatch->glLogicOp(GL_OR_INVERTED);
-		break;
-	case GXnand:
-		dispatch->glLogicOp(GL_NAND);
-		break;
-	case GXset:
-		dispatch->glLogicOp(GL_SET);
-		break;
-	default:
-		glamor_fallback("unsupported alu %x\n", alu);
-		return FALSE;
-	}
+    if (alu == GXcopy) {
+        dispatch->glDisable(GL_COLOR_LOGIC_OP);
+        return TRUE;
+    }
+    dispatch->glEnable(GL_COLOR_LOGIC_OP);
+    switch (alu) {
+    case GXclear:
+        dispatch->glLogicOp(GL_CLEAR);
+        break;
+    case GXand:
+        dispatch->glLogicOp(GL_AND);
+        break;
+    case GXandReverse:
+        dispatch->glLogicOp(GL_AND_REVERSE);
+        break;
+    case GXandInverted:
+        dispatch->glLogicOp(GL_AND_INVERTED);
+        break;
+    case GXnoop:
+        dispatch->glLogicOp(GL_NOOP);
+        break;
+    case GXxor:
+        dispatch->glLogicOp(GL_XOR);
+        break;
+    case GXor:
+        dispatch->glLogicOp(GL_OR);
+        break;
+    case GXnor:
+        dispatch->glLogicOp(GL_NOR);
+        break;
+    case GXequiv:
+        dispatch->glLogicOp(GL_EQUIV);
+        break;
+    case GXinvert:
+        dispatch->glLogicOp(GL_INVERT);
+        break;
+    case GXorReverse:
+        dispatch->glLogicOp(GL_OR_REVERSE);
+        break;
+    case GXcopyInverted:
+        dispatch->glLogicOp(GL_COPY_INVERTED);
+        break;
+    case GXorInverted:
+        dispatch->glLogicOp(GL_OR_INVERTED);
+        break;
+    case GXnand:
+        dispatch->glLogicOp(GL_NAND);
+        break;
+    case GXset:
+        dispatch->glLogicOp(GL_SET);
+        break;
+    default:
+        glamor_fallback("unsupported alu %x\n", alu);
+        return FALSE;
+    }
 #else
-	if (alu != GXcopy)
-		return FALSE;
+    if (alu != GXcopy)
+        return FALSE;
 #endif
-	return TRUE;
+    return TRUE;
 }
 
 static void *
-_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert)
+_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
+                            int stride, int revert)
 {
-	PictFormatShort dst_format, src_format;
-	pixman_image_t *dst_image;
-	pixman_image_t *src_image;
-	int src_stride;
-
-	if (revert == REVERT_UPLOADING_A1) {
-		src_format = PICT_a1;
-		dst_format = PICT_a8;
-		src_stride = PixmapBytePad(w, 1);
-	} else {
-		dst_format = PICT_a1;
-		src_format = PICT_a8;
-		src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
-	}
-
-	dst_image = pixman_image_create_bits(dst_format,
-					     w, h,
-					     dst_bits,
-					     stride);
-	if (dst_image == NULL) {
-		return NULL;
-	}
-
-	src_image = pixman_image_create_bits(src_format,
-					     w, h,
-					     src_bits,
-					     src_stride);
-
-	if (src_image == NULL) {
-		pixman_image_unref(dst_image);
-		return NULL;
-	}
-
-	pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
-			       0, 0, 0, 0, 0, 0,
-			       w,h);
-
-	pixman_image_unref(src_image);
-	pixman_image_unref(dst_image);
-	return dst_bits;
+    PictFormatShort dst_format, src_format;
+    pixman_image_t *dst_image;
+    pixman_image_t *src_image;
+    int src_stride;
+
+    if (revert == REVERT_UPLOADING_A1) {
+        src_format = PICT_a1;
+        dst_format = PICT_a8;
+        src_stride = PixmapBytePad(w, 1);
+    }
+    else {
+        dst_format = PICT_a1;
+        src_format = PICT_a8;
+        src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+    }
+
+    dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
+    if (dst_image == NULL) {
+        return NULL;
+    }
+
+    src_image = pixman_image_create_bits(src_format,
+                                         w, h, src_bits, src_stride);
+
+    if (src_image == NULL) {
+        pixman_image_unref(dst_image);
+        return NULL;
+    }
+
+    pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
+                           0, 0, 0, 0, 0, 0, w, h);
+
+    pixman_image_unref(src_image);
+    pixman_image_unref(dst_image);
+    return dst_bits;
 }
 
 #define ADJUST_BITS(d, src_bits, dst_bits)	(((dst_bits) == (src_bits)) ? (d) : 				\
@@ -273,76 +267,77 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 	} while (0)
 
 static void *
-_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
+                                 int stride, int no_alpha, int revert,
+                                 int swap_rb)
 {
-	int x,y;
-	unsigned int *words, *saved_words, *source_words;
-	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
-
-	source_words = src_bits;
-	words = dst_bits;
-	saved_words = words;
-
-	for (y = 0; y < h; y++)
-	{
-		DEBUGF("Line %d :  ", y);
-		for (x = 0; x < w; x++)
-		{
-			unsigned int pixel = source_words[x];
-
-			if (revert == REVERT_DOWNLOADING_2_10_10_10)
-				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-						  24, 8, 16, 8, 8, 8, 0, 8,
-						  30, 2, 20, 10, 10, 10, 0, 10);
-			else
-				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-						  30, 2, 20, 10, 10, 10, 0, 10,
-						  24, 8, 16, 8, 8, 8, 0, 8);
-			DEBUGF("%x:%x ", pixel, words[x]);
-		}
-		DEBUGF("\n");
-		words += stride / sizeof(*words);
-		source_words += stride / sizeof(*words);
-	}
-	DEBUGF("\n");
-	return saved_words;
+    int x, y;
+    unsigned int *words, *saved_words, *source_words;
+    int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+                 swap_rb == SWAP_NONE_UPLOADING);
+
+    source_words = src_bits;
+    words = dst_bits;
+    saved_words = words;
+
+    for (y = 0; y < h; y++) {
+        DEBUGF("Line %d :  ", y);
+        for (x = 0; x < w; x++) {
+            unsigned int pixel = source_words[x];
+
+            if (revert == REVERT_DOWNLOADING_2_10_10_10)
+                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                                  24, 8, 16, 8, 8, 8, 0, 8,
+                                  30, 2, 20, 10, 10, 10, 0, 10);
+            else
+                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                                  30, 2, 20, 10, 10, 10, 0, 10,
+                                  24, 8, 16, 8, 8, 8, 0, 8);
+            DEBUGF("%x:%x ", pixel, words[x]);
+        }
+        DEBUGF("\n");
+        words += stride / sizeof(*words);
+        source_words += stride / sizeof(*words);
+    }
+    DEBUGF("\n");
+    return saved_words;
 
 }
 
 static void *
-_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
+                              int stride, int no_alpha, int revert, int swap_rb)
 {
-	int x,y;
-	unsigned short *words, *saved_words, *source_words;
-	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
-
-	words = dst_bits;
-	source_words = src_bits;
-	saved_words = words;
-
-	for (y = 0; y < h; y++)
-	{
-		DEBUGF("Line %d :  ", y);
-		for (x = 0; x < w; x++)
-		{
-			unsigned short pixel = source_words[x];
-
-			if (revert == REVERT_DOWNLOADING_1_5_5_5)
-				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-						  0, 1, 1, 5, 6, 5, 11, 5,
-						  15, 1, 10, 5, 5, 5, 0, 5);
-			else
-				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
-						  15, 1, 10, 5, 5, 5, 0, 5,
-						  0, 1, 1, 5, 6, 5, 11, 5);
-			DEBUGF("%04x:%04x ", pixel, words[x]);
-		}
-		DEBUGF("\n");
-		words += stride / sizeof(*words);
-		source_words += stride / sizeof(*words);
-	}
-	DEBUGF("\n");
-	return saved_words;
+    int x, y;
+    unsigned short *words, *saved_words, *source_words;
+    int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+                 swap_rb == SWAP_NONE_UPLOADING);
+
+    words = dst_bits;
+    source_words = src_bits;
+    saved_words = words;
+
+    for (y = 0; y < h; y++) {
+        DEBUGF("Line %d :  ", y);
+        for (x = 0; x < w; x++) {
+            unsigned short pixel = source_words[x];
+
+            if (revert == REVERT_DOWNLOADING_1_5_5_5)
+                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                                  0, 1, 1, 5, 6, 5, 11, 5,
+                                  15, 1, 10, 5, 5, 5, 0, 5);
+            else
+                GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+                                  15, 1, 10, 5, 5, 5, 0, 5,
+                                  0, 1, 1, 5, 6, 5, 11, 5);
+            DEBUGF("%04x:%04x ", pixel, words[x]);
+        }
+        DEBUGF("\n");
+        words += stride / sizeof(*words);
+        source_words += stride / sizeof(*words);
+    }
+    DEBUGF("\n");
+    return saved_words;
 }
 
 /*
@@ -364,18 +359,28 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int
  */
 
 static void *
-glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
+                             int stride, int no_alpha, int revert, int swap_rb)
 {
-	if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
-		return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride, revert);
-	} else if (revert == REVERT_DOWNLOADING_2_10_10_10 || revert == REVERT_UPLOADING_2_10_10_10) {
-		return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
-	} else if (revert == REVERT_DOWNLOADING_1_5_5_5 || revert == REVERT_UPLOADING_1_5_5_5) {
-		return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
-	} else
-		ErrorF("convert a non-supported mode %x.\n", revert);
-
-	return NULL;
+    if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
+        return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride,
+                                           revert);
+    }
+    else if (revert == REVERT_DOWNLOADING_2_10_10_10 ||
+             revert == REVERT_UPLOADING_2_10_10_10) {
+        return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
+                                                stride, no_alpha, revert,
+                                                swap_rb);
+    }
+    else if (revert == REVERT_DOWNLOADING_1_5_5_5 ||
+             revert == REVERT_UPLOADING_1_5_5_5) {
+        return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
+                                             no_alpha, revert, swap_rb);
+    }
+    else
+        ErrorF("convert a non-supported mode %x.\n", revert);
+
+    return NULL;
 }
 
 /**
@@ -385,198 +390,182 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int s
 int in_restore = 0;
 static void
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
-				  GLenum format,
-				  GLenum type,
-				  int x, int y, int w, int h,
-				  void *bits, int pbo)
+                                  GLenum format,
+                                  GLenum type,
+                                  int x, int y, int w, int h,
+                                  void *bits, int pbo)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch;
-	int non_sub = 0;
-	unsigned int iformat = 0;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (*tex == 0) {
-		dispatch->glGenTextures(1, tex);
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-			gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
-		else
-			iformat = format;
-		non_sub = 1;
-		assert(x == 0 && y == 0);
-	}
-
-	dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
-	if (bits == NULL)
-		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-				       pbo);
-	if (non_sub)
-		dispatch->glTexImage2D(GL_TEXTURE_2D,
-				       0, iformat, w, h, 0,
-				       format, type,
-				       bits);
-	else
-		dispatch->glTexSubImage2D(GL_TEXTURE_2D,
-					  0, x, y, w, h,
-					  format, type,
-					  bits);
-
-	if (bits == NULL)
-		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+    glamor_gl_dispatch *dispatch;
+    int non_sub = 0;
+    unsigned int iformat = 0;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (*tex == 0) {
+        dispatch->glGenTextures(1, tex);
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+            gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+        else
+            iformat = format;
+        non_sub = 1;
+        assert(x == 0 && y == 0);
+    }
+
+    dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+    if (bits == NULL)
+        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
+    if (non_sub)
+        dispatch->glTexImage2D(GL_TEXTURE_2D,
+                               0, iformat, w, h, 0, format, type, bits);
+    else
+        dispatch->glTexSubImage2D(GL_TEXTURE_2D,
+                                  0, x, y, w, h, format, type, bits);
+
+    if (bits == NULL)
+        dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
-_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
-				     int no_alpha, int revert,
-				     int swap_rb, int x, int y, int w, int h,
-				     int stride, void* bits, int pbo)
+_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
+                                      GLenum type, int no_alpha, int revert,
+                                      int swap_rb, int x, int y, int w, int h,
+                                      int stride, void *bits, int pbo)
 {
-	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch;
-	static float vertices[8];
-	static float texcoords[8] = { 0, 1,
-		1, 1,
-		1, 0,
-		0, 0
-	};
-	static float texcoords_inv[8] = { 0, 0,
-		1, 0,
-		1, 1,
-		0, 1
-	};
-	float *ptexcoords;
-	float dst_xscale, dst_yscale;
-	GLuint tex = 0;
-	int need_flip;
-	int need_free_bits = 0;
-
-	need_flip = !glamor_priv->yInverted;
-
-	if (bits == NULL)
-		goto ready_to_upload;
-
-	if (revert > REVERT_NORMAL) {
-		/* XXX if we are restoring the pixmap, then we may not need to allocate
-		 * new buffer */
-		void *converted_bits;
-
-		if (pixmap->drawable.depth == 1)
-			stride = (((w * 8 + 7) / 8) + 3) & ~3;
-
-		converted_bits = malloc(h * stride);
-
-		if (converted_bits == NULL)
-			return FALSE;
-		bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
-						    stride,
-						    no_alpha, revert, swap_rb);
-		if (bits == NULL) {
-			ErrorF("Failed to convert pixmap no_alpha %d,"
-				"revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
-			return FALSE;
-		}
-		no_alpha = 0;
-		revert = REVERT_NONE;
-		swap_rb = SWAP_NONE_UPLOADING;
-		need_free_bits = TRUE;
-	}
-
-ready_to_upload:
-
-	/* Try fast path firstly, upload the pixmap to the texture attached
-	 * to the fbo directly. */
-	if (no_alpha == 0
-	    && revert == REVERT_NONE
-	    && swap_rb == SWAP_NONE_UPLOADING
-	    && !need_flip
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+    glamor_gl_dispatch *dispatch;
+    static float vertices[8];
+
+    static float texcoords[8] = { 0, 1,
+        1, 1,
+        1, 0,
+        0, 0
+    };
+    static float texcoords_inv[8] = { 0, 0,
+        1, 0,
+        1, 1,
+        0, 1
+    };
+    float *ptexcoords;
+    float dst_xscale, dst_yscale;
+    GLuint tex = 0;
+    int need_flip;
+    int need_free_bits = 0;
+
+    need_flip = !glamor_priv->yInverted;
+
+    if (bits == NULL)
+        goto ready_to_upload;
+
+    if (revert > REVERT_NORMAL) {
+        /* XXX if we are restoring the pixmap, then we may not need to allocate
+         * new buffer */
+        void *converted_bits;
+
+        if (pixmap->drawable.depth == 1)
+            stride = (((w * 8 + 7) / 8) + 3) & ~3;
+
+        converted_bits = malloc(h * stride);
+
+        if (converted_bits == NULL)
+            return FALSE;
+        bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
+                                            stride, no_alpha, revert, swap_rb);
+        if (bits == NULL) {
+            ErrorF("Failed to convert pixmap no_alpha %d,"
+                   "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
+            return FALSE;
+        }
+        no_alpha = 0;
+        revert = REVERT_NONE;
+        swap_rb = SWAP_NONE_UPLOADING;
+        need_free_bits = TRUE;
+    }
+
+ ready_to_upload:
+
+    /* Try fast path firstly, upload the pixmap to the texture attached
+     * to the fbo directly. */
+    if (no_alpha == 0
+        && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING && !need_flip
 #ifdef WALKAROUND_LARGE_TEXTURE_MAP
-	    && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
+        && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
 #endif
-		) {
-		int fbo_x_off, fbo_y_off;
-		assert(pixmap_priv->base.fbo->tex);
-		pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
-
-		assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
-		assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
-		assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
-		__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
-						  format, type,
-						  x + fbo_x_off, y + fbo_y_off, w, h,
-						  bits, pbo);
-		return TRUE;
-	}
-
-	if (need_flip)
-		ptexcoords = texcoords;
-	else
-		ptexcoords = texcoords_inv;
-
-	pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
-	glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
-				     dst_yscale,
-				     x, y,
-				     x + w, y + h,
-				     glamor_priv->yInverted,
-				     vertices);
-	/* Slow path, we need to flip y or wire alpha to 1. */
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					ptexcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	__glamor_upload_pixmap_to_texture(pixmap, &tex,
-					  format, type,
-					  0, 0, w, h,
-					  bits, pbo);
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
+        ) {
+        int fbo_x_off, fbo_y_off;
+
+        assert(pixmap_priv->base.fbo->tex);
+        pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
+        assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
+        assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
+        assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
+        __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
+                                          format, type,
+                                          x + fbo_x_off, y + fbo_y_off, w, h,
+                                          bits, pbo);
+        return TRUE;
+    }
+
+    if (need_flip)
+        ptexcoords = texcoords;
+    else
+        ptexcoords = texcoords_inv;
+
+    pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+    glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
+                                 dst_yscale,
+                                 x, y,
+                                 x + w, y + h,
+                                 glamor_priv->yInverted, vertices);
+    /* Slow path, we need to flip y or wire alpha to 1. */
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), vertices);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), ptexcoords);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    __glamor_upload_pixmap_to_texture(pixmap, &tex,
+                                      format, type, 0, 0, w, h, bits, pbo);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 #ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-	dispatch->glUniform1i(glamor_priv->
-			      finish_access_revert[no_alpha],
-			      revert);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      swap_rb);
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+                          swap_rb);
 
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 #ifndef GLAMOR_GLES2
-	dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUseProgram(0);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDeleteTextures(1, &tex);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    dispatch->glUseProgram(0);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDeleteTextures(1, &tex);
+    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-	glamor_put_dispatch(glamor_priv);
+    glamor_put_dispatch(glamor_priv);
 
-	if (need_free_bits)
-		free(bits);
-	return TRUE;
+    if (need_free_bits)
+        free(bits);
+    return TRUE;
 }
 
 /*
@@ -587,54 +576,53 @@ ready_to_upload:
  * 2. no_alpha != 0, we need to wire the alpha.
  * */
 static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
+                             int revert, int swap_rb)
 {
-	int flag = 0;
-	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv;
-	glamor_pixmap_fbo *fbo;
-	GLenum iformat;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-
-	if (pixmap_priv->base.gl_fbo)
-		return 0;
-
-	if (pixmap_priv->base.fbo
-	     && (pixmap_priv->base.fbo->width < pixmap->drawable.width
-           || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
-		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-		glamor_destroy_fbo(fbo);
-        }
-
-	if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
-		return 0;
-
-	if (!(no_alpha
-	      || (revert == REVERT_NORMAL)
-	      || (swap_rb != SWAP_NONE_UPLOADING)
-	      || !glamor_priv->yInverted)) {
-		/* We don't need a fbo, a simple texture uploading should work. */
-
-		flag = GLAMOR_CREATE_FBO_NO_FBO;
-	}
-
-	if ((flag == GLAMOR_CREATE_FBO_NO_FBO
-		&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
-	    || (flag == 0
-		&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
-		return 0;
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-		gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
-	else
-		iformat = format;
-
-	if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
-		return -1;
-
-	return 0;
+    int flag = 0;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv;
+    glamor_pixmap_fbo *fbo;
+    GLenum iformat;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+
+    if (pixmap_priv->base.gl_fbo)
+        return 0;
+
+    if (pixmap_priv->base.fbo
+        && (pixmap_priv->base.fbo->width < pixmap->drawable.width
+            || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
+        fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+        glamor_destroy_fbo(fbo);
+    }
+
+    if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
+        return 0;
+
+    if (!(no_alpha || (revert == REVERT_NORMAL)
+          || (swap_rb != SWAP_NONE_UPLOADING)
+          || !glamor_priv->yInverted)) {
+        /* We don't need a fbo, a simple texture uploading should work. */
+
+        flag = GLAMOR_CREATE_FBO_NO_FBO;
+    }
+
+    if ((flag == GLAMOR_CREATE_FBO_NO_FBO
+         && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
+        || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
+        return 0;
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+        gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+    else
+        iformat = format;
+
+    if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
+        return -1;
+
+    return 0;
 }
 
 /*
@@ -642,185 +630,188 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
  * */
 static void
 glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
-		int src_stride, int bpp,
-		int x, int y, int w, int h)
+                int src_stride, int bpp, int x, int y, int w, int h)
 {
-	int j;
-	int byte_per_pixel;
-
-	byte_per_pixel = bpp / 8;
-	src_bits += y * src_stride + (x * byte_per_pixel);
-
-	for(j = y; j < y + h; j++)
-	{
-		memcpy(dst_bits, src_bits, w * byte_per_pixel);
-		src_bits += src_stride;
-		dst_bits += dst_stride;
-	}
+    int j;
+    int byte_per_pixel;
+
+    byte_per_pixel = bpp / 8;
+    src_bits += y * src_stride + (x * byte_per_pixel);
+
+    for (j = y; j < y + h; j++) {
+        memcpy(dst_bits, src_bits, w * byte_per_pixel);
+        src_bits += src_stride;
+        dst_bits += dst_stride;
+    }
 }
+
 /*
  * download sub region from a large region.
  */
 static void
 glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits,
-		int src_stride, int bpp,
-		int x, int y, int w, int h)
+                int src_stride, int bpp, int x, int y, int w, int h)
 {
-	int j;
-	int byte_per_pixel;
-
-	byte_per_pixel = bpp / 8;
-	dst_bits += y * dst_stride + x * byte_per_pixel;
-
-	for(j = y; j < y + h; j++)
-	{
-		memcpy(dst_bits, src_bits, w * byte_per_pixel);
-		src_bits += src_stride;
-		dst_bits += dst_stride;
-	}
-}
+    int j;
+    int byte_per_pixel;
 
+    byte_per_pixel = bpp / 8;
+    dst_bits += y * dst_stride + x * byte_per_pixel;
+
+    for (j = y; j < y + h; j++) {
+        memcpy(dst_bits, src_bits, w * byte_per_pixel);
+        src_bits += src_stride;
+        dst_bits += dst_stride;
+    }
+}
 
 Bool
-glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
-				    int stride, void *bits, int pbo)
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
+                                    int h, int stride, void *bits, int pbo)
 {
-	GLenum format, type;
-	int no_alpha, revert, swap_rb;
-	glamor_pixmap_private *pixmap_priv;
-	Bool force_clip;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type,
-						   &no_alpha,
-						   &revert,
-						   &swap_rb, 1)) {
-		glamor_fallback("Unknown pixmap depth %d.\n",
-				pixmap->drawable.depth);
-		return TRUE;
-	}
-	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
-		return FALSE;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
-			&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
-
-	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
-		RegionRec region;
-		BoxRec box;
-		int n_region;
-		glamor_pixmap_clipped_regions *clipped_regions;
-		void *sub_bits;
-		int i,j;
-
-		sub_bits = malloc(h * stride);
-		if (sub_bits == NULL)
-			return FALSE;
-		box.x1 = x;
-		box.y1 = y;
-		box.x2 = x + w;
-		box.y2 = y + h;
-		RegionInitBoxes(&region, &box, 1);
-		if (!force_clip)
-			clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
-		else
-			clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
-							pixmap_priv->base.glamor_priv->max_fbo_size,
-							pixmap_priv->base.glamor_priv->max_fbo_size, 0, 0);
-		DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
-		for(i = 0; i < n_region; i++)
-		{
-			BoxPtr boxes;
-			int nbox;
-			int temp_stride;
-			void *temp_bits;
-
-			assert(pbo == 0);
-
-			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
-
-			boxes = RegionRects(clipped_regions[i].region);
-			nbox = RegionNumRects(clipped_regions[i].region);
-			DEBUGF("split to %d boxes\n", nbox);
-			for(j = 0; j < nbox; j++)
-			{
-				temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
-							    pixmap->drawable.depth);
-
-				if (boxes[j].x1 == x && temp_stride == stride) {
-					temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
-				} else {
-					temp_bits = sub_bits;
-					glamor_put_bits(temp_bits, temp_stride, bits, stride,
-							pixmap->drawable.bitsPerPixel,
-							boxes[j].x1 - x, boxes[j].y1 - y,
-							boxes[j].x2 - boxes[j].x1,
-							boxes[j].y2 - boxes[j].y1);
-				}
-				DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
-					boxes[j].x1 - x, boxes[j].y1 - y,
-					boxes[j].x2 - boxes[j].x1,
-					boxes[j].y2 - boxes[j].y1, temp_stride);
-				if (_glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha,
-									  revert, swap_rb, boxes[j].x1, boxes[j].y1,
-									  boxes[j].x2 - boxes[j].x1,
-									  boxes[j].y2 - boxes[j].y1,
-									  temp_stride, temp_bits, pbo) == FALSE) {
-					RegionUninit(&region);
-					free(sub_bits);
-					assert(0);
-					return FALSE;
-				}
-			}
-			RegionDestroy(clipped_regions[i].region);
-		}
-		free(sub_bits);
-		free(clipped_regions);
-		RegionUninit(&region);
-		return TRUE;
-	} else
-		return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
-						     x, y, w, h, stride, bits, pbo);
+    GLenum format, type;
+    int no_alpha, revert, swap_rb;
+    glamor_pixmap_private *pixmap_priv;
+    Bool force_clip;
+
+    if (glamor_get_tex_format_type_from_pixmap(pixmap,
+                                               &format,
+                                               &type,
+                                               &no_alpha,
+                                               &revert, &swap_rb, 1)) {
+        glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+        return TRUE;
+    }
+    if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
+        return FALSE;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+        && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+        RegionRec region;
+        BoxRec box;
+        int n_region;
+        glamor_pixmap_clipped_regions *clipped_regions;
+        void *sub_bits;
+        int i, j;
+
+        sub_bits = malloc(h * stride);
+        if (sub_bits == NULL)
+            return FALSE;
+        box.x1 = x;
+        box.y1 = y;
+        box.x2 = x + w;
+        box.y2 = y + h;
+        RegionInitBoxes(&region, &box, 1);
+        if (!force_clip)
+            clipped_regions =
+                glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+                                               0, 0, 0);
+        else
+            clipped_regions =
+                glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+                                                   &n_region,
+                                                   pixmap_priv->base.
+                                                   glamor_priv->max_fbo_size,
+                                                   pixmap_priv->base.
+                                                   glamor_priv->max_fbo_size, 0,
+                                                   0);
+        DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
+        for (i = 0; i < n_region; i++) {
+            BoxPtr boxes;
+            int nbox;
+            int temp_stride;
+            void *temp_bits;
+
+            assert(pbo == 0);
+
+            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+            boxes = RegionRects(clipped_regions[i].region);
+            nbox = RegionNumRects(clipped_regions[i].region);
+            DEBUGF("split to %d boxes\n", nbox);
+            for (j = 0; j < nbox; j++) {
+                temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
+                                            pixmap->drawable.depth);
+
+                if (boxes[j].x1 == x && temp_stride == stride) {
+                    temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
+                }
+                else {
+                    temp_bits = sub_bits;
+                    glamor_put_bits(temp_bits, temp_stride, bits, stride,
+                                    pixmap->drawable.bitsPerPixel,
+                                    boxes[j].x1 - x, boxes[j].y1 - y,
+                                    boxes[j].x2 - boxes[j].x1,
+                                    boxes[j].y2 - boxes[j].y1);
+                }
+                DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
+                       boxes[j].x1 - x, boxes[j].y1 - y,
+                       boxes[j].x2 - boxes[j].x1,
+                       boxes[j].y2 - boxes[j].y1, temp_stride);
+                if (_glamor_upload_bits_to_pixmap_texture
+                    (pixmap, format, type, no_alpha, revert, swap_rb,
+                     boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
+                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits,
+                     pbo) == FALSE) {
+                    RegionUninit(&region);
+                    free(sub_bits);
+                    assert(0);
+                    return FALSE;
+                }
+            }
+            RegionDestroy(clipped_regions[i].region);
+        }
+        free(sub_bits);
+        free(clipped_regions);
+        RegionUninit(&region);
+        return TRUE;
+    }
+    else
+        return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
+                                                     no_alpha, revert, swap_rb,
+                                                     x, y, w, h, stride, bits,
+                                                     pbo);
 }
 
 enum glamor_pixmap_status
 glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 {
-	glamor_pixmap_private *pixmap_priv;
-	void *data;
-	int pbo;
-	int ret;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if ((pixmap_priv->base.fbo)
-	    && (pixmap_priv->base.fbo->pbo_valid)) {
-		data = NULL;
-		pbo = pixmap_priv->base.fbo->pbo;
-	} else {
-		data = pixmap->devPrivate.ptr;
-		pbo = 0;
-	}
-
-	if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
-						pixmap->drawable.width,
-						pixmap->drawable.height,
-						pixmap->devKind,
-						data, pbo))
-		ret = GLAMOR_UPLOAD_DONE;
-	else
-		ret = GLAMOR_UPLOAD_FAILED;
-
-	return ret;
+    glamor_pixmap_private *pixmap_priv;
+    void *data;
+    int pbo;
+    int ret;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if ((pixmap_priv->base.fbo)
+        && (pixmap_priv->base.fbo->pbo_valid)) {
+        data = NULL;
+        pbo = pixmap_priv->base.fbo->pbo;
+    }
+    else {
+        data = pixmap->devPrivate.ptr;
+        pbo = 0;
+    }
+
+    if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
+                                            pixmap->drawable.width,
+                                            pixmap->drawable.height,
+                                            pixmap->devKind, data, pbo))
+        ret = GLAMOR_UPLOAD_DONE;
+    else
+        ret = GLAMOR_UPLOAD_FAILED;
+
+    return ret;
 }
 
 void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
-	if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
-		LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
+    if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
+        LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
 }
 
 /*
@@ -832,83 +823,68 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
  * */
 
 glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format,
-			       GLenum type, int no_alpha, int revert, int swap_rb)
-
+glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
+                               GLenum format, GLenum type, int no_alpha,
+                               int revert, int swap_rb)
 {
-	glamor_pixmap_private *source_priv;
-	glamor_screen_private *glamor_priv;
-	ScreenPtr screen;
-	glamor_pixmap_fbo *temp_fbo;
-	glamor_gl_dispatch *dispatch;
-	float temp_xscale, temp_yscale, source_xscale, source_yscale;
-	static float vertices[8];
-	static float texcoords[8];
-
-	screen = source->drawable.pScreen;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	source_priv = glamor_get_pixmap_private(source);
-	temp_fbo = glamor_create_fbo(glamor_priv,
-				     w, h,
-				     format,
-				     0);
-	if (temp_fbo == NULL)
-		return NULL;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	temp_xscale = 1.0 / w;
-	temp_yscale = 1.0 / h;
-
-	glamor_set_normalize_vcoords((struct glamor_pixmap_private*)NULL,temp_xscale,
-				     temp_yscale,
-				     0, 0,
-				     w, h,
-				     glamor_priv->yInverted,
-				     vertices);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
-	glamor_set_normalize_tcoords(source_priv, source_xscale,
-				     source_yscale,
-				     x, y,
-				     x + w, y + h,
-				     glamor_priv->yInverted,
-				     texcoords);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					texcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-
-	glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-	dispatch->glUniform1i(glamor_priv->
-			      finish_access_revert[no_alpha],
-			      revert);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      swap_rb);
-
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return temp_fbo;
+    glamor_pixmap_private *source_priv;
+    glamor_screen_private *glamor_priv;
+    ScreenPtr screen;
+    glamor_pixmap_fbo *temp_fbo;
+    glamor_gl_dispatch *dispatch;
+    float temp_xscale, temp_yscale, source_xscale, source_yscale;
+    static float vertices[8];
+    static float texcoords[8];
+
+    screen = source->drawable.pScreen;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    source_priv = glamor_get_pixmap_private(source);
+    temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
+    if (temp_fbo == NULL)
+        return NULL;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    temp_xscale = 1.0 / w;
+    temp_yscale = 1.0 / h;
+
+    glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
+                                 temp_xscale, temp_yscale, 0, 0, w, h,
+                                 glamor_priv->yInverted, vertices);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), vertices);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+    pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
+    glamor_set_normalize_tcoords(source_priv, source_xscale,
+                                 source_yscale,
+                                 x, y,
+                                 x + w, y + h,
+                                 glamor_priv->yInverted, texcoords);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), texcoords);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+    dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+                          swap_rb);
+
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    return temp_fbo;
 }
 
 /*
@@ -918,263 +894,263 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 
 static void *
 _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
-				   GLenum type, int no_alpha,
-				   int revert, int swap_rb,
-				   int x, int y, int w, int h,
-				   int stride, void *bits, int pbo, glamor_access_t access)
+                                   GLenum type, int no_alpha,
+                                   int revert, int swap_rb,
+                                   int x, int y, int w, int h,
+                                   int stride, void *bits, int pbo,
+                                   glamor_access_t access)
 {
-	glamor_pixmap_private *pixmap_priv;
-	GLenum gl_access = 0, gl_usage = 0;
-	void *data, *read;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch;
-	glamor_pixmap_fbo *temp_fbo = NULL;
-	int need_post_conversion = 0;
-	int need_free_data = 0;
-	int fbo_x_off, fbo_y_off;
-
-	data = bits;
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return NULL;
-
-	switch (access) {
-	case GLAMOR_ACCESS_RO:
-		gl_access = GL_READ_ONLY;
-		gl_usage = GL_STREAM_READ;
-		break;
-	case GLAMOR_ACCESS_WO:
-		return bits;
-	case GLAMOR_ACCESS_RW:
-		gl_access = GL_READ_WRITE;
-		gl_usage = GL_DYNAMIC_DRAW;
-		break;
-	default:
-		ErrorF("Glamor: Invalid access code. %d\n", access);
-		assert(0);
-	}
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	need_post_conversion = (revert > REVERT_NORMAL);
-	if (need_post_conversion) {
-		if (pixmap->drawable.depth == 1) {
-			int temp_stride;
-			temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
-			data = malloc(temp_stride * h);
-			if (data == NULL)
-				return NULL;
-			need_free_data = 1;
-		}
-	}
-
-	pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && !need_post_conversion
-	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
-		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
-								 format, type, no_alpha,
-								 revert, swap_rb))) {
-			free(data);
-			return NULL;
-		}
-		x = 0;
-		y = 0;
-		fbo_x_off = 0;
-		fbo_y_off = 0;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-
-	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
-
-		if (!glamor_priv->yInverted) {
-			assert(glamor_priv->gl_flavor ==
-			       GLAMOR_GL_DESKTOP);
-			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
-		}
-
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
-			assert(pbo > 0);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
-			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-					       stride *
-					       h,
-					       NULL, gl_usage);
-		}
-
-		dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
-
-		if (!glamor_priv->yInverted) {
-			assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
-		}
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
-			bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-						     gl_access);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-		}
-	} else {
-		unsigned int temp_pbo;
-		int yy;
-
-		dispatch = glamor_get_dispatch(glamor_priv);
-		dispatch->glGenBuffers(1, &temp_pbo);
-		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-				       temp_pbo);
-		dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-				       stride *
-				       h,
-				       NULL, GL_STREAM_READ);
-		dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
-				       format, type, 0);
-		read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-					     GL_READ_ONLY);
-		for (yy = 0; yy < pixmap->drawable.height; yy++)
-			memcpy((char*)data + yy * stride,
-			       (char*)read + (h - yy - 1) * stride, stride);
-		dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
-		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-		dispatch->glDeleteBuffers(1, &temp_pbo);
-	}
-
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
-	glamor_put_dispatch(glamor_priv);
-
-	if (need_post_conversion) {
-		/* As OpenGL desktop version never enters here.
-		 * Don't need to consider if the pbo is valid.*/
-		bits = glamor_color_convert_to_bits(data, bits,
-						    w, h,
-						    stride,
-						    no_alpha,
-						    revert, swap_rb);
-	}
-
-	if (temp_fbo != NULL)
-		glamor_destroy_fbo(temp_fbo);
-	if (need_free_data)
-		free(data);
-
-	return bits;
+    glamor_pixmap_private *pixmap_priv;
+    GLenum gl_access = 0, gl_usage = 0;
+    void *data, *read;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+    glamor_gl_dispatch *dispatch;
+    glamor_pixmap_fbo *temp_fbo = NULL;
+    int need_post_conversion = 0;
+    int need_free_data = 0;
+    int fbo_x_off, fbo_y_off;
+
+    data = bits;
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return NULL;
+
+    switch (access) {
+    case GLAMOR_ACCESS_RO:
+        gl_access = GL_READ_ONLY;
+        gl_usage = GL_STREAM_READ;
+        break;
+    case GLAMOR_ACCESS_WO:
+        return bits;
+    case GLAMOR_ACCESS_RW:
+        gl_access = GL_READ_WRITE;
+        gl_usage = GL_DYNAMIC_DRAW;
+        break;
+    default:
+        ErrorF("Glamor: Invalid access code. %d\n", access);
+        assert(0);
+    }
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+    need_post_conversion = (revert > REVERT_NORMAL);
+    if (need_post_conversion) {
+        if (pixmap->drawable.depth == 1) {
+            int temp_stride;
+
+            temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+            data = malloc(temp_stride * h);
+            if (data == NULL)
+                return NULL;
+            need_free_data = 1;
+        }
+    }
+
+    pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+        && !need_post_conversion
+        && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
+        if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
+                                                        format, type, no_alpha,
+                                                        revert, swap_rb))) {
+            free(data);
+            return NULL;
+        }
+        x = 0;
+        y = 0;
+        fbo_x_off = 0;
+        fbo_y_off = 0;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+
+    if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
+
+        if (!glamor_priv->yInverted) {
+            assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+            dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
+        }
+
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
+            assert(pbo > 0);
+            dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
+            dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+                                   stride * h, NULL, gl_usage);
+        }
+
+        dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type,
+                               data);
+
+        if (!glamor_priv->yInverted) {
+            assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+            dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
+        }
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
+            bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
+            dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+        }
+    }
+    else {
+        unsigned int temp_pbo;
+        int yy;
+
+        dispatch = glamor_get_dispatch(glamor_priv);
+        dispatch->glGenBuffers(1, &temp_pbo);
+        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
+        dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+                               stride * h, NULL, GL_STREAM_READ);
+        dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
+                               format, type, 0);
+        read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
+        for (yy = 0; yy < pixmap->drawable.height; yy++)
+            memcpy((char *) data + yy * stride,
+                   (char *) read + (h - yy - 1) * stride, stride);
+        dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+        dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+        dispatch->glDeleteBuffers(1, &temp_pbo);
+    }
+
+    dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glamor_put_dispatch(glamor_priv);
+
+    if (need_post_conversion) {
+        /* As OpenGL desktop version never enters here.
+         * Don't need to consider if the pbo is valid.*/
+        bits = glamor_color_convert_to_bits(data, bits,
+                                            w, h,
+                                            stride, no_alpha, revert, swap_rb);
+    }
+
+    if (temp_fbo != NULL)
+        glamor_destroy_fbo(temp_fbo);
+    if (need_free_data)
+        free(data);
+
+    return bits;
 }
 
 void *
 glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
-				  int stride, void *bits, int pbo, glamor_access_t access)
+                                  int stride, void *bits, int pbo,
+                                  glamor_access_t access)
 {
-	GLenum format, type;
-	int no_alpha, revert, swap_rb;
-	glamor_pixmap_private *pixmap_priv;
-	Bool force_clip;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type,
-						   &no_alpha,
-						   &revert,
-						   &swap_rb, 0)) {
-		glamor_fallback("Unknown pixmap depth %d.\n",
-				pixmap->drawable.depth);
-		return NULL;
-	}
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return NULL;
-
-	force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
-			&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
-
-	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
-
-		RegionRec region;
-		BoxRec box;
-		int n_region;
-		glamor_pixmap_clipped_regions *clipped_regions;
-		void *sub_bits;
-		int i,j;
-
-		sub_bits = malloc(h * stride);
-		if (sub_bits == NULL)
-			return FALSE;
-		box.x1 = x;
-		box.y1 = y;
-		box.x2 = x + w;
-		box.y2 = y + h;
-		RegionInitBoxes(&region, &box, 1);
-
-		if (!force_clip)
-			clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
-		else
-			clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
-							pixmap_priv->base.glamor_priv->max_fbo_size,
-							pixmap_priv->base.glamor_priv->max_fbo_size, 0, 0);
-
-		DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
-		for(i = 0; i < n_region; i++)
-		{
-			BoxPtr boxes;
-			int nbox;
-			int temp_stride;
-			void *temp_bits;
-
-			assert(pbo == 0);
-			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
-
-			boxes = RegionRects(clipped_regions[i].region);
-			nbox = RegionNumRects(clipped_regions[i].region);
-			for(j = 0; j < nbox; j++)
-			{
-				temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
-							    pixmap->drawable.depth);
-
-				if (boxes[j].x1 == x && temp_stride == stride) {
-					temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
-				} else {
-					temp_bits = sub_bits;
-				}
-				DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
-					boxes[j].x1, boxes[j].y1,
-					boxes[j].x2 - boxes[j].x1,
-					boxes[j].y2 - boxes[j].y1, temp_stride);
-
-				/* For large pixmap, we don't support pbo currently.*/
-				assert(pbo == 0);
-				if (_glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha,
-								       revert, swap_rb, boxes[j].x1, boxes[j].y1,
-								       boxes[j].x2 - boxes[j].x1,
-								       boxes[j].y2 - boxes[j].y1,
-								       temp_stride, temp_bits, pbo, access) == FALSE) {
-					RegionUninit(&region);
-					free(sub_bits);
-					assert(0);
-					return NULL;
-				}
-				if (boxes[j].x1 != x || temp_stride != stride)
-					glamor_get_bits(bits, stride, temp_bits, temp_stride,
-							pixmap->drawable.bitsPerPixel,
-							boxes[j].x1 - x , boxes[j].y1 - y,
-							boxes[j].x2 - boxes[j].x1,
-							boxes[j].y2 - boxes[j].y1);
-			}
-
-			RegionDestroy(clipped_regions[i].region);
-		}
-		free(sub_bits);
-		free(clipped_regions);
-		RegionUninit(&region);
-		return bits;
-	} else
-	return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha, revert, swap_rb,
-						  x, y, w, h, stride,
-						  bits, pbo, access);
+    GLenum format, type;
+    int no_alpha, revert, swap_rb;
+    glamor_pixmap_private *pixmap_priv;
+    Bool force_clip;
+
+    if (glamor_get_tex_format_type_from_pixmap(pixmap,
+                                               &format,
+                                               &type,
+                                               &no_alpha,
+                                               &revert, &swap_rb, 0)) {
+        glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+        return NULL;
+    }
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return NULL;
+
+    force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+        && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+
+        RegionRec region;
+        BoxRec box;
+        int n_region;
+        glamor_pixmap_clipped_regions *clipped_regions;
+        void *sub_bits;
+        int i, j;
+
+        sub_bits = malloc(h * stride);
+        if (sub_bits == NULL)
+            return FALSE;
+        box.x1 = x;
+        box.y1 = y;
+        box.x2 = x + w;
+        box.y2 = y + h;
+        RegionInitBoxes(&region, &box, 1);
+
+        if (!force_clip)
+            clipped_regions =
+                glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+                                               0, 0, 0);
+        else
+            clipped_regions =
+                glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+                                                   &n_region,
+                                                   pixmap_priv->base.
+                                                   glamor_priv->max_fbo_size,
+                                                   pixmap_priv->base.
+                                                   glamor_priv->max_fbo_size, 0,
+                                                   0);
+
+        DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
+        for (i = 0; i < n_region; i++) {
+            BoxPtr boxes;
+            int nbox;
+            int temp_stride;
+            void *temp_bits;
+
+            assert(pbo == 0);
+            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+            boxes = RegionRects(clipped_regions[i].region);
+            nbox = RegionNumRects(clipped_regions[i].region);
+            for (j = 0; j < nbox; j++) {
+                temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
+                                            pixmap->drawable.depth);
+
+                if (boxes[j].x1 == x && temp_stride == stride) {
+                    temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
+                }
+                else {
+                    temp_bits = sub_bits;
+                }
+                DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
+                       boxes[j].x1, boxes[j].y1,
+                       boxes[j].x2 - boxes[j].x1,
+                       boxes[j].y2 - boxes[j].y1, temp_stride);
+
+                /* For large pixmap, we don't support pbo currently. */
+                assert(pbo == 0);
+                if (_glamor_download_sub_pixmap_to_cpu
+                    (pixmap, format, type, no_alpha, revert, swap_rb,
+                     boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
+                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo,
+                     access) == FALSE) {
+                    RegionUninit(&region);
+                    free(sub_bits);
+                    assert(0);
+                    return NULL;
+                }
+                if (boxes[j].x1 != x || temp_stride != stride)
+                    glamor_get_bits(bits, stride, temp_bits, temp_stride,
+                                    pixmap->drawable.bitsPerPixel,
+                                    boxes[j].x1 - x, boxes[j].y1 - y,
+                                    boxes[j].x2 - boxes[j].x1,
+                                    boxes[j].y2 - boxes[j].y1);
+            }
+
+            RegionDestroy(clipped_regions[i].region);
+        }
+        free(sub_bits);
+        free(clipped_regions);
+        RegionUninit(&region);
+        return bits;
+    }
+    else
+        return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type,
+                                                  no_alpha, revert, swap_rb, x,
+                                                  y, w, h, stride, bits, pbo,
+                                                  access);
 }
 
-
 /**
  * Move a pixmap to CPU memory.
  * The input data is the pixmap's fbo.
@@ -1187,128 +1163,123 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 Bool
 glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 {
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	unsigned int stride;
-	void *data = NULL, *dst;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch;
-	int pbo = 0;
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return TRUE;
-
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
-			    "Downloading pixmap %p  %dx%d depth%d\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
-
-	stride = pixmap->devKind;
-
-	if (access == GLAMOR_ACCESS_WO
-	    || glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
-	    || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		data = malloc(stride * pixmap->drawable.height);
-	} else {
-		dispatch = glamor_get_dispatch(glamor_priv);
-		if (pixmap_priv->base.fbo->pbo == 0)
-			dispatch->glGenBuffers(1,
-					       &pixmap_priv->base.fbo->pbo);
-		glamor_put_dispatch(glamor_priv);
-		pbo = pixmap_priv->base.fbo->pbo;
-	}
-
-	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
-		stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
-		pixmap_priv->base.drm_stride = pixmap->devKind;
-		pixmap->devKind = stride;
-	}
-
-	dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
-						pixmap->drawable.width,
-						pixmap->drawable.height,
-						pixmap->devKind,
-						data, pbo, access);
-
-	if (!dst) {
-		if (data)
-			free(data);
-		return FALSE;
-	}
-
-	if (pbo != 0)
-		pixmap_priv->base.fbo->pbo_valid = 1;
-
-	pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
-
-	pixmap->devPrivate.ptr = dst;
-
-	return TRUE;
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    unsigned int stride;
+    void *data = NULL, *dst;
+    glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(pixmap->drawable.pScreen);
+    glamor_gl_dispatch *dispatch;
+    int pbo = 0;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return TRUE;
+
+    glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+                        "Downloading pixmap %p  %dx%d depth%d\n",
+                        pixmap,
+                        pixmap->drawable.width,
+                        pixmap->drawable.height, pixmap->drawable.depth);
+
+    stride = pixmap->devKind;
+
+    if (access == GLAMOR_ACCESS_WO
+        || glamor_priv->gl_flavor == GLAMOR_GL_ES2
+        || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
+        || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        data = malloc(stride * pixmap->drawable.height);
+    }
+    else {
+        dispatch = glamor_get_dispatch(glamor_priv);
+        if (pixmap_priv->base.fbo->pbo == 0)
+            dispatch->glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
+        glamor_put_dispatch(glamor_priv);
+        pbo = pixmap_priv->base.fbo->pbo;
+    }
+
+    if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
+        stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
+        pixmap_priv->base.drm_stride = pixmap->devKind;
+        pixmap->devKind = stride;
+    }
+
+    dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
+                                            pixmap->drawable.width,
+                                            pixmap->drawable.height,
+                                            pixmap->devKind, data, pbo, access);
+
+    if (!dst) {
+        if (data)
+            free(data);
+        return FALSE;
+    }
+
+    if (pbo != 0)
+        pixmap_priv->base.fbo->pbo_valid = 1;
+
+    pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
+
+    pixmap->devPrivate.ptr = dst;
+
+    return TRUE;
 }
 
 /* fixup a fbo to the exact size as the pixmap. */
 /* XXX LARGE pixmap? */
 Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv)
 {
-	glamor_pixmap_fbo *old_fbo;
-	glamor_pixmap_fbo *new_fbo = NULL;
-	PixmapPtr scratch = NULL;
-	glamor_pixmap_private *scratch_priv;
-	DrawablePtr drawable;
-	GCPtr gc = NULL;
-	int ret = FALSE;
-
-	drawable = &pixmap_priv->base.pixmap->drawable;
-
-	if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
-		return	TRUE;
-
-	old_fbo = pixmap_priv->base.fbo;
-
-	if (!old_fbo)
-		return FALSE;
-
-	gc = GetScratchGC(drawable->depth, screen);
-	if (!gc)
-		goto fail;
-
-	scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
-				       drawable->depth,
-				       GLAMOR_CREATE_PIXMAP_FIXUP);
-
-	scratch_priv = glamor_get_pixmap_private(scratch);
-
-	if (!scratch_priv->base.fbo)
-		goto fail;
-
-	ValidateGC(&scratch->drawable, gc);
-	glamor_copy_area(drawable,
-			 &scratch->drawable,
-			 gc, 0, 0,
-			 drawable->width, drawable->height,
-			 0, 0);
-	old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-	new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
-	glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
-	glamor_pixmap_attach_fbo(scratch, old_fbo);
-
-	DEBUGF("old %dx%d type %d\n",
-		drawable->width, drawable->height, pixmap_priv->type);
-	DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
-		old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height);
-	ret = TRUE;
-fail:
-	if (gc)
-		FreeScratchGC(gc);
-	if (scratch)
-		glamor_destroy_pixmap(scratch);
-
-	return ret;
+    glamor_pixmap_fbo *old_fbo;
+    glamor_pixmap_fbo *new_fbo = NULL;
+    PixmapPtr scratch = NULL;
+    glamor_pixmap_private *scratch_priv;
+    DrawablePtr drawable;
+    GCPtr gc = NULL;
+    int ret = FALSE;
+
+    drawable = &pixmap_priv->base.pixmap->drawable;
+
+    if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
+        return TRUE;
+
+    old_fbo = pixmap_priv->base.fbo;
+
+    if (!old_fbo)
+        return FALSE;
+
+    gc = GetScratchGC(drawable->depth, screen);
+    if (!gc)
+        goto fail;
+
+    scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
+                                   drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);
+
+    scratch_priv = glamor_get_pixmap_private(scratch);
+
+    if (!scratch_priv->base.fbo)
+        goto fail;
+
+    ValidateGC(&scratch->drawable, gc);
+    glamor_copy_area(drawable,
+                     &scratch->drawable,
+                     gc, 0, 0, drawable->width, drawable->height, 0, 0);
+    old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+    new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
+    glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
+    glamor_pixmap_attach_fbo(scratch, old_fbo);
+
+    DEBUGF("old %dx%d type %d\n",
+           drawable->width, drawable->height, pixmap_priv->type);
+    DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
+           old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
+           new_fbo->width, new_fbo->height);
+    ret = TRUE;
+ fail:
+    if (gc)
+        FreeScratchGC(gc);
+    if (scratch)
+        glamor_destroy_pixmap(scratch);
+
+    return ret;
 }
 
 /*
@@ -1328,106 +1299,120 @@ fail:
  *
  * */
 PixmapPtr
-glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h,
+                      glamor_access_t access)
 {
-	glamor_screen_private *glamor_priv;
-	PixmapPtr sub_pixmap;
-	glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
-	void *data;
-	int pbo;
-	int flag;
-	if (x < 0 || y < 0)
-		return NULL;
-	w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
-	h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
-	if (access == GLAMOR_ACCESS_WO) {
-		sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
-						  pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
-		return sub_pixmap;
-	}
-
-	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return NULL;
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
-		flag = GLAMOR_CREATE_PIXMAP_CPU;
-	else
-		flag = GLAMOR_CREATE_PIXMAP_MAP;
-
-	sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
-					  pixmap->drawable.depth, flag);
-
-	if (sub_pixmap == NULL)
-		return NULL;
-
-	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
-	pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
-
-	if (pixmap_priv->base.is_picture) {
-		sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
-		sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
-	}
-
-	if (pbo)
-		data = NULL;
-	else
-		data = sub_pixmap->devPrivate.ptr;
-
-	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
-						 data, pbo, access);
-	if(data == NULL) {
-		fbDestroyPixmap(sub_pixmap);
-		return NULL;
-	}
-	if (pbo) {
-		assert(sub_pixmap->devPrivate.ptr == NULL);
-		sub_pixmap->devPrivate.ptr = data;
-		sub_pixmap_priv->base.fbo->pbo_valid = 1;
-	}
+    glamor_screen_private *glamor_priv;
+    PixmapPtr sub_pixmap;
+    glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
+    void *data;
+    int pbo;
+    int flag;
+
+    if (x < 0 || y < 0)
+        return NULL;
+    w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
+    h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
+    if (access == GLAMOR_ACCESS_WO) {
+        sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+                                          pixmap->drawable.depth,
+                                          GLAMOR_CREATE_PIXMAP_CPU);
+        return sub_pixmap;
+    }
+
+    glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return NULL;
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 ||
+        pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
+        flag = GLAMOR_CREATE_PIXMAP_CPU;
+    else
+        flag = GLAMOR_CREATE_PIXMAP_MAP;
+
+    sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+                                      pixmap->drawable.depth, flag);
+
+    if (sub_pixmap == NULL)
+        return NULL;
+
+    sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+    pbo =
+        sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.
+                           fbo->pbo : 0) : 0;
+
+    if (pixmap_priv->base.is_picture) {
+        sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
+        sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
+    }
+
+    if (pbo)
+        data = NULL;
+    else
+        data = sub_pixmap->devPrivate.ptr;
+
+    data =
+        glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h,
+                                          sub_pixmap->devKind, data, pbo,
+                                          access);
+    if (data == NULL) {
+        fbDestroyPixmap(sub_pixmap);
+        return NULL;
+    }
+    if (pbo) {
+        assert(sub_pixmap->devPrivate.ptr == NULL);
+        sub_pixmap->devPrivate.ptr = data;
+        sub_pixmap_priv->base.fbo->pbo_valid = 1;
+    }
 #if 0
-	struct pixman_box16 box;
-	PixmapPtr new_sub_pixmap;
-	int dx, dy;
-	box.x1 = 0;
-	box.y1 = 0;
-	box.x2 = w;
-	box.y2 = h;
-
-	dx = x;
-	dy = y;
-
-	new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
-					      pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
-	glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
-	glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
+    struct pixman_box16 box;
+    PixmapPtr new_sub_pixmap;
+    int dx, dy;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = w;
+    box.y2 = h;
+
+    dx = x;
+    dy = y;
+
+    new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+                                          pixmap->drawable.depth,
+                                          GLAMOR_CREATE_PIXMAP_CPU);
+    glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box,
+                       1, dx, dy, 0, 0, 0, NULL);
+    glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
 #endif
 
-	return sub_pixmap;
+    return sub_pixmap;
 }
 
 void
-glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
+                      int w, int h, glamor_access_t access)
 {
-	void *bits;
-	int pbo;
-	glamor_pixmap_private *sub_pixmap_priv;
-	if (access != GLAMOR_ACCESS_RO) {
-		sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
-		if (sub_pixmap_priv->base.fbo
-		    && sub_pixmap_priv->base.fbo->pbo_valid) {
-			bits = NULL;
-			pbo = sub_pixmap_priv->base.fbo->pbo;
-		} else {
-			bits = sub_pixmap->devPrivate.ptr;
-			pbo = 0;
-		}
-
-		assert(x >= 0 && y >= 0);
-		w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
-		h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
-		glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
-	}
-	glamor_destroy_pixmap(sub_pixmap);
+    void *bits;
+    int pbo;
+    glamor_pixmap_private *sub_pixmap_priv;
+
+    if (access != GLAMOR_ACCESS_RO) {
+        sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+        if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) {
+            bits = NULL;
+            pbo = sub_pixmap_priv->base.fbo->pbo;
+        }
+        else {
+            bits = sub_pixmap->devPrivate.ptr;
+            pbo = 0;
+        }
+
+        assert(x >= 0 && y >= 0);
+        w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
+        h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
+        glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h,
+                                            sub_pixmap->devKind, bits, pbo);
+    }
+    glamor_destroy_pixmap(sub_pixmap);
 }
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 4e1f7b3..a25fc4e 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -35,93 +35,90 @@
 
 static Bool
 _glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc, int nrect, xRectangle * prect, Bool fallback)
+                       GCPtr gc, int nrect, xRectangle *prect, Bool fallback)
 {
-	int fullX1, fullX2, fullY1, fullY2;
-	int xorg, yorg;
-	int n;
-	register BoxPtr pbox;
-	RegionPtr pClip = fbGetCompositeClip(gc);
-	Bool ret = FALSE;
+    int fullX1, fullX2, fullY1, fullY2;
+    int xorg, yorg;
+    int n;
+    register BoxPtr pbox;
+    RegionPtr pClip = fbGetCompositeClip(gc);
+    Bool ret = FALSE;
 
-	xorg = drawable->x;
-	yorg = drawable->y;
+    xorg = drawable->x;
+    yorg = drawable->y;
 
-	while (nrect--) {
-		fullX1 = prect->x + xorg;
-		fullY1 = prect->y + yorg;
-		fullX2 = fullX1 + (int) prect->width;
-		fullY2 = fullY1 + (int) prect->height;
+    while (nrect--) {
+        fullX1 = prect->x + xorg;
+        fullY1 = prect->y + yorg;
+        fullX2 = fullX1 + (int) prect->width;
+        fullY2 = fullY1 + (int) prect->height;
 
-		n = REGION_NUM_RECTS(pClip);
-		pbox = REGION_RECTS(pClip);
-		/*
-		 * clip the rectangle to each box in the clip region
-		 * this is logically equivalent to calling Intersect(),
-		 * but rectangles may overlap each other here.
-		 */
-		while (n--) {
-			int x1 = fullX1;
-			int x2 = fullX2;
-			int y1 = fullY1;
-			int y2 = fullY2;
+        n = REGION_NUM_RECTS(pClip);
+        pbox = REGION_RECTS(pClip);
+        /*
+         * clip the rectangle to each box in the clip region
+         * this is logically equivalent to calling Intersect(),
+         * but rectangles may overlap each other here.
+         */
+        while (n--) {
+            int x1 = fullX1;
+            int x2 = fullX2;
+            int y1 = fullY1;
+            int y2 = fullY2;
 
-			if (pbox->x1 > x1)
-				x1 = pbox->x1;
-			if (pbox->x2 < x2)
-				x2 = pbox->x2;
-			if (pbox->y1 > y1)
-				y1 = pbox->y1;
-			if (pbox->y2 < y2)
-				y2 = pbox->y2;
+            if (pbox->x1 > x1)
+                x1 = pbox->x1;
+            if (pbox->x2 < x2)
+                x2 = pbox->x2;
+            if (pbox->y1 > y1)
+                y1 = pbox->y1;
+            if (pbox->y2 < y2)
+                y2 = pbox->y2;
 
-			pbox++;
-			if (x1 >= x2 || y1 >= y2)
-				continue;
-			if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
-					 y2 - y1, fallback)) {
-				nrect++;
-				goto fail;
-			}
-		}
-		prect++;
-	}
-	ret = TRUE;
-	goto done;
+            pbox++;
+            if (x1 >= x2 || y1 >= y2)
+                continue;
+            if (!glamor_fill(drawable, gc, x1, y1, x2 - x1, y2 - y1, fallback)) {
+                nrect++;
+                goto fail;
+            }
+        }
+        prect++;
+    }
+    ret = TRUE;
+    goto done;
 
-fail:
+ fail:
 
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(drawable)
-	    && glamor_ddx_fallback_check_gc(gc))
-		goto done;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
+        && glamor_ddx_fallback_check_gc(gc))
+        goto done;
 
-	glamor_fallback(" to %p (%c)\n",
-			drawable, glamor_get_drawable_location(drawable));
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		if (glamor_prepare_access_gc(gc)) {
-			fbPolyFillRect(drawable, gc, nrect, prect);
-			glamor_finish_access_gc(gc);
-		}
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-	}
-	ret = TRUE;
+    glamor_fallback(" to %p (%c)\n",
+                    drawable, glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+        if (glamor_prepare_access_gc(gc)) {
+            fbPolyFillRect(drawable, gc, nrect, prect);
+            glamor_finish_access_gc(gc);
+        }
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+    }
+    ret = TRUE;
 
-done:
-	return ret;
+ done:
+    return ret;
 }
 
-
 void
 glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc, int nrect, xRectangle * prect)
+                      GCPtr gc, int nrect, xRectangle *prect)
 {
-	_glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE);
+    _glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE);
 }
 
 Bool
 glamor_poly_fill_rect_nf(DrawablePtr drawable,
-		         GCPtr gc, int nrect, xRectangle * prect)
+                         GCPtr gc, int nrect, xRectangle *prect)
 {
-	return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE);
+    return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE);
 }
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index e723e95..b941617 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -40,96 +40,97 @@
  */
 static Bool
 _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		   DDXPointPtr points, Bool fallback)
+                   DDXPointPtr points, Bool fallback)
 {
-	xRectangle *rects;
-	int x1, x2, y1, y2;
-	int i;
+    xRectangle *rects;
+    int x1, x2, y1, y2;
+    int i;
 
-	/* Don't try to do wide lines or non-solid fill style. */
-	if (gc->lineWidth != 0) {
-		/* This ends up in miSetSpans, which is accelerated as well as we
-		 * can hope X wide lines will be.
-		 */
-		goto wide_line;
-	}
-	if (gc->lineStyle != LineSolid) {
-		glamor_fallback
-		    ("non-solid fill line style %d\n",
-		     gc->lineStyle);
-		goto fail;
-	}
-	rects = malloc(sizeof(xRectangle) * (n - 1));
-	x1 = points[0].x;
-	y1 = points[0].y;
-	/* If we have any non-horizontal/vertical, fall back. */
-	for (i = 0; i < n - 1; i++) {
-		if (mode == CoordModePrevious) {
-			x2 = x1 + points[i + 1].x;
-			y2 = y1 + points[i + 1].y;
-		} else {
-			x2 = points[i + 1].x;
-			y2 = points[i + 1].y;
-		}
-		if (x1 != x2 && y1 != y2) {
-			free(rects);
-			glamor_fallback("stub diagonal poly_line\n");
-			goto fail;
-		}
-		if (x1 < x2) {
-			rects[i].x = x1;
-			rects[i].width = x2 - x1 + 1;
-		} else {
-			rects[i].x = x2;
-			rects[i].width = x1 - x2 + 1;
-		}
-		if (y1 < y2) {
-			rects[i].y = y1;
-			rects[i].height = y2 - y1 + 1;
-		} else {
-			rects[i].y = y2;
-			rects[i].height = y1 - y2 + 1;
-		}
+    /* Don't try to do wide lines or non-solid fill style. */
+    if (gc->lineWidth != 0) {
+        /* This ends up in miSetSpans, which is accelerated as well as we
+         * can hope X wide lines will be.
+         */
+        goto wide_line;
+    }
+    if (gc->lineStyle != LineSolid) {
+        glamor_fallback("non-solid fill line style %d\n", gc->lineStyle);
+        goto fail;
+    }
+    rects = malloc(sizeof(xRectangle) * (n - 1));
+    x1 = points[0].x;
+    y1 = points[0].y;
+    /* If we have any non-horizontal/vertical, fall back. */
+    for (i = 0; i < n - 1; i++) {
+        if (mode == CoordModePrevious) {
+            x2 = x1 + points[i + 1].x;
+            y2 = y1 + points[i + 1].y;
+        }
+        else {
+            x2 = points[i + 1].x;
+            y2 = points[i + 1].y;
+        }
+        if (x1 != x2 && y1 != y2) {
+            free(rects);
+            glamor_fallback("stub diagonal poly_line\n");
+            goto fail;
+        }
+        if (x1 < x2) {
+            rects[i].x = x1;
+            rects[i].width = x2 - x1 + 1;
+        }
+        else {
+            rects[i].x = x2;
+            rects[i].width = x1 - x2 + 1;
+        }
+        if (y1 < y2) {
+            rects[i].y = y1;
+            rects[i].height = y2 - y1 + 1;
+        }
+        else {
+            rects[i].y = y2;
+            rects[i].height = y1 - y2 + 1;
+        }
 
-		x1 = x2;
-		y1 = y2;
-	}
-	gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
-	free(rects);
-	return TRUE;
+        x1 = x2;
+        y1 = y2;
+    }
+    gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
+    free(rects);
+    return TRUE;
 
-      fail:
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(drawable)
-	    && glamor_ddx_fallback_check_gc(gc))
-		return FALSE;
+ fail:
+    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
+        && glamor_ddx_fallback_check_gc(gc))
+        return FALSE;
 
-	if (gc->lineWidth == 0) {
-		if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-			if (glamor_prepare_access_gc(gc)) {
-				fbPolyLine(drawable, gc, mode, n, points);
-				glamor_finish_access_gc(gc);
-			}
-			glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-		}
-	} else {
-wide_line:
-		/* fb calls mi functions in the lineWidth != 0 case. */
-		fbPolyLine(drawable, gc, mode, n, points);
-	}
-	return TRUE;
+    if (gc->lineWidth == 0) {
+        if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+            if (glamor_prepare_access_gc(gc)) {
+                fbPolyLine(drawable, gc, mode, n, points);
+                glamor_finish_access_gc(gc);
+            }
+            glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+        }
+    }
+    else {
+ wide_line:
+        /* fb calls mi functions in the lineWidth != 0 case. */
+        fbPolyLine(drawable, gc, mode, n, points);
+    }
+    return TRUE;
 }
 
 void
 glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		  DDXPointPtr points)
+                  DDXPointPtr points)
 {
-	_glamor_poly_lines(drawable, gc, mode, n, points, TRUE);
+    _glamor_poly_lines(drawable, gc, mode, n, points, TRUE);
 }
 
 Bool
 glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		     DDXPointPtr points)
+                     DDXPointPtr points)
 {
-	return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE);
+    return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE);
 }
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
index 5930178..99c4de9 100644
--- a/glamor/glamor_polyops.c
+++ b/glamor/glamor_polyops.c
@@ -30,56 +30,53 @@
 
 static Bool
 _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		   DDXPointPtr ppt, Bool fallback)
+                   DDXPointPtr ppt, Bool fallback)
 {
-	if (!fallback 
-	    && glamor_ddx_fallback_check_gc(pGC)
-	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_gc(pGC)
+        && glamor_ddx_fallback_check_pixmap(pDrawable))
+        return FALSE;
 
-	miPolyPoint(pDrawable, pGC, mode, npt, ppt);
+    miPolyPoint(pDrawable, pGC, mode, npt, ppt);
 
-	return TRUE;
+    return TRUE;
 }
 
 void
 glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		  DDXPointPtr ppt)
+                  DDXPointPtr ppt)
 {
-	_glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE);
+    _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE);
 }
 
 Bool
 glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		     DDXPointPtr ppt)
+                     DDXPointPtr ppt)
 {
-	return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE);
+    return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE);
 }
 
 static Bool
 _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-		     xSegment *pSeg, Bool fallback)
+                     xSegment * pSeg, Bool fallback)
 {
-	if (!fallback 
-	    && glamor_ddx_fallback_check_gc(pGC)
-	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_gc(pGC)
+        && glamor_ddx_fallback_check_pixmap(pDrawable))
+        return FALSE;
 
-	miPolySegment(pDrawable, pGC, nseg, pSeg);
+    miPolySegment(pDrawable, pGC, nseg, pSeg);
 
-	return TRUE;
+    return TRUE;
 }
 
 void
-glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-		    xSegment *pSeg)
+glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
 {
-	_glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE);
+    _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE);
 }
 
 Bool
 glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-		     xSegment *pSeg)
+                       xSegment * pSeg)
 {
-	return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
+    return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 7b8f762..39226a8 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -78,108 +78,106 @@
 struct glamor_pixmap_private;
 
 typedef struct glamor_composite_shader {
-	GLuint prog;
-	GLint dest_to_dest_uniform_location;
-	GLint dest_to_source_uniform_location;
-	GLint dest_to_mask_uniform_location;
-	GLint source_uniform_location;
-	GLint mask_uniform_location;
-	GLint source_wh;
-	GLint mask_wh;
-	GLint source_repeat_mode;
-	GLint mask_repeat_mode;
-	union {
-		float source_solid_color[4];
-		struct {
-			struct glamor_pixmap_private *source_priv;
-			PicturePtr source;
-		};
-	};
-
-	union {
-		float mask_solid_color[4];
-		struct {
-			struct glamor_pixmap_private *mask_priv;
-			PicturePtr mask;
-		};
-	};
+    GLuint prog;
+    GLint dest_to_dest_uniform_location;
+    GLint dest_to_source_uniform_location;
+    GLint dest_to_mask_uniform_location;
+    GLint source_uniform_location;
+    GLint mask_uniform_location;
+    GLint source_wh;
+    GLint mask_wh;
+    GLint source_repeat_mode;
+    GLint mask_repeat_mode;
+    union {
+        float source_solid_color[4];
+        struct {
+            struct glamor_pixmap_private *source_priv;
+            PicturePtr source;
+        };
+    };
+
+    union {
+        float mask_solid_color[4];
+        struct {
+            struct glamor_pixmap_private *mask_priv;
+            PicturePtr mask;
+        };
+    };
 } glamor_composite_shader;
 
 enum shader_source {
-	SHADER_SOURCE_SOLID,
-	SHADER_SOURCE_TEXTURE,
-	SHADER_SOURCE_TEXTURE_ALPHA,
-	SHADER_SOURCE_COUNT,
+    SHADER_SOURCE_SOLID,
+    SHADER_SOURCE_TEXTURE,
+    SHADER_SOURCE_TEXTURE_ALPHA,
+    SHADER_SOURCE_COUNT,
 };
 
 enum shader_mask {
-	SHADER_MASK_NONE,
-	SHADER_MASK_SOLID,
-	SHADER_MASK_TEXTURE,
-	SHADER_MASK_TEXTURE_ALPHA,
-	SHADER_MASK_COUNT,
+    SHADER_MASK_NONE,
+    SHADER_MASK_SOLID,
+    SHADER_MASK_TEXTURE,
+    SHADER_MASK_TEXTURE_ALPHA,
+    SHADER_MASK_COUNT,
 };
 
 enum shader_in {
-	SHADER_IN_SOURCE_ONLY,
-	SHADER_IN_NORMAL,
-	SHADER_IN_CA_SOURCE,
-	SHADER_IN_CA_ALPHA,
-	SHADER_IN_COUNT,
+    SHADER_IN_SOURCE_ONLY,
+    SHADER_IN_NORMAL,
+    SHADER_IN_CA_SOURCE,
+    SHADER_IN_CA_ALPHA,
+    SHADER_IN_COUNT,
 };
 
 struct shader_key {
-	enum shader_source source;
-	enum shader_mask mask;
-	enum shader_in in;
+    enum shader_source source;
+    enum shader_mask mask;
+    enum shader_in in;
 };
 
 struct blendinfo {
-	Bool dest_alpha;
-	Bool source_alpha;
-	GLenum source_blend;
-	GLenum dest_blend;
+    Bool dest_alpha;
+    Bool source_alpha;
+    GLenum source_blend;
+    GLenum dest_blend;
 };
 
 typedef struct {
-	INT16 x_src;
-	INT16 y_src;
-	INT16 x_mask;
-	INT16 y_mask;
-	INT16 x_dst;
-	INT16 y_dst;
-	INT16 width;
-	INT16 height;
+    INT16 x_src;
+    INT16 y_src;
+    INT16 x_mask;
+    INT16 y_mask;
+    INT16 x_dst;
+    INT16 y_dst;
+    INT16 width;
+    INT16 height;
 } glamor_composite_rect_t;
 
-
 enum glamor_vertex_type {
-	GLAMOR_VERTEX_POS,
-	GLAMOR_VERTEX_SOURCE,
-	GLAMOR_VERTEX_MASK
+    GLAMOR_VERTEX_POS,
+    GLAMOR_VERTEX_SOURCE,
+    GLAMOR_VERTEX_MASK
 };
 
-
 enum gradient_shader {
-	SHADER_GRADIENT_LINEAR,
-	SHADER_GRADIENT_RADIAL,
-	SHADER_GRADIENT_CONICAL,
-	SHADER_GRADIENT_COUNT,
+    SHADER_GRADIENT_LINEAR,
+    SHADER_GRADIENT_RADIAL,
+    SHADER_GRADIENT_CONICAL,
+    SHADER_GRADIENT_COUNT,
 };
 
 enum gradient_shader_prog {
-	SHADER_GRADIENT_VS_PROG,
-	SHADER_GRADIENT_FS_MAIN_PROG,
-	SHADER_GRADIENT_FS_GETCOLOR_PROG,
-	SHADER_GRADIENT_PROG_COUNT,
+    SHADER_GRADIENT_VS_PROG,
+    SHADER_GRADIENT_FS_MAIN_PROG,
+    SHADER_GRADIENT_FS_GETCOLOR_PROG,
+    SHADER_GRADIENT_PROG_COUNT,
 };
 
 struct glamor_screen_private;
 struct glamor_pixmap_private;
 
 enum glamor_gl_flavor {
-	GLAMOR_GL_DESKTOP,	// OPENGL API
-	GLAMOR_GL_ES2		// OPENGL ES2.0 API
+    GLAMOR_GL_DESKTOP,          // OPENGL API
+    GLAMOR_GL_ES2               // OPENGL ES2.0 API
 };
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
@@ -194,34 +192,34 @@ enum glamor_gl_flavor {
 #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
 
 typedef struct {
-	PicturePtr picture;	/* Where the glyphs of the cache are stored */
-	GlyphPtr *glyphs;
-	uint16_t count;
-	uint16_t evict;
+    PicturePtr picture;         /* Where the glyphs of the cache are stored */
+    GlyphPtr *glyphs;
+    uint16_t count;
+    uint16_t evict;
 } glamor_glyph_cache_t;
 
 #include "glamor_gl_dispatch.h"
 
-struct glamor_saved_procs { 
-	CloseScreenProcPtr close_screen;
-	CreateGCProcPtr create_gc;
-	CreatePixmapProcPtr create_pixmap;
-	DestroyPixmapProcPtr destroy_pixmap;
-	GetSpansProcPtr get_spans;
-	GetImageProcPtr get_image;
-	CompositeProcPtr composite;
-	CompositeRectsProcPtr composite_rects;
-	TrapezoidsProcPtr trapezoids;
-	GlyphsProcPtr glyphs;
-	ChangeWindowAttributesProcPtr change_window_attributes;
-	CopyWindowProcPtr copy_window;
-	BitmapToRegionProcPtr bitmap_to_region;
-	TrianglesProcPtr triangles;
-	AddTrapsProcPtr addtraps;
-	CreatePictureProcPtr create_picture;
-	DestroyPictureProcPtr destroy_picture;
-	UnrealizeGlyphProcPtr unrealize_glyph;
-	SetWindowPixmapProcPtr set_window_pixmap;
+struct glamor_saved_procs {
+    CloseScreenProcPtr close_screen;
+    CreateGCProcPtr create_gc;
+    CreatePixmapProcPtr create_pixmap;
+    DestroyPixmapProcPtr destroy_pixmap;
+    GetSpansProcPtr get_spans;
+    GetImageProcPtr get_image;
+    CompositeProcPtr composite;
+    CompositeRectsProcPtr composite_rects;
+    TrapezoidsProcPtr trapezoids;
+    GlyphsProcPtr glyphs;
+    ChangeWindowAttributesProcPtr change_window_attributes;
+    CopyWindowProcPtr copy_window;
+    BitmapToRegionProcPtr bitmap_to_region;
+    TrianglesProcPtr triangles;
+    AddTrapsProcPtr addtraps;
+    CreatePictureProcPtr create_picture;
+    DestroyPictureProcPtr destroy_picture;
+    UnrealizeGlyphProcPtr unrealize_glyph;
+    SetWindowPixmapProcPtr set_window_pixmap;
 };
 
 #ifdef GLAMOR_GLES2
@@ -242,79 +240,80 @@ struct glamor_saved_procs {
 #define RENDER_IDEL_MAX 32
 
 typedef struct glamor_screen_private {
-	struct glamor_gl_dispatch _dispatch;
-	int yInverted;
-	unsigned int tick;
-	enum glamor_gl_flavor gl_flavor;
-	int has_pack_invert;
-	int has_fbo_blit;
-	int max_fbo_size;
-
-	struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
-	unsigned long    fbo_cache_watermark;
-
-	/* glamor_solid */
-	GLint solid_prog;
-	GLint solid_color_uniform_location;
-
-	/* vertext/elment_index buffer object for render */
-	GLuint vbo, ebo;
-	int vbo_offset;
-	int vbo_size;
-	char *vb;
-	int vb_stride;
-	Bool has_source_coords, has_mask_coords;
-	int render_nr_verts;
-	glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
-						[SHADER_MASK_COUNT]
-						[SHADER_IN_COUNT];
-	glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
-	Bool glyph_cache_initialized;
-
-	/* shaders to restore a texture to another texture.*/
-	GLint finish_access_prog[2];
-	GLint finish_access_revert[2];
-	GLint finish_access_swap_rb[2];
-
-	/* glamor_tile */
-	GLint tile_prog;
-	GLint tile_wh;
-
-	/* glamor gradient, 0 for small nstops, 1 for
-	   large nstops and 2 for dynamic generate. */
-	GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
-	GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
-	int linear_max_nstops;
-	GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
-	int radial_max_nstops;
-
-	/* glamor trapezoid shader. */
-	GLint trapezoid_prog;
-
-	/* glamor_putimage */
-	GLint put_image_xybitmap_prog;
-	GLint put_image_xybitmap_fg_uniform_location;
-	GLint put_image_xybitmap_bg_uniform_location;
-
-	PixmapPtr *back_pixmap;
-	int screen_fbo;
-	struct glamor_saved_procs saved_procs;
-	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
-	int delayed_fallback_pending;
-	int flags;
-	int state;
-	unsigned int render_idle_cnt;
-	ScreenPtr screen;
-	int dri3_enabled;
-
-	/* xv */
-	GLint xv_prog;
+    struct glamor_gl_dispatch _dispatch;
+    int yInverted;
+    unsigned int tick;
+    enum glamor_gl_flavor gl_flavor;
+    int has_pack_invert;
+    int has_fbo_blit;
+    int max_fbo_size;
+
+    struct xorg_list
+        fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+    unsigned long fbo_cache_watermark;
+
+    /* glamor_solid */
+    GLint solid_prog;
+    GLint solid_color_uniform_location;
+
+    /* vertext/elment_index buffer object for render */
+    GLuint vbo, ebo;
+    int vbo_offset;
+    int vbo_size;
+    char *vb;
+    int vb_stride;
+    Bool has_source_coords, has_mask_coords;
+    int render_nr_verts;
+    glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+        [SHADER_MASK_COUNT]
+        [SHADER_IN_COUNT];
+    glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
+    Bool glyph_cache_initialized;
+
+    /* shaders to restore a texture to another texture. */
+    GLint finish_access_prog[2];
+    GLint finish_access_revert[2];
+    GLint finish_access_swap_rb[2];
+
+    /* glamor_tile */
+    GLint tile_prog;
+    GLint tile_wh;
+
+    /* glamor gradient, 0 for small nstops, 1 for
+       large nstops and 2 for dynamic generate. */
+    GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
+    GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+    int linear_max_nstops;
+    GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+    int radial_max_nstops;
+
+    /* glamor trapezoid shader. */
+    GLint trapezoid_prog;
+
+    /* glamor_putimage */
+    GLint put_image_xybitmap_prog;
+    GLint put_image_xybitmap_fg_uniform_location;
+    GLint put_image_xybitmap_bg_uniform_location;
+
+    PixmapPtr *back_pixmap;
+    int screen_fbo;
+    struct glamor_saved_procs saved_procs;
+    char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
+    int delayed_fallback_pending;
+    int flags;
+    int state;
+    unsigned int render_idle_cnt;
+    ScreenPtr screen;
+    int dri3_enabled;
+
+    /* xv */
+    GLint xv_prog;
 } glamor_screen_private;
 
 typedef enum glamor_access {
-	GLAMOR_ACCESS_RO,
-	GLAMOR_ACCESS_RW,
-	GLAMOR_ACCESS_WO,
+    GLAMOR_ACCESS_RO,
+    GLAMOR_ACCESS_RW,
+    GLAMOR_ACCESS_WO,
 } glamor_access_t;
 
 #define GLAMOR_FBO_NORMAL     1
@@ -335,17 +334,17 @@ typedef enum glamor_access {
  * @glamor_priv: point to glamor private data.
  */
 typedef struct glamor_pixmap_fbo {
-	struct xorg_list list;
-	unsigned int expire;
-	unsigned char pbo_valid;
-	GLuint tex;
-	GLuint fb;
-	GLuint pbo;
-	int width;
-	int height;
-	GLenum format;
-	GLenum type;
-	glamor_screen_private *glamor_priv;
+    struct xorg_list list;
+    unsigned int expire;
+    unsigned char pbo_valid;
+    GLuint tex;
+    GLuint fb;
+    GLuint pbo;
+    int width;
+    int height;
+    GLenum format;
+    GLenum type;
+    glamor_screen_private *glamor_priv;
 } glamor_pixmap_fbo;
 
 /*
@@ -414,9 +413,9 @@ typedef struct glamor_pixmap_fbo {
  *
  **/
 
-typedef struct glamor_pixmap_clipped_regions{
-	int block_idx;
-	RegionPtr region;
+typedef struct glamor_pixmap_clipped_regions {
+    int block_idx;
+    RegionPtr region;
 } glamor_pixmap_clipped_regions;
 
 #define SET_PIXMAP_FBO_CURRENT(priv, idx) 				\
@@ -428,16 +427,16 @@ typedef struct glamor_pixmap_clipped_regions{
   } while(0)
 
 typedef struct glamor_pixmap_private_base {
-	glamor_pixmap_type_t type;
-	unsigned char gl_fbo:2;
-	unsigned char is_picture:1;
-	unsigned char gl_tex:1;
-	glamor_pixmap_fbo *fbo;
-	PixmapPtr pixmap;
-	int drm_stride;
-	glamor_screen_private *glamor_priv;
-	PicturePtr picture;
-}glamor_pixmap_private_base_t;
+    glamor_pixmap_type_t type;
+    unsigned char gl_fbo:2;
+    unsigned char is_picture:1;
+    unsigned char gl_tex:1;
+    glamor_pixmap_fbo *fbo;
+    PixmapPtr pixmap;
+    int drm_stride;
+    glamor_screen_private *glamor_priv;
+    PicturePtr picture;
+} glamor_pixmap_private_base_t;
 
 /*
  * @base.fbo: current fbo.
@@ -452,39 +451,39 @@ typedef struct glamor_pixmap_private_base {
  *
  **/
 typedef struct glamor_pixmap_private_large {
-	union {
-		glamor_pixmap_type_t type;
-		glamor_pixmap_private_base_t base;
-	};
-	BoxRec box;
-	int block_w;
-	int block_h;
-	int block_wcnt;
-	int block_hcnt;
-	int nbox;
-	BoxPtr box_array;
-	glamor_pixmap_fbo **fbo_array;
-}glamor_pixmap_private_large_t;
+    union {
+        glamor_pixmap_type_t type;
+        glamor_pixmap_private_base_t base;
+    };
+    BoxRec box;
+    int block_w;
+    int block_h;
+    int block_wcnt;
+    int block_hcnt;
+    int nbox;
+    BoxPtr box_array;
+    glamor_pixmap_fbo **fbo_array;
+} glamor_pixmap_private_large_t;
 
 /*
  * @box: the relative coords in the corresponding fbo.
  */
 typedef struct glamor_pixmap_private_atlas {
-	union {
-		glamor_pixmap_type_t type;
-		glamor_pixmap_private_base_t base;
-	};
-	BoxRec box;
-}glamor_pixmap_private_atlas_t;
+    union {
+        glamor_pixmap_type_t type;
+        glamor_pixmap_private_base_t base;
+    };
+    BoxRec box;
+} glamor_pixmap_private_atlas_t;
 
 typedef struct glamor_pixmap_private {
-	union {
-		glamor_pixmap_type_t type;
-		glamor_pixmap_private_base_t base;
-		glamor_pixmap_private_large_t large;
-		glamor_pixmap_private_atlas_t atlas;
-	};
-}glamor_pixmap_private;
+    union {
+        glamor_pixmap_type_t type;
+        glamor_pixmap_private_base_t base;
+        glamor_pixmap_private_large_t large;
+        glamor_pixmap_private_atlas_t atlas;
+    };
+} glamor_pixmap_private;
 
 /* 
  * Pixmap dynamic status, used by dynamic upload feature.
@@ -496,10 +495,10 @@ typedef struct glamor_pixmap_private {
  *
  * */
 typedef enum glamor_pixmap_status {
-	GLAMOR_NONE,
-	GLAMOR_UPLOAD_PENDING,
-	GLAMOR_UPLOAD_DONE,
-	GLAMOR_UPLOAD_FAILED
+    GLAMOR_NONE,
+    GLAMOR_UPLOAD_PENDING,
+    GLAMOR_UPLOAD_DONE,
+    GLAMOR_UPLOAD_FAILED
 } glamor_pixmap_status_t;
 
 extern DevPrivateKey glamor_screen_private_key;
@@ -507,36 +506,31 @@ extern DevPrivateKey glamor_pixmap_private_key;
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
 {
-	return (glamor_screen_private *)
-	    dixLookupPrivate(&screen->devPrivates,
-			     glamor_screen_private_key);
+    return (glamor_screen_private *)
+        dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key);
 }
 
 static inline void
-glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
+glamor_set_screen_private(ScreenPtr screen, glamor_screen_private * priv)
 {
-	dixSetPrivate(&screen->devPrivates,
-		      glamor_screen_private_key,
-		      priv);
+    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv);
 }
 
-
-
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
-	glamor_pixmap_private *priv;
-	priv = dixLookupPrivate(&pixmap->devPrivates,
-				glamor_pixmap_private_key);
-	if (!priv) {
-		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
-		priv = dixLookupPrivate(&pixmap->devPrivates,
-					glamor_pixmap_private_key);
-	}
-	return priv;
+    glamor_pixmap_private *priv;
+
+    priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+    if (!priv) {
+        glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+        priv = dixLookupPrivate(&pixmap->devPrivates,
+                                glamor_pixmap_private_key);
+    }
+    return priv;
 }
 
-void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
+void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private * priv);
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
@@ -545,8 +539,8 @@ void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
 static inline Bool
 glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
 {
-	return (planemask & FbFullMask(drawable->depth)) ==
-	    FbFullMask(drawable->depth);
+    return (planemask & FbFullMask(drawable->depth)) ==
+        FbFullMask(drawable->depth);
 }
 
 extern int glamor_debug_level;
@@ -556,38 +550,41 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
 Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 
-glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
-void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
-glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
-					       int w, int h, GLenum format, GLint tex, int flag);
-glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
-				      int w, int h, GLenum format, int flag);
-void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
-void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
+glamor_pixmap_fbo *glamor_pixmap_detach_fbo(glamor_pixmap_private *
+                                            pixmap_priv);
+void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo * fbo);
+glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
+                                              glamor_priv, int w, int h,
+                                              GLenum format, GLint tex,
+                                              int flag);
+glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private * glamor_priv, int w,
+                                     int h, GLenum format, int flag);
+void glamor_destroy_fbo(glamor_pixmap_fbo * fbo);
+void glamor_pixmap_destroy_fbo(glamor_pixmap_private * priv);
+void glamor_purge_fbo(glamor_pixmap_fbo * fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
 Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
-void glamor_fbo_expire(glamor_screen_private *glamor_priv);
+void glamor_fbo_expire(glamor_screen_private * glamor_priv);
 
-glamor_pixmap_fbo *
-glamor_create_fbo_array(glamor_screen_private *glamor_priv,
-			int w, int h, GLenum format, int flag,
-			int block_w, int block_h, glamor_pixmap_private *);
+glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private * glamor_priv,
+                                           int w, int h, GLenum format,
+                                           int flag, int block_w, int block_h,
+                                           glamor_pixmap_private *);
 
 /* glamor_copyarea.c */
 RegionPtr
+
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-		 int srcx, int srcy, int width, int height, int dstx,
-		 int dsty);
+                 int srcx, int srcy, int width, int height, int dstx, int dsty);
 void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-			BoxPtr box, int nbox, int dx, int dy, Bool reverse,
-			Bool upsidedown, Pixel bitplane, void *closure);
+                        BoxPtr box, int nbox, int dx, int dy, Bool reverse,
+                        Bool upsidedown, Pixel bitplane, void *closure);
 
 /* glamor_copywindow.c */
 void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
-			RegionPtr src_region);
+                        RegionPtr src_region);
 
 /* glamor_core.c */
 Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
@@ -600,36 +597,34 @@ void glamor_init_finish_access_shaders(ScreenPtr screen);
 void glamor_fini_finish_access_shaders(ScreenPtr screen);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
-				int *x, int *y);
+                                int *x, int *y);
 Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
-		    int x, int y, int width, int height,
-		    unsigned char alu, unsigned long planemask,
-		    unsigned long fg_pixel, unsigned long bg_pixel,
-		    int stipple_x, int stipple_y);
+                    int x, int y, int width, int height,
+                    unsigned char alu, unsigned long planemask,
+                    unsigned long fg_pixel, unsigned long bg_pixel,
+                    int stipple_x, int stipple_y);
 GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
-			       const char *source);
+                               const char *source);
 void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
-				    unsigned long fg_pixel,
-				    GLfloat * color);
+                                    unsigned long fg_pixel, GLfloat * color);
 
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
-				       pixmap_priv);
+int glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv);
 void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
  * */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *
-					   pixmap_priv);
+void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv);
 
-glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format,
-			       GLenum type, int no_alpha, int revert, int swap_rb);
+glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
+                                                  int y, int w, int h,
+                                                  GLenum format, GLenum type,
+                                                  int no_alpha, int revert,
+                                                  int swap_rb);
 
-Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch,
-		    unsigned char alu);
+Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
@@ -640,24 +635,21 @@ int glamor_gl_get_version(void);
           ((major) * 256)                       \
         + ((minor) *   1))
 
-
-
-
 /* glamor_fill.c */
 Bool glamor_fill(DrawablePtr drawable,
-		 GCPtr gc, int x, int y, int width, int height, Bool fallback);
+                 GCPtr gc, int x, int y, int width, int height, Bool fallback);
 Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-		  unsigned char alu, unsigned long planemask,
-		  unsigned long fg_pixel);
+                  unsigned char alu, unsigned long planemask,
+                  unsigned long fg_pixel);
 Bool
+
 glamor_solid_boxes(PixmapPtr pixmap,
-		   BoxPtr box, int nbox,
-		   unsigned long fg_pixel);
+                   BoxPtr box, int nbox, unsigned long fg_pixel);
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
-		       GCPtr gc,
-		       int n, DDXPointPtr points, int *widths, int sorted);
+                       GCPtr gc,
+                       int n, DDXPointPtr points, int *widths, int sorted);
 
 void glamor_init_solid_shader(ScreenPtr screen);
 void glamor_fini_solid_shader(ScreenPtr screen);
@@ -665,82 +657,80 @@ void glamor_fini_solid_shader(ScreenPtr screen);
 /* glamor_getspans.c */
 void
 
+
 glamor_get_spans(DrawablePtr drawable,
-		 int wmax,
-		 DDXPointPtr points,
-		 int *widths, int nspans, char *dst_start);
+                 int wmax,
+                 DDXPointPtr points, int *widths, int nspans, char *dst_start);
 
 /* glamor_glyphs.c */
 void glamor_glyphs_fini(ScreenPtr screen);
 void glamor_glyphs(CARD8 op,
-		   PicturePtr pSrc,
-		   PicturePtr pDst,
-		   PictFormatPtr maskFormat,
-		   INT16 xSrc,
-		   INT16 ySrc, int nlist, GlyphListPtr list,
-		   GlyphPtr * glyphs);
+                   PicturePtr pSrc,
+                   PicturePtr pDst,
+                   PictFormatPtr maskFormat,
+                   INT16 xSrc,
+                   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
 
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		      DDXPointPtr points, int *widths, int n, int sorted);
+                      DDXPointPtr points, int *widths, int n, int sorted);
 
 /* glamor_polyfillrect.c */
 void
+
 glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc, int nrect, xRectangle * prect);
+                      GCPtr gc, int nrect, xRectangle *prect);
 
 /* glamor_polylines.c */
 void
 
+
 glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		  DDXPointPtr points);
+                  DDXPointPtr points);
 
 /* glamor_putimage.c */
 void
 
+
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int leftPad, int format, char *bits);
+                 int w, int h, int leftPad, int format, char *bits);
 void glamor_init_putimage_shaders(ScreenPtr screen);
 void glamor_fini_putimage_shaders(ScreenPtr screen);
 
 /* glamor_render.c */
 Bool
+
 glamor_composite_clipped_region(CARD8 op,
-				PicturePtr source,
-				PicturePtr mask,
-				PicturePtr dest,
-				glamor_pixmap_private *soruce_pixmap_priv,
-				glamor_pixmap_private *mask_pixmap_priv,
-				glamor_pixmap_private *dest_pixmap_priv,
-				RegionPtr region,
-				int x_source,
-				int y_source,
-				int x_mask,
-				int y_mask,
-				int x_dest,
-				int y_dest);
+                                PicturePtr source,
+                                PicturePtr mask,
+                                PicturePtr dest,
+                                glamor_pixmap_private * soruce_pixmap_priv,
+                                glamor_pixmap_private * mask_pixmap_priv,
+                                glamor_pixmap_private * dest_pixmap_priv,
+                                RegionPtr region,
+                                int x_source,
+                                int y_source,
+                                int x_mask, int y_mask, int x_dest, int y_dest);
 
 void glamor_composite(CARD8 op,
-		      PicturePtr pSrc,
-		      PicturePtr pMask,
-		      PicturePtr pDst,
-		      INT16 xSrc,
-		      INT16 ySrc,
-		      INT16 xMask,
-		      INT16 yMask,
-		      INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+                      PicturePtr pSrc,
+                      PicturePtr pMask,
+                      PicturePtr pDst,
+                      INT16 xSrc,
+                      INT16 ySrc,
+                      INT16 xMask,
+                      INT16 yMask,
+                      INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
 
 void glamor_init_composite_shaders(ScreenPtr screen);
 void glamor_fini_composite_shaders(ScreenPtr screen);
 void glamor_composite_glyph_rects(CARD8 op,
-				  PicturePtr src, PicturePtr mask,
-				  PicturePtr dst, int nrect,
-				  glamor_composite_rect_t * rects);
-void glamor_composite_rects (CARD8         op,
-			     PicturePtr    pDst,
-			     xRenderColor  *color,
-			     int           nRect,
-			     xRectangle    *rects);
+                                  PicturePtr src, PicturePtr mask,
+                                  PicturePtr dst, int nrect,
+                                  glamor_composite_rect_t * rects);
+void glamor_composite_rects(CARD8 op,
+                            PicturePtr pDst,
+                            xRenderColor * color, int nRect, xRectangle *rects);
 void glamor_init_trapezoid_shader(ScreenPtr screen);
 void glamor_fini_trapezoid_shader(ScreenPtr screen);
 PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
@@ -752,19 +742,20 @@ Bool glamor_composite_choose_shader(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
                                     PicturePtr dest,
-			     	    glamor_pixmap_private *source_pixmap_priv,
-			     	    glamor_pixmap_private *mask_pixmap_priv,
-			     	    glamor_pixmap_private *dest_pixmap_priv,
+                                    glamor_pixmap_private * source_pixmap_priv,
+                                    glamor_pixmap_private * mask_pixmap_priv,
+                                    glamor_pixmap_private * dest_pixmap_priv,
                                     struct shader_key *s_key,
-				    glamor_composite_shader **shader, 
-				    struct blendinfo *op_info,
-                                    PictFormatShort *psaved_source_format);
+                                    glamor_composite_shader ** shader,
+                                    struct blendinfo *op_info,
+                                    PictFormatShort * psaved_source_format);
 
 void
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
-				  struct shader_key *key,
-				  glamor_composite_shader *shader,
-				  struct blendinfo *op_info);
+
+glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv,
+                                  struct shader_key *key,
+                                  glamor_composite_shader * shader,
+                                  struct blendinfo *op_info);
 
 void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
 void glamor_emit_composite_vert(ScreenPtr screen,
@@ -774,15 +765,15 @@ void glamor_emit_composite_vert(ScreenPtr screen,
 
 /* glamor_trapezoid.c */
 void glamor_trapezoids(CARD8 op,
-		       PicturePtr src, PicturePtr dst,
-		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		       int ntrap, xTrapezoid * traps);
+                       PicturePtr src, PicturePtr dst,
+                       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+                       int ntrap, xTrapezoid * traps);
 
 /* glamor_tile.c */
 Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
-		 int x, int y, int width, int height,
-		 unsigned char alu, unsigned long planemask,
-		 int tile_x, int tile_y);
+                 int x, int y, int width, int height,
+                 unsigned char alu, unsigned long planemask,
+                 int tile_x, int tile_y);
 void glamor_init_tile_shader(ScreenPtr screen);
 void glamor_fini_tile_shader(ScreenPtr screen);
 
@@ -803,16 +794,18 @@ PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen,
 /* glamor_triangles.c */
 void
 
+
 glamor_triangles(CARD8 op,
-		 PicturePtr pSrc,
-		 PicturePtr pDst,
-		 PictFormatPtr maskFormat,
-		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
+                 PicturePtr pSrc,
+                 PicturePtr pDst,
+                 PictFormatPtr maskFormat,
+                 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
 
 /* glamor_pixmap.c */
 
 void glamor_pixmap_init(ScreenPtr screen);
 void glamor_pixmap_fini(ScreenPtr screen);
+
 /** 
  * Download a pixmap's texture to cpu memory. If success,
  * One copy of current pixmap's texture will be put into
@@ -822,13 +815,11 @@ void glamor_pixmap_fini(ScreenPtr screen);
  * gl_tex must be 1. Used by glamor_prepare_access.
  *
  */
-Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
-				   glamor_access_t access);
-
-void *
-glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
-				  int stride, void *bits, int pbo, glamor_access_t access);
+Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
 
+void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w,
+                                        int h, int stride, void *bits, int pbo,
+                                        glamor_access_t access);
 
 /**
  * Restore a pixmap's data which is downloaded by 
@@ -849,7 +840,7 @@ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
  * If the fbo already has a valid glfbo then do nothing.
  */
 Bool
-glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
+ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
@@ -857,61 +848,70 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
  * This function will change current FBO and current shaders.
  */
 enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
-							  pixmap);
+                                                          pixmap);
 
 Bool
-glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
-				    int stride, void *bits, int pbo);
+
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
+                                    int h, int stride, void *bits, int pbo);
 
 PixmapPtr
+
 glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
-		      int w, int h, glamor_access_t access);
+                      int w, int h, glamor_access_t access);
 void
-glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
-		      int w, int h, glamor_access_t access);
 
-glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
-			       int *clipped_nbox, int repeat_type,
-			       int reverse, int upsidedown);
-
-glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
-				   RegionPtr region,
-				   int *n_region,
-				   int inner_block_w, int inner_block_h,
-			           int reverse, int upsidedown);
-
-glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
-					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type,
-			                 int reverse, int upsidedown);
+glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
+                      int w, int h, glamor_access_t access);
+
+glamor_pixmap_clipped_regions
+    *glamor_compute_clipped_regions(glamor_pixmap_private * priv,
+                                    RegionPtr region, int *clipped_nbox,
+                                    int repeat_type, int reverse,
+                                    int upsidedown);
+
+glamor_pixmap_clipped_regions
+    *glamor_compute_clipped_regions_ext(glamor_pixmap_private * pixmap_priv,
+                                        RegionPtr region, int *n_region,
+                                        int inner_block_w, int inner_block_h,
+                                        int reverse, int upsidedown);
+
+glamor_pixmap_clipped_regions
+    *glamor_compute_transform_clipped_regions(glamor_pixmap_private * priv,
+                                              struct pixman_transform
+                                              *transform, RegionPtr region,
+                                              int *n_region, int dx, int dy,
+                                              int repeat_type, int reverse,
+                                              int upsidedown);
 
 Bool
+
 glamor_composite_largepixmap_region(CARD8 op,
-			  PicturePtr source,
-			  PicturePtr mask,
-			  PicturePtr dest,
-			  glamor_pixmap_private * source_pixmap_priv,
-			  glamor_pixmap_private * mask_pixmap_priv,
-			  glamor_pixmap_private * dest_pixmap_priv,
-			  RegionPtr region, Bool force_clip,
-			  INT16 x_source,
-			  INT16 y_source,
-			  INT16 x_mask,
-			  INT16 y_mask,
-			  INT16 x_dest, INT16 y_dest,
-			  CARD16 width, CARD16 height);
+                                    PicturePtr source,
+                                    PicturePtr mask,
+                                    PicturePtr dest,
+                                    glamor_pixmap_private * source_pixmap_priv,
+                                    glamor_pixmap_private * mask_pixmap_priv,
+                                    glamor_pixmap_private * dest_pixmap_priv,
+                                    RegionPtr region, Bool force_clip,
+                                    INT16 x_source,
+                                    INT16 y_source,
+                                    INT16 x_mask,
+                                    INT16 y_mask,
+                                    INT16 x_dest, INT16 y_dest,
+                                    CARD16 width, CARD16 height);
 
 Bool
+
 glamor_get_transform_block_size(struct pixman_transform *transform,
-			   int block_w, int block_h,
-			   int *transformed_block_w,
-			   int *transformed_block_h);
+                                int block_w, int block_h,
+                                int *transformed_block_w,
+                                int *transformed_block_h);
 
 void
+
 glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
-		struct pixman_transform *transform);
+                                     struct pixman_transform *transform);
 
 /**
  * Upload a picture to gl texture. Similar to the
@@ -925,8 +925,9 @@ enum glamor_pixmap_status
  * convert the bits to the specified format/type format
  * if the conversion is unavoidable.
  **/
-Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
-					  int no_alpha, int revert, int swap_rb, void *bits);
+Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
+                                          GLenum type, int no_alpha, int revert,
+                                          int swap_rb, void *bits);
 
 /**
  * Destroy all the resources allocated on the uploading
@@ -939,7 +940,7 @@ int glamor_create_picture(PicturePtr picture);
 void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
 
 Bool
-glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
+ glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
 
 void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access);
 
@@ -947,63 +948,73 @@ void glamor_destroy_picture(PicturePtr picture);
 
 /* fixup a fbo to the exact size as the pixmap. */
 Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
+
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private * pixmap_priv);
 
 void
+
 glamor_picture_format_fixup(PicturePtr picture,
-			    glamor_pixmap_private * pixmap_priv);
+                            glamor_pixmap_private * pixmap_priv);
 
 void
+
 glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
-		 unsigned int format, unsigned long planeMask, char *d);
+                 unsigned int format, unsigned long planeMask, char *d);
 
 void
+
 glamor_add_traps(PicturePtr pPicture,
-		 INT16 x_off, 
-		 INT16 y_off, int ntrap, xTrap * traps);
+                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps);
 
 RegionPtr
+
 glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		  int srcx, int srcy, int w, int h, int dstx, int dsty,
-		  unsigned long bitPlane);
+                  int srcx, int srcy, int w, int h, int dstx, int dsty,
+                  unsigned long bitPlane);
 
 void
+
 glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase);
+                       int x, int y, unsigned int nglyph,
+                       CharInfoPtr * ppci, pointer pglyphBase);
 
 void
+
 glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
-                    int x, int y, unsigned int nglyph,
-                    CharInfoPtr * ppci, pointer pglyphBase);
+                      int x, int y, unsigned int nglyph,
+                      CharInfoPtr * ppci, pointer pglyphBase);
 
 void
+
 glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
-		   DrawablePtr pDrawable, int w, int h, int x, int y);
+                   DrawablePtr pDrawable, int w, int h, int x, int y);
 
 void
+
 glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		  DDXPointPtr ppt);
+                  DDXPointPtr ppt);
 
 void
+
 glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
-		    xSegment *pSeg);
+                    xSegment * pSeg);
 
 void
+
 glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		 DDXPointPtr ppt);
+                 DDXPointPtr ppt);
 
 void
-glamor_composite_rectangles(CARD8	 op,
-			 PicturePtr	 dst,
-			 xRenderColor	*color,
-			 int		 num_rects,
-			 xRectangle	*rects);
+
+glamor_composite_rectangles(CARD8 op,
+                            PicturePtr dst,
+                            xRenderColor * color,
+                            int num_rects, xRectangle *rects);
 
 /* glamor_xv */
 typedef struct {
-    uint32_t	 transform_index;
-    uint32_t	 gamma; /* gamma value x 1000 */
+    uint32_t transform_index;
+    uint32_t gamma;             /* gamma value x 1000 */
     int brightness;
     int saturation;
     int hue;
@@ -1016,8 +1027,8 @@ typedef struct {
     int src_w, src_h, dst_w, dst_h;
     int src_x, src_y, drw_x, drw_y;
     int w, h;
-    RegionRec     clip;
-    PixmapPtr src_pix[3]; /* y, u, v for planar */
+    RegionRec clip;
+    PixmapPtr src_pix[3];       /* y, u, v for planar */
     int src_pix_w, src_pix_h;
 } glamor_port_private;
 
@@ -1039,9 +1050,9 @@ void glamor_fini_xv_shader(ScreenPtr screen);
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #define WALKAROUND_LARGE_TEXTURE_MAP
 #if 0
-#define MAX_FBO_SIZE 32 /* For test purpose only. */
+#define MAX_FBO_SIZE 32         /* For test purpose only. */
 #endif
 //#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
 #define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
 
-#endif				/* GLAMOR_PRIV_H */
+#endif                          /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 99f7ac6..5d06912 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -26,7 +26,6 @@
  *
  */
 
-
 /** @file glamor_putaimge.c
  *
  * XPutImage implementation
@@ -37,54 +36,52 @@ void
 glamor_init_putimage_shaders(ScreenPtr screen)
 {
 #if 0
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	const char *xybitmap_vs =
-	    "uniform float x_bias;\n" "uniform float x_scale;\n"
-	    "uniform float y_bias;\n" "uniform float y_scale;\n"
-	    "varying vec2 bitmap_coords;\n" "void main()\n" "{\n"
-	    "	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
-	    "			   (gl_Vertex.y + y_bias) * y_scale,\n"
-	    "			   0,\n"
-	    "			   1);\n"
-	    "	bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n";
-	const char *xybitmap_fs =
-	    "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n"
-	    "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n"
-	    "	float bitmap_value = texture2D(bitmap_sampler,\n"
-	    "				       bitmap_coords).x;\n"
-	    "	gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n";
-	GLint fs_prog, vs_prog, prog;
-	GLint sampler_uniform_location;
-
-	if (!GLEW_ARB_fragment_shader)
-		return;
-
-	prog = dispatch->glCreateProgram();
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
-	fs_prog =
-	    glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
-	dispatch->glAttachShader(prog, vs_prog);
-	dispatch->glAttachShader(prog, fs_prog);
-	glamor_link_glsl_prog(prog);
-
-	dispatch->glUseProgram(prog);
-	sampler_uniform_location =
-	    dispatch->glGetUniformLocation(prog, "bitmap_sampler");
-	dispatch->glUniform1i(sampler_uniform_location, 0);
-
-	glamor_priv->put_image_xybitmap_fg_uniform_location =
-	    dispatch->glGetUniformLocation(prog, "fg");
-	glamor_priv->put_image_xybitmap_bg_uniform_location =
-	    dispatch->glGetUniformLocation(prog, "bg");
-	glamor_get_transform_uniform_locations(prog,
-					       &glamor_priv->put_image_xybitmap_transform);
-	glamor_priv->put_image_xybitmap_prog = prog;
-	dispatch->glUseProgram(0);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    const char *xybitmap_vs =
+        "uniform float x_bias;\n" "uniform float x_scale;\n"
+        "uniform float y_bias;\n" "uniform float y_scale;\n"
+        "varying vec2 bitmap_coords;\n" "void main()\n" "{\n"
+        "	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+        "			   (gl_Vertex.y + y_bias) * y_scale,\n"
+        "			   0,\n"
+        "			   1);\n"
+        "	bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n";
+    const char *xybitmap_fs =
+        "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n"
+        "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n"
+        "	float bitmap_value = texture2D(bitmap_sampler,\n"
+        "				       bitmap_coords).x;\n"
+        "	gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n";
+    GLint fs_prog, vs_prog, prog;
+    GLint sampler_uniform_location;
+
+    if (!GLEW_ARB_fragment_shader)
+        return;
+
+    prog = dispatch->glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
+    dispatch->glAttachShader(prog, vs_prog);
+    dispatch->glAttachShader(prog, fs_prog);
+    glamor_link_glsl_prog(prog);
+
+    dispatch->glUseProgram(prog);
+    sampler_uniform_location =
+        dispatch->glGetUniformLocation(prog, "bitmap_sampler");
+    dispatch->glUniform1i(sampler_uniform_location, 0);
+
+    glamor_priv->put_image_xybitmap_fg_uniform_location =
+        dispatch->glGetUniformLocation(prog, "fg");
+    glamor_priv->put_image_xybitmap_bg_uniform_location =
+        dispatch->glGetUniformLocation(prog, "bg");
+    glamor_get_transform_uniform_locations(prog,
+                                           &glamor_priv->
+                                           put_image_xybitmap_transform);
+    glamor_priv->put_image_xybitmap_prog = prog;
+    dispatch->glUseProgram(0);
 #endif
 }
 
-
 /* Do an XYBitmap putimage.  The bits are byte-aligned rows of bitmap
  * data (where each row starts at a bit index of left_pad), and the
  * destination gets filled with the gc's fg color where the bitmap is set
@@ -101,141 +98,136 @@ glamor_init_putimage_shaders(ScreenPtr screen)
 static int
 y_flip(PixmapPtr pixmap, int y)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 
-	if (pixmap == screen_pixmap)
-		return (pixmap->drawable.height - 1) - y;
-	else
-		return y;
+    if (pixmap == screen_pixmap)
+        return (pixmap->drawable.height - 1) - y;
+    else
+        return y;
 }
 
-
 static void
 glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
-			  int x, int y, int w, int h, int left_pad,
-			  int image_format, char *bits)
+                          int x, int y, int w, int h, int left_pad,
+                          int image_format, char *bits)
 {
-	ScreenPtr screen = drawable->pScreen;
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	float fg[4], bg[4];
-	GLuint tex;
-	unsigned int stride = PixmapBytePad(1, w + left_pad);
-	RegionPtr clip;
-	BoxPtr box;
-	int nbox;
-	float dest_coords[8];
-	const float bitmap_coords[8] = {
-		0.0, 0.0,
-		1.0, 0.0,
-		1.0, 1.0,
-		0.0, 1.0,
-	};
-	GLfloat xscale, yscale;
-	glamor_pixmap_private *pixmap_priv;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
-	glamor_set_normalize_vcoords(xscale, yscale,
-				     x, y,
-				     x + w, y + h,
-				     glamor_priv->yInverted, dest_coords);
-
-	glamor_fallback("glamor_put_image_xybitmap: disabled\n");
-	goto fail;
-
-	if (glamor_priv->put_image_xybitmap_prog == 0) {
-		ErrorF("no program for xybitmap putimage\n");
-		goto fail;
-	}
-
-	glamor_set_alu(gc->alu);
-	if (!glamor_set_planemask(pixmap, gc->planemask))
-		goto fail;
-
-	dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
-
-	glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
-	dispatch->glUniform4fv
-	    (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
-	glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
-	dispatch->glUniform4fv
-	    (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
-
-	dispatch->glGenTextures(1, &tex);
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glEnable(GL_TEXTURE_2D);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
-			       w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
-	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-
-	/* Now that we've set up our bitmap texture and the shader, shove
-	 * the destination rectangle through the cliprects and run the
-	 * shader on the resulting fragments.
-	 */
-	dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
-	dispatch->glEnableClientState(GL_VERTEX_ARRAY);
-	dispatch->glClientActiveTexture(GL_TEXTURE0);
-	dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
-	dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-	dispatch->glEnable(GL_SCISSOR_TEST);
-	clip = fbGetCompositeClip(gc);
-	for (nbox = REGION_NUM_RECTS(clip),
-	     box = REGION_RECTS(clip); nbox--; box++) {
-		int x1 = x;
-		int y1 = y;
-		int x2 = x + w;
-		int y2 = y + h;
-
-		if (x1 < box->x1)
-			x1 = box->x1;
-		if (y1 < box->y1)
-			y1 = box->y1;
-		if (x2 > box->x2)
-			x2 = box->x2;
-		if (y2 > box->y2)
-			y2 = box->y2;
-		if (x1 >= x2 || y1 >= y2)
-			continue;
-
-		dispatch->glScissor(box->x1,
-				    y_flip(pixmap, box->y1),
-				    box->x2 - box->x1, box->y2 - box->y1);
-		dispatch->glDrawArrays(GL_QUADS, 0, 4);
-	}
-
-	dispatch->glDisable(GL_SCISSOR_TEST);
-	glamor_set_alu(GXcopy);
-	glamor_set_planemask(pixmap, ~0);
-	dispatch->glDeleteTextures(1, &tex);
-	dispatch->glDisable(GL_TEXTURE_2D);
-	dispatch->glDisableClientState(GL_VERTEX_ARRAY);
-	dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	return;
-	glamor_set_alu(GXcopy);
-	glamor_set_planemask(pixmap, ~0);
-	glamor_fallback(": to %p (%c)\n",
-			drawable, glamor_get_drawable_location(drawable));
-fail:
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
-			   bits);
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-	}
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    float fg[4], bg[4];
+    GLuint tex;
+    unsigned int stride = PixmapBytePad(1, w + left_pad);
+    RegionPtr clip;
+    BoxPtr box;
+    int nbox;
+    float dest_coords[8];
+
+    const float bitmap_coords[8] = {
+        0.0, 0.0,
+        1.0, 0.0,
+        1.0, 1.0,
+        0.0, 1.0,
+    };
+    GLfloat xscale, yscale;
+    glamor_pixmap_private *pixmap_priv;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
+    glamor_set_normalize_vcoords(xscale, yscale,
+                                 x, y,
+                                 x + w, y + h,
+                                 glamor_priv->yInverted, dest_coords);
+
+    glamor_fallback("glamor_put_image_xybitmap: disabled\n");
+    goto fail;
+
+    if (glamor_priv->put_image_xybitmap_prog == 0) {
+        ErrorF("no program for xybitmap putimage\n");
+        goto fail;
+    }
+
+    glamor_set_alu(gc->alu);
+    if (!glamor_set_planemask(pixmap, gc->planemask))
+        goto fail;
+
+    dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
+
+    glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
+    dispatch->glUniform4fv
+        (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
+    glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
+    dispatch->glUniform4fv
+        (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
+
+    dispatch->glGenTextures(1, &tex);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
+    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+                           w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
+    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+
+    /* Now that we've set up our bitmap texture and the shader, shove
+     * the destination rectangle through the cliprects and run the
+     * shader on the resulting fragments.
+     */
+    dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
+    dispatch->glEnableClientState(GL_VERTEX_ARRAY);
+    dispatch->glClientActiveTexture(GL_TEXTURE0);
+    dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
+    dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    dispatch->glEnable(GL_SCISSOR_TEST);
+    clip = fbGetCompositeClip(gc);
+    for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) {
+        int x1 = x;
+        int y1 = y;
+        int x2 = x + w;
+        int y2 = y + h;
+
+        if (x1 < box->x1)
+            x1 = box->x1;
+        if (y1 < box->y1)
+            y1 = box->y1;
+        if (x2 > box->x2)
+            x2 = box->x2;
+        if (y2 > box->y2)
+            y2 = box->y2;
+        if (x1 >= x2 || y1 >= y2)
+            continue;
+
+        dispatch->glScissor(box->x1,
+                            y_flip(pixmap, box->y1),
+                            box->x2 - box->x1, box->y2 - box->y1);
+        dispatch->glDrawArrays(GL_QUADS, 0, 4);
+    }
+
+    dispatch->glDisable(GL_SCISSOR_TEST);
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
+    dispatch->glDeleteTextures(1, &tex);
+    dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glDisableClientState(GL_VERTEX_ARRAY);
+    dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    return;
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
+    glamor_fallback(": to %p (%c)\n",
+                    drawable, glamor_get_drawable_location(drawable));
+ fail:
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+        fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits);
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+    }
 }
 #endif
 
@@ -244,120 +236,120 @@ glamor_fini_putimage_shaders(ScreenPtr screen)
 {
 }
 
-
-static Bool 
+static Bool
 _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int left_pad, int image_format, char *bits, Bool fallback)
+                  int w, int h, int left_pad, int image_format, char *bits,
+                  Bool fallback)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	RegionPtr clip;
-	int x_off, y_off;
-	Bool ret = FALSE;
-	PixmapPtr temp_pixmap, sub_pixmap;
-	glamor_pixmap_private *temp_pixmap_priv;
-	BoxRec box;
-
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-	clip = fbGetCompositeClip(gc);
-	if (image_format == XYBitmap) {
-		assert(depth == 1);
-		goto fail;
-	}
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-		glamor_fallback("has no fbo.\n");
-		goto fail;
-	}
-
-	if (image_format != ZPixmap) {
-		glamor_fallback("non-ZPixmap\n");
-		goto fail;
-	}
-
-	if (!glamor_set_planemask(pixmap, gc->planemask)) {
-		goto fail;
-	}
-	/* create a temporary pixmap and upload the bits to that
-	 * pixmap, then apply clip copy it to the destination pixmap.*/
-	box.x1 = x + drawable->x;
-	box.y1 = y + drawable->y;
-	box.x2 = x + w + drawable->x;
-	box.y2 = y + h + drawable->y;
-
-	if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
-	     || gc->alu != GXcopy) {
-		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
-		if (temp_pixmap == NULL)
-			goto fail;
-
-		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-
-		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
-			temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
-			temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
-		}
-
-		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
-						    pixmap->devKind, bits, 0);
-
-		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
-		glamor_destroy_pixmap(temp_pixmap);
-	} else
-		glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off,
-						    w, h, PixmapBytePad(w, depth), bits, 0);
-	ret = TRUE;
-	goto done;
-
-fail:
-	glamor_set_planemask(pixmap, ~0);
-
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
-		goto done;
-
-	glamor_fallback("to %p (%c)\n",
-			drawable, glamor_get_drawable_location(drawable));
-
-	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
-					   y + y_off + drawable->y, w, h,
-					   GLAMOR_ACCESS_RW);
-	if (sub_pixmap) {
-		if (clip != NULL)
-			pixman_region_translate (clip, -x - drawable->x, -y - drawable->y);
-
-		fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
-			   left_pad, image_format, bits);
-
-		glamor_put_sub_pixmap(sub_pixmap, pixmap,
-				      x + x_off + drawable->x,
-				      y + y_off + drawable->y,
-				      w, h, GLAMOR_ACCESS_RW);
-		if (clip != NULL)
-			pixman_region_translate (clip, x + drawable->x, y + drawable->y);
-	} else
-		fbPutImage(drawable, gc, depth, x, y, w, h,
-			   left_pad, image_format, bits);
-	ret = TRUE;
-
-done:
-	return ret;
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    RegionPtr clip;
+    int x_off, y_off;
+    Bool ret = FALSE;
+    PixmapPtr temp_pixmap, sub_pixmap;
+    glamor_pixmap_private *temp_pixmap_priv;
+    BoxRec box;
+
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+    clip = fbGetCompositeClip(gc);
+    if (image_format == XYBitmap) {
+        assert(depth == 1);
+        goto fail;
+    }
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+        glamor_fallback("has no fbo.\n");
+        goto fail;
+    }
+
+    if (image_format != ZPixmap) {
+        glamor_fallback("non-ZPixmap\n");
+        goto fail;
+    }
+
+    if (!glamor_set_planemask(pixmap, gc->planemask)) {
+        goto fail;
+    }
+    /* create a temporary pixmap and upload the bits to that
+     * pixmap, then apply clip copy it to the destination pixmap.*/
+    box.x1 = x + drawable->x;
+    box.y1 = y + drawable->y;
+    box.x2 = x + w + drawable->x;
+    box.y2 = y + h + drawable->y;
+
+    if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
+        || gc->alu != GXcopy) {
+        temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
+        if (temp_pixmap == NULL)
+            goto fail;
+
+        temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+
+        if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
+            temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
+            temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
+        }
+
+        glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
+                                            pixmap->devKind, bits, 0);
+
+        glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x,
+                         y);
+        glamor_destroy_pixmap(temp_pixmap);
+    }
+    else
+        glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off,
+                                            y + drawable->y + y_off, w, h,
+                                            PixmapBytePad(w, depth), bits, 0);
+    ret = TRUE;
+    goto done;
+
+ fail:
+    glamor_set_planemask(pixmap, ~0);
+
+    if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
+        goto done;
+
+    glamor_fallback("to %p (%c)\n",
+                    drawable, glamor_get_drawable_location(drawable));
+
+    sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
+                                       y + y_off + drawable->y, w, h,
+                                       GLAMOR_ACCESS_RW);
+    if (sub_pixmap) {
+        if (clip != NULL)
+            pixman_region_translate(clip, -x - drawable->x, -y - drawable->y);
+
+        fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
+                   left_pad, image_format, bits);
+
+        glamor_put_sub_pixmap(sub_pixmap, pixmap,
+                              x + x_off + drawable->x,
+                              y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW);
+        if (clip != NULL)
+            pixman_region_translate(clip, x + drawable->x, y + drawable->y);
+    }
+    else
+        fbPutImage(drawable, gc, depth, x, y, w, h,
+                   left_pad, image_format, bits);
+    ret = TRUE;
+
+ done:
+    return ret;
 }
 
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int left_pad, int image_format, char *bits)
+                 int w, int h, int left_pad, int image_format, char *bits)
 {
-	_glamor_put_image(drawable, gc, depth, x, y, w, h, 
-			left_pad, image_format, bits, TRUE);
+    _glamor_put_image(drawable, gc, depth, x, y, w, h,
+                      left_pad, image_format, bits, TRUE);
 }
 
 Bool
 glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int left_pad, int image_format, char *bits)
+                    int w, int h, int left_pad, int image_format, char *bits)
 {
-	return _glamor_put_image(drawable, gc, depth, x, y, w, h, 
-				left_pad, image_format, bits, FALSE);
+    return _glamor_put_image(drawable, gc, depth, x, y, w, h,
+                             left_pad, image_format, bits, FALSE);
 }
-
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 76a571f..d6ccf81 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -45,1425 +45,1403 @@
 #endif
 
 static struct blendinfo composite_op_info[] = {
-	[PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
-	[PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
-	[PictOpDst] = {0, 0, GL_ZERO, GL_ONE},
-	[PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
-	[PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
-	[PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO},
-	[PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA},
-	[PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
-	[PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
-	[PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
-	[PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
-	[PictOpXor] =
-	    {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
-	[PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
+    [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
+    [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
+    [PictOpDst] = {0, 0, GL_ZERO, GL_ONE},
+    [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+    [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO},
+    [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA},
+    [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+    [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+    [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
 };
+
 #define RepeatFix			10
 static GLuint
 glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
-			   struct shader_key *key)
+                           struct shader_key *key)
 {
-	const char *repeat_define =
-	    "#define RepeatNone               	      0\n"
-	    "#define RepeatNormal                     1\n"
-	    "#define RepeatPad                        2\n"
-	    "#define RepeatReflect                    3\n"
-	    "#define RepeatFix		      	      10\n"
-	    "uniform int 			source_repeat_mode;\n"
-	    "uniform int 			mask_repeat_mode;\n";
-	const char *relocate_texture =
-	    GLAMOR_DEFAULT_PRECISION
-	    "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
-	    "{\n"
-	    "   vec2 rel_tex; \n"
-	    "   rel_tex = texture * wh.xy; \n"
-	    "	if (repeat == RepeatNone)\n"
-	    "		return rel_tex; \n"
-	    "   else if (repeat == RepeatNormal) \n"
-	    "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); 	\n"
-	    "   else if(repeat == RepeatPad) { \n"
-	    "           if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.;  	\n"
-	    "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;	  	\n"
-	    "           if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.;	\n"
-	    "		else if(rel_tex.y < 0.0) rel_tex.y = 0.0;	\n"
-	    "   	rel_tex = rel_tex / wh.xy; \n"
-	    "    } \n"
-	    "   else if(repeat == RepeatReflect) {\n"
-	    "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
-	    "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n"
-	    "		else \n"
-	    "			rel_tex.x = fract(rel_tex.x)/wh.x;\n"
-	    "		if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n"
-	    "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
-	    "		else \n"
-	    "			rel_tex.y = fract(rel_tex.y)/wh.y;\n"
-	    "    } \n"
-            "   return rel_tex; \n"
-	    "}\n";
-	/* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
-	 * rel_sampler will recalculate the texture coords.*/
-	const char *rel_sampler =
-	    " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
-	    "{\n"
-	    "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
-	    "   if (repeat == RepeatFix) {\n"
-	    "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
-	    "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
-	    "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
-	    "		tex = (fract(tex) / wh.xy);\n"
-	    "	}\n"
-	    "	if (set_alpha != 1)\n"
-	    "		return texture2D(tex_image, tex);\n"
-	    "	else\n"
-	    "		return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
-	    "}\n";
-
-	const char *source_solid_fetch =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform vec4 source;\n"
-	    "vec4 get_source()\n" "{\n" "	return source;\n" "}\n";
-	const char *source_alpha_pixmap_fetch =
-	    GLAMOR_DEFAULT_PRECISION
-	    "varying vec2 source_texture;\n"
-	    "uniform sampler2D source_sampler;\n"
-	    "uniform vec4 source_wh;"
-	    "vec4 get_source()\n"
-	    "{\n"
-	    "   if (source_repeat_mode < RepeatFix)\n"
-	    "		return texture2D(source_sampler, source_texture);\n"
-	    "   else \n"
-	    "		return rel_sampler(source_sampler, source_texture,\n"
-	    "				   source_wh, source_repeat_mode, 0);\n"
-	    "}\n";
-	const char *source_pixmap_fetch =
-	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
-	    "uniform sampler2D source_sampler;\n"
-	    "uniform vec4 source_wh;\n"
-	    "vec4 get_source()\n"
-	    "{\n"
-	    "   if (source_repeat_mode < RepeatFix) \n"
-	    "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
-	    "	else \n"
-	    "		return rel_sampler(source_sampler, source_texture,\n"
-	    "				   source_wh, source_repeat_mode, 1);\n"
-	    "}\n";
-	const char *mask_solid_fetch =
-	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
-	    "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
-	const char *mask_alpha_pixmap_fetch =
-	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec4 mask_wh;\n"
-	    "vec4 get_mask()\n"
-	    "{\n"
-	    "   if (mask_repeat_mode < RepeatFix) \n"
-	    "		return texture2D(mask_sampler, mask_texture);\n"
-	    "   else \n"
-	    "		return rel_sampler(mask_sampler, mask_texture,\n"
-	    "				   mask_wh, mask_repeat_mode, 0);\n"
-	    "}\n";
-	const char *mask_pixmap_fetch =
-	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec4 mask_wh;\n"
-	    "vec4 get_mask()\n"
-	    "{\n"
-	    "   if (mask_repeat_mode < RepeatFix) \n"
-	    "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
-	    "   else \n"
-	    "		return rel_sampler(mask_sampler, mask_texture,\n"
-	    "				   mask_wh, mask_repeat_mode, 1);\n"
-	    "}\n";
-	const char *in_source_only =
-	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-	    "	gl_FragColor = get_source();\n" "}\n";
-	const char *in_normal =
-	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-	    "	gl_FragColor = get_source() * get_mask().a;\n" "}\n";
-	const char *in_ca_source =
-	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-	    "	gl_FragColor = get_source() * get_mask();\n" "}\n";
-	const char *in_ca_alpha =
-	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
-	    "	gl_FragColor = get_source().a * get_mask();\n" "}\n";
-	char *source;
-	const char *source_fetch;
-	const char *mask_fetch = "";
-	const char *in;
-	GLuint prog;
-
-	switch (key->source) {
-	case SHADER_SOURCE_SOLID:
-		source_fetch = source_solid_fetch;
-		break;
-	case SHADER_SOURCE_TEXTURE_ALPHA:
-		source_fetch = source_alpha_pixmap_fetch;
-		break;
-	case SHADER_SOURCE_TEXTURE:
-		source_fetch = source_pixmap_fetch;
-		break;
-	default:
-		FatalError("Bad composite shader source");
-	}
-
-	switch (key->mask) {
-	case SHADER_MASK_NONE:
-		break;
-	case SHADER_MASK_SOLID:
-		mask_fetch = mask_solid_fetch;
-		break;
-	case SHADER_MASK_TEXTURE_ALPHA:
-		mask_fetch = mask_alpha_pixmap_fetch;
-		break;
-	case SHADER_MASK_TEXTURE:
-		mask_fetch = mask_pixmap_fetch;
-		break;
-	default:
-		FatalError("Bad composite shader mask");
-	}
-
-	switch (key->in) {
-	case SHADER_IN_SOURCE_ONLY:
-		in = in_source_only;
-		break;
-	case SHADER_IN_NORMAL:
-		in = in_normal;
-		break;
-	case SHADER_IN_CA_SOURCE:
-		in = in_ca_source;
-		break;
-	case SHADER_IN_CA_ALPHA:
-		in = in_ca_alpha;
-		break;
-	default:
-		FatalError("Bad composite IN type");
-	}
-
-	XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, rel_sampler,source_fetch, mask_fetch, in);
-
-
-	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-					source);
-	free(source);
-
-	return prog;
+    const char *repeat_define =
+        "#define RepeatNone               	      0\n"
+        "#define RepeatNormal                     1\n"
+        "#define RepeatPad                        2\n"
+        "#define RepeatReflect                    3\n"
+        "#define RepeatFix		      	      10\n"
+        "uniform int 			source_repeat_mode;\n"
+        "uniform int 			mask_repeat_mode;\n";
+    const char *relocate_texture =
+        GLAMOR_DEFAULT_PRECISION
+        "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
+        "{\n"
+        "   vec2 rel_tex; \n"
+        "   rel_tex = texture * wh.xy; \n"
+        "	if (repeat == RepeatNone)\n"
+        "		return rel_tex; \n"
+        "   else if (repeat == RepeatNormal) \n"
+        "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); 	\n"
+        "   else if(repeat == RepeatPad) { \n"
+        "           if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.;  	\n"
+        "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;	  	\n"
+        "           if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.;	\n"
+        "		else if(rel_tex.y < 0.0) rel_tex.y = 0.0;	\n"
+        "   	rel_tex = rel_tex / wh.xy; \n"
+        "    } \n"
+        "   else if(repeat == RepeatReflect) {\n"
+        "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
+        "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n"
+        "		else \n"
+        "			rel_tex.x = fract(rel_tex.x)/wh.x;\n"
+        "		if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n"
+        "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
+        "		else \n"
+        "			rel_tex.y = fract(rel_tex.y)/wh.y;\n"
+        "    } \n" "   return rel_tex; \n" "}\n";
+    /* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
+     * rel_sampler will recalculate the texture coords.*/
+    const char *rel_sampler =
+        " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
+        "{\n"
+        "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
+        "   if (repeat == RepeatFix) {\n"
+        "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
+        "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
+        "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
+        "		tex = (fract(tex) / wh.xy);\n"
+        "	}\n"
+        "	if (set_alpha != 1)\n"
+        "		return texture2D(tex_image, tex);\n"
+        "	else\n"
+        "		return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+        "}\n";
+
+    const char *source_solid_fetch =
+        GLAMOR_DEFAULT_PRECISION
+        "uniform vec4 source;\n"
+        "vec4 get_source()\n" "{\n" "	return source;\n" "}\n";
+    const char *source_alpha_pixmap_fetch =
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 source_texture;\n"
+        "uniform sampler2D source_sampler;\n"
+        "uniform vec4 source_wh;"
+        "vec4 get_source()\n"
+        "{\n"
+        "   if (source_repeat_mode < RepeatFix)\n"
+        "		return texture2D(source_sampler, source_texture);\n"
+        "   else \n"
+        "		return rel_sampler(source_sampler, source_texture,\n"
+        "				   source_wh, source_repeat_mode, 0);\n"
+        "}\n";
+    const char *source_pixmap_fetch =
+        GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
+        "uniform sampler2D source_sampler;\n"
+        "uniform vec4 source_wh;\n"
+        "vec4 get_source()\n"
+        "{\n"
+        "   if (source_repeat_mode < RepeatFix) \n"
+        "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
+        "	else \n"
+        "		return rel_sampler(source_sampler, source_texture,\n"
+        "				   source_wh, source_repeat_mode, 1);\n"
+        "}\n";
+    const char *mask_solid_fetch =
+        GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
+        "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
+    const char *mask_alpha_pixmap_fetch =
+        GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+        "uniform sampler2D mask_sampler;\n"
+        "uniform vec4 mask_wh;\n"
+        "vec4 get_mask()\n"
+        "{\n"
+        "   if (mask_repeat_mode < RepeatFix) \n"
+        "		return texture2D(mask_sampler, mask_texture);\n"
+        "   else \n"
+        "		return rel_sampler(mask_sampler, mask_texture,\n"
+        "				   mask_wh, mask_repeat_mode, 0);\n"
+        "}\n";
+    const char *mask_pixmap_fetch =
+        GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+        "uniform sampler2D mask_sampler;\n"
+        "uniform vec4 mask_wh;\n"
+        "vec4 get_mask()\n"
+        "{\n"
+        "   if (mask_repeat_mode < RepeatFix) \n"
+        "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+        "   else \n"
+        "		return rel_sampler(mask_sampler, mask_texture,\n"
+        "				   mask_wh, mask_repeat_mode, 1);\n"
+        "}\n";
+    const char *in_source_only =
+        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+        "	gl_FragColor = get_source();\n" "}\n";
+    const char *in_normal =
+        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+        "	gl_FragColor = get_source() * get_mask().a;\n" "}\n";
+    const char *in_ca_source =
+        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+        "	gl_FragColor = get_source() * get_mask();\n" "}\n";
+    const char *in_ca_alpha =
+        GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+        "	gl_FragColor = get_source().a * get_mask();\n" "}\n";
+    char *source;
+    const char *source_fetch;
+    const char *mask_fetch = "";
+    const char *in;
+    GLuint prog;
+
+    switch (key->source) {
+    case SHADER_SOURCE_SOLID:
+        source_fetch = source_solid_fetch;
+        break;
+    case SHADER_SOURCE_TEXTURE_ALPHA:
+        source_fetch = source_alpha_pixmap_fetch;
+        break;
+    case SHADER_SOURCE_TEXTURE:
+        source_fetch = source_pixmap_fetch;
+        break;
+    default:
+        FatalError("Bad composite shader source");
+    }
+
+    switch (key->mask) {
+    case SHADER_MASK_NONE:
+        break;
+    case SHADER_MASK_SOLID:
+        mask_fetch = mask_solid_fetch;
+        break;
+    case SHADER_MASK_TEXTURE_ALPHA:
+        mask_fetch = mask_alpha_pixmap_fetch;
+        break;
+    case SHADER_MASK_TEXTURE:
+        mask_fetch = mask_pixmap_fetch;
+        break;
+    default:
+        FatalError("Bad composite shader mask");
+    }
+
+    switch (key->in) {
+    case SHADER_IN_SOURCE_ONLY:
+        in = in_source_only;
+        break;
+    case SHADER_IN_NORMAL:
+        in = in_normal;
+        break;
+    case SHADER_IN_CA_SOURCE:
+        in = in_ca_source;
+        break;
+    case SHADER_IN_CA_ALPHA:
+        in = in_ca_alpha;
+        break;
+    default:
+        FatalError("Bad composite IN type");
+    }
+
+    XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture,
+                rel_sampler, source_fetch, mask_fetch, in);
+
+    prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
+    free(source);
+
+    return prog;
 }
 
 static GLuint
 glamor_create_composite_vs(glamor_gl_dispatch * dispatch,
-			   struct shader_key *key)
+                           struct shader_key *key)
 {
-	const char *main_opening =
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord0;\n"
-	    "attribute vec4 v_texcoord1;\n"
-	    "varying vec2 source_texture;\n"
-	    "varying vec2 mask_texture;\n"
-	    "void main()\n" "{\n" "	gl_Position = v_position;\n";
-	const char *source_coords =
-	    "	source_texture = v_texcoord0.xy;\n";
-	const char *mask_coords = "	mask_texture = v_texcoord1.xy;\n";
-	const char *main_closing = "}\n";
-	const char *source_coords_setup = "";
-	const char *mask_coords_setup = "";
-	char *source;
-	GLuint prog;
-
-	if (key->source != SHADER_SOURCE_SOLID)
-		source_coords_setup = source_coords;
-
-	if (key->mask != SHADER_MASK_NONE
-	    && key->mask != SHADER_MASK_SOLID)
-		mask_coords_setup = mask_coords;
-
-	XNFasprintf(&source,
-		    "%s%s%s%s",
-		    main_opening,
-		    source_coords_setup, mask_coords_setup, main_closing);
-
-	prog =
-	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
-	free(source);
-
-	return prog;
+    const char *main_opening =
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord0;\n"
+        "attribute vec4 v_texcoord1;\n"
+        "varying vec2 source_texture;\n"
+        "varying vec2 mask_texture;\n"
+        "void main()\n" "{\n" "	gl_Position = v_position;\n";
+    const char *source_coords = "	source_texture = v_texcoord0.xy;\n";
+    const char *mask_coords = "	mask_texture = v_texcoord1.xy;\n";
+    const char *main_closing = "}\n";
+    const char *source_coords_setup = "";
+    const char *mask_coords_setup = "";
+    char *source;
+    GLuint prog;
+
+    if (key->source != SHADER_SOURCE_SOLID)
+        source_coords_setup = source_coords;
+
+    if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
+        mask_coords_setup = mask_coords;
+
+    XNFasprintf(&source,
+                "%s%s%s%s",
+                main_opening,
+                source_coords_setup, mask_coords_setup, main_closing);
+
+    prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
+    free(source);
+
+    return prog;
 }
 
 static void
 glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
-			       glamor_composite_shader * shader)
+                               glamor_composite_shader * shader)
 {
-	GLuint vs, fs, prog;
-	GLint source_sampler_uniform_location,
-	    mask_sampler_uniform_location;
-	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	vs = glamor_create_composite_vs(dispatch, key);
-	if (vs == 0)
-		goto out;
-	fs = glamor_create_composite_fs(dispatch, key);
-	if (fs == 0)
-		goto out;
-
-	prog = dispatch->glCreateProgram();
-	dispatch->glAttachShader(prog, vs);
-	dispatch->glAttachShader(prog, fs);
-
-	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS,
-				       "v_position");
-	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE,
-				       "v_texcoord0");
-	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK,
-				       "v_texcoord1");
-
-	glamor_link_glsl_prog(dispatch, prog);
-
-	shader->prog = prog;
-
-	dispatch->glUseProgram(prog);
-
-	if (key->source == SHADER_SOURCE_SOLID) {
-		shader->source_uniform_location =
-		    dispatch->glGetUniformLocation(prog, "source");
-	} else {
-		source_sampler_uniform_location =
-		    dispatch->glGetUniformLocation(prog, "source_sampler");
-		dispatch->glUniform1i(source_sampler_uniform_location, 0);
-		shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
-		shader->source_repeat_mode = dispatch->glGetUniformLocation(prog, "source_repeat_mode");
-	}
-
-	if (key->mask != SHADER_MASK_NONE) {
-		if (key->mask == SHADER_MASK_SOLID) {
-			shader->mask_uniform_location =
-			    dispatch->glGetUniformLocation(prog, "mask");
-		} else {
-			mask_sampler_uniform_location =
-			    dispatch->glGetUniformLocation(prog,
-							   "mask_sampler");
-			dispatch->glUniform1i
-			    (mask_sampler_uniform_location, 1);
-			shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
-			shader->mask_repeat_mode = dispatch->glGetUniformLocation(prog, "mask_repeat_mode");
-		}
-	}
-
-out:
-	glamor_put_dispatch(glamor_priv);
+    GLuint vs, fs, prog;
+    GLint source_sampler_uniform_location, mask_sampler_uniform_location;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    vs = glamor_create_composite_vs(dispatch, key);
+    if (vs == 0)
+        goto out;
+    fs = glamor_create_composite_fs(dispatch, key);
+    if (fs == 0)
+        goto out;
+
+    prog = dispatch->glCreateProgram();
+    dispatch->glAttachShader(prog, vs);
+    dispatch->glAttachShader(prog, fs);
+
+    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
+
+    glamor_link_glsl_prog(dispatch, prog);
+
+    shader->prog = prog;
+
+    dispatch->glUseProgram(prog);
+
+    if (key->source == SHADER_SOURCE_SOLID) {
+        shader->source_uniform_location =
+            dispatch->glGetUniformLocation(prog, "source");
+    }
+    else {
+        source_sampler_uniform_location =
+            dispatch->glGetUniformLocation(prog, "source_sampler");
+        dispatch->glUniform1i(source_sampler_uniform_location, 0);
+        shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
+        shader->source_repeat_mode =
+            dispatch->glGetUniformLocation(prog, "source_repeat_mode");
+    }
+
+    if (key->mask != SHADER_MASK_NONE) {
+        if (key->mask == SHADER_MASK_SOLID) {
+            shader->mask_uniform_location =
+                dispatch->glGetUniformLocation(prog, "mask");
+        }
+        else {
+            mask_sampler_uniform_location =
+                dispatch->glGetUniformLocation(prog, "mask_sampler");
+            dispatch->glUniform1i(mask_sampler_uniform_location, 1);
+            shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
+            shader->mask_repeat_mode =
+                dispatch->glGetUniformLocation(prog, "mask_repeat_mode");
+        }
+    }
+
+ out:
+    glamor_put_dispatch(glamor_priv);
 }
 
 static glamor_composite_shader *
 glamor_lookup_composite_shader(ScreenPtr screen, struct
-			       shader_key
-			       *key)
+                               shader_key
+                               *key)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_composite_shader *shader;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_composite_shader *shader;
 
-	shader =
-	    &glamor_priv->composite_shader[key->source][key->
-							mask][key->in];
-	if (shader->prog == 0)
-		glamor_create_composite_shader(screen, key, shader);
+    shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
+    if (shader->prog == 0)
+        glamor_create_composite_shader(screen, key, shader);
 
-	return shader;
+    return shader;
 }
 
 static void
 glamor_init_eb(unsigned short *eb, int vert_cnt)
 {
-	int i, j;
-	for(i = 0, j = 0; j < vert_cnt; i += 6, j += 4)
-	{
-		eb[i] = j;
-		eb[i + 1] = j + 1;
-		eb[i + 2] = j + 2;
-		eb[i + 3] = j;
-		eb[i + 4] = j + 2;
-		eb[i + 5] = j + 3;
-	}
+    int i, j;
+
+    for (i = 0, j = 0; j < vert_cnt; i += 6, j += 4) {
+        eb[i] = j;
+        eb[i + 1] = j + 1;
+        eb[i + 2] = j + 2;
+        eb[i + 3] = j;
+        eb[i + 4] = j + 2;
+        eb[i + 5] = j + 3;
+    }
 }
 
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	unsigned short *eb;
-	float *vb = NULL;
-	int eb_size;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glGenBuffers(1, &glamor_priv->vbo);
-	dispatch->glGenBuffers(1, &glamor_priv->ebo);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
-	eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-				       eb_size,
-				       NULL, GL_STATIC_DRAW);
-		eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
-	}
-	else {
-		vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
-		if (vb == NULL)
-			FatalError("Failed to allocate vb memory.\n");
-		eb = malloc(eb_size);
-	}
-
-	if (eb == NULL)
-		FatalError("fatal error, fail to get element buffer. GL context may be not created correctly.\n");
-	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-	} else {
-		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-				       eb_size,
-				       eb, GL_STATIC_DRAW);
-		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-				       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2,
-				       NULL, GL_DYNAMIC_DRAW);
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-		free(eb);
-		glamor_priv->vb = (char*)vb;
-	}
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    unsigned short *eb;
+    float *vb = NULL;
+    int eb_size;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glGenBuffers(1, &glamor_priv->vbo);
+    dispatch->glGenBuffers(1, &glamor_priv->ebo);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+    eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+                               eb_size, NULL, GL_STATIC_DRAW);
+        eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+    }
+    else {
+        vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
+        if (vb == NULL)
+            FatalError("Failed to allocate vb memory.\n");
+        eb = malloc(eb_size);
+    }
+
+    if (eb == NULL)
+        FatalError
+            ("fatal error, fail to get element buffer. GL context may be not created correctly.\n");
+    glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    }
+    else {
+        dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+                               eb_size, eb, GL_STATIC_DRAW);
+        dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        dispatch->glBufferData(GL_ARRAY_BUFFER,
+                               GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) *
+                               2, NULL, GL_DYNAMIC_DRAW);
+        dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+        free(eb);
+        glamor_priv->vb = (char *) vb;
+    }
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_composite_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	glamor_composite_shader *shader;
-	int i,j,k;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
-	dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
-
-	for(i = 0; i < SHADER_SOURCE_COUNT; i++)
-		for(j = 0; j < SHADER_MASK_COUNT; j++)
-			for(k = 0; k < SHADER_IN_COUNT; k++)
-			{
-				shader = &glamor_priv->composite_shader[i][j][k];
-				if (shader->prog)
-					dispatch->glDeleteProgram(shader->prog);
-			}
-	if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
-	    && glamor_priv->vb)
-		free(glamor_priv->vb);
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    glamor_composite_shader *shader;
+    int i, j, k;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
+    dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
+
+    for (i = 0; i < SHADER_SOURCE_COUNT; i++)
+        for (j = 0; j < SHADER_MASK_COUNT; j++)
+            for (k = 0; k < SHADER_IN_COUNT; k++) {
+                shader = &glamor_priv->composite_shader[i][j][k];
+                if (shader->prog)
+                    dispatch->glDeleteProgram(shader->prog);
+            }
+    if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb)
+        free(glamor_priv->vb);
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
-			CARD8 op, struct blendinfo *op_info_result,
-			PicturePtr dest, PicturePtr mask)
+                        CARD8 op, struct blendinfo *op_info_result,
+                        PicturePtr dest, PicturePtr mask)
 {
-	GLenum source_blend, dest_blend;
-	struct blendinfo *op_info;
-
-	if (op >= ARRAY_SIZE(composite_op_info)) {
-		glamor_fallback("unsupported render op %d \n", op);
-		return GL_FALSE;
-	}
-	op_info = &composite_op_info[op];
-
-	source_blend = op_info->source_blend;
-	dest_blend = op_info->dest_blend;
-
-	/* If there's no dst alpha channel, adjust the blend op so that we'll treat
-	 * it as always 1.
-	 */
-	if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
-		if (source_blend == GL_DST_ALPHA)
-			source_blend = GL_ONE;
-		else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
-			source_blend = GL_ZERO;
-	}
-
-	/* Set up the source alpha value for blending in component alpha mode. */
-	if (mask && mask->componentAlpha
-	    && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha)
-	{
-		if (dest_blend == GL_SRC_ALPHA)
-			dest_blend = GL_SRC_COLOR;
-		else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
-			dest_blend = GL_ONE_MINUS_SRC_COLOR;
-	}
-
-	op_info_result->source_blend = source_blend;
-	op_info_result->dest_blend = dest_blend;
-	op_info_result->source_alpha = op_info->source_alpha;
-	op_info_result->dest_alpha = op_info->dest_alpha;
-
-	return TRUE;
+    GLenum source_blend, dest_blend;
+    struct blendinfo *op_info;
+
+    if (op >= ARRAY_SIZE(composite_op_info)) {
+        glamor_fallback("unsupported render op %d \n", op);
+        return GL_FALSE;
+    }
+    op_info = &composite_op_info[op];
+
+    source_blend = op_info->source_blend;
+    dest_blend = op_info->dest_blend;
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
+        if (source_blend == GL_DST_ALPHA)
+            source_blend = GL_ONE;
+        else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
+            source_blend = GL_ZERO;
+    }
+
+    /* Set up the source alpha value for blending in component alpha mode. */
+    if (mask && mask->componentAlpha
+        && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) {
+        if (dest_blend == GL_SRC_ALPHA)
+            dest_blend = GL_SRC_COLOR;
+        else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+            dest_blend = GL_ONE_MINUS_SRC_COLOR;
+    }
+
+    op_info_result->source_blend = source_blend;
+    op_info_result->dest_blend = dest_blend;
+    op_info_result->source_alpha = op_info->source_alpha;
+    op_info_result->dest_alpha = op_info->dest_alpha;
+
+    return TRUE;
 }
 
 static void
-glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
-			     PicturePtr picture,
-			     glamor_pixmap_private * pixmap_priv,
-			     GLuint wh_location, GLuint repeat_location)
+glamor_set_composite_texture(glamor_screen_private * glamor_priv, int unit,
+                             PicturePtr picture,
+                             glamor_pixmap_private * pixmap_priv,
+                             GLuint wh_location, GLuint repeat_location)
 {
-	glamor_gl_dispatch *dispatch;
-	float wh[4];
-	int repeat_type;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
-	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
-	repeat_type = picture->repeatType;
-	switch (picture->repeatType) {
-	case RepeatNone:
+    glamor_gl_dispatch *dispatch;
+    float wh[4];
+    int repeat_type;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glActiveTexture(GL_TEXTURE0 + unit);
+    dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
+    repeat_type = picture->repeatType;
+    switch (picture->repeatType) {
+    case RepeatNone:
 #ifndef GLAMOR_GLES2
-		/* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_CLAMP_TO_BORDER);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_CLAMP_TO_BORDER);
+        /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                                  GL_CLAMP_TO_BORDER);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                                  GL_CLAMP_TO_BORDER);
 #else
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_CLAMP_TO_EDGE);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_CLAMP_TO_EDGE);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                                  GL_CLAMP_TO_EDGE);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                                  GL_CLAMP_TO_EDGE);
 #endif
-		break;
-	case RepeatNormal:
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_REPEAT);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_REPEAT);
-		break;
-	case RepeatPad:
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_CLAMP_TO_EDGE);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_CLAMP_TO_EDGE);
-		break;
-	case RepeatReflect:
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_MIRRORED_REPEAT);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_MIRRORED_REPEAT);
-		break;
-	}
-
-	switch (picture->filter) {
-	default:
-	case PictFilterFast:
-	case PictFilterNearest:
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-		break;
-	case PictFilterGood:
-	case PictFilterBest:
-	case PictFilterBilinear:
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_LINEAR);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_LINEAR);
-		break;
-	}
+        break;
+    case RepeatNormal:
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        break;
+    case RepeatPad:
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                                  GL_CLAMP_TO_EDGE);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                                  GL_CLAMP_TO_EDGE);
+        break;
+    case RepeatReflect:
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                                  GL_MIRRORED_REPEAT);
+        dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                                  GL_MIRRORED_REPEAT);
+        break;
+    }
+
+    switch (picture->filter) {
+    default:
+    case PictFilterFast:
+    case PictFilterNearest:
+        dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                  GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                  GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        break;
+    case PictFilterGood:
+    case PictFilterBest:
+    case PictFilterBilinear:
+        dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                  GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        dispatch->glTexParameteri(GL_TEXTURE_2D,
+                                  GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        break;
+    }
 #ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glEnable(GL_TEXTURE_2D);
 #endif
 
-	/*
-	 *  GLES2 doesn't support RepeatNone. We need to fix it anyway.
-	 *
-	 **/
-	if (repeat_type != RepeatNone)
-		repeat_type += RepeatFix;
-	else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-		 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		if (picture->transform
-		   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
-			repeat_type += RepeatFix;
-	}
-	if (repeat_type >= RepeatFix) {
-		glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
-		if ((wh[0] != 1.0 || wh[1] != 1.0 )
-		     || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-			  && repeat_type == RepeatFix))
-			dispatch->glUniform4fv(wh_location, 1, wh);
-		else
-			repeat_type -= RepeatFix;
-	}
-	dispatch->glUniform1i(repeat_location, repeat_type);
-	glamor_put_dispatch(glamor_priv);
+    /*
+     *  GLES2 doesn't support RepeatNone. We need to fix it anyway.
+     *
+     **/
+    if (repeat_type != RepeatNone)
+        repeat_type += RepeatFix;
+    else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+             || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        if (picture->transform
+            || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
+            repeat_type += RepeatFix;
+    }
+    if (repeat_type >= RepeatFix) {
+        glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
+        if ((wh[0] != 1.0 || wh[1] != 1.0)
+            || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+                && repeat_type == RepeatFix))
+            dispatch->glUniform4fv(wh_location, 1, wh);
+        else
+            repeat_type -= RepeatFix;
+    }
+    dispatch->glUniform1i(repeat_location, repeat_type);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
 glamor_set_composite_solid(glamor_gl_dispatch * dispatch, float *color,
-			   GLint uniform_location)
+                           GLint uniform_location)
 {
-	dispatch->glUniform4fv(uniform_location, 1, color);
+    dispatch->glUniform4fv(uniform_location, 1, color);
 }
 
 static int
 compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src)
 {
-	if (op == PictOpSrc) {
-		if (src->format == dst->format)
-			return 1;
-
-		if (src->format == PICT_a8r8g8b8
-		    && dst->format == PICT_x8r8g8b8)
-			return 1;
-
-		if (src->format == PICT_a8b8g8r8
-		    && dst->format == PICT_x8b8g8r8)
-			return 1;
-	} else if (op == PictOpOver) {
-		if (src->alphaMap || dst->alphaMap)
-			return 0;
-
-		if (src->format != dst->format)
-			return 0;
-
-		if (src->format == PICT_x8r8g8b8
-		    || src->format == PICT_x8b8g8r8)
-			return 1;
-	}
-
-	return 0;
+    if (op == PictOpSrc) {
+        if (src->format == dst->format)
+            return 1;
+
+        if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
+            return 1;
+
+        if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
+            return 1;
+    }
+    else if (op == PictOpOver) {
+        if (src->alphaMap || dst->alphaMap)
+            return 0;
+
+        if (src->format != dst->format)
+            return 0;
+
+        if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
+            return 1;
+    }
+
+    return 0;
 }
 
 static char
 glamor_get_picture_location(PicturePtr picture)
 {
-	if (picture == NULL)
-		return ' ';
-
-	if (picture->pDrawable == NULL) {
-		switch (picture->pSourcePict->type) {
-		case SourcePictTypeSolidFill:
-			return 'c';
-		case SourcePictTypeLinear:
-			return 'l';
-		case SourcePictTypeRadial:
-			return 'r';
-		default:
-			return '?';
-		}
-	}
-	return glamor_get_drawable_location(picture->pDrawable);
+    if (picture == NULL)
+        return ' ';
+
+    if (picture->pDrawable == NULL) {
+        switch (picture->pSourcePict->type) {
+        case SourcePictTypeSolidFill:
+            return 'c';
+        case SourcePictTypeLinear:
+            return 'l';
+        case SourcePictTypeRadial:
+            return 'r';
+        default:
+            return '?';
+        }
+    }
+    return glamor_get_drawable_location(picture->pDrawable);
 }
 
 static Bool
 glamor_composite_with_copy(CARD8 op,
-			   PicturePtr source,
-			   PicturePtr dest,
-			   INT16 x_source,
-			   INT16 y_source,
-			   INT16 x_dest,
-			   INT16 y_dest,
-			   RegionPtr region)
+                           PicturePtr source,
+                           PicturePtr dest,
+                           INT16 x_source,
+                           INT16 y_source,
+                           INT16 x_dest, INT16 y_dest, RegionPtr region)
 {
-	int ret = FALSE;
-	if (!source->pDrawable)
-		return FALSE;
-
-	if (!compatible_formats(op, dest, source))
-		return FALSE;
-
-	if (source->repeat || source->transform) {
-		return FALSE;
-	}
-
-	x_dest += dest->pDrawable->x;
-	y_dest += dest->pDrawable->y;
-	x_source += source->pDrawable->x;
-	y_source += source->pDrawable->y;
-	if (PICT_FORMAT_A(source->format) == 0) {
-		/* Fallback if we sample outside the source so that we
-		 * swizzle the correct clear color for out-of-bounds texels.
-		 */
-		if (region->extents.x1 + x_source - x_dest < 0)
-			goto cleanup_region;
-		if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
-			goto cleanup_region;
-
-		if (region->extents.y1 + y_source - y_dest < 0)
-			goto cleanup_region;
-		if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
-			goto cleanup_region;
-	}
-	ret = glamor_copy_n_to_n_nf(source->pDrawable,
-				    dest->pDrawable, NULL,
-				    RegionRects(region), RegionNumRects(region),
-				    x_source - x_dest, y_source - y_dest,
-				    FALSE, FALSE, 0, NULL);
-cleanup_region:
-	return ret;
+    int ret = FALSE;
+
+    if (!source->pDrawable)
+        return FALSE;
+
+    if (!compatible_formats(op, dest, source))
+        return FALSE;
+
+    if (source->repeat || source->transform) {
+        return FALSE;
+    }
+
+    x_dest += dest->pDrawable->x;
+    y_dest += dest->pDrawable->y;
+    x_source += source->pDrawable->x;
+    y_source += source->pDrawable->y;
+    if (PICT_FORMAT_A(source->format) == 0) {
+        /* Fallback if we sample outside the source so that we
+         * swizzle the correct clear color for out-of-bounds texels.
+         */
+        if (region->extents.x1 + x_source - x_dest < 0)
+            goto cleanup_region;
+        if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
+            goto cleanup_region;
+
+        if (region->extents.y1 + y_source - y_dest < 0)
+            goto cleanup_region;
+        if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
+            goto cleanup_region;
+    }
+    ret = glamor_copy_n_to_n_nf(source->pDrawable,
+                                dest->pDrawable, NULL,
+                                RegionRects(region), RegionNumRects(region),
+                                x_source - x_dest, y_source - y_dest,
+                                FALSE, FALSE, 0, NULL);
+ cleanup_region:
+    return ret;
 }
 
 void
 glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-	int vert_size;
-
-	glamor_priv->render_nr_verts = 0;
-	glamor_priv->vb_stride = 2 * sizeof(float);
-	if (glamor_priv->has_source_coords)
-		glamor_priv->vb_stride += 2 * sizeof(float);
-	if (glamor_priv->has_mask_coords)
-		glamor_priv->vb_stride += 2 * sizeof(float);
-
-	vert_size = n_verts * glamor_priv->vb_stride;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
-			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
-				glamor_priv->vb_stride;
-			glamor_priv->vbo_offset = 0;
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-					       glamor_priv->vbo_size,
-					       NULL, GL_STREAM_DRAW);
-		}
-
-		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
-							     glamor_priv->vbo_offset,
-							     vert_size,
-							     GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
-		assert(glamor_priv->vb != NULL);
-		glamor_priv->vb -= glamor_priv->vbo_offset;
-	} else
-		glamor_priv->vbo_offset = 0;
-
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, glamor_priv->vb_stride,
-					(void *) ((long)
-						  glamor_priv->vbo_offset));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	if (glamor_priv->has_source_coords) {
-		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-						GL_FLOAT, GL_FALSE,
-						glamor_priv->vb_stride,
-						(void *) ((long)
-							  glamor_priv->vbo_offset
-							  +
-							  2 *
-							  sizeof(float)));
-		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	}
-
-	if (glamor_priv->has_mask_coords) {
-		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2,
-						GL_FLOAT, GL_FALSE,
-						glamor_priv->vb_stride,
-						(void *) ((long)
-							  glamor_priv->vbo_offset
-							  +
-							  (glamor_priv->has_source_coords
-							   ? 4 : 2) *
-							  sizeof(float)));
-		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
-	}
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+    int vert_size;
+
+    glamor_priv->render_nr_verts = 0;
+    glamor_priv->vb_stride = 2 * sizeof(float);
+    if (glamor_priv->has_source_coords)
+        glamor_priv->vb_stride += 2 * sizeof(float);
+    if (glamor_priv->has_mask_coords)
+        glamor_priv->vb_stride += 2 * sizeof(float);
+
+    vert_size = n_verts * glamor_priv->vb_stride;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
+            glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
+                glamor_priv->vb_stride;
+            glamor_priv->vbo_offset = 0;
+            dispatch->glBufferData(GL_ARRAY_BUFFER,
+                                   glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+        }
+
+        glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+                                                     glamor_priv->vbo_offset,
+                                                     vert_size,
+                                                     GL_MAP_WRITE_BIT |
+                                                     GL_MAP_UNSYNCHRONIZED_BIT);
+        assert(glamor_priv->vb != NULL);
+        glamor_priv->vb -= glamor_priv->vbo_offset;
+    }
+    else
+        glamor_priv->vbo_offset = 0;
+
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long)
+                                              glamor_priv->vbo_offset));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+    if (glamor_priv->has_source_coords) {
+        dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                                        GL_FLOAT, GL_FALSE,
+                                        glamor_priv->vb_stride, (void *) ((long)
+                                                                          glamor_priv->
+                                                                          vbo_offset
+                                                                          +
+                                                                          2 *
+                                                                          sizeof
+                                                                          (float)));
+        dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    }
+
+    if (glamor_priv->has_mask_coords) {
+        dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2,
+                                        GL_FLOAT, GL_FALSE,
+                                        glamor_priv->vb_stride, (void *) ((long)
+                                                                          glamor_priv->
+                                                                          vbo_offset
+                                                                          +
+                                                                          (glamor_priv->
+                                                                           has_source_coords
+                                                                           ? 4 :
+                                                                           2) *
+                                                                          sizeof
+                                                                          (float)));
+        dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    }
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_emit_composite_vert(ScreenPtr screen,
-			   const float *src_coords,
-			   const float *mask_coords,
-			   const float *dst_coords, int i)
+                           const float *src_coords,
+                           const float *mask_coords,
+                           const float *dst_coords, int i)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
-	int j = 0;
-
-	vb[j++] = dst_coords[i * 2 + 0];
-	vb[j++] = dst_coords[i * 2 + 1];
-	if (glamor_priv->has_source_coords) {
-		vb[j++] = src_coords[i * 2 + 0];
-		vb[j++] = src_coords[i * 2 + 1];
-	}
-	if (glamor_priv->has_mask_coords) {
-		vb[j++] = mask_coords[i * 2 + 0];
-		vb[j++] = mask_coords[i * 2 + 1];
-	}
-
-	glamor_priv->render_nr_verts++;
-	glamor_priv->vbo_offset += glamor_priv->vb_stride;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
+    int j = 0;
+
+    vb[j++] = dst_coords[i * 2 + 0];
+    vb[j++] = dst_coords[i * 2 + 1];
+    if (glamor_priv->has_source_coords) {
+        vb[j++] = src_coords[i * 2 + 0];
+        vb[j++] = src_coords[i * 2 + 1];
+    }
+    if (glamor_priv->has_mask_coords) {
+        vb[j++] = mask_coords[i * 2 + 0];
+        vb[j++] = mask_coords[i * 2 + 1];
+    }
+
+    glamor_priv->render_nr_verts++;
+    glamor_priv->vbo_offset += glamor_priv->vb_stride;
 }
 
-
-
 static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
 
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-	else {
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+        dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+    else {
 
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-				       glamor_priv->vbo_offset,
-				       glamor_priv->vb, GL_DYNAMIC_DRAW);
-	}
+        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        dispatch->glBufferData(GL_ARRAY_BUFFER,
+                               glamor_priv->vbo_offset,
+                               glamor_priv->vb, GL_DYNAMIC_DRAW);
+    }
 
-	if (!glamor_priv->render_nr_verts)
-		return;
+    if (!glamor_priv->render_nr_verts)
+        return;
 
 #ifndef GLAMOR_GLES2
-	dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
-				      (glamor_priv->render_nr_verts * 3) / 2,
-				      GL_UNSIGNED_SHORT, NULL);
+    dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
+                                  (glamor_priv->render_nr_verts * 3) / 2,
+                                  GL_UNSIGNED_SHORT, NULL);
 #else
-	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
-				 GL_UNSIGNED_SHORT, NULL);
+    dispatch->glDrawElements(GL_TRIANGLES,
+                             (glamor_priv->render_nr_verts * 3) / 2,
+                             GL_UNSIGNED_SHORT, NULL);
 #endif
-	glamor_put_dispatch(glamor_priv);
+    glamor_put_dispatch(glamor_priv);
 }
 
 int pict_format_combine_tab[][3] = {
-	{PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
-	{PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
+    {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
+    {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
 };
 
 static Bool
 combine_pict_format(PictFormatShort * des, const PictFormatShort src,
-		    const PictFormatShort mask, enum shader_in in_ca)
+                    const PictFormatShort mask, enum shader_in in_ca)
 {
-	PictFormatShort new_vis;
-	int src_type, mask_type, src_bpp, mask_bpp;
-	int i;
-	if (src == mask) {
-		*des = src;
-		return TRUE;
-	}
-	src_bpp = PICT_FORMAT_BPP(src);
-	mask_bpp = PICT_FORMAT_BPP(mask);
-
-	assert(src_bpp == mask_bpp);
-
-	new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
-
-	switch (in_ca) {
-	case SHADER_IN_SOURCE_ONLY:
-		return TRUE;
-	case SHADER_IN_NORMAL:
-		src_type = PICT_FORMAT_TYPE(src);
-		mask_type = PICT_TYPE_A;
-		break;
-	case SHADER_IN_CA_SOURCE:
-		src_type = PICT_FORMAT_TYPE(src);
-		mask_type = PICT_FORMAT_TYPE(mask);
-		break;
-	case SHADER_IN_CA_ALPHA:
-		src_type = PICT_TYPE_A;
-		mask_type = PICT_FORMAT_TYPE(mask);
-		break;
-	default:
-		return FALSE;
-	}
-
-	if (src_type == mask_type) {
-		*des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
-		return TRUE;
-	}
-
-	for (i = 0;
-	     i <
-	     sizeof(pict_format_combine_tab) /
-	     sizeof(pict_format_combine_tab[0]); i++) {
-		if ((src_type == pict_format_combine_tab[i][0]
-		     && mask_type == pict_format_combine_tab[i][1])
-		    || (src_type == pict_format_combine_tab[i][1]
-			&& mask_type == pict_format_combine_tab[i][0])) {
-			*des = PICT_VISFORMAT(src_bpp,
-					      pict_format_combine_tab[i]
-					      [2], new_vis);
-			return TRUE;
-		}
-	}
-	return FALSE;
+    PictFormatShort new_vis;
+    int src_type, mask_type, src_bpp, mask_bpp;
+    int i;
+
+    if (src == mask) {
+        *des = src;
+        return TRUE;
+    }
+    src_bpp = PICT_FORMAT_BPP(src);
+    mask_bpp = PICT_FORMAT_BPP(mask);
+
+    assert(src_bpp == mask_bpp);
+
+    new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
+
+    switch (in_ca) {
+    case SHADER_IN_SOURCE_ONLY:
+        return TRUE;
+    case SHADER_IN_NORMAL:
+        src_type = PICT_FORMAT_TYPE(src);
+        mask_type = PICT_TYPE_A;
+        break;
+    case SHADER_IN_CA_SOURCE:
+        src_type = PICT_FORMAT_TYPE(src);
+        mask_type = PICT_FORMAT_TYPE(mask);
+        break;
+    case SHADER_IN_CA_ALPHA:
+        src_type = PICT_TYPE_A;
+        mask_type = PICT_FORMAT_TYPE(mask);
+        break;
+    default:
+        return FALSE;
+    }
+
+    if (src_type == mask_type) {
+        *des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
+        return TRUE;
+    }
+
+    for (i = 0;
+         i <
+         sizeof(pict_format_combine_tab) /
+         sizeof(pict_format_combine_tab[0]); i++) {
+        if ((src_type == pict_format_combine_tab[i][0]
+             && mask_type == pict_format_combine_tab[i][1])
+            || (src_type == pict_format_combine_tab[i][1]
+                && mask_type == pict_format_combine_tab[i][0])) {
+            *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i]
+                                  [2], new_vis);
+            return TRUE;
+        }
+    }
+    return FALSE;
 }
 
 static void
-glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
-				     int repeat_type,
-				     float *matrix,
-				     float xscale, float yscale,
-				     int x1, int y1, int x2, int y2,
-				     int yInverted, float *texcoords,
-				     int stride)
+glamor_set_normalize_tcoords_generic(glamor_pixmap_private * priv,
+                                     int repeat_type,
+                                     float *matrix,
+                                     float xscale, float yscale,
+                                     int x1, int y1, int x2, int y2,
+                                     int yInverted, float *texcoords,
+                                     int stride)
 {
-	if (!matrix && repeat_type == RepeatNone)
-		glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
-					     x1, y1,
-					     x2, y2,
-					     yInverted,
-					     texcoords, stride);
-	else if (matrix && repeat_type == RepeatNone)
-		glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
-							 yscale, x1, y1,
-							 x2, y2,
-							 yInverted,
-							 texcoords, stride);
-	else if (!matrix && repeat_type != RepeatNone)
-		glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
-						    xscale, yscale,
-						    x1, y1,
-						    x2, y2,
-						    yInverted,
-						    texcoords, stride);
-	else if (matrix && repeat_type != RepeatNone)
-		glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
-								matrix, xscale, yscale,
-								x1, y1,
-								x2, y2,
-								yInverted,
-								texcoords, stride);
+    if (!matrix && repeat_type == RepeatNone)
+        glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
+                                         x1, y1,
+                                         x2, y2, yInverted, texcoords, stride);
+    else if (matrix && repeat_type == RepeatNone)
+        glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
+                                                     yscale, x1, y1,
+                                                     x2, y2,
+                                                     yInverted,
+                                                     texcoords, stride);
+    else if (!matrix && repeat_type != RepeatNone)
+        glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
+                                                xscale, yscale,
+                                                x1, y1,
+                                                x2, y2,
+                                                yInverted, texcoords, stride);
+    else if (matrix && repeat_type != RepeatNone)
+        glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
+                                                            matrix, xscale,
+                                                            yscale, x1, y1, x2,
+                                                            y2, yInverted,
+                                                            texcoords, stride);
 }
 
-Bool glamor_composite_choose_shader(CARD8 op,
-                                    PicturePtr source,
-                                    PicturePtr mask,
-                                    PicturePtr dest,
-			     	    glamor_pixmap_private *source_pixmap_priv,
-			     	    glamor_pixmap_private *mask_pixmap_priv,
-			     	    glamor_pixmap_private *dest_pixmap_priv,
-                                    struct shader_key *s_key,
-				    glamor_composite_shader **shader,
-				    struct blendinfo *op_info,
-                                    PictFormatShort *psaved_source_format)
+Bool
+glamor_composite_choose_shader(CARD8 op,
+                               PicturePtr source,
+                               PicturePtr mask,
+                               PicturePtr dest,
+                               glamor_pixmap_private * source_pixmap_priv,
+                               glamor_pixmap_private * mask_pixmap_priv,
+                               glamor_pixmap_private * dest_pixmap_priv,
+                               struct shader_key *s_key,
+                               glamor_composite_shader ** shader,
+                               struct blendinfo *op_info,
+                               PictFormatShort * psaved_source_format)
 {
-	ScreenPtr screen = dest->pDrawable->pScreen;
-	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
-	PixmapPtr source_pixmap = NULL;
-	PixmapPtr mask_pixmap = NULL;
-	enum glamor_pixmap_status source_status = GLAMOR_NONE;
-	enum glamor_pixmap_status mask_status = GLAMOR_NONE;
-	PictFormatShort saved_source_format = 0;
-	struct shader_key key;
-	GLfloat source_solid_color[4];
-	GLfloat mask_solid_color[4];
-	Bool ret = FALSE;
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-		glamor_fallback("dest has no fbo.\n");
-		goto fail;
-	}
-
-	memset(&key, 0, sizeof(key));
-	if (!source) {
-		key.source = SHADER_SOURCE_SOLID;
-		source_solid_color[0] = 0.0;
-		source_solid_color[1] = 0.0;
-		source_solid_color[2] = 0.0;
-		source_solid_color[3] = 0.0;
-	} else if (!source->pDrawable) {
-			if (source->pSourcePict->type == SourcePictTypeSolidFill) {
-				key.source = SHADER_SOURCE_SOLID;
-				glamor_get_rgba_from_pixel(source->
-							   pSourcePict->solidFill.
-							   color,
-							   &source_solid_color[0],
-							   &source_solid_color[1],
-							   &source_solid_color[2],
-							   &source_solid_color[3],
-							   PICT_a8r8g8b8);
-		} else
-			goto fail;
-	} else {
-		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
-	}
-
-	if (mask) {
-		if (!mask->pDrawable) {
-			if (mask->pSourcePict->type ==
-			     SourcePictTypeSolidFill) {
-				key.mask = SHADER_MASK_SOLID;
-				glamor_get_rgba_from_pixel
-				    (mask->pSourcePict->solidFill.color,
-				     &mask_solid_color[0],
-				     &mask_solid_color[1],
-				     &mask_solid_color[2],
-				     &mask_solid_color[3], PICT_a8r8g8b8);
-			} else
-				goto fail;
-		} else {
-			key.mask = SHADER_MASK_TEXTURE_ALPHA;
-		}
-
-		if (!mask->componentAlpha) {
-			key.in = SHADER_IN_NORMAL;
-		} else {
-			if (op == PictOpClear)
-				key.mask = SHADER_MASK_NONE;
-			else if (op == PictOpSrc || op == PictOpAdd
-			         || op == PictOpIn || op == PictOpOut
-			         || op == PictOpOverReverse)
-				key.in = SHADER_IN_CA_SOURCE;
-			else if (op == PictOpOutReverse || op == PictOpInReverse) {
-				key.in = SHADER_IN_CA_ALPHA;
-			} else {
-				glamor_fallback("Unsupported component alpha op: %d\n", op);
-				goto fail;
-			}
-		}
-	} else {
-		key.mask = SHADER_MASK_NONE;
-		key.in = SHADER_IN_SOURCE_ONLY;
-	}
-
-	if (source && source->alphaMap) {
-		glamor_fallback("source alphaMap\n");
-		goto fail;
-	}
-	if (mask && mask->alphaMap) {
-		glamor_fallback("mask alphaMap\n");
-		goto fail;
-	}
-
-	if (key.source == SHADER_SOURCE_TEXTURE ||
-	    key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
-		source_pixmap = source_pixmap_priv->base.pixmap;
-		if (source_pixmap == dest_pixmap) {
-			/* XXX source and the dest share the same texture.
-			 * Does it need special handle? */
-			glamor_fallback("source == dest\n");
-		}
-		if (source_pixmap_priv->base.gl_fbo == 0) {
-			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
-			 * equal to zero when the pixmap is screen pixmap. Then we may
-			 * refer the tex zero directly latter in the composition.
-			 * It seems that it works fine, but it may have potential problem*/
+    ScreenPtr screen = dest->pDrawable->pScreen;
+    PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
+    PixmapPtr source_pixmap = NULL;
+    PixmapPtr mask_pixmap = NULL;
+    enum glamor_pixmap_status source_status = GLAMOR_NONE;
+    enum glamor_pixmap_status mask_status = GLAMOR_NONE;
+    PictFormatShort saved_source_format = 0;
+    struct shader_key key;
+    GLfloat source_solid_color[4];
+    GLfloat mask_solid_color[4];
+    Bool ret = FALSE;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+        glamor_fallback("dest has no fbo.\n");
+        goto fail;
+    }
+
+    memset(&key, 0, sizeof(key));
+    if (!source) {
+        key.source = SHADER_SOURCE_SOLID;
+        source_solid_color[0] = 0.0;
+        source_solid_color[1] = 0.0;
+        source_solid_color[2] = 0.0;
+        source_solid_color[3] = 0.0;
+    }
+    else if (!source->pDrawable) {
+        if (source->pSourcePict->type == SourcePictTypeSolidFill) {
+            key.source = SHADER_SOURCE_SOLID;
+            glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color,
+                                       &source_solid_color[0],
+                                       &source_solid_color[1],
+                                       &source_solid_color[2],
+                                       &source_solid_color[3], PICT_a8r8g8b8);
+        }
+        else
+            goto fail;
+    }
+    else {
+        key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+    }
+
+    if (mask) {
+        if (!mask->pDrawable) {
+            if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
+                key.mask = SHADER_MASK_SOLID;
+                glamor_get_rgba_from_pixel
+                    (mask->pSourcePict->solidFill.color,
+                     &mask_solid_color[0],
+                     &mask_solid_color[1],
+                     &mask_solid_color[2], &mask_solid_color[3], PICT_a8r8g8b8);
+            }
+            else
+                goto fail;
+        }
+        else {
+            key.mask = SHADER_MASK_TEXTURE_ALPHA;
+        }
+
+        if (!mask->componentAlpha) {
+            key.in = SHADER_IN_NORMAL;
+        }
+        else {
+            if (op == PictOpClear)
+                key.mask = SHADER_MASK_NONE;
+            else if (op == PictOpSrc || op == PictOpAdd
+                     || op == PictOpIn || op == PictOpOut
+                     || op == PictOpOverReverse)
+                key.in = SHADER_IN_CA_SOURCE;
+            else if (op == PictOpOutReverse || op == PictOpInReverse) {
+                key.in = SHADER_IN_CA_ALPHA;
+            }
+            else {
+                glamor_fallback("Unsupported component alpha op: %d\n", op);
+                goto fail;
+            }
+        }
+    }
+    else {
+        key.mask = SHADER_MASK_NONE;
+        key.in = SHADER_IN_SOURCE_ONLY;
+    }
+
+    if (source && source->alphaMap) {
+        glamor_fallback("source alphaMap\n");
+        goto fail;
+    }
+    if (mask && mask->alphaMap) {
+        glamor_fallback("mask alphaMap\n");
+        goto fail;
+    }
+
+    if (key.source == SHADER_SOURCE_TEXTURE ||
+        key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
+        source_pixmap = source_pixmap_priv->base.pixmap;
+        if (source_pixmap == dest_pixmap) {
+            /* XXX source and the dest share the same texture.
+             * Does it need special handle? */
+            glamor_fallback("source == dest\n");
+        }
+        if (source_pixmap_priv->base.gl_fbo == 0) {
+            /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
+             * equal to zero when the pixmap is screen pixmap. Then we may
+             * refer the tex zero directly latter in the composition.
+             * It seems that it works fine, but it may have potential problem*/
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-			source_status = GLAMOR_UPLOAD_PENDING;
+            source_status = GLAMOR_UPLOAD_PENDING;
 #else
-			glamor_fallback("no texture in source\n");
-			goto fail;
+            glamor_fallback("no texture in source\n");
+            goto fail;
 #endif
-		}
-	}
-
-	if (key.mask == SHADER_MASK_TEXTURE ||
-	    key.mask == SHADER_MASK_TEXTURE_ALPHA) {
-		mask_pixmap = mask_pixmap_priv->base.pixmap;
-		if (mask_pixmap == dest_pixmap) {
-			glamor_fallback("mask == dest\n");
-			goto fail;
-		}
-		if (mask_pixmap_priv->base.gl_fbo == 0) {
+        }
+    }
+
+    if (key.mask == SHADER_MASK_TEXTURE ||
+        key.mask == SHADER_MASK_TEXTURE_ALPHA) {
+        mask_pixmap = mask_pixmap_priv->base.pixmap;
+        if (mask_pixmap == dest_pixmap) {
+            glamor_fallback("mask == dest\n");
+            goto fail;
+        }
+        if (mask_pixmap_priv->base.gl_fbo == 0) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-			mask_status = GLAMOR_UPLOAD_PENDING;
+            mask_status = GLAMOR_UPLOAD_PENDING;
 #else
-			glamor_fallback("no texture in mask\n");
-			goto fail;
+            glamor_fallback("no texture in mask\n");
+            goto fail;
 #endif
-		}
-	}
+        }
+    }
 
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-	if (source_status == GLAMOR_UPLOAD_PENDING
-	     && mask_status == GLAMOR_UPLOAD_PENDING
-	     && source_pixmap == mask_pixmap) {
-
-		if (source->format != mask->format) {
-			saved_source_format = source->format;
-
-			if (!combine_pict_format(&source->format, source->format,
-			                         mask->format, key.in)) {
-				glamor_fallback("combine source %x mask %x failed.\n",
-				                source->format, mask->format);
-				goto fail;
-			}
-
-			if (source->format != saved_source_format) {
-				glamor_picture_format_fixup(source,
-				        source_pixmap_priv);
-			}
-			/* XXX
-			 * By default, glamor_upload_picture_to_texture will wire alpha to 1
-			 * if one picture doesn't have alpha. So we don't do that again in
-			 * rendering function. But here is a special case, as source and
-			 * mask share the same texture but may have different formats. For
-			 * example, source doesn't have alpha, but mask has alpha. Then the
-			 * texture will have the alpha value for the mask. And will not wire
-			 * to 1 for the source. In this case, we have to use different shader
-			 * to wire the source's alpha to 1.
-			 *
-			 * But this may cause a potential problem if the source's repeat mode
-			 * is REPEAT_NONE, and if the source is smaller than the dest, then
-			 * for the region not covered by the source may be painted incorrectly.
-			 * because we wire the alpha to 1.
-			 *
-			 **/
-			if (!PICT_FORMAT_A(saved_source_format)
-			     && PICT_FORMAT_A(mask->format))
-				key.source = SHADER_SOURCE_TEXTURE;
-
-			if (!PICT_FORMAT_A(mask->format)
-			     && PICT_FORMAT_A(saved_source_format))
-				key.mask = SHADER_MASK_TEXTURE;
-
-			mask_status = GLAMOR_NONE;
-		}
-
-		source_status = glamor_upload_picture_to_texture(source);
-		if (source_status != GLAMOR_UPLOAD_DONE) {
-			glamor_fallback("Failed to upload source texture.\n");
-			goto fail;
-		}
-	} else {
-		if (source_status == GLAMOR_UPLOAD_PENDING) {
-			source_status = glamor_upload_picture_to_texture(source);
-			if (source_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback("Failed to upload source texture.\n");
-				goto fail;
-			}
-		}
-
-		if (mask_status == GLAMOR_UPLOAD_PENDING) {
-			mask_status = glamor_upload_picture_to_texture(mask);
-			if (mask_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback("Failed to upload mask texture.\n");
-				goto fail;
-			}
-		}
-	}
+    if (source_status == GLAMOR_UPLOAD_PENDING
+        && mask_status == GLAMOR_UPLOAD_PENDING
+        && source_pixmap == mask_pixmap) {
+
+        if (source->format != mask->format) {
+            saved_source_format = source->format;
+
+            if (!combine_pict_format(&source->format, source->format,
+                                     mask->format, key.in)) {
+                glamor_fallback("combine source %x mask %x failed.\n",
+                                source->format, mask->format);
+                goto fail;
+            }
+
+            if (source->format != saved_source_format) {
+                glamor_picture_format_fixup(source, source_pixmap_priv);
+            }
+            /* XXX
+             * By default, glamor_upload_picture_to_texture will wire alpha to 1
+             * if one picture doesn't have alpha. So we don't do that again in
+             * rendering function. But here is a special case, as source and
+             * mask share the same texture but may have different formats. For
+             * example, source doesn't have alpha, but mask has alpha. Then the
+             * texture will have the alpha value for the mask. And will not wire
+             * to 1 for the source. In this case, we have to use different shader
+             * to wire the source's alpha to 1.
+             *
+             * But this may cause a potential problem if the source's repeat mode
+             * is REPEAT_NONE, and if the source is smaller than the dest, then
+             * for the region not covered by the source may be painted incorrectly.
+             * because we wire the alpha to 1.
+             *
+             **/
+            if (!PICT_FORMAT_A(saved_source_format)
+                && PICT_FORMAT_A(mask->format))
+                key.source = SHADER_SOURCE_TEXTURE;
+
+            if (!PICT_FORMAT_A(mask->format)
+                && PICT_FORMAT_A(saved_source_format))
+                key.mask = SHADER_MASK_TEXTURE;
+
+            mask_status = GLAMOR_NONE;
+        }
+
+        source_status = glamor_upload_picture_to_texture(source);
+        if (source_status != GLAMOR_UPLOAD_DONE) {
+            glamor_fallback("Failed to upload source texture.\n");
+            goto fail;
+        }
+    }
+    else {
+        if (source_status == GLAMOR_UPLOAD_PENDING) {
+            source_status = glamor_upload_picture_to_texture(source);
+            if (source_status != GLAMOR_UPLOAD_DONE) {
+                glamor_fallback("Failed to upload source texture.\n");
+                goto fail;
+            }
+        }
+
+        if (mask_status == GLAMOR_UPLOAD_PENDING) {
+            mask_status = glamor_upload_picture_to_texture(mask);
+            if (mask_status != GLAMOR_UPLOAD_DONE) {
+                glamor_fallback("Failed to upload mask texture.\n");
+                goto fail;
+            }
+        }
+    }
 #endif
 
-	/*Before enter the rendering stage, we need to fixup
-	 * transformed source and mask, if the transform is not int translate. */
-	if (key.source != SHADER_SOURCE_SOLID
-	    && source->transform
-	    && !pixman_transform_is_int_translate(source->transform)
-	    && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-		if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
-			goto fail;
-	}
-	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
-	    && mask->transform
-	    && !pixman_transform_is_int_translate(mask->transform)
-	    && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
-		if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
-			goto fail;
-	}
-
-
-	if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
-		goto fail;
-
-	*shader = glamor_lookup_composite_shader(screen, &key);
-	if ((*shader)->prog == 0) {
-		glamor_fallback("no shader program for this"
-		                "render acccel mode\n");
-		goto fail;
-	}
-
-	if (key.source == SHADER_SOURCE_SOLID)
-		memcpy(&(*shader)->source_solid_color[0],
-			source_solid_color, 4*sizeof(float));
-	else {
-		(*shader)->source_priv = source_pixmap_priv;
-		(*shader)->source = source;
-	}
-
-	if (key.mask == SHADER_MASK_SOLID)
-		memcpy(&(*shader)->mask_solid_color[0],
-			mask_solid_color, 4*sizeof(float));
-	else {
-		(*shader)->mask_priv = mask_pixmap_priv;
-		(*shader)->mask = mask;
-	}
-
-	ret = TRUE;
-	memcpy(s_key, &key, sizeof(key));
-	*psaved_source_format = saved_source_format;
-	goto done;
-
-fail:
-	if (saved_source_format)
-		source->format = saved_source_format;
-done:
-	return ret;
+    /*Before enter the rendering stage, we need to fixup
+     * transformed source and mask, if the transform is not int translate. */
+    if (key.source != SHADER_SOURCE_SOLID
+        && source->transform
+        && !pixman_transform_is_int_translate(source->transform)
+        && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+        if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
+            goto fail;
+    }
+    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
+        && mask->transform
+        && !pixman_transform_is_int_translate(mask->transform)
+        && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+        if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
+            goto fail;
+    }
+
+    if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
+        goto fail;
+
+    *shader = glamor_lookup_composite_shader(screen, &key);
+    if ((*shader)->prog == 0) {
+        glamor_fallback("no shader program for this" "render acccel mode\n");
+        goto fail;
+    }
+
+    if (key.source == SHADER_SOURCE_SOLID)
+        memcpy(&(*shader)->source_solid_color[0],
+               source_solid_color, 4 * sizeof(float));
+    else {
+        (*shader)->source_priv = source_pixmap_priv;
+        (*shader)->source = source;
+    }
+
+    if (key.mask == SHADER_MASK_SOLID)
+        memcpy(&(*shader)->mask_solid_color[0],
+               mask_solid_color, 4 * sizeof(float));
+    else {
+        (*shader)->mask_priv = mask_pixmap_priv;
+        (*shader)->mask = mask;
+    }
+
+    ret = TRUE;
+    memcpy(s_key, &key, sizeof(key));
+    *psaved_source_format = saved_source_format;
+    goto done;
+
+ fail:
+    if (saved_source_format)
+        source->format = saved_source_format;
+ done:
+    return ret;
 }
 
 void
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
-				  struct shader_key *key,
-				  glamor_composite_shader *shader,
-				  struct blendinfo *op_info)
+glamor_composite_set_shader_blend(glamor_pixmap_private * dest_priv,
+                                  struct shader_key *key,
+                                  glamor_composite_shader * shader,
+                                  struct blendinfo *op_info)
 {
-	glamor_gl_dispatch *dispatch;
-	glamor_screen_private *glamor_priv;
-
-	glamor_priv = dest_priv->base.glamor_priv;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glUseProgram(shader->prog);
-
-	if (key->source == SHADER_SOURCE_SOLID) {
-		glamor_set_composite_solid(dispatch,
-			shader->source_solid_color,
-		        shader->source_uniform_location);
-	} else {
-		glamor_set_composite_texture(glamor_priv, 0,
-			shader->source,
-		        shader->source_priv, shader->source_wh,
-		        shader->source_repeat_mode);
-	}
-
-	if (key->mask != SHADER_MASK_NONE) {
-		if (key->mask == SHADER_MASK_SOLID) {
-			glamor_set_composite_solid(dispatch,
-			        shader->mask_solid_color,
-			        shader->mask_uniform_location);
-		} else {
-			glamor_set_composite_texture(glamor_priv, 1,
-				shader->mask,
-			        shader->mask_priv, shader->mask_wh,
-			        shader->mask_repeat_mode);
-		}
-	}
-
-	if (op_info->source_blend == GL_ONE
-	    && op_info->dest_blend == GL_ZERO) {
-		dispatch->glDisable(GL_BLEND);
-	} else {
-		dispatch->glEnable(GL_BLEND);
-		dispatch->glBlendFunc(op_info->source_blend,
-				      op_info->dest_blend);
-	}
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+
+    glamor_priv = dest_priv->base.glamor_priv;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glUseProgram(shader->prog);
+
+    if (key->source == SHADER_SOURCE_SOLID) {
+        glamor_set_composite_solid(dispatch,
+                                   shader->source_solid_color,
+                                   shader->source_uniform_location);
+    }
+    else {
+        glamor_set_composite_texture(glamor_priv, 0,
+                                     shader->source,
+                                     shader->source_priv, shader->source_wh,
+                                     shader->source_repeat_mode);
+    }
+
+    if (key->mask != SHADER_MASK_NONE) {
+        if (key->mask == SHADER_MASK_SOLID) {
+            glamor_set_composite_solid(dispatch,
+                                       shader->mask_solid_color,
+                                       shader->mask_uniform_location);
+        }
+        else {
+            glamor_set_composite_texture(glamor_priv, 1,
+                                         shader->mask,
+                                         shader->mask_priv, shader->mask_wh,
+                                         shader->mask_repeat_mode);
+        }
+    }
+
+    if (op_info->source_blend == GL_ONE && op_info->dest_blend == GL_ZERO) {
+        dispatch->glDisable(GL_BLEND);
+    }
+    else {
+        dispatch->glEnable(GL_BLEND);
+        dispatch->glBlendFunc(op_info->source_blend, op_info->dest_blend);
+    }
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
 glamor_composite_with_shader(CARD8 op,
-			     PicturePtr source,
-			     PicturePtr mask,
-			     PicturePtr dest,
-			     glamor_pixmap_private *source_pixmap_priv,
-			     glamor_pixmap_private *mask_pixmap_priv,
-			     glamor_pixmap_private *dest_pixmap_priv,
-			     int nrect, glamor_composite_rect_t * rects,
-			     Bool two_pass_ca)
+                             PicturePtr source,
+                             PicturePtr mask,
+                             PicturePtr dest,
+                             glamor_pixmap_private * source_pixmap_priv,
+                             glamor_pixmap_private * mask_pixmap_priv,
+                             glamor_pixmap_private * dest_pixmap_priv,
+                             int nrect, glamor_composite_rect_t * rects,
+                             Bool two_pass_ca)
 {
-	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
-	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
-	PixmapPtr source_pixmap = NULL;
-	PixmapPtr mask_pixmap = NULL;
-	glamor_gl_dispatch *dispatch = NULL;
-	GLfloat dst_xscale, dst_yscale;
-	GLfloat mask_xscale = 1, mask_yscale = 1,
-	        src_xscale = 1, src_yscale = 1;
-	struct shader_key key, key_ca;
-	float *vertices;
-	int dest_x_off, dest_y_off;
-	int source_x_off, source_y_off;
-	int mask_x_off, mask_y_off;
-	PictFormatShort saved_source_format = 0;
-	float src_matrix[9], mask_matrix[9];
-	float *psrc_matrix = NULL, *pmask_matrix = NULL;
-	int vert_stride = 4;
-	int nrect_max;
-	Bool ret = FALSE;
-	glamor_composite_shader *shader = NULL, *shader_ca = NULL;
-	struct blendinfo op_info, op_info_ca;
-
-	if(!glamor_composite_choose_shader(op, source, mask, dest,
-					   source_pixmap_priv, mask_pixmap_priv,
-					   dest_pixmap_priv,
-	                                   &key, &shader, &op_info,
-					   &saved_source_format)) {
-		glamor_fallback("glamor_composite_choose_shader failed\n");
-		return ret;
-	}
-	if (two_pass_ca) {
-		if(!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
-						   source_pixmap_priv, mask_pixmap_priv,
-						   dest_pixmap_priv,
-						   &key_ca, &shader_ca, &op_info_ca,
-						   &saved_source_format)) {
-			glamor_fallback("glamor_composite_choose_shader failed\n");
-			return ret;
-		}
-	}
-
-	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
-	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
-					key.mask != SHADER_MASK_SOLID);
-
-	dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-	glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
-				   &dest_x_off, &dest_y_off);
-	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
-
-	if (glamor_priv->has_source_coords) {
-		source_pixmap = source_pixmap_priv->base.pixmap;
-		glamor_get_drawable_deltas(source->pDrawable,
-					   source_pixmap, &source_x_off,
-					   &source_y_off);
-		pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
-				      &src_yscale);
-		if (source->transform) {
-			psrc_matrix = src_matrix;
-			glamor_picture_get_matrixf(source, psrc_matrix);
-		}
-		vert_stride += 4;
-	}
-
-	if (glamor_priv->has_mask_coords) {
-		mask_pixmap = mask_pixmap_priv->base.pixmap;
-		glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
-					   &mask_x_off, &mask_y_off);
-		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
-				      &mask_yscale);
-		if (mask->transform) {
-			pmask_matrix = mask_matrix;
-			glamor_picture_get_matrixf(mask, pmask_matrix);
-		}
-		vert_stride += 4;
-	}
-
-	nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
-			 (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect;
-
-	while(nrect) {
-		int mrect, rect_processed;
-		int vb_stride;
-
-		mrect = nrect > nrect_max ? nrect_max : nrect ;
-		glamor_setup_composite_vbo(screen, mrect * vert_stride);
-		rect_processed = mrect;
-		vb_stride = glamor_priv->vb_stride/sizeof(float);
-		while (mrect--) {
-			INT16 x_source;
-			INT16 y_source;
-			INT16 x_mask;
-			INT16 y_mask;
-			INT16 x_dest;
-			INT16 y_dest;
-			CARD16 width;
-			CARD16 height;
-
-			x_dest = rects->x_dst + dest_x_off;
-			y_dest = rects->y_dst + dest_y_off;
-			x_source = rects->x_src + source_x_off;
-			y_source = rects->y_src + source_y_off;
-			x_mask = rects->x_mask + mask_x_off;
-			y_mask = rects->y_mask + mask_y_off;
-			width = rects->width;
-			height = rects->height;
-
-			DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
-				x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height);
-			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset);
-			assert(glamor_priv->vbo_offset < glamor_priv->vbo_size - glamor_priv->vb_stride);
-			glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
-						     dst_yscale,
-						     x_dest, y_dest,
-						     x_dest + width, y_dest + height,
-						     glamor_priv->yInverted,
-						     vertices, vb_stride);
-			vertices += 2;
-			if (key.source != SHADER_SOURCE_SOLID) {
-				glamor_set_normalize_tcoords_generic(
-					source_pixmap_priv, source->repeatType, psrc_matrix,
-					src_xscale, src_yscale, x_source, y_source,
-					x_source + width, y_source + height,
-					glamor_priv->yInverted, vertices, vb_stride);
-				vertices += 2;
-			}
-
-			if (key.mask != SHADER_MASK_NONE
-			    && key.mask != SHADER_MASK_SOLID) {
-				glamor_set_normalize_tcoords_generic(
-					mask_pixmap_priv, mask->repeatType, pmask_matrix,
-					mask_xscale, mask_yscale, x_mask, y_mask,
-					x_mask + width, y_mask + height,
-					glamor_priv->yInverted, vertices, vb_stride);
-			}
-			glamor_priv->render_nr_verts += 4;
-			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
-			rects++;
-		}
-		glamor_flush_composite_rects(screen);
-		nrect -= rect_processed;
-		if (two_pass_ca) {
-			glamor_composite_set_shader_blend(dest_pixmap_priv,
-							&key_ca, shader_ca,
-							&op_info_ca);
-			glamor_flush_composite_rects(screen);
-			if (nrect)
-				glamor_composite_set_shader_blend(dest_pixmap_priv,
-								&key, shader,
-								&op_info);
-		}
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-	dispatch->glDisable(GL_BLEND);
+    ScreenPtr screen = dest->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
+    PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
+    PixmapPtr source_pixmap = NULL;
+    PixmapPtr mask_pixmap = NULL;
+    glamor_gl_dispatch *dispatch = NULL;
+    GLfloat dst_xscale, dst_yscale;
+    GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
+    struct shader_key key, key_ca;
+    float *vertices;
+    int dest_x_off, dest_y_off;
+    int source_x_off, source_y_off;
+    int mask_x_off, mask_y_off;
+    PictFormatShort saved_source_format = 0;
+    float src_matrix[9], mask_matrix[9];
+    float *psrc_matrix = NULL, *pmask_matrix = NULL;
+    int vert_stride = 4;
+    int nrect_max;
+    Bool ret = FALSE;
+    glamor_composite_shader *shader = NULL, *shader_ca = NULL;
+    struct blendinfo op_info, op_info_ca;
+
+    if (!glamor_composite_choose_shader(op, source, mask, dest,
+                                        source_pixmap_priv, mask_pixmap_priv,
+                                        dest_pixmap_priv,
+                                        &key, &shader, &op_info,
+                                        &saved_source_format)) {
+        glamor_fallback("glamor_composite_choose_shader failed\n");
+        return ret;
+    }
+    if (two_pass_ca) {
+        if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+                                            source_pixmap_priv,
+                                            mask_pixmap_priv, dest_pixmap_priv,
+                                            &key_ca, &shader_ca, &op_info_ca,
+                                            &saved_source_format)) {
+            glamor_fallback("glamor_composite_choose_shader failed\n");
+            return ret;
+        }
+    }
+
+    glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+    glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+    glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+                                    key.mask != SHADER_MASK_SOLID);
+
+    dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+    glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
+                               &dest_x_off, &dest_y_off);
+    pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+
+    if (glamor_priv->has_source_coords) {
+        source_pixmap = source_pixmap_priv->base.pixmap;
+        glamor_get_drawable_deltas(source->pDrawable,
+                                   source_pixmap, &source_x_off, &source_y_off);
+        pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
+        if (source->transform) {
+            psrc_matrix = src_matrix;
+            glamor_picture_get_matrixf(source, psrc_matrix);
+        }
+        vert_stride += 4;
+    }
+
+    if (glamor_priv->has_mask_coords) {
+        mask_pixmap = mask_pixmap_priv->base.pixmap;
+        glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
+                                   &mask_x_off, &mask_y_off);
+        pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
+        if (mask->transform) {
+            pmask_matrix = mask_matrix;
+            glamor_picture_get_matrixf(mask, pmask_matrix);
+        }
+        vert_stride += 4;
+    }
+
+    nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
+        (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect;
+
+    while (nrect) {
+        int mrect, rect_processed;
+        int vb_stride;
+
+        mrect = nrect > nrect_max ? nrect_max : nrect;
+        glamor_setup_composite_vbo(screen, mrect * vert_stride);
+        rect_processed = mrect;
+        vb_stride = glamor_priv->vb_stride / sizeof(float);
+        while (mrect--) {
+            INT16 x_source;
+            INT16 y_source;
+            INT16 x_mask;
+            INT16 y_mask;
+            INT16 x_dest;
+            INT16 y_dest;
+            CARD16 width;
+            CARD16 height;
+
+            x_dest = rects->x_dst + dest_x_off;
+            y_dest = rects->y_dst + dest_y_off;
+            x_source = rects->x_src + source_x_off;
+            y_source = rects->y_src + source_y_off;
+            x_mask = rects->x_mask + mask_x_off;
+            y_mask = rects->y_mask + mask_y_off;
+            width = rects->width;
+            height = rects->height;
+
+            DEBUGF
+                ("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
+                 x_dest, y_dest, x_source, y_source, x_mask, y_mask, width,
+                 height);
+            vertices = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
+            assert(glamor_priv->vbo_offset <
+                   glamor_priv->vbo_size - glamor_priv->vb_stride);
+            glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
+                                             dst_yscale, x_dest, y_dest,
+                                             x_dest + width, y_dest + height,
+                                             glamor_priv->yInverted, vertices,
+                                             vb_stride);
+            vertices += 2;
+            if (key.source != SHADER_SOURCE_SOLID) {
+                glamor_set_normalize_tcoords_generic(source_pixmap_priv,
+                                                     source->repeatType,
+                                                     psrc_matrix, src_xscale,
+                                                     src_yscale, x_source,
+                                                     y_source, x_source + width,
+                                                     y_source + height,
+                                                     glamor_priv->yInverted,
+                                                     vertices, vb_stride);
+                vertices += 2;
+            }
+
+            if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
+                glamor_set_normalize_tcoords_generic(mask_pixmap_priv,
+                                                     mask->repeatType,
+                                                     pmask_matrix, mask_xscale,
+                                                     mask_yscale, x_mask,
+                                                     y_mask, x_mask + width,
+                                                     y_mask + height,
+                                                     glamor_priv->yInverted,
+                                                     vertices, vb_stride);
+            }
+            glamor_priv->render_nr_verts += 4;
+            glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
+            rects++;
+        }
+        glamor_flush_composite_rects(screen);
+        nrect -= rect_processed;
+        if (two_pass_ca) {
+            glamor_composite_set_shader_blend(dest_pixmap_priv,
+                                              &key_ca, shader_ca, &op_info_ca);
+            glamor_flush_composite_rects(screen);
+            if (nrect)
+                glamor_composite_set_shader_blend(dest_pixmap_priv,
+                                                  &key, shader, &op_info);
+        }
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    dispatch->glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glDisable(GL_TEXTURE_2D);
-	dispatch->glActiveTexture(GL_TEXTURE1);
-	dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glActiveTexture(GL_TEXTURE1);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	DEBUGF("finish rendering.\n");
-	dispatch->glUseProgram(0);
-	glamor_priv->state = RENDER_STATE;
-	glamor_priv->render_idle_cnt = 0;
-	if (saved_source_format)
-		source->format = saved_source_format;
-	glamor_put_dispatch(glamor_priv);
-
-	ret = TRUE;
-	return ret;
+    DEBUGF("finish rendering.\n");
+    dispatch->glUseProgram(0);
+    glamor_priv->state = RENDER_STATE;
+    glamor_priv->render_idle_cnt = 0;
+    if (saved_source_format)
+        source->format = saved_source_format;
+    glamor_put_dispatch(glamor_priv);
+
+    ret = TRUE;
+    return ret;
 }
 
 PicturePtr
@@ -1472,411 +1450,412 @@ glamor_convert_gradient_picture(ScreenPtr screen,
                                 int x_source,
                                 int y_source, int width, int height)
 {
-	PixmapPtr pixmap;
-	PicturePtr dst = NULL;
-	int error;
-	PictFormatShort format;
-	if (!source->pDrawable)
-		format = PICT_a8r8g8b8;
-	else
-		format = source->format;
+    PixmapPtr pixmap;
+    PicturePtr dst = NULL;
+    int error;
+    PictFormatShort format;
+
+    if (!source->pDrawable)
+        format = PICT_a8r8g8b8;
+    else
+        format = source->format;
 #ifdef GLAMOR_GRADIENT_SHADER
-	if (!source->pDrawable) {
-		if (source->pSourcePict->type == SourcePictTypeLinear) {
-			dst = glamor_generate_linear_gradient_picture(screen,
-				source, x_source, y_source, width, height, format);
-		} else if (source->pSourcePict->type == SourcePictTypeRadial) {
-			dst = glamor_generate_radial_gradient_picture(screen,
-		                  source, x_source, y_source, width, height, format);
-		}
-
-		if (dst) {
-#if 0			/* Debug to compare it to pixman, Enable it if needed. */
-			glamor_compare_pictures(screen, source,
-					dst, x_source, y_source, width, height,
-					0, 3);
+    if (!source->pDrawable) {
+        if (source->pSourcePict->type == SourcePictTypeLinear) {
+            dst = glamor_generate_linear_gradient_picture(screen,
+                                                          source, x_source,
+                                                          y_source, width,
+                                                          height, format);
+        }
+        else if (source->pSourcePict->type == SourcePictTypeRadial) {
+            dst = glamor_generate_radial_gradient_picture(screen,
+                                                          source, x_source,
+                                                          y_source, width,
+                                                          height, format);
+        }
+
+        if (dst) {
+#if 0                           /* Debug to compare it to pixman, Enable it if needed. */
+            glamor_compare_pictures(screen, source,
+                                    dst, x_source, y_source, width, height,
+                                    0, 3);
 #endif
-			return dst;
-		}
-	}
+            return dst;
+        }
+    }
 #endif
-	pixmap = glamor_create_pixmap(screen,
-				      width,
-				      height,
-				      PIXMAN_FORMAT_DEPTH(format),
-				      GLAMOR_CREATE_PIXMAP_CPU);
-
-	if (!pixmap)
-		return NULL;
-
-	dst = CreatePicture(0,
-	                    &pixmap->drawable,
-	                    PictureMatchFormat(screen,
-	                                       PIXMAN_FORMAT_DEPTH(format),
-	                                       format),
-	                    0, 0, serverClient, &error);
-	glamor_destroy_pixmap(pixmap);
-	if (!dst)
-		return NULL;
-
-	ValidatePicture(dst);
-
-	fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
-	            0, 0, 0, 0, width, height);
-	return dst;
+    pixmap = glamor_create_pixmap(screen,
+                                  width,
+                                  height,
+                                  PIXMAN_FORMAT_DEPTH(format),
+                                  GLAMOR_CREATE_PIXMAP_CPU);
+
+    if (!pixmap)
+        return NULL;
+
+    dst = CreatePicture(0,
+                        &pixmap->drawable,
+                        PictureMatchFormat(screen,
+                                           PIXMAN_FORMAT_DEPTH(format),
+                                           format), 0, 0, serverClient, &error);
+    glamor_destroy_pixmap(pixmap);
+    if (!dst)
+        return NULL;
+
+    ValidatePicture(dst);
+
+    fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
+                0, 0, 0, 0, width, height);
+    return dst;
 }
 
 Bool
 glamor_composite_clipped_region(CARD8 op,
-				PicturePtr source,
-				PicturePtr mask,
-				PicturePtr dest,
-				glamor_pixmap_private *source_pixmap_priv,
-				glamor_pixmap_private *mask_pixmap_priv,
-				glamor_pixmap_private *dest_pixmap_priv,
-				RegionPtr region,
-				int x_source,
-				int y_source,
-				int x_mask,
-				int y_mask,
-				int x_dest,
-				int y_dest)
+                                PicturePtr source,
+                                PicturePtr mask,
+                                PicturePtr dest,
+                                glamor_pixmap_private * source_pixmap_priv,
+                                glamor_pixmap_private * mask_pixmap_priv,
+                                glamor_pixmap_private * dest_pixmap_priv,
+                                RegionPtr region,
+                                int x_source,
+                                int y_source,
+                                int x_mask, int y_mask, int x_dest, int y_dest)
 {
-	ScreenPtr screen = dest->pDrawable->pScreen;
-	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-	PicturePtr temp_src = source, temp_mask = mask;
-	glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
-	glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
-	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
-	BoxPtr extent;
-	glamor_composite_rect_t rect[10];
-	glamor_composite_rect_t *prect = rect;
-	int prect_size = ARRAY_SIZE(rect);
-	int ok = FALSE;
-	int i;
-	int width;
-	int height;
-	BoxPtr box;
-	int nbox;
-	Bool two_pass_ca = FALSE;
-
-	extent = RegionExtents(region);
-	box = RegionRects(region);
-	nbox = RegionNumRects(region);
-	width = extent->x2 - extent->x1;
-	height = extent->y2 - extent->y1;
-
-	x_temp_src = x_source;
-	y_temp_src = y_source;
-	x_temp_mask = x_mask;
-	y_temp_mask = y_mask;
-
-	DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
-		x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
-
-	if (source_pixmap_priv)
-		source_pixmap = source_pixmap_priv->base.pixmap;
-
-	if (mask_pixmap_priv)
-		mask_pixmap = mask_pixmap_priv->base.pixmap;
-
-	/* XXX is it possible source mask have non-zero drawable.x/y? */
-	if (source
-	    && ((!source->pDrawable
-	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
-	    || (source->pDrawable
-		&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
-		&& (source_pixmap->drawable.width != width
-		    || source_pixmap->drawable.height != height)))) {
-		temp_src =
-		    glamor_convert_gradient_picture(screen, source,
-						    extent->x1 + x_source - x_dest,
-						    extent->y1 + y_source - y_dest,
-						    width, height);
-		if (!temp_src) {
-			temp_src = source;
-			goto out;
-		}
-		temp_src_priv = glamor_get_pixmap_private((PixmapPtr)(temp_src->pDrawable));
-		x_temp_src = - extent->x1 + x_dest;
-		y_temp_src = - extent->y1 + y_dest;
-	}
-
-	if (mask
-	    &&
-	    ((!mask->pDrawable
-	      && (mask->pSourcePict->type != SourcePictTypeSolidFill))
-	     || (mask->pDrawable
-		 && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)
-		 && (mask_pixmap->drawable.width != width
-		    || mask_pixmap->drawable.height != height)))) {
-		/* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
-		 * to do reduce one convertion. */
-		temp_mask =
-		    glamor_convert_gradient_picture(screen, mask,
-						    extent->x1 + x_mask - x_dest,
-						    extent->y1 + y_mask - y_dest,
-						    width, height);
-		if (!temp_mask) {
-			temp_mask = mask;
-			goto out;
-		}
-		temp_mask_priv = glamor_get_pixmap_private((PixmapPtr)(temp_mask->pDrawable));
-		x_temp_mask = - extent->x1 + x_dest;
-		y_temp_mask = - extent->y1 + y_dest;
-	}
-	/* Do two-pass PictOpOver componentAlpha, until we enable
-	 * dual source color blending.
-	 */
-
-	if (mask && mask->componentAlpha) {
-		if (op == PictOpOver) {
-			two_pass_ca = TRUE;
-			op = PictOpOutReverse;
-		}
-	}
-
-	if (!mask && temp_src) {
-		if (glamor_composite_with_copy(op, temp_src, dest,
-					       x_temp_src, y_temp_src,
-					       x_dest, y_dest, region)) {
-			ok = TRUE;
-			goto out;
-		}
-	}
-
-	/*XXXXX, self copy?*/
-
-	x_dest += dest->pDrawable->x;
-	y_dest += dest->pDrawable->y;
-	if (temp_src && temp_src->pDrawable) {
-		x_temp_src += temp_src->pDrawable->x;
-		y_temp_src += temp_src->pDrawable->y;
-	}
-	if (temp_mask && temp_mask->pDrawable) {
-		x_temp_mask += temp_mask->pDrawable->x;
-		y_temp_mask += temp_mask->pDrawable->y;
-	}
-
-	if (nbox > ARRAY_SIZE(rect)) {
-		prect = calloc(nbox, sizeof(*prect));
-		if (prect)
-			prect_size = nbox;
-		else {
-			prect = rect;
-			prect_size = ARRAY_SIZE(rect);
-		}
-	}
-	while(nbox) {
-		int box_cnt;
-		box_cnt = nbox > prect_size ? prect_size : nbox;
-		for (i = 0; i < box_cnt; i++) {
-			prect[i].x_src = box[i].x1 + x_temp_src - x_dest;
-			prect[i].y_src = box[i].y1 + y_temp_src - y_dest;
-			prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest;
-			prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest;
-			prect[i].x_dst = box[i].x1;
-			prect[i].y_dst = box[i].y1;
-			prect[i].width = box[i].x2 - box[i].x1;
-			prect[i].height = box[i].y2 - box[i].y1;
-			DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
-		}
-		ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
-						  temp_src_priv, temp_mask_priv,
-						  dest_pixmap_priv,
-						  box_cnt, prect, two_pass_ca);
-		if (!ok)
-			break;
-		nbox -= box_cnt;
-		box += box_cnt;
-	}
-
-	if (prect != rect)
-		free(prect);
-out:
-	if (temp_src != source)
-		FreePicture(temp_src, 0);
-	if (temp_mask != mask)
-		FreePicture(temp_mask, 0);
-
-	return ok;
+    ScreenPtr screen = dest->pDrawable->pScreen;
+    PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+    PicturePtr temp_src = source, temp_mask = mask;
+    glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
+    glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
+    int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
+    BoxPtr extent;
+    glamor_composite_rect_t rect[10];
+    glamor_composite_rect_t *prect = rect;
+    int prect_size = ARRAY_SIZE(rect);
+    int ok = FALSE;
+    int i;
+    int width;
+    int height;
+    BoxPtr box;
+    int nbox;
+    Bool two_pass_ca = FALSE;
+
+    extent = RegionExtents(region);
+    box = RegionRects(region);
+    nbox = RegionNumRects(region);
+    width = extent->x2 - extent->x1;
+    height = extent->y2 - extent->y1;
+
+    x_temp_src = x_source;
+    y_temp_src = y_source;
+    x_temp_mask = x_mask;
+    y_temp_mask = y_mask;
+
+    DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
+           x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+
+    if (source_pixmap_priv)
+        source_pixmap = source_pixmap_priv->base.pixmap;
+
+    if (mask_pixmap_priv)
+        mask_pixmap = mask_pixmap_priv->base.pixmap;
+
+    /* XXX is it possible source mask have non-zero drawable.x/y? */
+    if (source
+        && ((!source->pDrawable
+             && (source->pSourcePict->type != SourcePictTypeSolidFill))
+            || (source->pDrawable
+                && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
+                && (source_pixmap->drawable.width != width
+                    || source_pixmap->drawable.height != height)))) {
+        temp_src =
+            glamor_convert_gradient_picture(screen, source,
+                                            extent->x1 + x_source - x_dest,
+                                            extent->y1 + y_source - y_dest,
+                                            width, height);
+        if (!temp_src) {
+            temp_src = source;
+            goto out;
+        }
+        temp_src_priv =
+            glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
+        x_temp_src = -extent->x1 + x_dest;
+        y_temp_src = -extent->y1 + y_dest;
+    }
+
+    if (mask
+        &&
+        ((!mask->pDrawable
+          && (mask->pSourcePict->type != SourcePictTypeSolidFill))
+         || (mask->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)
+             && (mask_pixmap->drawable.width != width
+                 || mask_pixmap->drawable.height != height)))) {
+        /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
+         * to do reduce one convertion. */
+        temp_mask =
+            glamor_convert_gradient_picture(screen, mask,
+                                            extent->x1 + x_mask - x_dest,
+                                            extent->y1 + y_mask - y_dest,
+                                            width, height);
+        if (!temp_mask) {
+            temp_mask = mask;
+            goto out;
+        }
+        temp_mask_priv =
+            glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
+        x_temp_mask = -extent->x1 + x_dest;
+        y_temp_mask = -extent->y1 + y_dest;
+    }
+    /* Do two-pass PictOpOver componentAlpha, until we enable
+     * dual source color blending.
+     */
+
+    if (mask && mask->componentAlpha) {
+        if (op == PictOpOver) {
+            two_pass_ca = TRUE;
+            op = PictOpOutReverse;
+        }
+    }
+
+    if (!mask && temp_src) {
+        if (glamor_composite_with_copy(op, temp_src, dest,
+                                       x_temp_src, y_temp_src,
+                                       x_dest, y_dest, region)) {
+            ok = TRUE;
+            goto out;
+        }
+    }
+
+    /*XXXXX, self copy? */
+
+    x_dest += dest->pDrawable->x;
+    y_dest += dest->pDrawable->y;
+    if (temp_src && temp_src->pDrawable) {
+        x_temp_src += temp_src->pDrawable->x;
+        y_temp_src += temp_src->pDrawable->y;
+    }
+    if (temp_mask && temp_mask->pDrawable) {
+        x_temp_mask += temp_mask->pDrawable->x;
+        y_temp_mask += temp_mask->pDrawable->y;
+    }
+
+    if (nbox > ARRAY_SIZE(rect)) {
+        prect = calloc(nbox, sizeof(*prect));
+        if (prect)
+            prect_size = nbox;
+        else {
+            prect = rect;
+            prect_size = ARRAY_SIZE(rect);
+        }
+    }
+    while (nbox) {
+        int box_cnt;
+
+        box_cnt = nbox > prect_size ? prect_size : nbox;
+        for (i = 0; i < box_cnt; i++) {
+            prect[i].x_src = box[i].x1 + x_temp_src - x_dest;
+            prect[i].y_src = box[i].y1 + y_temp_src - y_dest;
+            prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest;
+            prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest;
+            prect[i].x_dst = box[i].x1;
+            prect[i].y_dst = box[i].y1;
+            prect[i].width = box[i].x2 - box[i].x1;
+            prect[i].height = box[i].y2 - box[i].y1;
+            DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
+        }
+        ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
+                                          temp_src_priv, temp_mask_priv,
+                                          dest_pixmap_priv,
+                                          box_cnt, prect, two_pass_ca);
+        if (!ok)
+            break;
+        nbox -= box_cnt;
+        box += box_cnt;
+    }
+
+    if (prect != rect)
+        free(prect);
+ out:
+    if (temp_src != source)
+        FreePicture(temp_src, 0);
+    if (temp_mask != mask)
+        FreePicture(temp_mask, 0);
+
+    return ok;
 }
 
 static Bool
 _glamor_composite(CARD8 op,
-		  PicturePtr source,
-		  PicturePtr mask,
-		  PicturePtr dest,
-		  INT16 x_source,
-		  INT16 y_source,
-		  INT16 x_mask,
-		  INT16 y_mask,
-		  INT16 x_dest, INT16 y_dest,
-		  CARD16 width, CARD16 height, Bool fallback)
+                  PicturePtr source,
+                  PicturePtr mask,
+                  PicturePtr dest,
+                  INT16 x_source,
+                  INT16 y_source,
+                  INT16 x_mask,
+                  INT16 y_mask,
+                  INT16 x_dest, INT16 y_dest,
+                  CARD16 width, CARD16 height, Bool fallback)
 {
-	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_pixmap_private *dest_pixmap_priv;
-	glamor_pixmap_private *source_pixmap_priv =
-	    NULL, *mask_pixmap_priv = NULL;
-	PixmapPtr dest_pixmap =
-	    glamor_get_drawable_pixmap(dest->pDrawable);
-	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	Bool ret = TRUE;
-	RegionRec region;
-	BoxPtr extent;
-	int nbox, ok = FALSE;
-	PixmapPtr sub_dest_pixmap = NULL;
-	PixmapPtr sub_source_pixmap = NULL;
-	PixmapPtr sub_mask_pixmap = NULL;
-	int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
-	int source_x_off, source_y_off, saved_source_x, saved_source_y;
-	int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
-	DrawablePtr saved_dest_drawable;
-	DrawablePtr saved_source_drawable;
-	DrawablePtr saved_mask_drawable;
-	int force_clip = 0;
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
-	if (source->pDrawable) {
-		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
-			goto fail;
-	}
-
-	if (mask && mask->pDrawable) {
-		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
-			goto fail;
-	}
-
-	DEBUGF("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n",
-		source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-		goto fail;
-	}
-
-	if (op >= ARRAY_SIZE(composite_op_info))
-		goto fail;
-
-	if (mask && mask->componentAlpha) {
-		if (op == PictOpAtop
-		    || op == PictOpAtopReverse
-		    || op == PictOpXor
-		    || op >= PictOpSaturate) {
-			glamor_fallback
-				("glamor_composite(): component alpha op %x\n", op);
-			goto fail;
-		}
-	}
-
-	if ((source && source->filter >= PictFilterConvolution)
-			|| (mask && mask->filter >= PictFilterConvolution)) {
-		glamor_fallback("glamor_composite(): unsupported filter\n");
-		goto fail;
-	}
-
-	if (!miComputeCompositeRegion(&region,
-				      source, mask, dest,
-				      x_source + (source_pixmap ? source->pDrawable->x : 0),
-				      y_source + (source_pixmap ? source->pDrawable->y : 0),
-				      x_mask + (mask_pixmap ? mask->pDrawable->x : 0),
-				      y_mask + (mask_pixmap ? mask->pDrawable->y : 0),
-				      x_dest + dest->pDrawable->x,
-				      y_dest + dest->pDrawable->y,
-				      width,
-				      height)) {
-		ret = TRUE;
-		goto done;
-	}
-
-	nbox = REGION_NUM_RECTS(&region);
-	DEBUGF("first clipped when compositing.\n");
-	DEBUGRegionPrint(&region);
-	extent = RegionExtents(&region);
-	if (nbox == 0) {
-		ret = TRUE;
-		goto done;
-	}
-	/* If destination is not a large pixmap, but the region is larger
-	 * than texture size limitation, and source or mask is memory pixmap,
-	 * then there may be need to load a large memory pixmap to a
-	 * texture, and this is not permitted. Then we force to clip the
-	 * destination and make sure latter will not upload a large memory
-	 * pixmap. */
-	if (!glamor_check_fbo_size(glamor_priv,
-		extent->x2 - extent->x1, extent->y2 - extent->y1)
-	   && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
-           && ((source_pixmap_priv
-	        && (source_pixmap_priv->type == GLAMOR_MEMORY || source->repeatType == RepeatPad))
-	     || (mask_pixmap_priv
-		&& (mask_pixmap_priv->type == GLAMOR_MEMORY || mask->repeatType == RepeatPad))
-	     || (!source_pixmap_priv
-		   && (source->pSourcePict->type != SourcePictTypeSolidFill))
-	     || (!mask_pixmap_priv && mask
-		  && mask->pSourcePict->type != SourcePictTypeSolidFill)))
-		force_clip = 1;
-
-	if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-	    || (source_pixmap_priv
-		&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
-	    || (mask_pixmap_priv
-		&& mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
-		ok = glamor_composite_largepixmap_region(op,
-						   source, mask, dest,
-						   source_pixmap_priv,
-						   mask_pixmap_priv,
-						   dest_pixmap_priv,
-						   &region, force_clip,
-						   x_source, y_source,
-						   x_mask, y_mask,
-						   x_dest, y_dest,
-						   width, height);
-	else
-		ok = glamor_composite_clipped_region(op, source,
-						     mask, dest,
-						     source_pixmap_priv,
-						     mask_pixmap_priv,
-						     dest_pixmap_priv,
-						     &region,
-						     x_source, y_source,
-						     x_mask, y_mask,
-						     x_dest, y_dest);
-
-	REGION_UNINIT(dest->pDrawable->pScreen, &region);
-
-	if (ok)
-		goto done;
-fail:
-
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
-	    && (!source_pixmap
-		|| glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
-	    && (!mask_pixmap
-		|| glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
-		ret = FALSE;
-		goto done;
-	}
-
-	glamor_fallback
-	    ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
-	     source, source->pDrawable,
-	     source->pDrawable ? source->pDrawable->width : 0,
-	     source->pDrawable ? source->pDrawable->height : 0, mask,
-	     (!mask) ? NULL : mask->pDrawable, (!mask
-						|| !mask->pDrawable) ? 0 :
-	     mask->pDrawable->width, (!mask
-				      || !mask->
-				      pDrawable) ? 0 : mask->pDrawable->
-	     height, glamor_get_picture_location(source),
-	     glamor_get_picture_location(mask), dest, dest->pDrawable,
-	     dest->pDrawable->width, dest->pDrawable->height,
-	     glamor_get_picture_location(dest));
+    ScreenPtr screen = dest->pDrawable->pScreen;
+    glamor_pixmap_private *dest_pixmap_priv;
+    glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+    PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    Bool ret = TRUE;
+    RegionRec region;
+    BoxPtr extent;
+    int nbox, ok = FALSE;
+    PixmapPtr sub_dest_pixmap = NULL;
+    PixmapPtr sub_source_pixmap = NULL;
+    PixmapPtr sub_mask_pixmap = NULL;
+    int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
+    int source_x_off, source_y_off, saved_source_x, saved_source_y;
+    int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
+    DrawablePtr saved_dest_drawable;
+    DrawablePtr saved_source_drawable;
+    DrawablePtr saved_mask_drawable;
+    int force_clip = 0;
+
+    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+    if (source->pDrawable) {
+        source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+        source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+        if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+            goto fail;
+    }
+
+    if (mask && mask->pDrawable) {
+        mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+        mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+        if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+            goto fail;
+    }
+
+    DEBUGF
+        ("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n",
+         source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest,
+         width, height);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+        goto fail;
+    }
+
+    if (op >= ARRAY_SIZE(composite_op_info))
+        goto fail;
+
+    if (mask && mask->componentAlpha) {
+        if (op == PictOpAtop
+            || op == PictOpAtopReverse
+            || op == PictOpXor || op >= PictOpSaturate) {
+            glamor_fallback("glamor_composite(): component alpha op %x\n", op);
+            goto fail;
+        }
+    }
+
+    if ((source && source->filter >= PictFilterConvolution)
+        || (mask && mask->filter >= PictFilterConvolution)) {
+        glamor_fallback("glamor_composite(): unsupported filter\n");
+        goto fail;
+    }
+
+    if (!miComputeCompositeRegion(&region,
+                                  source, mask, dest,
+                                  x_source +
+                                  (source_pixmap ? source->pDrawable->x : 0),
+                                  y_source +
+                                  (source_pixmap ? source->pDrawable->y : 0),
+                                  x_mask +
+                                  (mask_pixmap ? mask->pDrawable->x : 0),
+                                  y_mask +
+                                  (mask_pixmap ? mask->pDrawable->y : 0),
+                                  x_dest + dest->pDrawable->x,
+                                  y_dest + dest->pDrawable->y, width, height)) {
+        ret = TRUE;
+        goto done;
+    }
+
+    nbox = REGION_NUM_RECTS(&region);
+    DEBUGF("first clipped when compositing.\n");
+    DEBUGRegionPrint(&region);
+    extent = RegionExtents(&region);
+    if (nbox == 0) {
+        ret = TRUE;
+        goto done;
+    }
+    /* If destination is not a large pixmap, but the region is larger
+     * than texture size limitation, and source or mask is memory pixmap,
+     * then there may be need to load a large memory pixmap to a
+     * texture, and this is not permitted. Then we force to clip the
+     * destination and make sure latter will not upload a large memory
+     * pixmap. */
+    if (!glamor_check_fbo_size(glamor_priv,
+                               extent->x2 - extent->x1, extent->y2 - extent->y1)
+        && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
+        && ((source_pixmap_priv
+             && (source_pixmap_priv->type == GLAMOR_MEMORY ||
+                 source->repeatType == RepeatPad))
+            || (mask_pixmap_priv &&
+                (mask_pixmap_priv->type == GLAMOR_MEMORY ||
+                 mask->repeatType == RepeatPad))
+            || (!source_pixmap_priv &&
+                (source->pSourcePict->type != SourcePictTypeSolidFill))
+            || (!mask_pixmap_priv && mask &&
+                mask->pSourcePict->type != SourcePictTypeSolidFill)))
+        force_clip = 1;
+
+    if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+        || (source_pixmap_priv
+            && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
+        || (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
+        ok = glamor_composite_largepixmap_region(op,
+                                                 source, mask, dest,
+                                                 source_pixmap_priv,
+                                                 mask_pixmap_priv,
+                                                 dest_pixmap_priv,
+                                                 &region, force_clip,
+                                                 x_source, y_source,
+                                                 x_mask, y_mask,
+                                                 x_dest, y_dest, width, height);
+    else
+        ok = glamor_composite_clipped_region(op, source,
+                                             mask, dest,
+                                             source_pixmap_priv,
+                                             mask_pixmap_priv,
+                                             dest_pixmap_priv,
+                                             &region,
+                                             x_source, y_source,
+                                             x_mask, y_mask, x_dest, y_dest);
+
+    REGION_UNINIT(dest->pDrawable->pScreen, &region);
+
+    if (ok)
+        goto done;
+ fail:
+
+    if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
+        && (!source_pixmap
+            || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
+        && (!mask_pixmap
+            || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
+        ret = FALSE;
+        goto done;
+    }
+
+    glamor_fallback
+        ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
+         source, source->pDrawable,
+         source->pDrawable ? source->pDrawable->width : 0,
+         source->pDrawable ? source->pDrawable->height : 0, mask,
+         (!mask) ? NULL : mask->pDrawable, (!mask
+                                            || !mask->pDrawable) ? 0 :
+         mask->pDrawable->width, (!mask
+                                  || !mask->pDrawable) ? 0 : mask->
+         pDrawable->height, glamor_get_picture_location(source),
+         glamor_get_picture_location(mask), dest, dest->pDrawable,
+         dest->pDrawable->width, dest->pDrawable->height,
+         glamor_get_picture_location(dest));
 
 #define GET_SUB_PICTURE(p, access)		do {					\
 	glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap,				\
@@ -1897,32 +1876,28 @@ fail:
 		x_ ##p = 0;								\
 		y_ ##p = 0;								\
 	} } while(0)
-	GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
-	if (source->pDrawable && !source->transform)
-		GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
-	if (mask && mask->pDrawable && !mask->transform)
-		GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
-
-	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
-		if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
-		    (source, GLAMOR_ACCESS_RO)) {
-			if (!mask
-			    || glamor_prepare_access_picture(mask,
-							     GLAMOR_ACCESS_RO))
-			{
-				fbComposite(op,
-					    source, mask, dest,
-					    x_source, y_source,
-					    x_mask, y_mask, x_dest,
-					    y_dest, width, height);
-				if (mask)
-					glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO);
-			}
-			if (source_pixmap != dest_pixmap)
-				glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
-		}
-		glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
-	}
+    GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
+    if (source->pDrawable && !source->transform)
+        GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
+    if (mask && mask->pDrawable && !mask->transform)
+        GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
+
+    if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
+        if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
+            (source, GLAMOR_ACCESS_RO)) {
+            if (!mask || glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) {
+                fbComposite(op,
+                            source, mask, dest,
+                            x_source, y_source,
+                            x_mask, y_mask, x_dest, y_dest, width, height);
+                if (mask)
+                    glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO);
+            }
+            if (source_pixmap != dest_pixmap)
+                glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
+        }
+        glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
+    }
 
 #define PUT_SUB_PICTURE(p, access)		do {				\
 	if (sub_ ##p ##_pixmap != NULL) {					\
@@ -1938,198 +1913,196 @@ fail:
 				      y_ ##p + p ##_y_off + p->pDrawable->y,	\
 				      width, height, access);			\
 	}} while(0)
-	if (mask && mask->pDrawable)
-		PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
-	if (source->pDrawable)
-		PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
-	PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
-      done:
-	return ret;
+    if (mask && mask->pDrawable)
+        PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
+    if (source->pDrawable)
+        PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
+    PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
+ done:
+    return ret;
 }
 
 void
 glamor_composite(CARD8 op,
-		 PicturePtr source,
-		 PicturePtr mask,
-		 PicturePtr dest,
-		 INT16 x_source,
-		 INT16 y_source,
-		 INT16 x_mask,
-		 INT16 y_mask,
-		 INT16 x_dest, INT16 y_dest,
-		 CARD16 width, CARD16 height)
+                 PicturePtr source,
+                 PicturePtr mask,
+                 PicturePtr dest,
+                 INT16 x_source,
+                 INT16 y_source,
+                 INT16 x_mask,
+                 INT16 y_mask,
+                 INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
 {
-	_glamor_composite(op, source, mask, dest, x_source, y_source,
-			  x_mask, y_mask, x_dest, y_dest, width, height,
-			  TRUE);
+    _glamor_composite(op, source, mask, dest, x_source, y_source,
+                      x_mask, y_mask, x_dest, y_dest, width, height, TRUE);
 }
 
 Bool
 glamor_composite_nf(CARD8 op,
-		    PicturePtr source,
-		    PicturePtr mask,
-		    PicturePtr dest,
-		    INT16 x_source,
-		    INT16 y_source,
-		    INT16 x_mask,
-		    INT16 y_mask,
-		    INT16 x_dest, INT16 y_dest,
-		    CARD16 width, CARD16 height)
+                    PicturePtr source,
+                    PicturePtr mask,
+                    PicturePtr dest,
+                    INT16 x_source,
+                    INT16 y_source,
+                    INT16 x_mask,
+                    INT16 y_mask,
+                    INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
 {
-	return _glamor_composite(op, source, mask, dest, x_source, y_source,
-				 x_mask, y_mask, x_dest, y_dest, width, height,
-				 FALSE);
+    return _glamor_composite(op, source, mask, dest, x_source, y_source,
+                             x_mask, y_mask, x_dest, y_dest, width, height,
+                             FALSE);
 }
 
 static void
 glamor_get_src_rect_extent(int nrect,
-			   glamor_composite_rect_t *rects,
-			   BoxPtr extent)
+                           glamor_composite_rect_t * rects, BoxPtr extent)
 {
-	extent->x1 = MAXSHORT;
-	extent->y1 = MAXSHORT;
-	extent->x2 = MINSHORT;
-	extent->y2 = MINSHORT;
-
-	while(nrect--) {
-		if (extent->x1 > rects->x_src)
-			extent->x1 = rects->x_src;
-		if (extent->y1 > rects->y_src)
-			extent->y1 = rects->y_src;
-		if (extent->x2 < rects->x_src + rects->width)
-			extent->x2 = rects->x_src + rects->width;
-		if (extent->y2 < rects->y_src + rects->height)
-			extent->y2 = rects->y_src + rects->height;
-		rects++;
-	}
+    extent->x1 = MAXSHORT;
+    extent->y1 = MAXSHORT;
+    extent->x2 = MINSHORT;
+    extent->y2 = MINSHORT;
+
+    while (nrect--) {
+        if (extent->x1 > rects->x_src)
+            extent->x1 = rects->x_src;
+        if (extent->y1 > rects->y_src)
+            extent->y1 = rects->y_src;
+        if (extent->x2 < rects->x_src + rects->width)
+            extent->x2 = rects->x_src + rects->width;
+        if (extent->y2 < rects->y_src + rects->height)
+            extent->y2 = rects->y_src + rects->height;
+        rects++;
+    }
 }
 
 static void
 glamor_composite_src_rect_translate(int nrect,
-				    glamor_composite_rect_t *rects,
-				    int x, int y)
+                                    glamor_composite_rect_t * rects,
+                                    int x, int y)
 {
-	while(nrect--) {
-		rects->x_src += x;
-		rects->y_src += y;
-		rects++;
-	}
+    while (nrect--) {
+        rects->x_src += x;
+        rects->y_src += y;
+        rects++;
+    }
 }
 
 void
 glamor_composite_glyph_rects(CARD8 op,
-			     PicturePtr src, PicturePtr mask, PicturePtr dst,
-			     int nrect, glamor_composite_rect_t * rects)
+                             PicturePtr src, PicturePtr mask, PicturePtr dst,
+                             int nrect, glamor_composite_rect_t * rects)
 {
-	int n;
-	PicturePtr temp_src = NULL;
-	glamor_composite_rect_t *r;
-
-	ValidatePicture(src);
-	ValidatePicture(dst);
-	if (!(glamor_is_large_picture(src)
-	    || (mask && glamor_is_large_picture(mask))
-	    || glamor_is_large_picture(dst))) {
-		glamor_pixmap_private *src_pixmap_priv = NULL;
-		glamor_pixmap_private *mask_pixmap_priv = NULL;
-		glamor_pixmap_private *dst_pixmap_priv;
-		glamor_pixmap_private *temp_src_priv = NULL;
-		BoxRec src_extent;
-
-		dst_pixmap_priv = glamor_get_pixmap_private
-					(glamor_get_drawable_pixmap(dst->pDrawable));
-
-		if (mask && mask->pDrawable)
-			mask_pixmap_priv = glamor_get_pixmap_private
-						(glamor_get_drawable_pixmap(mask->pDrawable));
-		if (src->pDrawable)
-			src_pixmap_priv = glamor_get_pixmap_private
-						(glamor_get_drawable_pixmap(src->pDrawable));
-
-		if (!src->pDrawable
-		    && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
-			glamor_get_src_rect_extent(nrect, rects, &src_extent);
-			temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
-						    src,
-						    src_extent.x1, src_extent.y1,
-						    src_extent.x2 - src_extent.x1,
-						    src_extent.y2 - src_extent.y1);
-			if (!temp_src)
-				goto fallback;
-
-			temp_src_priv = glamor_get_pixmap_private
-						((PixmapPtr)(temp_src->pDrawable));
-			glamor_composite_src_rect_translate(nrect, rects,
-							-src_extent.x1, -src_extent.y1);
-		} else {
-			temp_src = src;
-			temp_src_priv = src_pixmap_priv;
-		}
-
-		if (mask && mask->componentAlpha) {
-			if (op == PictOpOver) {
-				if (glamor_composite_with_shader(PictOpOutReverse,
-						 temp_src, mask, dst, temp_src_priv,
-						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects,
-						 TRUE))
-					goto done;
-			}
-		} else {
-				if (glamor_composite_with_shader(op, temp_src, mask, dst, temp_src_priv,
-						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects, FALSE))
-					goto done;
-		}
-	}
-fallback:
-	n = nrect;
-	r = rects;
-
-	while (n--) {
-		CompositePicture(op,
-				 temp_src ? temp_src : src,
-				 mask,
-				 dst,
-				 r->x_src, r->y_src,
-				 r->x_mask, r->y_mask,
-				 r->x_dst, r->y_dst, r->width, r->height);
-		r++;
-	}
-
-done:
-	if (temp_src && temp_src != src)
-		FreePicture(temp_src, 0);
+    int n;
+    PicturePtr temp_src = NULL;
+    glamor_composite_rect_t *r;
+
+    ValidatePicture(src);
+    ValidatePicture(dst);
+    if (!(glamor_is_large_picture(src)
+          || (mask && glamor_is_large_picture(mask))
+          || glamor_is_large_picture(dst))) {
+        glamor_pixmap_private *src_pixmap_priv = NULL;
+        glamor_pixmap_private *mask_pixmap_priv = NULL;
+        glamor_pixmap_private *dst_pixmap_priv;
+        glamor_pixmap_private *temp_src_priv = NULL;
+        BoxRec src_extent;
+
+        dst_pixmap_priv = glamor_get_pixmap_private
+            (glamor_get_drawable_pixmap(dst->pDrawable));
+
+        if (mask && mask->pDrawable)
+            mask_pixmap_priv = glamor_get_pixmap_private
+                (glamor_get_drawable_pixmap(mask->pDrawable));
+        if (src->pDrawable)
+            src_pixmap_priv = glamor_get_pixmap_private
+                (glamor_get_drawable_pixmap(src->pDrawable));
+
+        if (!src->pDrawable
+            && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
+            glamor_get_src_rect_extent(nrect, rects, &src_extent);
+            temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
+                                                       src,
+                                                       src_extent.x1,
+                                                       src_extent.y1,
+                                                       src_extent.x2 -
+                                                       src_extent.x1,
+                                                       src_extent.y2 -
+                                                       src_extent.y1);
+            if (!temp_src)
+                goto fallback;
+
+            temp_src_priv = glamor_get_pixmap_private
+                ((PixmapPtr) (temp_src->pDrawable));
+            glamor_composite_src_rect_translate(nrect, rects,
+                                                -src_extent.x1, -src_extent.y1);
+        }
+        else {
+            temp_src = src;
+            temp_src_priv = src_pixmap_priv;
+        }
+
+        if (mask && mask->componentAlpha) {
+            if (op == PictOpOver) {
+                if (glamor_composite_with_shader(PictOpOutReverse,
+                                                 temp_src, mask, dst,
+                                                 temp_src_priv,
+                                                 mask_pixmap_priv,
+                                                 dst_pixmap_priv, nrect, rects,
+                                                 TRUE))
+                    goto done;
+            }
+        }
+        else {
+            if (glamor_composite_with_shader
+                (op, temp_src, mask, dst, temp_src_priv, mask_pixmap_priv,
+                 dst_pixmap_priv, nrect, rects, FALSE))
+                goto done;
+        }
+    }
+ fallback:
+    n = nrect;
+    r = rects;
+
+    while (n--) {
+        CompositePicture(op,
+                         temp_src ? temp_src : src,
+                         mask,
+                         dst,
+                         r->x_src, r->y_src,
+                         r->x_mask, r->y_mask,
+                         r->x_dst, r->y_dst, r->width, r->height);
+        r++;
+    }
+
+ done:
+    if (temp_src && temp_src != src)
+        FreePicture(temp_src, 0);
 }
 
 static Bool
-_glamor_composite_rects (CARD8         op,
-			      PicturePtr    pDst,
-			      xRenderColor  *color,
-			      int           nRect,
-			      xRectangle    *rects,
-			      Bool	    fallback)
+_glamor_composite_rects(CARD8 op,
+                        PicturePtr pDst,
+                        xRenderColor * color,
+                        int nRect, xRectangle *rects, Bool fallback)
 {
-	miCompositeRects(op, pDst, color, nRect, rects);
-	return TRUE;
+    miCompositeRects(op, pDst, color, nRect, rects);
+    return TRUE;
 }
 
 void
-glamor_composite_rects (CARD8         op,
-			PicturePtr    pDst,
-			xRenderColor  *color,
-			int           nRect,
-			xRectangle    *rects)
+glamor_composite_rects(CARD8 op,
+                       PicturePtr pDst,
+                       xRenderColor * color, int nRect, xRectangle *rects)
 {
-	_glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
+    _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
 }
 
 Bool
-glamor_composite_rects_nf (CARD8         op,
-			   PicturePtr    pDst,
-			   xRenderColor  *color,
-			   int           nRect,
-			   xRectangle    *rects)
+glamor_composite_rects_nf(CARD8 op,
+                          PicturePtr pDst,
+                          xRenderColor * color, int nRect, xRectangle *rects)
 {
-	return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
+    return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
 }
 
-#endif				/* RENDER */
+#endif                          /* RENDER */
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 3d447b6..22fe88c 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -30,82 +30,83 @@
 
 static Bool
 _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		 DDXPointPtr points, int *widths, int numPoints, int sorted,
-		 Bool fallback)
+                  DDXPointPtr points, int *widths, int numPoints, int sorted,
+                  Bool fallback)
 {
-	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *dest_pixmap_priv;
-	int i;
-	uint8_t *drawpixels_src = (uint8_t *) src;
-	RegionPtr clip = fbGetCompositeClip(gc);
-	BoxRec *pbox;
-	int x_off, y_off;
-	Bool ret = FALSE;
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *dest_pixmap_priv;
+    int i;
+    uint8_t *drawpixels_src = (uint8_t *) src;
+    RegionPtr clip = fbGetCompositeClip(gc);
+    BoxRec *pbox;
+    int x_off, y_off;
+    Bool ret = FALSE;
 
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-		glamor_fallback("pixmap has no fbo.\n");
-		goto fail;
-	}
+    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+        glamor_fallback("pixmap has no fbo.\n");
+        goto fail;
+    }
 
-	/* XXX Shall we set alu here? */
-	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
-		goto fail;
+    /* XXX Shall we set alu here? */
+    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
+        goto fail;
 
-	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
-	for (i = 0; i < numPoints; i++) {
+    glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
+    for (i = 0; i < numPoints; i++) {
 
-		int n = REGION_NUM_RECTS(clip);
-		pbox = REGION_RECTS(clip);
-		while (n--) {
-			int x1 = points[i].x;
-			int x2 = x1 + widths[i];
-			int y1 = points[i].y;
+        int n = REGION_NUM_RECTS(clip);
 
-			if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
-				break;
-			x1 = x1 > pbox->x1 ? x1 : pbox->x1;
-			x2 = x2 < pbox->x2 ? x2 : pbox->x2;
-			if (x1 >= x2)
-				continue;
-			glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,  y1 + y_off, x2 - x1, 1,
-							    PixmapBytePad(widths[i], drawable->depth),
-							    drawpixels_src, 0);
-		}
-		drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
-	}
-	ret = TRUE;
-	goto done;
+        pbox = REGION_RECTS(clip);
+        while (n--) {
+            int x1 = points[i].x;
+            int x2 = x1 + widths[i];
+            int y1 = points[i].y;
 
-fail:
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(drawable))
-		goto done;
+            if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
+                break;
+            x1 = x1 > pbox->x1 ? x1 : pbox->x1;
+            x2 = x2 < pbox->x2 ? x2 : pbox->x2;
+            if (x1 >= x2)
+                continue;
+            glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,
+                                                y1 + y_off, x2 - x1, 1,
+                                                PixmapBytePad(widths[i],
+                                                              drawable->depth),
+                                                drawpixels_src, 0);
+        }
+        drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
+    }
+    ret = TRUE;
+    goto done;
 
-	glamor_fallback("to %p (%c)\n",
-			drawable, glamor_get_drawable_location(drawable));
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
-		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
-	}
-	ret = TRUE;
+ fail:
+    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
+        goto done;
 
-done:
-	return ret;
+    glamor_fallback("to %p (%c)\n",
+                    drawable, glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+        fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
+        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+    }
+    ret = TRUE;
+
+ done:
+    return ret;
 }
 
 void
 glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		    DDXPointPtr points, int *widths, int n, int sorted)
+                 DDXPointPtr points, int *widths, int n, int sorted)
 {
-	_glamor_set_spans(drawable, gc, src, points, 
-			     widths, n, sorted, TRUE);
+    _glamor_set_spans(drawable, gc, src, points, widths, n, sorted, TRUE);
 }
 
 Bool
 glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
-		    DDXPointPtr points, int *widths, int n, int sorted)
+                    DDXPointPtr points, int *widths, int n, int sorted)
 {
-	return _glamor_set_spans(drawable, gc, src, points, 
-				    widths, n, sorted, FALSE);
+    return _glamor_set_spans(drawable, gc, src, points,
+                             widths, n, sorted, FALSE);
 }
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 60486cf..0012653 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -36,290 +36,274 @@
 void
 glamor_init_tile_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	const char *tile_vs =
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord0;\n"
-	    "varying vec2 tile_texture;\n"
-	    "void main()\n"
-	    "{\n"
-	    "       gl_Position = v_position;\n"
-	    "       tile_texture = v_texcoord0.xy;\n" "}\n";
-	const char *tile_fs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "varying vec2 tile_texture;\n"
-	    "uniform sampler2D sampler;\n"
-	    "uniform vec2	wh;"
-	    "void main()\n"
-	    "{\n"
-	    "   vec2 rel_tex;"
-	    "   rel_tex = tile_texture * wh; \n"
-	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
-	    "	gl_FragColor = texture2D(sampler, rel_tex);\n"
-	    "}\n";
-	GLint fs_prog, vs_prog;
-	GLint sampler_uniform_location;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_priv->tile_prog = dispatch->glCreateProgram();
-	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
-	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-					   tile_fs);
-	dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
-	dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
-
-	dispatch->glBindAttribLocation(glamor_priv->tile_prog,
-				       GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(glamor_priv->tile_prog,
-				       GLAMOR_VERTEX_SOURCE,
-				       "v_texcoord0");
-	glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
-
-	sampler_uniform_location =
-	    dispatch->glGetUniformLocation(glamor_priv->tile_prog,
-					   "sampler");
-	dispatch->glUseProgram(glamor_priv->tile_prog);
-	dispatch->glUniform1i(sampler_uniform_location, 0);
-
-	glamor_priv->tile_wh =
-	    dispatch->glGetUniformLocation(glamor_priv->tile_prog,
-					   "wh");
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    const char *tile_vs =
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord0;\n"
+        "varying vec2 tile_texture;\n"
+        "void main()\n"
+        "{\n"
+        "       gl_Position = v_position;\n"
+        "       tile_texture = v_texcoord0.xy;\n" "}\n";
+    const char *tile_fs =
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 tile_texture;\n"
+        "uniform sampler2D sampler;\n"
+        "uniform vec2	wh;"
+        "void main()\n"
+        "{\n"
+        "   vec2 rel_tex;"
+        "   rel_tex = tile_texture * wh; \n"
+        "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+        "	gl_FragColor = texture2D(sampler, rel_tex);\n" "}\n";
+    GLint fs_prog, vs_prog;
+    GLint sampler_uniform_location;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_priv->tile_prog = dispatch->glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs);
+    dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
+
+    dispatch->glBindAttribLocation(glamor_priv->tile_prog,
+                                   GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(glamor_priv->tile_prog,
+                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
+
+    sampler_uniform_location =
+        dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler");
+    dispatch->glUseProgram(glamor_priv->tile_prog);
+    dispatch->glUniform1i(sampler_uniform_location, 0);
+
+    glamor_priv->tile_wh =
+        dispatch->glGetUniformLocation(glamor_priv->tile_prog, "wh");
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_tile_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
 
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glDeleteProgram(glamor_priv->tile_prog);
-	glamor_put_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glDeleteProgram(glamor_priv->tile_prog);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static void
 _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
-	    int x, int y, int width, int height,
-	    int tile_x, int tile_y)
+             int x, int y, int width, int height, int tile_x, int tile_y)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-	int x1 = x;
-	int x2 = x + width;
-	int y1 = y;
-	int y2 = y + height;
-	int tile_x1 = tile_x;
-	int tile_x2 = tile_x + width;
-	int tile_y1 = tile_y;
-	int tile_y2 = tile_y + height;
-	float vertices[8];
-	float source_texcoords[8];
-	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-	glamor_pixmap_private *src_pixmap_priv;
-	glamor_pixmap_private *dst_pixmap_priv;
-	float wh[4];
-	src_pixmap_priv = glamor_get_pixmap_private(tile);
-	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
-			      &src_yscale);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glUseProgram(glamor_priv->tile_prog);
-
-	glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
-	dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D,
-				src_pixmap_priv->base.fbo->tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-				  GL_REPEAT);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-				  GL_REPEAT);
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+    int x1 = x;
+    int x2 = x + width;
+    int y1 = y;
+    int y2 = y + height;
+    int tile_x1 = tile_x;
+    int tile_x2 = tile_x + width;
+    int tile_y1 = tile_y;
+    int tile_y2 = tile_y + height;
+    float vertices[8];
+    float source_texcoords[8];
+    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+    glamor_pixmap_private *src_pixmap_priv;
+    glamor_pixmap_private *dst_pixmap_priv;
+    float wh[4];
+
+    src_pixmap_priv = glamor_get_pixmap_private(tile);
+    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glUseProgram(glamor_priv->tile_prog);
+
+    glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
+    dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 #ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	glamor_set_repeat_normalize_tcoords
-			(src_pixmap_priv, RepeatNormal,
-			 src_xscale, src_yscale,
-			 tile_x1, tile_y1,
-			 tile_x2, tile_y2,
-			 glamor_priv->yInverted,
-			 source_texcoords);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-					GL_FLOAT, GL_FALSE,
-					2 * sizeof(float),
-					source_texcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
-				     x1, y1,
-				     x2, y2,
-				     glamor_priv->yInverted, vertices);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glamor_set_repeat_normalize_tcoords
+        (src_pixmap_priv, RepeatNormal,
+         src_xscale, src_yscale,
+         tile_x1, tile_y1,
+         tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                                    GL_FLOAT, GL_FALSE,
+                                    2 * sizeof(float), source_texcoords);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
+                                 x1, y1,
+                                 x2, y2, glamor_priv->yInverted, vertices);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), vertices);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-		dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
 
-	glamor_priv->state = RENDER_STATE;
-	glamor_priv->render_idle_cnt = 0;
+    glamor_priv->state = RENDER_STATE;
+    glamor_priv->render_idle_cnt = 0;
 }
 
 Bool
 glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
-	    int x, int y, int width, int height,
-	    unsigned char alu, unsigned long planemask,
-	    int tile_x, int tile_y)
+            int x, int y, int width, int height,
+            unsigned char alu, unsigned long planemask, int tile_x, int tile_y)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_pixmap_private *dst_pixmap_priv;
-	glamor_pixmap_private *src_pixmap_priv;
-	glamor_gl_dispatch *dispatch;
-
-	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
-	src_pixmap_priv = glamor_get_pixmap_private(tile);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
-		return FALSE;
-
-	if (glamor_priv->tile_prog == 0) {
-		glamor_fallback("Tiling unsupported\n");
-		goto fail;
-	}
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
-		/* XXX dynamic uploading candidate. */
-		glamor_fallback("Non-texture tile pixmap\n");
-		goto fail;
-	}
-
-	if (!glamor_set_planemask(pixmap, planemask)) {
-		glamor_fallback("unsupported planemask %lx\n", planemask);
-		goto fail;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, alu)) {
-		glamor_fallback("unsupported alu %x\n", alu);
-		glamor_put_dispatch(glamor_priv);
-		goto fail;
-	}
-
-	if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-	    || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-			glamor_pixmap_clipped_regions *clipped_dst_regions;
-			int n_dst_region, i, j, k;
-			BoxRec box;
-			RegionRec region;
-
-			box.x1 = x;
-			box.y1 = y;
-			box.x2 = x + width;
-			box.y2 = y + height;
-			RegionInitBoxes(&region, &box, 1);
-			clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
-									     &region, &n_dst_region, 0, 0, 0);
-			for(i = 0; i < n_dst_region; i++)
-			{
-				int n_src_region;
-				glamor_pixmap_clipped_regions *clipped_src_regions;
-				BoxPtr current_boxes;
-				int n_current_boxes;
-
-				SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
-
-				if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-					RegionTranslate(clipped_dst_regions[i].region,
-							tile_x - x, tile_y - y);
-					DEBUGF("tiled a large src pixmap. %dx%d \n", tile->drawable.width, tile->drawable.height);
-					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
-											     clipped_dst_regions[i].region,
-											     &n_src_region, 1, 0, 0);
-					DEBUGF("got %d src regions %d \n", n_src_region);
-					for (j = 0; j < n_src_region; j++)
-					{
-
-						SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
-
-						RegionTranslate(clipped_src_regions[j].region,
-								x - tile_x,
-								y - tile_y);
-						current_boxes = RegionRects(clipped_src_regions[j].region);
-						n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
-						for(k = 0; k < n_current_boxes; k++)
-						{
-							DEBUGF("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
-								     current_boxes[k].x1, current_boxes[k].y1,
-								     current_boxes[k].x2 - current_boxes[k].x1,
-								     current_boxes[k].y2 - current_boxes[k].y1,
-									clipped_dst_regions[i].block_idx,
-									clipped_src_regions[j].block_idx,
-								     (tile_x + (current_boxes[k].x1 - x)),
-								     tile_y + (current_boxes[k].y1 - y));
-
-							_glamor_tile(pixmap, tile,
-								     current_boxes[k].x1, current_boxes[k].y1,
-								     current_boxes[k].x2 - current_boxes[k].x1,
-								     current_boxes[k].y2 - current_boxes[k].y1,
-								     (tile_x + (current_boxes[k].x1 - x)),
-								     (tile_y + (current_boxes[k].y1 - y)));
-						}
-
-						RegionDestroy(clipped_src_regions[j].region);
-					}
-					free(clipped_src_regions);
-				} else {
-					current_boxes = RegionRects(clipped_dst_regions[i].region);
-					n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
-					for(k = 0; k < n_current_boxes; k++)
-					{
-						_glamor_tile(pixmap, tile,
-							     current_boxes[k].x1, current_boxes[k].y1,
-							     current_boxes[k].x2 - current_boxes[k].x1,
-							     current_boxes[k].y2 - current_boxes[k].y1,
-							     (tile_x + (current_boxes[k].x1 - x)),
-							     (tile_y + (current_boxes[k].y1 - y)));
-					}
-				}
-				RegionDestroy(clipped_dst_regions[i].region);
-			}
-			free(clipped_dst_regions);
-			RegionUninit(&region);
-	}
-	else
-		_glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
-
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_put_dispatch(glamor_priv);
-	return TRUE;
-fail:
-	return FALSE;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *dst_pixmap_priv;
+    glamor_pixmap_private *src_pixmap_priv;
+    glamor_gl_dispatch *dispatch;
+
+    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+    src_pixmap_priv = glamor_get_pixmap_private(tile);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
+        return FALSE;
+
+    if (glamor_priv->tile_prog == 0) {
+        glamor_fallback("Tiling unsupported\n");
+        goto fail;
+    }
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+        /* XXX dynamic uploading candidate. */
+        glamor_fallback("Non-texture tile pixmap\n");
+        goto fail;
+    }
+
+    if (!glamor_set_planemask(pixmap, planemask)) {
+        glamor_fallback("unsupported planemask %lx\n", planemask);
+        goto fail;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (!glamor_set_alu(dispatch, alu)) {
+        glamor_fallback("unsupported alu %x\n", alu);
+        glamor_put_dispatch(glamor_priv);
+        goto fail;
+    }
+
+    if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+        || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        glamor_pixmap_clipped_regions *clipped_dst_regions;
+        int n_dst_region, i, j, k;
+        BoxRec box;
+        RegionRec region;
+
+        box.x1 = x;
+        box.y1 = y;
+        box.x2 = x + width;
+        box.y2 = y + height;
+        RegionInitBoxes(&region, &box, 1);
+        clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
+                                                             &region,
+                                                             &n_dst_region, 0,
+                                                             0, 0);
+        for (i = 0; i < n_dst_region; i++) {
+            int n_src_region;
+            glamor_pixmap_clipped_regions *clipped_src_regions;
+            BoxPtr current_boxes;
+            int n_current_boxes;
+
+            SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
+                                   clipped_dst_regions[i].block_idx);
+
+            if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+                RegionTranslate(clipped_dst_regions[i].region,
+                                tile_x - x, tile_y - y);
+                DEBUGF("tiled a large src pixmap. %dx%d \n",
+                       tile->drawable.width, tile->drawable.height);
+                clipped_src_regions =
+                    glamor_compute_clipped_regions(src_pixmap_priv,
+                                                   clipped_dst_regions[i].
+                                                   region, &n_src_region, 1, 0,
+                                                   0);
+                DEBUGF("got %d src regions %d \n", n_src_region);
+                for (j = 0; j < n_src_region; j++) {
+
+                    SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
+                                           clipped_src_regions[j].block_idx);
+
+                    RegionTranslate(clipped_src_regions[j].region,
+                                    x - tile_x, y - tile_y);
+                    current_boxes = RegionRects(clipped_src_regions[j].region);
+                    n_current_boxes =
+                        RegionNumRects(clipped_src_regions[j].region);
+                    for (k = 0; k < n_current_boxes; k++) {
+                        DEBUGF
+                            ("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
+                             current_boxes[k].x1, current_boxes[k].y1,
+                             current_boxes[k].x2 - current_boxes[k].x1,
+                             current_boxes[k].y2 - current_boxes[k].y1,
+                             clipped_dst_regions[i].block_idx,
+                             clipped_src_regions[j].block_idx,
+                             (tile_x + (current_boxes[k].x1 - x)),
+                             tile_y + (current_boxes[k].y1 - y));
+
+                        _glamor_tile(pixmap, tile,
+                                     current_boxes[k].x1, current_boxes[k].y1,
+                                     current_boxes[k].x2 - current_boxes[k].x1,
+                                     current_boxes[k].y2 - current_boxes[k].y1,
+                                     (tile_x + (current_boxes[k].x1 - x)),
+                                     (tile_y + (current_boxes[k].y1 - y)));
+                    }
+
+                    RegionDestroy(clipped_src_regions[j].region);
+                }
+                free(clipped_src_regions);
+            }
+            else {
+                current_boxes = RegionRects(clipped_dst_regions[i].region);
+                n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
+                for (k = 0; k < n_current_boxes; k++) {
+                    _glamor_tile(pixmap, tile,
+                                 current_boxes[k].x1, current_boxes[k].y1,
+                                 current_boxes[k].x2 - current_boxes[k].x1,
+                                 current_boxes[k].y2 - current_boxes[k].y1,
+                                 (tile_x + (current_boxes[k].x1 - x)),
+                                 (tile_y + (current_boxes[k].y1 - y)));
+                }
+            }
+            RegionDestroy(clipped_dst_regions[i].region);
+        }
+        free(clipped_dst_regions);
+        RegionUninit(&region);
+    }
+    else
+        _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
+
+    glamor_set_alu(dispatch, GXcopy);
+    glamor_put_dispatch(glamor_priv);
+    return TRUE;
+ fail:
+    return FALSE;
 
 }
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 76b3729..c7f7a62 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -37,25 +37,27 @@
 #include "fbpict.h"
 
 static xFixed
-_glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil)
+_glamor_linefixedX(xLineFixed * l, xFixed y, Bool ceil)
 {
-	xFixed dx = l->p2.x - l->p1.x;
-	xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
-	xFixed dy = l->p2.y - l->p1.y;
-	if (ceil)
-		ex += (dy - 1);
-	return l->p1.x + (xFixed) (ex / dy);
+    xFixed dx = l->p2.x - l->p1.x;
+    xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed dy = l->p2.y - l->p1.y;
+
+    if (ceil)
+        ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
 }
 
 static xFixed
-_glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
+_glamor_linefixedY(xLineFixed * l, xFixed x, Bool ceil)
 {
-	xFixed dy = l->p2.y - l->p1.y;
-	xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
-	xFixed dx = l->p2.x - l->p1.x;
-	if (ceil)
-		ey += (dx - 1);
-	return l->p1.y + (xFixed) (ey / dx);
+    xFixed dy = l->p2.y - l->p1.y;
+    xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
+    xFixed dx = l->p2.x - l->p1.x;
+
+    if (ceil)
+        ey += (dx - 1);
+    return l->p1.y + (xFixed) (ey / dx);
 }
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
@@ -73,204 +75,206 @@ _glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
      && point[1] <= IntToxFixed(rect->y2))
 
 static xFixed
-_glamor_lines_crossfixedY (xLineFixed *l, xLineFixed *r)
+_glamor_lines_crossfixedY(xLineFixed * l, xLineFixed * r)
 {
-	xFixed dx1 = l->p2.x - l->p1.x;
-	xFixed dx2 = r->p2.x - r->p1.x;
-	xFixed dy1 = l->p2.y - l->p1.y;
-	xFixed dy2 = r->p2.y - r->p1.y;
-	xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1;
-	xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x);
-	xFixed_32_32 dividend2;
-	xFixed_32_32 dividend3;
-	xFixed_32_32 divisor;
-
-	tmp = (xFixed_32_32) dx1 * dy2;
-	dividend2 = (tmp >> 32) * l->p1.y;
-	tmp = (xFixed_32_32) dy1 * dx2;
-	dividend3 = (tmp >> 32) * r->p1.y;
-	divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
-	            - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
-
-	if (divisor)
-		return (xFixed)((dividend2 - dividend1 - dividend3) / divisor);
-
-	return 0xFFFFFFFF;
-}
+    xFixed dx1 = l->p2.x - l->p1.x;
+    xFixed dx2 = r->p2.x - r->p1.x;
+    xFixed dy1 = l->p2.y - l->p1.y;
+    xFixed dy2 = r->p2.y - r->p1.y;
+    xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1;
+    xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x);
+    xFixed_32_32 dividend2;
+    xFixed_32_32 dividend3;
+    xFixed_32_32 divisor;
 
-static Bool
-point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
-{
-	int ret = TRUE;
-	int tmp;
-	if (point[1] > trap->bottom) {
-		ret = FALSE;
-		if (DEBUG_CLIP_VTX) {
-			ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), "
-			       "bottom = %d(0x%x)\n",
-			       (unsigned int)xFixedToInt(point[1]), point[1],
-			       (unsigned int)xFixedToInt(trap->bottom),
-			       (unsigned int)trap->bottom);
-		}
-
-		return ret;
-	}
+    tmp = (xFixed_32_32) dx1 *dy2;
 
-	if (point[1] < trap->top) {
-		ret = FALSE;
-		if (DEBUG_CLIP_VTX) {
-			ErrorF("Out of Trap top, point[1] = %d(0x%x)), "
-			       "top = %d(0x%x)\n",
-			       (unsigned int)xFixedToInt(point[1]), point[1],
-			       (unsigned int)xFixedToInt(trap->top),
-			       (unsigned int)trap->top);
-		}
-
-		return ret;
-	}
+    dividend2 = (tmp >> 32) * l->p1.y;
+    tmp = (xFixed_32_32) dy1 *dx2;
 
-	tmp = _glamor_linefixedX (&trap->left, point[1], FALSE);
-	if (point[0] < tmp) {
-		ret = FALSE;
-
-		if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
-		           abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
-		           tmp - point[0] < pixman_fixed_1_minus_e) {
-			ret = TRUE;
-		} else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
-		           point[1] - trap->bottom < pixman_fixed_1_minus_e &&
-		           tmp - point[0] < pixman_fixed_1_minus_e) {
-			ret = TRUE;
-		}
-
-		if (DEBUG_CLIP_VTX && !ret) {
-			ErrorF("Out of Trap left, point[0] = %d(0x%x)), "
-			       "left = %d(0x%x)\n",
-			       (unsigned int)xFixedToInt(point[0]), point[0],
-			       (unsigned int)xFixedToInt(tmp), (unsigned int)tmp);
-		}
-
-		if (!ret)
-			return ret;
-	}
+    dividend3 = (tmp >> 32) * r->p1.y;
+    divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
+               - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
 
-	tmp = _glamor_linefixedX (&trap->right, point[1], TRUE);
-	if (point[0] > tmp) {
-		ret = FALSE;
-
-		if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
-		           abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
-		           point[0] - tmp < pixman_fixed_1_minus_e) {
-			ret = TRUE;
-		} else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
-		           abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e &&
-		           point[0] - tmp < pixman_fixed_1_minus_e) {
-			ret = TRUE;
-		}
-
-		if (DEBUG_CLIP_VTX && !ret) {
-			ErrorF("Out of Trap right, point[0] = %d(0x%x)), "
-			       "right = %d(0x%x)\n",
-			       (unsigned int)xFixedToInt(point[0]), point[0],
-			       (unsigned int)xFixedToInt(tmp), (unsigned int)tmp);
-		}
-
-		if (!ret)
-			return ret;
-	}
+    if (divisor)
+        return (xFixed) ((dividend2 - dividend1 - dividend3) / divisor);
 
-	return ret;
+    return 0xFFFFFFFF;
+}
+
+static Bool
+point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
+{
+    int ret = TRUE;
+    int tmp;
+
+    if (point[1] > trap->bottom) {
+        ret = FALSE;
+        if (DEBUG_CLIP_VTX) {
+            ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), "
+                   "bottom = %d(0x%x)\n",
+                   (unsigned int) xFixedToInt(point[1]), point[1],
+                   (unsigned int) xFixedToInt(trap->bottom),
+                   (unsigned int) trap->bottom);
+        }
+
+        return ret;
+    }
+
+    if (point[1] < trap->top) {
+        ret = FALSE;
+        if (DEBUG_CLIP_VTX) {
+            ErrorF("Out of Trap top, point[1] = %d(0x%x)), "
+                   "top = %d(0x%x)\n",
+                   (unsigned int) xFixedToInt(point[1]), point[1],
+                   (unsigned int) xFixedToInt(trap->top),
+                   (unsigned int) trap->top);
+        }
+
+        return ret;
+    }
+
+    tmp = _glamor_linefixedX(&trap->left, point[1], FALSE);
+    if (point[0] < tmp) {
+        ret = FALSE;
+
+        if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
+            abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
+            tmp - point[0] < pixman_fixed_1_minus_e) {
+            ret = TRUE;
+        }
+        else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
+                 point[1] - trap->bottom < pixman_fixed_1_minus_e &&
+                 tmp - point[0] < pixman_fixed_1_minus_e) {
+            ret = TRUE;
+        }
+
+        if (DEBUG_CLIP_VTX && !ret) {
+            ErrorF("Out of Trap left, point[0] = %d(0x%x)), "
+                   "left = %d(0x%x)\n",
+                   (unsigned int) xFixedToInt(point[0]), point[0],
+                   (unsigned int) xFixedToInt(tmp), (unsigned int) tmp);
+        }
+
+        if (!ret)
+            return ret;
+    }
+
+    tmp = _glamor_linefixedX(&trap->right, point[1], TRUE);
+    if (point[0] > tmp) {
+        ret = FALSE;
+
+        if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
+            abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
+            point[0] - tmp < pixman_fixed_1_minus_e) {
+            ret = TRUE;
+        }
+        else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
+                 abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e &&
+                 point[0] - tmp < pixman_fixed_1_minus_e) {
+            ret = TRUE;
+        }
+
+        if (DEBUG_CLIP_VTX && !ret) {
+            ErrorF("Out of Trap right, point[0] = %d(0x%x)), "
+                   "right = %d(0x%x)\n",
+                   (unsigned int) xFixedToInt(point[0]), point[0],
+                   (unsigned int) xFixedToInt(tmp), (unsigned int) tmp);
+        }
+
+        if (!ret)
+            return ret;
+    }
+
+    return ret;
 }
 
 static void
 glamor_emit_composite_triangle(ScreenPtr screen,
-        const float *src_coords,
-        const float *mask_coords,
-        const float *dst_coords)
+                               const float *src_coords,
+                               const float *mask_coords,
+                               const float *dst_coords)
 {
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-	        dst_coords, 0);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-	        dst_coords, 1);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-	        dst_coords, 2);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
 }
 
 static void
 glamor_flush_composite_triangles(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-	else {
-
-		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-		        glamor_priv->vbo_offset,
-		        glamor_priv->vb, GL_DYNAMIC_DRAW);
-	}
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+        dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+    else {
 
-	if (!glamor_priv->render_nr_verts)
-		return;
+        dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+        dispatch->glBufferData(GL_ARRAY_BUFFER,
+                               glamor_priv->vbo_offset,
+                               glamor_priv->vb, GL_DYNAMIC_DRAW);
+    }
 
-	dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
-	glamor_put_dispatch(glamor_priv);
+    if (!glamor_priv->render_nr_verts)
+        return;
+
+    dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
 _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
-        int vertex[6], int *num)
+                              int vertex[6], int *num)
 {
-	xFixed edge_cross_y = 0xFFFFFFFF;
-	int tl[2];
-	int bl[2];
-	int tr[2];
-	int br[2];
-	int left_cut_top[2];
-	int left_cut_left[2];
-	int left_cut_right[2];
-	int left_cut_bottom[2];
-	int right_cut_top[2];
-	int right_cut_left[2];
-	int right_cut_right[2];
-	int right_cut_bottom[2];
-	int tmp[2];
-	int tmp_vtx[20*2];
-	float tmp_vtx_slope[20];
-	BoxRec trap_bound;
-	int i = 0;
-	int vertex_num = 0;
-
-	if (DEBUG_CLIP_VTX) {
-		ErrorF("The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
-		       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
-		       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
-		       xFixedToInt(trap->top), (unsigned int)trap->top,
-		       xFixedToInt(trap->bottom), (unsigned int)trap->bottom,
-		       xFixedToInt(trap->left.p1.x), (unsigned int)trap->left.p1.x,
-		       xFixedToInt(trap->left.p1.y), (unsigned int)trap->left.p1.y,
-		       xFixedToInt(trap->left.p2.x), (unsigned int)trap->left.p2.x,
-		       xFixedToInt(trap->left.p2.y), (unsigned int)trap->left.p2.y,
-		       xFixedToInt(trap->right.p1.x), (unsigned int)trap->right.p1.x,
-		       xFixedToInt(trap->right.p1.y), (unsigned int)trap->right.p1.y,
-		       xFixedToInt(trap->right.p2.x), (unsigned int)trap->right.p2.x,
-		       xFixedToInt(trap->right.p2.y), (unsigned int)trap->right.p2.y);
-	}
-
-	miTrapezoidBounds(1, trap, &trap_bound);
-	if (DEBUG_CLIP_VTX)
-		ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, "
-		       "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2,
-		       trap_bound.y1, trap_bound.y2);
-
-	if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1)
-		return FALSE;
-	if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1)
-		return FALSE;
+    xFixed edge_cross_y = 0xFFFFFFFF;
+    int tl[2];
+    int bl[2];
+    int tr[2];
+    int br[2];
+    int left_cut_top[2];
+    int left_cut_left[2];
+    int left_cut_right[2];
+    int left_cut_bottom[2];
+    int right_cut_top[2];
+    int right_cut_left[2];
+    int right_cut_right[2];
+    int right_cut_bottom[2];
+    int tmp[2];
+    int tmp_vtx[20 * 2];
+    float tmp_vtx_slope[20];
+    BoxRec trap_bound;
+    int i = 0;
+    int vertex_num = 0;
+
+    if (DEBUG_CLIP_VTX) {
+        ErrorF
+            ("The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
+             "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
+             "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
+             xFixedToInt(trap->top), (unsigned int) trap->top,
+             xFixedToInt(trap->bottom), (unsigned int) trap->bottom,
+             xFixedToInt(trap->left.p1.x), (unsigned int) trap->left.p1.x,
+             xFixedToInt(trap->left.p1.y), (unsigned int) trap->left.p1.y,
+             xFixedToInt(trap->left.p2.x), (unsigned int) trap->left.p2.x,
+             xFixedToInt(trap->left.p2.y), (unsigned int) trap->left.p2.y,
+             xFixedToInt(trap->right.p1.x), (unsigned int) trap->right.p1.x,
+             xFixedToInt(trap->right.p1.y), (unsigned int) trap->right.p1.y,
+             xFixedToInt(trap->right.p2.x), (unsigned int) trap->right.p2.x,
+             xFixedToInt(trap->right.p2.y), (unsigned int) trap->right.p2.y);
+    }
+
+    miTrapezoidBounds(1, trap, &trap_bound);
+    if (DEBUG_CLIP_VTX)
+        ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, "
+               "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2,
+               trap_bound.y1, trap_bound.y2);
+
+    if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1)
+        return FALSE;
+    if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1)
+        return FALSE;
 
 #define IS_TRAP_EDGE_VERTICAL(edge)		\
 	(edge->p1.x == edge->p2.x)
@@ -334,1319 +338,1347 @@ _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
 		       "the Rect\n");				\
 	}
 
-	/*Trap's right edge cut right edge. */
-	if((!IS_TRAP_EDGE_VERTICAL((&trap->left))) ||
-	        (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) {
-		edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right));
-		if (DEBUG_CLIP_VTX) {
-			ErrorF("Trap's left edge cut right edge at %d(0x%x), "
-			       "trap_top = %x, trap_bottom = %x\n",
-			       xFixedToInt(edge_cross_y), edge_cross_y,
-			       (unsigned int)trap->top, (unsigned int)trap->bottom);
-		}
-	}
-
-	/*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */
-	CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left));
-	CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left));
-	CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right));
-	CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right));
-
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n");
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Caculate the vertex of trapezoid:\n"
-		       "      (%3d, %3d)-------------------------(%3d, %3d)\n"
-		       "              /                           \\       \n"
-		       "             /                             \\      \n"
-		       "            /                               \\     \n"
-		       "  (%3d, %3d)---------------------------------(%3d, %3d)\n"
-		       "Clip with rect:\n"
-		       "  (%3d, %3d)------------------------(%3d, %3d)    \n"
-		       "           |                        |             \n"
-		       "           |                        |             \n"
-		       "           |                        |             \n"
-		       "  (%3d, %3d)------------------------(%3d, %3d)    \n",
-		       xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]),
-		       xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]),
-		       xFixedToInt(br[0]), xFixedToInt(br[1]),
-		       pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2,
-		       pbox->x2, pbox->y2);
-
-	ADD_VERTEX_IF_INSIDE(tl);
-	ADD_VERTEX_IF_INSIDE(bl);
-	ADD_VERTEX_IF_INSIDE(tr);
-	ADD_VERTEX_IF_INSIDE(br);
-
-	/*Trap's left edge cut Rect. */
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Trap's left edge cut Rect\n");
-	CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1), (&trap->left));
-	ADD_VERTEX_IF_INSIDE(left_cut_top);
-	if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
-		CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1), (&trap->left));
-		ADD_VERTEX_IF_INSIDE(left_cut_left);
-	}
-	CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2), (&trap->left));
-	ADD_VERTEX_IF_INSIDE(left_cut_bottom);
-	if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
-		CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2), (&trap->left));
-		ADD_VERTEX_IF_INSIDE(left_cut_right);
-	}
-
-	/*Trap's right edge cut Rect. */
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Trap's right edge cut Rect\n");
-	CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1), (&trap->right));
-	ADD_VERTEX_IF_INSIDE(right_cut_top);
-	if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
-		CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1), (&trap->right));
-		ADD_VERTEX_IF_INSIDE(right_cut_left);
-	}
-	CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2), (&trap->right));
-	ADD_VERTEX_IF_INSIDE(right_cut_bottom);
-	if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
-		CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2), (&trap->right));
-		ADD_VERTEX_IF_INSIDE(right_cut_right);
-	}
-
-	/* Trap's top cut Left and Right of rect. */
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Trap's top cut Left and Right of rect\n");
-	tmp[0] = IntToxFixed(pbox->x1);
-	tmp[1] = trap->top;
-	ADD_VERTEX_IF_INSIDE(tmp);
-	tmp[0] = IntToxFixed(pbox->x2);
-	tmp[1] = trap->top;
-	ADD_VERTEX_IF_INSIDE(tmp);
-
-	/* Trap's bottom cut Left and Right of rect. */
-	if (DEBUG_CLIP_VTX)
-		ErrorF("Trap's bottom cut Left and Right of rect\n");
-	tmp[0] = IntToxFixed(pbox->x1);
-	tmp[1] = trap->bottom;
-	ADD_VERTEX_IF_INSIDE(tmp);
-	tmp[0] = IntToxFixed(pbox->x2);
-	tmp[1] = trap->bottom;
-	ADD_VERTEX_IF_INSIDE(tmp);
-
-	/* The orginal 4 vertex of rect. */
-	if (DEBUG_CLIP_VTX)
-		ErrorF("The orginal 4 vertex of rect\n");
-	tmp[0] = IntToxFixed(pbox->x1);
-	tmp[1] = IntToxFixed(pbox->y1);
-	ADD_VERTEX_IF_INSIDE(tmp);
-	tmp[0] = IntToxFixed(pbox->x1);
-	tmp[1] = IntToxFixed(pbox->y2);
-	ADD_VERTEX_IF_INSIDE(tmp);
-	tmp[0] = IntToxFixed(pbox->x2);
-	tmp[1] = IntToxFixed(pbox->y2);
-	ADD_VERTEX_IF_INSIDE(tmp);
-	tmp[0] = IntToxFixed(pbox->x2);
-	tmp[1] = IntToxFixed(pbox->y1);
-	ADD_VERTEX_IF_INSIDE(tmp);
-
-	if (DEBUG_CLIP_VTX) {
-		ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2);
-		for (i = 0; i < vertex_num / 2; i++) {
-			ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]);
-		}
-		ErrorF("\n");
-	}
-
-	/* Sort the vertex by X and then Y. */
-	for (i = 0; i < vertex_num / 2; i++) {
-		int j;
-		for (j = 0; j < vertex_num / 2 - i - 1; j++) {
-			if (tmp_vtx[2*j] > tmp_vtx[2*(j+1)]
-			     || (tmp_vtx[2*j] == tmp_vtx[2*(j+1)]
-			         && tmp_vtx[2*j + 1] > tmp_vtx[2*(j+1) + 1])) {
-				tmp[0] = tmp_vtx[2*j];
-				tmp[1] = tmp_vtx[2*j + 1];
-				tmp_vtx[2*j] = tmp_vtx[2*(j+1)];
-				tmp_vtx[2*j + 1] = tmp_vtx[2*(j+1) + 1];
-				tmp_vtx[2*(j+1)] = tmp[0];
-				tmp_vtx[2*(j+1) + 1] = tmp[1];
-			}
-		}
-
-	}
-
-	if (DEBUG_CLIP_VTX) {
-		ErrorF("\nAfter sort vertex number is:\n");
-		for (i = 0; i < vertex_num / 2; i++) {
-			ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]);
-		}
-		ErrorF("\n");
-	}
-
-	memset(vertex, -1, 2*6);
-	*num = 0;
-
-	for (i = 0; i < vertex_num / 2; i++) {
-		if (*num > 0 && vertex[2*(*num - 1)] == tmp_vtx[2*i]
-		     && vertex[2*(*num - 1) + 1] == tmp_vtx[2*i + 1]) {
-			/*same vertex.*/
-			if (DEBUG_CLIP_VTX)
-				ErrorF("X Point:(%d, %d) discard\n",
-				       tmp_vtx[2*i], tmp_vtx[2*i + 1]);
-			continue;
-		}
-
-		(*num)++;
-		if (*num > 6) {
-			if (DEBUG_CLIP_VTX)
-				FatalError("Trapezoid clip with Rect can never have vtx"
-				           "number bigger than 6\n");
-			else {
-				ErrorF("Trapezoid clip with Rect can never have vtx"
-				       "number bigger than 6\n");
-				*num = 6;
-				break;
-			}
-		}
-
-		vertex[2*(*num - 1)] = tmp_vtx[2*i];
-		vertex[2*(*num - 1) + 1] = tmp_vtx[2*i + 1];
-		if (DEBUG_CLIP_VTX)
-			ErrorF("@ Point:(%d, %d) select, num now is %d\n",
-			       tmp_vtx[2*i], tmp_vtx[2*i + 1], *num);
-	}
-
-	/* Now we need to arrange the vtx in the polygon's counter-clockwise
-	order. We first select the left and top point as the start point and
-	sort every vtx by the slope from vtx to the start vtx. */
-	for (i = 1; i < *num; i++) {
-		tmp_vtx_slope[i] = (vertex[2*i] != vertex[0] ?
-		                    (float)(vertex[2*i + 1] - vertex[1]) / (float)(vertex[2*i] - vertex[0])
-		                    : (float)INT_MAX);
-	}
-
-	if (DEBUG_CLIP_VTX) {
-		ErrorF("\nvtx number: %d, VTX and slope:\n", *num);
-		for (i = 0; i < *num; i++) {
-			ErrorF("(%d, %d):%f ",
-			       vertex[2*i], vertex[2*i + 1],
-			       tmp_vtx_slope[i]);
-		}
-		ErrorF("\n");
-	}
-
-	/* Sort the vertex by slope. */
-	for (i = 0; i < *num - 1; i++) {
-		int j;
-		float tmp_slope;
-		for (j = 1; j < *num - i - 1; j++) {
-			if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) {
-				tmp_slope = tmp_vtx_slope[j];
-				tmp_vtx_slope[j] = tmp_vtx_slope[j + 1];
-				tmp_vtx_slope[j + 1] = tmp_slope;
-				tmp[0] = vertex[2*j];
-				tmp[1] = vertex[2*j + 1];
-				vertex[2*j] = vertex[2*(j+1)];
-				vertex[2*j + 1] = vertex[2*(j+1) + 1];
-				vertex[2*(j+1)] = tmp[0];
-				vertex[2*(j+1) + 1] = tmp[1];
-			}
-		}
-	}
-
-	if (DEBUG_CLIP_VTX) {
-		ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num);
-		for (i = 0; i < *num; i++) {
-			ErrorF("(%d, %d):%f ",
-			       vertex[2*i], vertex[2*i + 1],
-			       tmp_vtx_slope[i]);
-		}
-		ErrorF("\n");
-	}
-
-	return TRUE;
+    /*Trap's right edge cut right edge. */
+    if ((!IS_TRAP_EDGE_VERTICAL((&trap->left))) ||
+        (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) {
+        edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right));
+        if (DEBUG_CLIP_VTX) {
+            ErrorF("Trap's left edge cut right edge at %d(0x%x), "
+                   "trap_top = %x, trap_bottom = %x\n",
+                   xFixedToInt(edge_cross_y), edge_cross_y,
+                   (unsigned int) trap->top, (unsigned int) trap->bottom);
+        }
+    }
+
+    /*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */
+    CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left));
+    CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left));
+    CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right));
+    CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right));
+
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n");
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Caculate the vertex of trapezoid:\n"
+               "      (%3d, %3d)-------------------------(%3d, %3d)\n"
+               "              /                           \\       \n"
+               "             /                             \\      \n"
+               "            /                               \\     \n"
+               "  (%3d, %3d)---------------------------------(%3d, %3d)\n"
+               "Clip with rect:\n"
+               "  (%3d, %3d)------------------------(%3d, %3d)    \n"
+               "           |                        |             \n"
+               "           |                        |             \n"
+               "           |                        |             \n"
+               "  (%3d, %3d)------------------------(%3d, %3d)    \n",
+               xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]),
+               xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]),
+               xFixedToInt(br[0]), xFixedToInt(br[1]),
+               pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2,
+               pbox->x2, pbox->y2);
+
+    ADD_VERTEX_IF_INSIDE(tl);
+    ADD_VERTEX_IF_INSIDE(bl);
+    ADD_VERTEX_IF_INSIDE(tr);
+    ADD_VERTEX_IF_INSIDE(br);
+
+    /*Trap's left edge cut Rect. */
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Trap's left edge cut Rect\n");
+    CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1),
+                        (&trap->left));
+    ADD_VERTEX_IF_INSIDE(left_cut_top);
+    if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
+        CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1),
+                            (&trap->left));
+        ADD_VERTEX_IF_INSIDE(left_cut_left);
+    }
+    CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2),
+                        (&trap->left));
+    ADD_VERTEX_IF_INSIDE(left_cut_bottom);
+    if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
+        CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2),
+                            (&trap->left));
+        ADD_VERTEX_IF_INSIDE(left_cut_right);
+    }
+
+    /*Trap's right edge cut Rect. */
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Trap's right edge cut Rect\n");
+    CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1),
+                        (&trap->right));
+    ADD_VERTEX_IF_INSIDE(right_cut_top);
+    if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
+        CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1),
+                            (&trap->right));
+        ADD_VERTEX_IF_INSIDE(right_cut_left);
+    }
+    CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2),
+                        (&trap->right));
+    ADD_VERTEX_IF_INSIDE(right_cut_bottom);
+    if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
+        CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2),
+                            (&trap->right));
+        ADD_VERTEX_IF_INSIDE(right_cut_right);
+    }
+
+    /* Trap's top cut Left and Right of rect. */
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Trap's top cut Left and Right of rect\n");
+    tmp[0] = IntToxFixed(pbox->x1);
+    tmp[1] = trap->top;
+    ADD_VERTEX_IF_INSIDE(tmp);
+    tmp[0] = IntToxFixed(pbox->x2);
+    tmp[1] = trap->top;
+    ADD_VERTEX_IF_INSIDE(tmp);
+
+    /* Trap's bottom cut Left and Right of rect. */
+    if (DEBUG_CLIP_VTX)
+        ErrorF("Trap's bottom cut Left and Right of rect\n");
+    tmp[0] = IntToxFixed(pbox->x1);
+    tmp[1] = trap->bottom;
+    ADD_VERTEX_IF_INSIDE(tmp);
+    tmp[0] = IntToxFixed(pbox->x2);
+    tmp[1] = trap->bottom;
+    ADD_VERTEX_IF_INSIDE(tmp);
+
+    /* The orginal 4 vertex of rect. */
+    if (DEBUG_CLIP_VTX)
+        ErrorF("The orginal 4 vertex of rect\n");
+    tmp[0] = IntToxFixed(pbox->x1);
+    tmp[1] = IntToxFixed(pbox->y1);
+    ADD_VERTEX_IF_INSIDE(tmp);
+    tmp[0] = IntToxFixed(pbox->x1);
+    tmp[1] = IntToxFixed(pbox->y2);
+    ADD_VERTEX_IF_INSIDE(tmp);
+    tmp[0] = IntToxFixed(pbox->x2);
+    tmp[1] = IntToxFixed(pbox->y2);
+    ADD_VERTEX_IF_INSIDE(tmp);
+    tmp[0] = IntToxFixed(pbox->x2);
+    tmp[1] = IntToxFixed(pbox->y1);
+    ADD_VERTEX_IF_INSIDE(tmp);
+
+    if (DEBUG_CLIP_VTX) {
+        ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2);
+        for (i = 0; i < vertex_num / 2; i++) {
+            ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
+        }
+        ErrorF("\n");
+    }
+
+    /* Sort the vertex by X and then Y. */
+    for (i = 0; i < vertex_num / 2; i++) {
+        int j;
+
+        for (j = 0; j < vertex_num / 2 - i - 1; j++) {
+            if (tmp_vtx[2 * j] > tmp_vtx[2 * (j + 1)]
+                || (tmp_vtx[2 * j] == tmp_vtx[2 * (j + 1)]
+                    && tmp_vtx[2 * j + 1] > tmp_vtx[2 * (j + 1) + 1])) {
+                tmp[0] = tmp_vtx[2 * j];
+                tmp[1] = tmp_vtx[2 * j + 1];
+                tmp_vtx[2 * j] = tmp_vtx[2 * (j + 1)];
+                tmp_vtx[2 * j + 1] = tmp_vtx[2 * (j + 1) + 1];
+                tmp_vtx[2 * (j + 1)] = tmp[0];
+                tmp_vtx[2 * (j + 1) + 1] = tmp[1];
+            }
+        }
+
+    }
+
+    if (DEBUG_CLIP_VTX) {
+        ErrorF("\nAfter sort vertex number is:\n");
+        for (i = 0; i < vertex_num / 2; i++) {
+            ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
+        }
+        ErrorF("\n");
+    }
+
+    memset(vertex, -1, 2 * 6);
+    *num = 0;
+
+    for (i = 0; i < vertex_num / 2; i++) {
+        if (*num > 0 && vertex[2 * (*num - 1)] == tmp_vtx[2 * i]
+            && vertex[2 * (*num - 1) + 1] == tmp_vtx[2 * i + 1]) {
+            /*same vertex. */
+            if (DEBUG_CLIP_VTX)
+                ErrorF("X Point:(%d, %d) discard\n",
+                       tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
+            continue;
+        }
+
+        (*num)++;
+        if (*num > 6) {
+            if (DEBUG_CLIP_VTX)
+                FatalError("Trapezoid clip with Rect can never have vtx"
+                           "number bigger than 6\n");
+            else {
+                ErrorF("Trapezoid clip with Rect can never have vtx"
+                       "number bigger than 6\n");
+                *num = 6;
+                break;
+            }
+        }
+
+        vertex[2 * (*num - 1)] = tmp_vtx[2 * i];
+        vertex[2 * (*num - 1) + 1] = tmp_vtx[2 * i + 1];
+        if (DEBUG_CLIP_VTX)
+            ErrorF("@ Point:(%d, %d) select, num now is %d\n",
+                   tmp_vtx[2 * i], tmp_vtx[2 * i + 1], *num);
+    }
+
+    /* Now we need to arrange the vtx in the polygon's counter-clockwise
+       order. We first select the left and top point as the start point and
+       sort every vtx by the slope from vtx to the start vtx. */
+    for (i = 1; i < *num; i++) {
+        tmp_vtx_slope[i] = (vertex[2 * i] != vertex[0] ?
+                            (float) (vertex[2 * i + 1] -
+                                     vertex[1]) / (float) (vertex[2 * i] -
+                                                           vertex[0])
+                            : (float) INT_MAX);
+    }
+
+    if (DEBUG_CLIP_VTX) {
+        ErrorF("\nvtx number: %d, VTX and slope:\n", *num);
+        for (i = 0; i < *num; i++) {
+            ErrorF("(%d, %d):%f ",
+                   vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]);
+        }
+        ErrorF("\n");
+    }
+
+    /* Sort the vertex by slope. */
+    for (i = 0; i < *num - 1; i++) {
+        int j;
+        float tmp_slope;
+
+        for (j = 1; j < *num - i - 1; j++) {
+            if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) {
+                tmp_slope = tmp_vtx_slope[j];
+                tmp_vtx_slope[j] = tmp_vtx_slope[j + 1];
+                tmp_vtx_slope[j + 1] = tmp_slope;
+                tmp[0] = vertex[2 * j];
+                tmp[1] = vertex[2 * j + 1];
+                vertex[2 * j] = vertex[2 * (j + 1)];
+                vertex[2 * j + 1] = vertex[2 * (j + 1) + 1];
+                vertex[2 * (j + 1)] = tmp[0];
+                vertex[2 * (j + 1) + 1] = tmp[1];
+            }
+        }
+    }
+
+    if (DEBUG_CLIP_VTX) {
+        ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num);
+        for (i = 0; i < *num; i++) {
+            ErrorF("(%d, %d):%f ",
+                   vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]);
+        }
+        ErrorF("\n");
+    }
+
+    return TRUE;
 }
 
 static void
 glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-	int stride;
-	int vert_size;
-
-	glamor_priv->render_nr_verts = 0;
-
-	/* For GLAMOR_VERTEX_POS */
-	glamor_priv->vb_stride = 2 * sizeof(float);
-
-	/* For GLAMOR_GLAMOR_VERTEX_SOURCE */
-	glamor_priv->vb_stride += 2 * sizeof(float);
-
-	/* For GLAMOR_VERTEX_TOP_BOTTOM */
-	glamor_priv->vb_stride += 2 * sizeof(float);
-
-	/* For GLAMOR_VERTEX_LEFT_PARAM */
-	glamor_priv->vb_stride += 4 * sizeof(float);
-
-	/* For GLAMOR_VERTEX_RIGHT_PARAM */
-	glamor_priv->vb_stride += 4 * sizeof(float);
-
-	vert_size = n_verts * glamor_priv->vb_stride;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
-			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
-				glamor_priv->vb_stride;
-			glamor_priv->vbo_offset = 0;
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-					       glamor_priv->vbo_size,
-					       NULL, GL_STREAM_DRAW);
-		}
-
-		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
-		                                             glamor_priv->vbo_offset,
-		                                             vert_size,
-		                                             GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
-
-		assert(glamor_priv->vb != NULL);
-		glamor_priv->vb -= glamor_priv->vbo_offset;
-	} else {
-		glamor_priv->vbo_offset = 0;
-	}
-
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
-	/* Set the vertex pointer. */
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	stride = 2;
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	stride += 2;
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
-	stride += 2;
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
-	stride += 4;
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
-	        GL_FALSE, glamor_priv->vb_stride,
-	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch;
+    int stride;
+    int vert_size;
+
+    glamor_priv->render_nr_verts = 0;
+
+    /* For GLAMOR_VERTEX_POS */
+    glamor_priv->vb_stride = 2 * sizeof(float);
+
+    /* For GLAMOR_GLAMOR_VERTEX_SOURCE */
+    glamor_priv->vb_stride += 2 * sizeof(float);
+
+    /* For GLAMOR_VERTEX_TOP_BOTTOM */
+    glamor_priv->vb_stride += 2 * sizeof(float);
+
+    /* For GLAMOR_VERTEX_LEFT_PARAM */
+    glamor_priv->vb_stride += 4 * sizeof(float);
+
+    /* For GLAMOR_VERTEX_RIGHT_PARAM */
+    glamor_priv->vb_stride += 4 * sizeof(float);
+
+    vert_size = n_verts * glamor_priv->vb_stride;
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+        if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
+            glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
+                glamor_priv->vb_stride;
+            glamor_priv->vbo_offset = 0;
+            dispatch->glBufferData(GL_ARRAY_BUFFER,
+                                   glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
+        }
+
+        glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+                                                     glamor_priv->vbo_offset,
+                                                     vert_size,
+                                                     GL_MAP_WRITE_BIT |
+                                                     GL_MAP_UNSYNCHRONIZED_BIT);
+
+        assert(glamor_priv->vb != NULL);
+        glamor_priv->vb -= glamor_priv->vbo_offset;
+    }
+    else {
+        glamor_priv->vbo_offset = 0;
+    }
+
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+    /* Set the vertex pointer. */
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long) glamor_priv->vbo_offset));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    stride = 2;
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long) glamor_priv->vbo_offset +
+                                              stride * sizeof(float)));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    stride += 2;
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long) glamor_priv->vbo_offset +
+                                              stride * sizeof(float)));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    stride += 2;
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long) glamor_priv->vbo_offset +
+                                              stride * sizeof(float)));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    stride += 4;
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
+                                    GL_FALSE, glamor_priv->vb_stride,
+                                    (void *) ((long) glamor_priv->vbo_offset +
+                                              stride * sizeof(float)));
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
 _glamor_trapezoids_with_shader(CARD8 op,
-        PicturePtr src, PicturePtr dst,
-        PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-        int ntrap, xTrapezoid * traps)
+                               PicturePtr src, PicturePtr dst,
+                               PictFormatPtr mask_format, INT16 x_src,
+                               INT16 y_src, int ntrap, xTrapezoid * traps)
 {
-	ScreenPtr screen = dst->pDrawable->pScreen;
-	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-	struct shader_key key;
-	glamor_composite_shader *shader = NULL;
-	struct blendinfo op_info;
-	PictFormatShort saved_source_format = 0;
-	PixmapPtr source_pixmap = NULL;
-	PixmapPtr dest_pixmap = NULL;
-	glamor_pixmap_private *source_pixmap_priv = NULL;
-	glamor_pixmap_private *dest_pixmap_priv = NULL;
-	glamor_pixmap_private *temp_src_priv = NULL;
-	int x_temp_src, y_temp_src;
-	int src_width, src_height;
-	int source_x_off, source_y_off;
-	GLfloat src_xscale = 1, src_yscale = 1;
-	int x_dst, y_dst;
-	int dest_x_off, dest_y_off;
-	GLfloat dst_xscale, dst_yscale;
-	BoxRec bounds;
-	PicturePtr temp_src = src;
-	glamor_gl_dispatch *dispatch = NULL;
-	int vert_stride = 3;
-	int ntriangle_per_loop;
-	int nclip_rect;
-	int mclip_rect;
-	int clip_processed;
-	int clipped_vtx[6*2];
-	RegionRec region;
-	BoxPtr box = NULL;
-	BoxPtr pbox = NULL;
-	int traps_count = 0;
-	int traps_not_completed = 0;
-	xTrapezoid * ptrap = NULL;
-	int nbox;
-	float src_matrix[9];
-	Bool ret = FALSE;
-
-	/* If a mask format wasn't provided, we get to choose, but behavior should
-	 * be as if there was no temporary mask the traps were accumulated into.
-	 */
-	if (!mask_format) {
-		if (dst->polyEdge == PolyEdgeSharp)
-			mask_format = PictureMatchFormat(screen, 1, PICT_a1);
-		else
-			mask_format = PictureMatchFormat(screen, 8, PICT_a8);
-		for (; ntrap; ntrap--, traps++)
-			glamor_trapezoids(op, src, dst, mask_format, x_src,
-			                  y_src, 1, traps);
-		return TRUE;
-	}
-
-	miTrapezoidBounds(ntrap, traps, &bounds);
-	DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
-	       "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2,
-	       bounds.y1, bounds.y2);
-
-	/* No area need to render. */
-	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-		return TRUE;
-
-	dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)
-	    || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-		/* Currently. Always fallback to cpu if destination is in CPU memory.*/
-		ret = FALSE;
-		DEBUGF("dst pixmap has no FBO.\n");
-		goto TRAPEZOID_OUT;
-	}
-
-	if (src->pDrawable) {
-		source_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
-		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		temp_src_priv = source_pixmap_priv;
-		if (source_pixmap_priv
-		    && (source_pixmap_priv->type == GLAMOR_DRM_ONLY
-		       || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) {
-			ret = FALSE;
-			goto TRAPEZOID_OUT;
-		}
-	}
-
-	x_dst = bounds.x1;
-	y_dst = bounds.y1;
-
-	src_width = bounds.x2 - bounds.x1;
-	src_height = bounds.y2 - bounds.y1;
-
-	x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16);
-	y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16);
-
-	if ((!src->pDrawable &&
-	     (src->pSourcePict->type != SourcePictTypeSolidFill)) //1. The Gradient case.
-	     /* 2. Has no fbo but can upload.*/
-	     || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
-	         && ((src_width * src_height * 4 <
-	              source_pixmap->drawable.width * source_pixmap->drawable.height)
-	             || !glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width,
-	                     source_pixmap->drawable.height)))) {
-
-		if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) {
-			ret = FALSE;
-			goto TRAPEZOID_OUT;
-		}
-		temp_src = glamor_convert_gradient_picture(screen, src,
-		           x_src, y_src,
-		           src_width, src_height);
-		if (!temp_src) {
-			temp_src = src;
-			ret = FALSE;
-			DEBUGF("Convert gradient picture failed\n");
-			goto TRAPEZOID_OUT;
-		}
-		temp_src_priv = glamor_get_pixmap_private((PixmapPtr)temp_src->pDrawable);
-		x_temp_src = y_temp_src = 0;
-	}
-
-	x_dst += dst->pDrawable->x;
-	y_dst += dst->pDrawable->y;
-	if (temp_src->pDrawable) {
-		x_temp_src += temp_src->pDrawable->x;
-		y_temp_src += temp_src->pDrawable->y;
-	}
-
-	if (!miComputeCompositeRegion(&region,
-	        temp_src, NULL, dst,
-	        x_temp_src, y_temp_src,
-	        0, 0,
-	        x_dst, y_dst,
-	        src_width, src_height)) {
-		DEBUGF("All the regions are clipped out, do nothing\n");
-		goto TRAPEZOID_OUT;
-	}
-
-	box = REGION_RECTS(&region);
-	nbox = REGION_NUM_RECTS(&region);
-	pbox = box;
-
-	ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
-					     temp_src_priv, NULL, dest_pixmap_priv,
-					     &key, &shader, &op_info, &saved_source_format);
-	if (ret == FALSE) {
-		DEBUGF("can not set the shader program for composite\n");
-		goto TRAPEZOID_RESET_GL;
-	}
-	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
-	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
-	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
-	        key.mask != SHADER_MASK_SOLID);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
-	        &dest_x_off, &dest_y_off);
-
-	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
-
-	if (glamor_priv->has_source_coords) {
-		source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable);
-		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		glamor_get_drawable_deltas(temp_src->pDrawable,
-		        source_pixmap,
-		        &source_x_off, &source_y_off);
-		pixmap_priv_get_scale(source_pixmap_priv,
-		        &src_xscale, &src_yscale);
-		glamor_picture_get_matrixf(temp_src, src_matrix);
-		vert_stride += 3;
-	}
-
-	if (glamor_priv->has_mask_coords) {
-		DEBUGF("Should never have mask coords here!\n");
-		ret = FALSE;
-		goto TRAPEZOID_RESET_GL;
-	}
-
-	/* A trapezoid clip with a rectangle will at most generate a hexagon,
-	   which can be devided	into 4 triangles to render. */
-	ntriangle_per_loop = (vert_stride * nbox * ntrap * 4) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
-	        (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nbox * ntrap * 4;
-	ntriangle_per_loop = (ntriangle_per_loop / 4) * 4;
-
-	nclip_rect = nbox;
-	while (nclip_rect) {
-		mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ?
-		             (ntriangle_per_loop / (4 * ntrap)) : nclip_rect;
-
-		if (!mclip_rect) {/* Maybe too many traps. */
-			mclip_rect = 1;
-			ptrap = traps;
-			traps_count = ntriangle_per_loop / 4;
-			traps_not_completed = ntrap - traps_count;
-		} else {
-			traps_count = ntrap;
-			ptrap = traps;
-			traps_not_completed = 0;
-		}
-
-NTRAPS_LOOP_AGAIN:
-
-		glamor_setup_composite_vbo(screen,  mclip_rect * traps_count * 4 * vert_stride);
-		clip_processed = mclip_rect;
-
-
-		while (mclip_rect--) {
-			while (traps_count--) {
-				int vtx_num;
-				int i;
-				float vertices[3*2], source_texcoords[3*2];
-
-				DEBUGF("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, "
-				       "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n",
-				       nclip_rect, mclip_rect, clip_processed, traps_count, traps_not_completed);
-
-				if (_glamor_clip_trapezoid_vertex(ptrap, pbox, clipped_vtx, &vtx_num)) {
-					for (i = 0; i < vtx_num - 2; i++) {
-						int clipped_vtx_tmp[3*2];
-
-						clipped_vtx_tmp[0] = clipped_vtx[0];
-						clipped_vtx_tmp[1] = clipped_vtx[1];
-						clipped_vtx_tmp[2] = clipped_vtx[(i+1)*2];
-						clipped_vtx_tmp[3] = clipped_vtx[(i+1)*2 + 1];
-						clipped_vtx_tmp[4] = clipped_vtx[(i+2)*2];
-						clipped_vtx_tmp[5] = clipped_vtx[(i+2)*2 + 1];
-						glamor_set_normalize_tri_vcoords(
-						    dst_xscale, dst_yscale, clipped_vtx_tmp,
-						    glamor_priv->yInverted, vertices);
-						DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
-						       "(%f X %f)\n", vertices[0], vertices[1],
-						       vertices[2], vertices[3], vertices[4], vertices[5]);
-
-
-						if (key.source != SHADER_SOURCE_SOLID) {
-							if (src->transform) {
-								glamor_set_transformed_normalize_tri_tcoords(
-								    source_pixmap_priv,
-								    src_matrix, src_xscale, src_yscale,
-								    clipped_vtx_tmp,
-								    glamor_priv->yInverted,
-								    source_texcoords);
-							} else {
-								glamor_set_normalize_tri_tcoords(
-								    src_xscale, src_yscale,
-								    clipped_vtx_tmp,
-								    glamor_priv->yInverted,
-								    source_texcoords);
-							}
-
-							DEBUGF("source_texcoords of triangle: (%f X %f), "
-							       "(%f X %f), (%f X %f)\n",
-							       source_texcoords[0], source_texcoords[1],
-							       source_texcoords[2], source_texcoords[3],
-							       source_texcoords[4], source_texcoords[5]);
-						}
-
-						glamor_emit_composite_triangle(screen, source_texcoords,
-						        NULL, vertices);
-					}
-				}
-
-				ptrap++;
-			}
-
-			if (traps_not_completed) { /* one loop of ntraps not completed */
-				mclip_rect = 1;
-				traps_count = traps_not_completed > (ntriangle_per_loop / 4) ?
-				              (ntriangle_per_loop / 4) : traps_not_completed;
-				traps_not_completed -= traps_count;
-				glamor_flush_composite_triangles(screen);
-				goto NTRAPS_LOOP_AGAIN;
-			} else {
-				ptrap = traps;
-				traps_count = ntrap;
-			}
-
-			pbox++;
-		}
-
-		glamor_flush_composite_triangles(screen);
-
-		nclip_rect -= clip_processed;
-	}
-
-	ret = TRUE;
-
-TRAPEZOID_RESET_GL:
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-	dispatch->glDisable(GL_BLEND);
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    struct shader_key key;
+    glamor_composite_shader *shader = NULL;
+    struct blendinfo op_info;
+    PictFormatShort saved_source_format = 0;
+    PixmapPtr source_pixmap = NULL;
+    PixmapPtr dest_pixmap = NULL;
+    glamor_pixmap_private *source_pixmap_priv = NULL;
+    glamor_pixmap_private *dest_pixmap_priv = NULL;
+    glamor_pixmap_private *temp_src_priv = NULL;
+    int x_temp_src, y_temp_src;
+    int src_width, src_height;
+    int source_x_off, source_y_off;
+    GLfloat src_xscale = 1, src_yscale = 1;
+    int x_dst, y_dst;
+    int dest_x_off, dest_y_off;
+    GLfloat dst_xscale, dst_yscale;
+    BoxRec bounds;
+    PicturePtr temp_src = src;
+    glamor_gl_dispatch *dispatch = NULL;
+    int vert_stride = 3;
+    int ntriangle_per_loop;
+    int nclip_rect;
+    int mclip_rect;
+    int clip_processed;
+    int clipped_vtx[6 * 2];
+    RegionRec region;
+    BoxPtr box = NULL;
+    BoxPtr pbox = NULL;
+    int traps_count = 0;
+    int traps_not_completed = 0;
+    xTrapezoid *ptrap = NULL;
+    int nbox;
+    float src_matrix[9];
+    Bool ret = FALSE;
+
+    /* If a mask format wasn't provided, we get to choose, but behavior should
+     * be as if there was no temporary mask the traps were accumulated into.
+     */
+    if (!mask_format) {
+        if (dst->polyEdge == PolyEdgeSharp)
+            mask_format = PictureMatchFormat(screen, 1, PICT_a1);
+        else
+            mask_format = PictureMatchFormat(screen, 8, PICT_a8);
+        for (; ntrap; ntrap--, traps++)
+            glamor_trapezoids(op, src, dst, mask_format, x_src,
+                              y_src, 1, traps);
+        return TRUE;
+    }
+
+    miTrapezoidBounds(ntrap, traps, &bounds);
+    DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
+           "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2,
+           bounds.y1, bounds.y2);
+
+    /* No area need to render. */
+    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+        return TRUE;
+
+    dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)
+        || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+        /* Currently. Always fallback to cpu if destination is in CPU memory. */
+        ret = FALSE;
+        DEBUGF("dst pixmap has no FBO.\n");
+        goto TRAPEZOID_OUT;
+    }
+
+    if (src->pDrawable) {
+        source_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
+        source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+        temp_src_priv = source_pixmap_priv;
+        if (source_pixmap_priv
+            && (source_pixmap_priv->type == GLAMOR_DRM_ONLY
+                || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) {
+            ret = FALSE;
+            goto TRAPEZOID_OUT;
+        }
+    }
+
+    x_dst = bounds.x1;
+    y_dst = bounds.y1;
+
+    src_width = bounds.x2 - bounds.x1;
+    src_height = bounds.y2 - bounds.y1;
+
+    x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16);
+    y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16);
+
+    if ((!src->pDrawable && (src->pSourcePict->type != SourcePictTypeSolidFill))        //1. The Gradient case.
+        /* 2. Has no fbo but can upload. */
+        || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
+            && ((src_width * src_height * 4 <
+                 source_pixmap->drawable.width * source_pixmap->drawable.height)
+                || !glamor_check_fbo_size(glamor_priv,
+                                          source_pixmap->drawable.width,
+                                          source_pixmap->drawable.height)))) {
+
+        if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) {
+            ret = FALSE;
+            goto TRAPEZOID_OUT;
+        }
+        temp_src = glamor_convert_gradient_picture(screen, src,
+                                                   x_src, y_src,
+                                                   src_width, src_height);
+        if (!temp_src) {
+            temp_src = src;
+            ret = FALSE;
+            DEBUGF("Convert gradient picture failed\n");
+            goto TRAPEZOID_OUT;
+        }
+        temp_src_priv =
+            glamor_get_pixmap_private((PixmapPtr) temp_src->pDrawable);
+        x_temp_src = y_temp_src = 0;
+    }
+
+    x_dst += dst->pDrawable->x;
+    y_dst += dst->pDrawable->y;
+    if (temp_src->pDrawable) {
+        x_temp_src += temp_src->pDrawable->x;
+        y_temp_src += temp_src->pDrawable->y;
+    }
+
+    if (!miComputeCompositeRegion(&region,
+                                  temp_src, NULL, dst,
+                                  x_temp_src, y_temp_src,
+                                  0, 0, x_dst, y_dst, src_width, src_height)) {
+        DEBUGF("All the regions are clipped out, do nothing\n");
+        goto TRAPEZOID_OUT;
+    }
+
+    box = REGION_RECTS(&region);
+    nbox = REGION_NUM_RECTS(&region);
+    pbox = box;
+
+    ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
+                                         temp_src_priv, NULL, dest_pixmap_priv,
+                                         &key, &shader, &op_info,
+                                         &saved_source_format);
+    if (ret == FALSE) {
+        DEBUGF("can not set the shader program for composite\n");
+        goto TRAPEZOID_RESET_GL;
+    }
+    glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+    glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
+    glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+    glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+                                    key.mask != SHADER_MASK_SOLID);
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
+                               &dest_x_off, &dest_y_off);
+
+    pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+
+    if (glamor_priv->has_source_coords) {
+        source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable);
+        source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+        glamor_get_drawable_deltas(temp_src->pDrawable,
+                                   source_pixmap, &source_x_off, &source_y_off);
+        pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
+        glamor_picture_get_matrixf(temp_src, src_matrix);
+        vert_stride += 3;
+    }
+
+    if (glamor_priv->has_mask_coords) {
+        DEBUGF("Should never have mask coords here!\n");
+        ret = FALSE;
+        goto TRAPEZOID_RESET_GL;
+    }
+
+    /* A trapezoid clip with a rectangle will at most generate a hexagon,
+       which can be devided into 4 triangles to render. */
+    ntriangle_per_loop =
+        (vert_stride * nbox * ntrap * 4) >
+        GLAMOR_COMPOSITE_VBO_VERT_CNT ? (GLAMOR_COMPOSITE_VBO_VERT_CNT /
+                                         vert_stride) : nbox * ntrap * 4;
+    ntriangle_per_loop = (ntriangle_per_loop / 4) * 4;
+
+    nclip_rect = nbox;
+    while (nclip_rect) {
+        mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ?
+            (ntriangle_per_loop / (4 * ntrap)) : nclip_rect;
+
+        if (!mclip_rect) {      /* Maybe too many traps. */
+            mclip_rect = 1;
+            ptrap = traps;
+            traps_count = ntriangle_per_loop / 4;
+            traps_not_completed = ntrap - traps_count;
+        }
+        else {
+            traps_count = ntrap;
+            ptrap = traps;
+            traps_not_completed = 0;
+        }
+
+ NTRAPS_LOOP_AGAIN:
+
+        glamor_setup_composite_vbo(screen,
+                                   mclip_rect * traps_count * 4 * vert_stride);
+        clip_processed = mclip_rect;
+
+        while (mclip_rect--) {
+            while (traps_count--) {
+                int vtx_num;
+                int i;
+                float vertices[3 * 2], source_texcoords[3 * 2];
+
+                DEBUGF
+                    ("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, "
+                     "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n",
+                     nclip_rect, mclip_rect, clip_processed, traps_count,
+                     traps_not_completed);
+
+                if (_glamor_clip_trapezoid_vertex
+                    (ptrap, pbox, clipped_vtx, &vtx_num)) {
+                    for (i = 0; i < vtx_num - 2; i++) {
+                        int clipped_vtx_tmp[3 * 2];
+
+                        clipped_vtx_tmp[0] = clipped_vtx[0];
+                        clipped_vtx_tmp[1] = clipped_vtx[1];
+                        clipped_vtx_tmp[2] = clipped_vtx[(i + 1) * 2];
+                        clipped_vtx_tmp[3] = clipped_vtx[(i + 1) * 2 + 1];
+                        clipped_vtx_tmp[4] = clipped_vtx[(i + 2) * 2];
+                        clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
+                        glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
+                                                         clipped_vtx_tmp,
+                                                         glamor_priv->yInverted,
+                                                         vertices);
+                        DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
+                               "(%f X %f)\n", vertices[0], vertices[1],
+                               vertices[2], vertices[3], vertices[4],
+                               vertices[5]);
+
+                        if (key.source != SHADER_SOURCE_SOLID) {
+                            if (src->transform) {
+                                glamor_set_transformed_normalize_tri_tcoords
+                                    (source_pixmap_priv, src_matrix, src_xscale,
+                                     src_yscale, clipped_vtx_tmp,
+                                     glamor_priv->yInverted, source_texcoords);
+                            }
+                            else {
+                                glamor_set_normalize_tri_tcoords(src_xscale,
+                                                                 src_yscale,
+                                                                 clipped_vtx_tmp,
+                                                                 glamor_priv->
+                                                                 yInverted,
+                                                                 source_texcoords);
+                            }
+
+                            DEBUGF("source_texcoords of triangle: (%f X %f), "
+                                   "(%f X %f), (%f X %f)\n",
+                                   source_texcoords[0], source_texcoords[1],
+                                   source_texcoords[2], source_texcoords[3],
+                                   source_texcoords[4], source_texcoords[5]);
+                        }
+
+                        glamor_emit_composite_triangle(screen, source_texcoords,
+                                                       NULL, vertices);
+                    }
+                }
+
+                ptrap++;
+            }
+
+            if (traps_not_completed) {  /* one loop of ntraps not completed */
+                mclip_rect = 1;
+                traps_count = traps_not_completed > (ntriangle_per_loop / 4) ?
+                    (ntriangle_per_loop / 4) : traps_not_completed;
+                traps_not_completed -= traps_count;
+                glamor_flush_composite_triangles(screen);
+                goto NTRAPS_LOOP_AGAIN;
+            }
+            else {
+                ptrap = traps;
+                traps_count = ntrap;
+            }
+
+            pbox++;
+        }
+
+        glamor_flush_composite_triangles(screen);
+
+        nclip_rect -= clip_processed;
+    }
+
+    ret = TRUE;
+
+ TRAPEZOID_RESET_GL:
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    dispatch->glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glDisable(GL_TEXTURE_2D);
-	dispatch->glActiveTexture(GL_TEXTURE1);
-	dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glActiveTexture(GL_TEXTURE1);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUseProgram(0);
-
-TRAPEZOID_OUT:
-	if (box) {
-		REGION_UNINIT(dst->pDrawable->pScreen, &region);
-	}
-
-	if (temp_src != src) {
-		FreePicture(temp_src, 0);
-	} else {
-		if (saved_source_format) {
-			src->format = saved_source_format;
-		}
-	}
-
-	if (dispatch) {
-		glamor_put_dispatch(glamor_priv);
-	}
-
-	return ret;
+    dispatch->glUseProgram(0);
+
+ TRAPEZOID_OUT:
+    if (box) {
+        REGION_UNINIT(dst->pDrawable->pScreen, &region);
+    }
+
+    if (temp_src != src) {
+        FreePicture(temp_src, 0);
+    }
+    else {
+        if (saved_source_format) {
+            src->format = saved_source_format;
+        }
+    }
+
+    if (dispatch) {
+        glamor_put_dispatch(glamor_priv);
+    }
+
+    return ret;
 }
 
 void
 glamor_init_trapezoid_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	GLint fs_prog, vs_prog;
-
-	const char *trapezoid_vs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "attribute vec4 v_position;\n"
-	    "attribute vec2 v_texcoord;\n"
-	    /* v_top_bottom, v_left_param and v_right_param contain the
-	       constant value for all the vertex of one rect. Using uniform
-	       is more suitable but we need to reset the uniform variables
-	       for every rect rendering and can not use the vbo, which causes
-	       performance loss. So we set these attributes to same value
-	       for every vertex of one rect and so it is also a constant in FS */
-	    "attribute vec2 v_top_bottom;\n"
-	    "attribute vec4 v_left_param;\n"
-	    "attribute vec4 v_right_param;\n"
-	    "\n"
-	    "varying vec2 source_texture;\n"
-	    "varying float trap_top;\n"
-	    "varying float trap_bottom;\n"
-	    "varying float trap_left_x;\n"
-	    "varying float trap_left_y;\n"
-	    "varying float trap_left_slope;\n"
-	    "varying float trap_left_vertical_f;\n"
-	    "varying float trap_right_x;\n"
-	    "varying float trap_right_y;\n"
-	    "varying float trap_right_slope;\n"
-	    "varying float trap_right_vertical_f;\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_Position = v_position;\n"
-	    "    source_texture = v_texcoord.xy;\n"
-	    "    trap_top = v_top_bottom.x;\n"
-	    "    trap_bottom = v_top_bottom.y;\n"
-	    "    \n"
-	    "    trap_left_x = v_left_param.x;\n"
-	    "    trap_left_y = v_left_param.y;\n"
-	    "    trap_left_slope = v_left_param.z;\n"
-	    "    trap_left_vertical_f = v_left_param.w;\n"
-	    "    \n"
-	    "    trap_right_x = v_right_param.x;\n"
-	    "    trap_right_y = v_right_param.y;\n"
-	    "    trap_right_slope = v_right_param.z;\n"
-	    "    trap_right_vertical_f = v_right_param.w;\n"
-	    "}\n";
-
-	/*
-	 * Because some GL fill function do not support the MultSample
-	 * anti-alias, we need to do the MSAA here. This manner like
-	 * pixman, will caculate the value of area in trapezoid dividing
-	 * the totol area for each pixel, as follow:
-	     |
-	 ----+------------------------------------------------------>
-	     |
-	     |              -------------
-	     |             /             \
-	     |            /               \
-	     |           /                 \
-	     |          /              +----------------+
-	     |         /               |.....\          |
-	     |        /                |......\         |
-	     |       /                 |.......\        |
-	     |      /                  |........\       |
-	     |     /-------------------+---------\      |
-	     |                         |                |
-	     |                         |                |
-	     |                         +----------------+
-	     |
-	    \|/
-
-	 */
-	const char *trapezoid_fs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "varying vec2 source_texture;  \n"
-	    "varying float trap_top;  \n"
-	    "varying float trap_bottom;  \n"
-	    "varying float trap_left_x;  \n"
-	    "varying float trap_left_y;  \n"
-	    "varying float trap_left_slope;  \n"
-	    "varying float trap_left_vertical_f;  \n"
-	    "varying float trap_right_x;  \n"
-	    "varying float trap_right_y;  \n"
-	    "varying float trap_right_slope;  \n"
-	    "varying float trap_right_vertical_f;  \n"
-	    "float x_per_pix = 1.0;"
-	    "float y_per_pix = 1.0;"
-	    "\n"
-	    "float get_alpha_val() \n"
-	    "{  \n"
-	    "    float x_up_cut_left;  \n"
-	    "    float x_bottom_cut_left;  \n"
-	    "    float x_up_cut_right;  \n"
-	    "    float x_bottom_cut_right;  \n"
-	    "    bool trap_left_vertical;\n"
-	    "    bool trap_right_vertical;\n"
-	    "	 if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n"
-	    "		trap_left_vertical = true;\n"
-	    "	 else\n"
-	    "		trap_left_vertical = false;\n"
-	    "	 if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n"
-	    "		trap_right_vertical = true;\n"
-	    "	 else\n"
-	    "		trap_right_vertical = false;\n"
-	    "    \n"
-	    "    if(trap_left_vertical == true) {  \n"
-	    "        x_up_cut_left = trap_left_x;  \n"
-	    "        x_bottom_cut_left = trap_left_x;  \n"
-	    "    } else {  \n"
-	    "        x_up_cut_left = trap_left_x  \n"
-	    "            + (source_texture.y - y_per_pix/2.0 - trap_left_y)  \n"
-	    "              / trap_left_slope;  \n"
-	    "        x_bottom_cut_left = trap_left_x  \n"
-	    "            + (source_texture.y + y_per_pix/2.0 - trap_left_y)  \n"
-	    "              / trap_left_slope;  \n"
-	    "    }  \n"
-	    "    \n"
-	    "    if(trap_right_vertical == true) {  \n"
-	    "        x_up_cut_right = trap_right_x;  \n"
-	    "        x_bottom_cut_right = trap_right_x;  \n"
-	    "    } else {  \n"
-	    "        x_up_cut_right = trap_right_x  \n"
-	    "            + (source_texture.y - y_per_pix/2.0 - trap_right_y)  \n"
-	    "              / trap_right_slope;  \n"
-	    "        x_bottom_cut_right = trap_right_x  \n"
-	    "            + (source_texture.y + y_per_pix/2.0 - trap_right_y)  \n"
-	    "              / trap_right_slope;  \n"
-	    "    }  \n"
-	    "    \n"
-	    "    if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
-	    "          (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
-	    "          (x_up_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
-	    "          (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
-	    "          (trap_top <= source_texture.y - y_per_pix/2.0) &&  \n"
-	    "          (trap_bottom >= source_texture.y + y_per_pix/2.0)) {  \n"
-	    //       The complete inside case.
-	    "        return 1.0;  \n"
-	    "    } else if((trap_top > source_texture.y + y_per_pix/2.0) ||  \n"
-	    "                (trap_bottom < source_texture.y - y_per_pix/2.0)) {  \n"
-	    //       The complete outside. Above the top or Below the bottom.
-	    "        return 0.0;  \n"
-	    "    } else {  \n"
-	    "        if((x_up_cut_right < source_texture.x - x_per_pix/2.0 &&  \n"
-	    "                   x_bottom_cut_right < source_texture.x - x_per_pix/2.0)  \n"
-	    "            || (x_up_cut_left > source_texture.x + x_per_pix/2.0  &&  \n"
-	    "                   x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) {  \n"
-	    //            The complete outside. At Left or Right of the trapezoide.
-	    "             return 0.0;  \n"
-	    "        }  \n"
-	    "    }  \n"
-	    //   Get here, the pix is partly inside the trapezoid.
-	    "    {  \n"
-	    "        float percent = 0.0;  \n"
-	    "        float up = (source_texture.y - y_per_pix/2.0) >= trap_top ?  \n"
-	    "                       (source_texture.y - y_per_pix/2.0) : trap_top;  \n"
-	    "        float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ?  \n"
-	    "                       (source_texture.y + y_per_pix/2.0) : trap_bottom;  \n"
-	    "        float left = source_texture.x - x_per_pix/2.0;  \n"
-	    "        float right = source_texture.x + x_per_pix/2.0;  \n"
-	    "        \n"
-	    "        percent = (bottom - up) / y_per_pix;  \n"
-	    "        \n"
-	    "	     if(trap_left_vertical == true) {  \n"
-	    "            if(trap_left_x > source_texture.x - x_per_pix/2.0 &&  \n"
-	    "                     trap_left_x < source_texture.x + x_per_pix/2.0)  \n"
-	    "                left = trap_left_x;  \n"
-	    "        }  \n"
-	    "	     if(trap_right_vertical == true) {  \n"
-	    "            if(trap_right_x > source_texture.x - x_per_pix/2.0 &&  \n"
-	    "                     trap_right_x < source_texture.x + x_per_pix/2.0)  \n"
-	    "                right = trap_right_x;  \n"
-	    "        }  \n"
-	    "        if((up >= bottom) || (left >= right))  \n"
-	    "            return 0.0;  \n"
-	    "        \n"
-	    "        percent = percent * ((right - left)/x_per_pix);  \n"
-	    "        if(trap_left_vertical == true && trap_right_vertical == true)  \n"
-	    "            return percent;  \n"
-	    "        \n"
-	    "        if(trap_left_vertical != true) {  \n"
-	    "            float area;  \n"
-	    //           the slope should never be 0.0 here
-	    "            float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope;  \n"
-	    "            float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope;  \n"
-	    "            if(trap_left_slope < 0.0 && up_x > left) {  \n"
-	    /*   case 1
-	         |
-	     ----+------------------------------------->
-	         |                 /
-	         |                /
-	         |           +---/--------+
-	         |           |  /.........|
-	         |           | /..........|
-	         |           |/...........|
-	         |           /............|
-	         |          /|............|
-	         |           +------------+
-	         |
-	        \|/
-	    */
-	    "                float left_y = trap_left_y + trap_left_slope*(left - trap_left_x);  \n"
-	    "                if((up_x > left) && (left_y > up)) {  \n"
-	    "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
-	    "                    if(up_x > right) {  \n"
-	    "                        float right_y = trap_left_y  \n"
-	    "                                  + trap_left_slope*(right - trap_left_x);  \n"
-	    "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
-	    "                    }  \n"
-	    "                    if(left_y > bottom) {  \n"
-	    "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
-	    "                    }  \n"
-	    "                } else {  \n"
-	    "                    area = 0.0;  \n"
-	    "                }  \n"
-	    "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
-	    "            } else if(trap_left_slope > 0.0 && bottom_x > left) {  \n"
-	    /*   case 2
-	         |
-	     ----+------------------------------------->
-	         |          \
-	         |           \
-	         |           +\-----------+
-	         |           | \..........|
-	         |           |  \.........|
-	         |           |   \........|
-	         |           |    \.......|
-	         |           |     \......|
-	         |           +------\-----+
-	         |                   \
-	         |                    \
-	        \|/
-	    */
-	    "                float right_y = trap_left_y + trap_left_slope*(right - trap_left_x);  \n"
-	    "                if((up_x < right) && (right_y > up)) {  \n"
-	    "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
-	    "                    if(up_x < left) {  \n"
-	    "                        float left_y = trap_left_y  \n"
-	    "                                  + trap_left_slope*(left - trap_left_x);  \n"
-	    "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
-	    "                    }  \n"
-	    "                    if(right_y > bottom) {  \n"
-	    "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
-	    "                    }  \n"
-	    "                } else {  \n"
-	    "                    area = 0.0;  \n"
-	    "                }  \n"
-	    "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
-	    "            }  \n"
-	    "        }  \n"
-	    "        \n"
-	    "        if(trap_right_vertical != true) {  \n"
-	    "            float area;  \n"
-	    //           the slope should never be 0.0 here
-	    "            float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope;  \n"
-	    "            float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope;  \n"
-	    "            if(trap_right_slope < 0.0 && bottom_x < right) {  \n"
-	    /*   case 3
-	         |
-	     ----+------------------------------------->
-	         |                     /
-	         |           +--------/---+
-	         |           |......./    |
-	         |           |....../     |
-	         |           |...../      |
-	         |           |..../       |
-	         |           |.../        |
-	         |           +--/---------+
-	         |             /
-	         |
-	        \|/
-	    */
-	    "                float left_y = trap_right_y + trap_right_slope*(left - trap_right_x);  \n"
-	    "                if((up_x > left) && (left_y > up)) {  \n"
-	    "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
-	    "                    if(up_x > right) {  \n"
-	    "                        float right_y = trap_right_y  \n"
-	    "                                  + trap_right_slope*(right - trap_right_x);  \n"
-	    "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
-	    "                    }  \n"
-	    "                    if(left_y > bottom) {  \n"
-	    "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
-	    "                    }  \n"
-	    "                } else {  \n"
-	    "                    area = 0.0;  \n"
-	    "                }  \n"
-	    "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
-	    "            } else if(trap_right_slope > 0.0 && up_x < right) {  \n"
-	    /*   case 4
-	         |
-	     ----+------------------------------------->
-	         |                   \
-	         |           +--------\---+
-	         |           |.........\  |
-	         |           |..........\ |
-	         |           |...........\|
-	         |           |............\
-	         |           |............|\
-	         |           +------------+ \
-	         |                           \
-	         |
-	        \|/
-	    */
-	    "                float right_y = trap_right_y + trap_right_slope*(right - trap_right_x);  \n"
-	    "                if((up_x < right) && (right_y > up)) {  \n"
-	    "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
-	    "                    if(up_x < left) {  \n"
-	    "                        float left_y = trap_right_y  \n"
-	    "                                  + trap_right_slope*(left - trap_right_x);  \n"
-	    "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
-	    "                    }  \n"
-	    "                    if(right_y > bottom) {  \n"
-	    "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
-	    "                    }  \n"
-	    "                } else {  \n"
-	    "                    area = 0.0;  \n"
-	    "                }  \n"
-	    "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
-	    "            }  \n"
-	    "        }  \n"
-	    "        \n"
-	    "        return percent;  \n"
-	    "    }  \n"
-	    "}  \n"
-	    "\n"
-	    "void main()  \n"
-	    "{  \n"
-	    "    float alpha_val = get_alpha_val();  \n"
-	    "    gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val);  \n"
-	    "}\n";
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	glamor_priv->trapezoid_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch,
-	                  GL_VERTEX_SHADER, trapezoid_vs);
-	fs_prog = glamor_compile_glsl_prog(dispatch,
-	                  GL_FRAGMENT_SHADER, trapezoid_fs);
-
-	dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
-	dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
-
-	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	        GLAMOR_VERTEX_POS, "v_positionsition");
-	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	        GLAMOR_VERTEX_SOURCE, "v_texcoord");
-	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	        GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
-	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	        GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
-	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	        GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
-
-	glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog);
-
-	dispatch->glUseProgram(0);
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    GLint fs_prog, vs_prog;
+
+    const char *trapezoid_vs =
+        GLAMOR_DEFAULT_PRECISION
+        "attribute vec4 v_position;\n" "attribute vec2 v_texcoord;\n"
+        /* v_top_bottom, v_left_param and v_right_param contain the
+           constant value for all the vertex of one rect. Using uniform
+           is more suitable but we need to reset the uniform variables
+           for every rect rendering and can not use the vbo, which causes
+           performance loss. So we set these attributes to same value
+           for every vertex of one rect and so it is also a constant in FS */
+        "attribute vec2 v_top_bottom;\n"
+        "attribute vec4 v_left_param;\n"
+        "attribute vec4 v_right_param;\n"
+        "\n"
+        "varying vec2 source_texture;\n"
+        "varying float trap_top;\n"
+        "varying float trap_bottom;\n"
+        "varying float trap_left_x;\n"
+        "varying float trap_left_y;\n"
+        "varying float trap_left_slope;\n"
+        "varying float trap_left_vertical_f;\n"
+        "varying float trap_right_x;\n"
+        "varying float trap_right_y;\n"
+        "varying float trap_right_slope;\n"
+        "varying float trap_right_vertical_f;\n"
+        "\n"
+        "void main()\n"
+        "{\n"
+        "    gl_Position = v_position;\n"
+        "    source_texture = v_texcoord.xy;\n"
+        "    trap_top = v_top_bottom.x;\n"
+        "    trap_bottom = v_top_bottom.y;\n"
+        "    \n"
+        "    trap_left_x = v_left_param.x;\n"
+        "    trap_left_y = v_left_param.y;\n"
+        "    trap_left_slope = v_left_param.z;\n"
+        "    trap_left_vertical_f = v_left_param.w;\n"
+        "    \n"
+        "    trap_right_x = v_right_param.x;\n"
+        "    trap_right_y = v_right_param.y;\n"
+        "    trap_right_slope = v_right_param.z;\n"
+        "    trap_right_vertical_f = v_right_param.w;\n" "}\n";
+
+    /*
+     * Because some GL fill function do not support the MultSample
+     * anti-alias, we need to do the MSAA here. This manner like
+     * pixman, will caculate the value of area in trapezoid dividing
+     * the totol area for each pixel, as follow:
+     |
+     ----+------------------------------------------------------>
+     |
+     |              -------------
+     |             /             \
+     |            /               \
+     |           /                 \
+     |          /              +----------------+
+     |         /               |.....\          |
+     |        /                |......\         |
+     |       /                 |.......\        |
+     |      /                  |........\       |
+     |     /-------------------+---------\      |
+     |                         |                |
+     |                         |                |
+     |                         +----------------+
+     |
+     \|/
+
+     */
+    const char *trapezoid_fs =
+        GLAMOR_DEFAULT_PRECISION
+        "varying vec2 source_texture;  \n"
+        "varying float trap_top;  \n"
+        "varying float trap_bottom;  \n"
+        "varying float trap_left_x;  \n"
+        "varying float trap_left_y;  \n"
+        "varying float trap_left_slope;  \n"
+        "varying float trap_left_vertical_f;  \n"
+        "varying float trap_right_x;  \n"
+        "varying float trap_right_y;  \n"
+        "varying float trap_right_slope;  \n"
+        "varying float trap_right_vertical_f;  \n"
+        "float x_per_pix = 1.0;"
+        "float y_per_pix = 1.0;"
+        "\n"
+        "float get_alpha_val() \n"
+        "{  \n"
+        "    float x_up_cut_left;  \n"
+        "    float x_bottom_cut_left;  \n"
+        "    float x_up_cut_right;  \n"
+        "    float x_bottom_cut_right;  \n"
+        "    bool trap_left_vertical;\n"
+        "    bool trap_right_vertical;\n"
+        "	 if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n"
+        "		trap_left_vertical = true;\n"
+        "	 else\n"
+        "		trap_left_vertical = false;\n"
+        "	 if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n"
+        "		trap_right_vertical = true;\n"
+        "	 else\n"
+        "		trap_right_vertical = false;\n"
+        "    \n"
+        "    if(trap_left_vertical == true) {  \n"
+        "        x_up_cut_left = trap_left_x;  \n"
+        "        x_bottom_cut_left = trap_left_x;  \n"
+        "    } else {  \n"
+        "        x_up_cut_left = trap_left_x  \n"
+        "            + (source_texture.y - y_per_pix/2.0 - trap_left_y)  \n"
+        "              / trap_left_slope;  \n"
+        "        x_bottom_cut_left = trap_left_x  \n"
+        "            + (source_texture.y + y_per_pix/2.0 - trap_left_y)  \n"
+        "              / trap_left_slope;  \n"
+        "    }  \n"
+        "    \n"
+        "    if(trap_right_vertical == true) {  \n"
+        "        x_up_cut_right = trap_right_x;  \n"
+        "        x_bottom_cut_right = trap_right_x;  \n"
+        "    } else {  \n"
+        "        x_up_cut_right = trap_right_x  \n"
+        "            + (source_texture.y - y_per_pix/2.0 - trap_right_y)  \n"
+        "              / trap_right_slope;  \n"
+        "        x_bottom_cut_right = trap_right_x  \n"
+        "            + (source_texture.y + y_per_pix/2.0 - trap_right_y)  \n"
+        "              / trap_right_slope;  \n"
+        "    }  \n"
+        "    \n"
+        "    if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
+        "          (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
+        "          (x_up_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
+        "          (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
+        "          (trap_top <= source_texture.y - y_per_pix/2.0) &&  \n"
+        "          (trap_bottom >= source_texture.y + y_per_pix/2.0)) {  \n"
+        //       The complete inside case.
+        "        return 1.0;  \n"
+        "    } else if((trap_top > source_texture.y + y_per_pix/2.0) ||  \n"
+        "                (trap_bottom < source_texture.y - y_per_pix/2.0)) {  \n"
+        //       The complete outside. Above the top or Below the bottom.
+        "        return 0.0;  \n"
+        "    } else {  \n"
+        "        if((x_up_cut_right < source_texture.x - x_per_pix/2.0 &&  \n"
+        "                   x_bottom_cut_right < source_texture.x - x_per_pix/2.0)  \n"
+        "            || (x_up_cut_left > source_texture.x + x_per_pix/2.0  &&  \n"
+        "                   x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) {  \n"
+        //            The complete outside. At Left or Right of the trapezoide.
+        "             return 0.0;  \n" "        }  \n" "    }  \n"
+        //   Get here, the pix is partly inside the trapezoid.
+        "    {  \n"
+        "        float percent = 0.0;  \n"
+        "        float up = (source_texture.y - y_per_pix/2.0) >= trap_top ?  \n"
+        "                       (source_texture.y - y_per_pix/2.0) : trap_top;  \n"
+        "        float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ?  \n"
+        "                       (source_texture.y + y_per_pix/2.0) : trap_bottom;  \n"
+        "        float left = source_texture.x - x_per_pix/2.0;  \n"
+        "        float right = source_texture.x + x_per_pix/2.0;  \n"
+        "        \n"
+        "        percent = (bottom - up) / y_per_pix;  \n"
+        "        \n"
+        "	     if(trap_left_vertical == true) {  \n"
+        "            if(trap_left_x > source_texture.x - x_per_pix/2.0 &&  \n"
+        "                     trap_left_x < source_texture.x + x_per_pix/2.0)  \n"
+        "                left = trap_left_x;  \n"
+        "        }  \n"
+        "	     if(trap_right_vertical == true) {  \n"
+        "            if(trap_right_x > source_texture.x - x_per_pix/2.0 &&  \n"
+        "                     trap_right_x < source_texture.x + x_per_pix/2.0)  \n"
+        "                right = trap_right_x;  \n"
+        "        }  \n"
+        "        if((up >= bottom) || (left >= right))  \n"
+        "            return 0.0;  \n"
+        "        \n"
+        "        percent = percent * ((right - left)/x_per_pix);  \n"
+        "        if(trap_left_vertical == true && trap_right_vertical == true)  \n"
+        "            return percent;  \n"
+        "        \n"
+        "        if(trap_left_vertical != true) {  \n"
+        "            float area;  \n"
+        //           the slope should never be 0.0 here
+        "            float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope;  \n"
+        "            float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope;  \n"
+        "            if(trap_left_slope < 0.0 && up_x > left) {  \n"
+        /*   case 1
+           |
+           ----+------------------------------------->
+           |                 /
+           |                /
+           |           +---/--------+
+           |           |  /.........|
+           |           | /..........|
+           |           |/...........|
+           |           /............|
+           |          /|............|
+           |           +------------+
+           |
+           \|/
+         */
+        "                float left_y = trap_left_y + trap_left_slope*(left - trap_left_x);  \n"
+        "                if((up_x > left) && (left_y > up)) {  \n"
+        "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
+        "                    if(up_x > right) {  \n"
+        "                        float right_y = trap_left_y  \n"
+        "                                  + trap_left_slope*(right - trap_left_x);  \n"
+        "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
+        "                    }  \n"
+        "                    if(left_y > bottom) {  \n"
+        "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
+        "                    }  \n"
+        "                } else {  \n"
+        "                    area = 0.0;  \n"
+        "                }  \n"
+        "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
+        "            } else if(trap_left_slope > 0.0 && bottom_x > left) {  \n"
+        /*   case 2
+           |
+           ----+------------------------------------->
+           |          \
+           |           \
+           |           +\-----------+
+           |           | \..........|
+           |           |  \.........|
+           |           |   \........|
+           |           |    \.......|
+           |           |     \......|
+           |           +------\-----+
+           |                   \
+           |                    \
+           \|/
+         */
+        "                float right_y = trap_left_y + trap_left_slope*(right - trap_left_x);  \n"
+        "                if((up_x < right) && (right_y > up)) {  \n"
+        "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
+        "                    if(up_x < left) {  \n"
+        "                        float left_y = trap_left_y  \n"
+        "                                  + trap_left_slope*(left - trap_left_x);  \n"
+        "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
+        "                    }  \n"
+        "                    if(right_y > bottom) {  \n"
+        "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
+        "                    }  \n"
+        "                } else {  \n"
+        "                    area = 0.0;  \n"
+        "                }  \n"
+        "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
+        "            }  \n"
+        "        }  \n"
+        "        \n"
+        "        if(trap_right_vertical != true) {  \n"
+        "            float area;  \n"
+        //           the slope should never be 0.0 here
+        "            float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope;  \n"
+        "            float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope;  \n"
+        "            if(trap_right_slope < 0.0 && bottom_x < right) {  \n"
+        /*   case 3
+           |
+           ----+------------------------------------->
+           |                     /
+           |           +--------/---+
+           |           |......./    |
+           |           |....../     |
+           |           |...../      |
+           |           |..../       |
+           |           |.../        |
+           |           +--/---------+
+           |             /
+           |
+           \|/
+         */
+        "                float left_y = trap_right_y + trap_right_slope*(left - trap_right_x);  \n"
+        "                if((up_x > left) && (left_y > up)) {  \n"
+        "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
+        "                    if(up_x > right) {  \n"
+        "                        float right_y = trap_right_y  \n"
+        "                                  + trap_right_slope*(right - trap_right_x);  \n"
+        "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
+        "                    }  \n"
+        "                    if(left_y > bottom) {  \n"
+        "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
+        "                    }  \n"
+        "                } else {  \n"
+        "                    area = 0.0;  \n"
+        "                }  \n"
+        "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
+        "            } else if(trap_right_slope > 0.0 && up_x < right) {  \n"
+        /*   case 4
+           |
+           ----+------------------------------------->
+           |                   \
+           |           +--------\---+
+           |           |.........\  |
+           |           |..........\ |
+           |           |...........\|
+           |           |............\
+           |           |............|\
+           |           +------------+ \
+           |                           \
+           |
+           \|/
+         */
+        "                float right_y = trap_right_y + trap_right_slope*(right - trap_right_x);  \n"
+        "                if((up_x < right) && (right_y > up)) {  \n"
+        "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
+        "                    if(up_x < left) {  \n"
+        "                        float left_y = trap_right_y  \n"
+        "                                  + trap_right_slope*(left - trap_right_x);  \n"
+        "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
+        "                    }  \n"
+        "                    if(right_y > bottom) {  \n"
+        "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
+        "                    }  \n"
+        "                } else {  \n"
+        "                    area = 0.0;  \n"
+        "                }  \n"
+        "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
+        "            }  \n"
+        "        }  \n"
+        "        \n"
+        "        return percent;  \n"
+        "    }  \n"
+        "}  \n"
+        "\n"
+        "void main()  \n"
+        "{  \n"
+        "    float alpha_val = get_alpha_val();  \n"
+        "    gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val);  \n" "}\n";
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    glamor_priv->trapezoid_prog = dispatch->glCreateProgram();
+
+    vs_prog = glamor_compile_glsl_prog(dispatch,
+                                       GL_VERTEX_SHADER, trapezoid_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch,
+                                       GL_FRAGMENT_SHADER, trapezoid_fs);
+
+    dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
+
+    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+                                   GLAMOR_VERTEX_POS, "v_positionsition");
+    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+                                   GLAMOR_VERTEX_SOURCE, "v_texcoord");
+    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+                                   GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
+    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+                                   GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
+    dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+                                   GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
+
+    glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog);
+
+    dispatch->glUseProgram(0);
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_trapezoid_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
 
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glDeleteProgram(glamor_priv->trapezoid_prog);
-	glamor_put_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glDeleteProgram(glamor_priv->trapezoid_prog);
+    glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
 _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
-        xTrapezoid * traps, int ntrap, BoxRec *bounds)
+                                       xTrapezoid * traps, int ntrap,
+                                       BoxRec * bounds)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	glamor_pixmap_private *pixmap_priv;
-	PixmapPtr pixmap = NULL;
-	GLint trapezoid_prog;
-	GLfloat xscale, yscale;
-	float left_slope, right_slope;
-	xTrapezoid *ptrap;
-	BoxRec one_trap_bound;
-	int nrect_max;
-	int i, j;
-	float *vertices;
-	float params[4];
-
-	glamor_priv = glamor_get_screen_private(screen);
-	trapezoid_prog = glamor_priv->trapezoid_prog;
-
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)
-	     || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */
-		DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n");
-		return FALSE;
-	}
-
-	/* First, clear all to zero */
-	if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
-	                  pixmap_priv->base.pixmap->drawable.height,
-	                  GXclear, 0xFFFFFFFF, 0)) {
-		DEBUGF("glamor_solid failed, fallback\n");
-		return FALSE;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	/* Now draw the Trapezoid mask. */
-	dispatch->glUseProgram(trapezoid_prog);
-
-	dispatch->glEnable(GL_BLEND);
-	dispatch->glBlendFunc(GL_ONE, GL_ONE);
-
-	nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
-
-	for (i = 0; i < ntrap;) {
-		int mrect;
-		int stride;
-
-		mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i);
-		glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
-		stride = glamor_priv->vb_stride / sizeof(float);
-
-		for (j = 0; j < mrect; j++) {
-			ptrap = traps + i + j;
-
-			DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
-			       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
-			       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
-			       xFixedToInt(ptrap->top), ptrap->top,
-			       xFixedToInt(ptrap->bottom), ptrap->bottom,
-			       xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x,
-			       xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y,
-			       xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x,
-			       xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y,
-			       xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x,
-			       xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y,
-			       xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x,
-			       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
-
-			miTrapezoidBounds(1, ptrap, &one_trap_bound);
-
-			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset) + 2;
-			glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
-			        (pixmap_priv->base.pixmap->drawable.height),
-			        (one_trap_bound.x1),
-			        (one_trap_bound.y1),
-			        (one_trap_bound.x2),
-			        (one_trap_bound.y2),
-			        glamor_priv->yInverted, vertices, stride);
-			DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
-			       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-			       vertices[0], vertices[1],
-			       vertices[1*stride], vertices[1*stride + 1],
-			       vertices[2*stride], vertices[2*stride + 1],
-			       vertices[3*stride], vertices[3*stride + 1]);
-
-			/* Need to rebase. */
-			one_trap_bound.x1 -= bounds->x1;
-			one_trap_bound.x2 -= bounds->x1;
-			one_trap_bound.y1 -= bounds->y1;
-			one_trap_bound.y2 -= bounds->y1;
-
-			vertices -= 2;
-
-			glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale,
-			        one_trap_bound.x1, one_trap_bound.y1,
-			        one_trap_bound.x2, one_trap_bound.y2,
-			        glamor_priv->yInverted, vertices, stride);
-			DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
-			       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-			       vertices[0], vertices[1],
-			       vertices[1*stride], vertices[1*stride + 1],
-			       vertices[2*stride], vertices[2*stride + 1],
-			       vertices[3*stride], vertices[3*stride + 1]);
-			vertices += 4;
-
-			/* Set the top and bottom. */
-			params[0] = ((float)ptrap->top) / 65536;
-			params[1] = ((float)ptrap->bottom) / 65536;
-			glamor_set_const_ext(params, 2, vertices, 4, stride);
-			vertices += 2;
-
-			/* Set the left params. */
-			params[0] = ((float)ptrap->left.p1.x) / 65536;
-			params[1] = ((float)ptrap->left.p1.y) / 65536;
-
-			if (ptrap->left.p1.x == ptrap->left.p2.x) {
-				left_slope = 0.0;
-				params[3] = 1.0;
-			} else {
-				left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y))
-				             / ((float)(ptrap->left.p1.x - ptrap->left.p2.x));
-				params[3] = 0.0;
-			}
-			params[2] = left_slope;
-			glamor_set_const_ext(params, 4, vertices, 4, stride);
-			vertices += 4;
-
-			/* Set the left params. */
-			params[0] = ((float)ptrap->right.p1.x) / 65536;
-			params[1] = ((float)ptrap->right.p1.y) / 65536;
-
-			if (ptrap->right.p1.x == ptrap->right.p2.x) {
-				right_slope = 0.0;
-				params[3] = 1.0;
-			} else {
-				right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y))
-				              / ((float)(ptrap->right.p1.x - ptrap->right.p2.x));
-				params[3] = 0.0;
-			}
-			params[2] = right_slope;
-			glamor_set_const_ext(params, 4, vertices, 4, stride);
-
-			DEBUGF("trap_top = %f, trap_bottom = %f, "
-			       "trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
-			       "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n",
-			       ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536,
-			       ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536,
-			       left_slope,
-			       ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536,
-			       right_slope);
-
-			glamor_priv->render_nr_verts += 4;
-			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
-		}
-
-		i += mrect;
-
-		/* Now rendering. */
-		if (!glamor_priv->render_nr_verts)
-			continue;
-
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-		else {
-			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-			        glamor_priv->vbo_offset,
-			        glamor_priv->vb, GL_DYNAMIC_DRAW);
-		}
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    glamor_pixmap_private *pixmap_priv;
+    PixmapPtr pixmap = NULL;
+    GLint trapezoid_prog;
+    GLfloat xscale, yscale;
+    float left_slope, right_slope;
+    xTrapezoid *ptrap;
+    BoxRec one_trap_bound;
+    int nrect_max;
+    int i, j;
+    float *vertices;
+    float params[4];
+
+    glamor_priv = glamor_get_screen_private(screen);
+    trapezoid_prog = glamor_priv->trapezoid_prog;
+
+    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)
+        || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */
+        DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n");
+        return FALSE;
+    }
+
+    /* First, clear all to zero */
+    if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
+                      pixmap_priv->base.pixmap->drawable.height,
+                      GXclear, 0xFFFFFFFF, 0)) {
+        DEBUGF("glamor_solid failed, fallback\n");
+        return FALSE;
+    }
+
+    dispatch = glamor_get_dispatch(glamor_priv);
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+    pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+    /* Now draw the Trapezoid mask. */
+    dispatch->glUseProgram(trapezoid_prog);
+
+    dispatch->glEnable(GL_BLEND);
+    dispatch->glBlendFunc(GL_ONE, GL_ONE);
+
+    nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
+
+    for (i = 0; i < ntrap;) {
+        int mrect;
+        int stride;
+
+        mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i);
+        glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
+        stride = glamor_priv->vb_stride / sizeof(float);
+
+        for (j = 0; j < mrect; j++) {
+            ptrap = traps + i + j;
+
+            DEBUGF
+                ("--- The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
+                 "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
+                 "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
+                 xFixedToInt(ptrap->top), ptrap->top,
+                 xFixedToInt(ptrap->bottom), ptrap->bottom,
+                 xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x,
+                 xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y,
+                 xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x,
+                 xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y,
+                 xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x,
+                 xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y,
+                 xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x,
+                 xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
+
+            miTrapezoidBounds(1, ptrap, &one_trap_bound);
+
+            vertices =
+                (float *) (glamor_priv->vb + glamor_priv->vbo_offset) + 2;
+            glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
+                                   (pixmap_priv->base.pixmap->drawable.height),
+                                   (one_trap_bound.x1), (one_trap_bound.y1),
+                                   (one_trap_bound.x2), (one_trap_bound.y2),
+                                   glamor_priv->yInverted, vertices, stride);
+            DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+                   "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
+                   vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
+                   vertices[2 * stride], vertices[2 * stride + 1],
+                   vertices[3 * stride], vertices[3 * stride + 1]);
+
+            /* Need to rebase. */
+            one_trap_bound.x1 -= bounds->x1;
+            one_trap_bound.x2 -= bounds->x1;
+            one_trap_bound.y1 -= bounds->y1;
+            one_trap_bound.y2 -= bounds->y1;
+
+            vertices -= 2;
+
+            glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale,
+                                             one_trap_bound.x1,
+                                             one_trap_bound.y1,
+                                             one_trap_bound.x2,
+                                             one_trap_bound.y2,
+                                             glamor_priv->yInverted, vertices,
+                                             stride);
+            DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+                   "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
+                   vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
+                   vertices[2 * stride], vertices[2 * stride + 1],
+                   vertices[3 * stride], vertices[3 * stride + 1]);
+            vertices += 4;
+
+            /* Set the top and bottom. */
+            params[0] = ((float) ptrap->top) / 65536;
+            params[1] = ((float) ptrap->bottom) / 65536;
+            glamor_set_const_ext(params, 2, vertices, 4, stride);
+            vertices += 2;
+
+            /* Set the left params. */
+            params[0] = ((float) ptrap->left.p1.x) / 65536;
+            params[1] = ((float) ptrap->left.p1.y) / 65536;
+
+            if (ptrap->left.p1.x == ptrap->left.p2.x) {
+                left_slope = 0.0;
+                params[3] = 1.0;
+            }
+            else {
+                left_slope = ((float) (ptrap->left.p1.y - ptrap->left.p2.y))
+                    / ((float) (ptrap->left.p1.x - ptrap->left.p2.x));
+                params[3] = 0.0;
+            }
+            params[2] = left_slope;
+            glamor_set_const_ext(params, 4, vertices, 4, stride);
+            vertices += 4;
+
+            /* Set the left params. */
+            params[0] = ((float) ptrap->right.p1.x) / 65536;
+            params[1] = ((float) ptrap->right.p1.y) / 65536;
+
+            if (ptrap->right.p1.x == ptrap->right.p2.x) {
+                right_slope = 0.0;
+                params[3] = 1.0;
+            }
+            else {
+                right_slope = ((float) (ptrap->right.p1.y - ptrap->right.p2.y))
+                    / ((float) (ptrap->right.p1.x - ptrap->right.p2.x));
+                params[3] = 0.0;
+            }
+            params[2] = right_slope;
+            glamor_set_const_ext(params, 4, vertices, 4, stride);
+
+            DEBUGF("trap_top = %f, trap_bottom = %f, "
+                   "trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
+                   "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n",
+                   ((float) ptrap->top) / 65536,
+                   ((float) ptrap->bottom) / 65536,
+                   ((float) ptrap->left.p1.x) / 65536,
+                   ((float) ptrap->left.p1.y) / 65536, left_slope,
+                   ((float) ptrap->right.p1.x) / 65536,
+                   ((float) ptrap->right.p1.y) / 65536, right_slope);
+
+            glamor_priv->render_nr_verts += 4;
+            glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
+        }
+
+        i += mrect;
+
+        /* Now rendering. */
+        if (!glamor_priv->render_nr_verts)
+            continue;
+
+        if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+            dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+        else {
+            dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+            dispatch->glBufferData(GL_ARRAY_BUFFER,
+                                   glamor_priv->vbo_offset,
+                                   glamor_priv->vb, GL_DYNAMIC_DRAW);
+        }
 
 #ifndef GLAMOR_GLES2
-		dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
-			(glamor_priv->render_nr_verts * 3) / 2,
-		        GL_UNSIGNED_SHORT, NULL);
+        dispatch->glDrawRangeElements(GL_TRIANGLES, 0,
+                                      glamor_priv->render_nr_verts,
+                                      (glamor_priv->render_nr_verts * 3) / 2,
+                                      GL_UNSIGNED_SHORT, NULL);
 #else
-		dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
-		        GL_UNSIGNED_SHORT, NULL);
+        dispatch->glDrawElements(GL_TRIANGLES,
+                                 (glamor_priv->render_nr_verts * 3) / 2,
+                                 GL_UNSIGNED_SHORT, NULL);
 #endif
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-	dispatch->glBlendFunc(GL_ONE, GL_ZERO);
-	dispatch->glDisable(GL_BLEND);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return TRUE;
+    }
+
+    dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    dispatch->glBlendFunc(GL_ONE, GL_ZERO);
+    dispatch->glDisable(GL_BLEND);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    return TRUE;
 }
 
-#endif                           /*GLAMOR_TRAPEZOID_SHADER */
+#endif                          /*GLAMOR_TRAPEZOID_SHADER */
 
 /**
  * Creates an appropriate picture for temp mask use.
  */
 static PicturePtr
 glamor_create_mask_picture(ScreenPtr screen,
-        PicturePtr dst,
-        PictFormatPtr pict_format,
-        CARD16 width, CARD16 height, int gpu)
+                           PicturePtr dst,
+                           PictFormatPtr pict_format,
+                           CARD16 width, CARD16 height, int gpu)
 {
-	PixmapPtr pixmap;
-	PicturePtr picture;
-	int error;
-
-	if (!pict_format) {
-		if (dst->polyEdge == PolyEdgeSharp)
-			pict_format =
-			    PictureMatchFormat(screen, 1, PICT_a1);
-		else
-			pict_format =
-			    PictureMatchFormat(screen, 8, PICT_a8);
-		if (!pict_format)
-			return 0;
-	}
-
-	if (gpu) {
-		pixmap = glamor_create_pixmap(screen, width, height,
-		         pict_format->depth, 0);
-	} else {
-		pixmap = glamor_create_pixmap(screen, 0, 0,
-		         pict_format->depth,
-		         GLAMOR_CREATE_PIXMAP_CPU);
-	}
-
-	if (!pixmap)
-		return 0;
-	picture = CreatePicture(0, &pixmap->drawable, pict_format,
-	                        0, 0, serverClient, &error);
-	glamor_destroy_pixmap(pixmap);
-	return picture;
+    PixmapPtr pixmap;
+    PicturePtr picture;
+    int error;
+
+    if (!pict_format) {
+        if (dst->polyEdge == PolyEdgeSharp)
+            pict_format = PictureMatchFormat(screen, 1, PICT_a1);
+        else
+            pict_format = PictureMatchFormat(screen, 8, PICT_a8);
+        if (!pict_format)
+            return 0;
+    }
+
+    if (gpu) {
+        pixmap = glamor_create_pixmap(screen, width, height,
+                                      pict_format->depth, 0);
+    }
+    else {
+        pixmap = glamor_create_pixmap(screen, 0, 0,
+                                      pict_format->depth,
+                                      GLAMOR_CREATE_PIXMAP_CPU);
+    }
+
+    if (!pixmap)
+        return 0;
+    picture = CreatePicture(0, &pixmap->drawable, pict_format,
+                            0, 0, serverClient, &error);
+    glamor_destroy_pixmap(pixmap);
+    return picture;
 }
 
 static int
-_glamor_trapezoid_bounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+_glamor_trapezoid_bounds(int ntrap, xTrapezoid * traps, BoxPtr box)
 {
-	int has_large_trapezoid = 0;
-	box->y1 = MAXSHORT;
-	box->y2 = MINSHORT;
-	box->x1 = MAXSHORT;
-	box->x2 = MINSHORT;
-
-	for (; ntrap; ntrap--, traps++) {
-		INT16 x1, y1, x2, y2;
-
-		if (!xTrapezoidValid(traps))
-			continue;
-		y1 = xFixedToInt (traps->top);
-		if (y1 < box->y1)
-			box->y1 = y1;
-
-		y2 = xFixedToInt (xFixedCeil (traps->bottom));
-		if (y2 > box->y2)
-			box->y2 = y2;
-
-		x1 = xFixedToInt (min (_glamor_linefixedX (&traps->left, traps->top, FALSE),
-		                  _glamor_linefixedX (&traps->left, traps->bottom, FALSE)));
-		if (x1 < box->x1)
-			box->x1 = x1;
-
-		x2 = xFixedToInt (xFixedCeil (max (_glamor_linefixedX (&traps->right, traps->top, TRUE),
-		                  _glamor_linefixedX (&traps->right, traps->bottom, TRUE))));
-		if (x2 > box->x2)
-			box->x2 = x2;
-
-		if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32)
-			has_large_trapezoid = 1;
-	}
-
-	return has_large_trapezoid;
+    int has_large_trapezoid = 0;
+
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+
+    for (; ntrap; ntrap--, traps++) {
+        INT16 x1, y1, x2, y2;
+
+        if (!xTrapezoidValid(traps))
+            continue;
+        y1 = xFixedToInt(traps->top);
+        if (y1 < box->y1)
+            box->y1 = y1;
+
+        y2 = xFixedToInt(xFixedCeil(traps->bottom));
+        if (y2 > box->y2)
+            box->y2 = y2;
+
+        x1 = xFixedToInt(min
+                         (_glamor_linefixedX(&traps->left, traps->top, FALSE),
+                          _glamor_linefixedX(&traps->left, traps->bottom,
+                                             FALSE)));
+        if (x1 < box->x1)
+            box->x1 = x1;
+
+        x2 = xFixedToInt(xFixedCeil
+                         (max
+                          (_glamor_linefixedX(&traps->right, traps->top, TRUE),
+                           _glamor_linefixedX(&traps->right, traps->bottom,
+                                              TRUE))));
+        if (x2 > box->x2)
+            box->x2 = x2;
+
+        if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32)
+            has_large_trapezoid = 1;
+    }
+
+    return has_large_trapezoid;
 }
 
 /**
@@ -1660,135 +1692,137 @@ _glamor_trapezoids(CARD8 op,
                    PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
                    int ntrap, xTrapezoid * traps, Bool fallback)
 {
-	ScreenPtr screen = dst->pDrawable->pScreen;
-	BoxRec bounds;
-	PicturePtr picture;
-	INT16 x_dst, y_dst;
-	INT16 x_rel, y_rel;
-	int width, height, stride;
-	PixmapPtr pixmap;
-	pixman_image_t *image = NULL;
-	int ret = 0;
-	int has_large_trapezoid;
-
-	/* If a mask format wasn't provided, we get to choose, but behavior should
-	 * be as if there was no temporary mask the traps were accumulated into.
-	 */
-	if (!mask_format) {
-		if (dst->polyEdge == PolyEdgeSharp)
-			mask_format =
-			    PictureMatchFormat(screen, 1, PICT_a1);
-		else
-			mask_format =
-			    PictureMatchFormat(screen, 8, PICT_a8);
-		for (; ntrap; ntrap--, traps++)
-			glamor_trapezoids(op, src, dst, mask_format, x_src,
-			                  y_src, 1, traps);
-		return TRUE;
-	}
-
-	has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds);
-	DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
-	       "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1,
-	       bounds.x2, bounds.y1, bounds.y2, ntrap);
-
-	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-		return TRUE;
-
-	x_dst = traps[0].left.p1.x >> 16;
-	y_dst = traps[0].left.p1.y >> 16;
-
-	width = bounds.x2 - bounds.x1;
-	height = bounds.y2 - bounds.y1;
-	stride = PixmapBytePad(width, mask_format->depth);
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    BoxRec bounds;
+    PicturePtr picture;
+    INT16 x_dst, y_dst;
+    INT16 x_rel, y_rel;
+    int width, height, stride;
+    PixmapPtr pixmap;
+    pixman_image_t *image = NULL;
+    int ret = 0;
+    int has_large_trapezoid;
+
+    /* If a mask format wasn't provided, we get to choose, but behavior should
+     * be as if there was no temporary mask the traps were accumulated into.
+     */
+    if (!mask_format) {
+        if (dst->polyEdge == PolyEdgeSharp)
+            mask_format = PictureMatchFormat(screen, 1, PICT_a1);
+        else
+            mask_format = PictureMatchFormat(screen, 8, PICT_a8);
+        for (; ntrap; ntrap--, traps++)
+            glamor_trapezoids(op, src, dst, mask_format, x_src,
+                              y_src, 1, traps);
+        return TRUE;
+    }
+
+    has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds);
+    DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
+           "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1,
+           bounds.x2, bounds.y1, bounds.y2, ntrap);
+
+    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+        return TRUE;
+
+    x_dst = traps[0].left.p1.x >> 16;
+    y_dst = traps[0].left.p1.y >> 16;
+
+    width = bounds.x2 - bounds.x1;
+    height = bounds.y2 - bounds.y1;
+    stride = PixmapBytePad(width, mask_format->depth);
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
-	/* We seperate the render to two paths.
-	   Some GL implemetation do not implement the Anti-Alias for triangles
-	   and polygen's filling. So when the edge is not vertical or horizontal,
-	   sawtooth will be obvious. The trapezoid is widely used to render wide
-	   lines and circles. In these case, the line or circle will be divided
-	   into a large number of small trapezoids to approximate it, so the sawtooth
-	   at the edge will cause the result not be acceptable.
-	   When the depth of the mask is 1, there is no Anti-Alias needed, so we
-	   use the clip logic to generate the result directly(fast path).
-	   When the depth is not 1, AA is needed and we use a shader to generate
-	   a temp mask pixmap.
-	 */
-	if (mask_format->depth == 1) {
-		ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format,
-		                                     x_src, y_src, ntrap, traps);
-		if(ret)
-			return TRUE;
-	} else {
-		if (has_large_trapezoid || ntrap > 256) {
-			/* The shader speed is relative slower than pixman when generating big chunk
-			   trapezoid mask. We fallback to pixman to improve the performance. */
-			;
-		} else if (dst->polyMode == PolyModeImprecise) {
-			/*  The precise mode is that we sample the trapezoid on the centre points of
-			    an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
-			    and we use inside area ratio to replace it if the polymode == Imprecise. */
-			picture = glamor_create_mask_picture(screen, dst, mask_format,
-			          width, height, 1);
-			if (!picture)
-				return TRUE;
-
-			ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
-
-			if (!ret)
-				FreePicture(picture, 0);
-		}
-	}
+    /* We seperate the render to two paths.
+       Some GL implemetation do not implement the Anti-Alias for triangles
+       and polygen's filling. So when the edge is not vertical or horizontal,
+       sawtooth will be obvious. The trapezoid is widely used to render wide
+       lines and circles. In these case, the line or circle will be divided
+       into a large number of small trapezoids to approximate it, so the sawtooth
+       at the edge will cause the result not be acceptable.
+       When the depth of the mask is 1, there is no Anti-Alias needed, so we
+       use the clip logic to generate the result directly(fast path).
+       When the depth is not 1, AA is needed and we use a shader to generate
+       a temp mask pixmap.
+     */
+    if (mask_format->depth == 1) {
+        ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format,
+                                             x_src, y_src, ntrap, traps);
+        if (ret)
+            return TRUE;
+    }
+    else {
+        if (has_large_trapezoid || ntrap > 256) {
+            /* The shader speed is relative slower than pixman when generating big chunk
+               trapezoid mask. We fallback to pixman to improve the performance. */
+            ;
+        }
+        else if (dst->polyMode == PolyModeImprecise) {
+            /*  The precise mode is that we sample the trapezoid on the centre points of
+               an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
+               and we use inside area ratio to replace it if the polymode == Imprecise. */
+            picture = glamor_create_mask_picture(screen, dst, mask_format,
+                                                 width, height, 1);
+            if (!picture)
+                return TRUE;
+
+            ret =
+                _glamor_generate_trapezoid_with_shader(screen, picture, traps,
+                                                       ntrap, &bounds);
+
+            if (!ret)
+                FreePicture(picture, 0);
+        }
+    }
 #endif
 
-	if (!ret) {
-		DEBUGF("Fallback to sw rasterize of trapezoid\n");
-
-		picture = glamor_create_mask_picture(screen, dst, mask_format,
-		          width, height, 0);
-		if (!picture)
-			return TRUE;
-
-		image = pixman_image_create_bits(picture->format,
-		        width, height, NULL, stride);
-		if (!image) {
-			FreePicture(picture, 0);
-			return TRUE;
-		}
-
-		for (; ntrap; ntrap--, traps++)
-			pixman_rasterize_trapezoid(image,
-			        (pixman_trapezoid_t *) traps,
-			        -bounds.x1, -bounds.y1);
-
-		pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-
-		screen->ModifyPixmapHeader(pixmap, width, height,
-		        mask_format->depth,
-		        BitsPerPixel(mask_format->depth),
-		        PixmapBytePad(width,
-		                      mask_format->depth),
-		        pixman_image_get_data(image));
-	}
-
-	x_rel = bounds.x1 + x_src - x_dst;
-	y_rel = bounds.y1 + y_src - y_dst;
-	DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, "
-	       "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst,
-	       y_dst, x_rel, y_rel);
-
-	CompositePicture(op, src, picture, dst,
-	                 x_rel, y_rel,
-	                 0, 0,
-	                 bounds.x1, bounds.y1,
-	                 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
-
-	if (image)
-		pixman_image_unref(image);
-
-	FreePicture(picture, 0);
-	return TRUE;
+    if (!ret) {
+        DEBUGF("Fallback to sw rasterize of trapezoid\n");
+
+        picture = glamor_create_mask_picture(screen, dst, mask_format,
+                                             width, height, 0);
+        if (!picture)
+            return TRUE;
+
+        image = pixman_image_create_bits(picture->format,
+                                         width, height, NULL, stride);
+        if (!image) {
+            FreePicture(picture, 0);
+            return TRUE;
+        }
+
+        for (; ntrap; ntrap--, traps++)
+            pixman_rasterize_trapezoid(image,
+                                       (pixman_trapezoid_t *) traps,
+                                       -bounds.x1, -bounds.y1);
+
+        pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+
+        screen->ModifyPixmapHeader(pixmap, width, height,
+                                   mask_format->depth,
+                                   BitsPerPixel(mask_format->depth),
+                                   PixmapBytePad(width,
+                                                 mask_format->depth),
+                                   pixman_image_get_data(image));
+    }
+
+    x_rel = bounds.x1 + x_src - x_dst;
+    y_rel = bounds.y1 + y_src - y_dst;
+    DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, "
+           "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst,
+           y_dst, x_rel, y_rel);
+
+    CompositePicture(op, src, picture, dst,
+                     x_rel, y_rel,
+                     0, 0,
+                     bounds.x1, bounds.y1,
+                     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+
+    if (image)
+        pixman_image_unref(image);
+
+    FreePicture(picture, 0);
+    return TRUE;
 }
 
 void
@@ -1797,23 +1831,22 @@ glamor_trapezoids(CARD8 op,
                   PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
                   int ntrap, xTrapezoid * traps)
 {
-	DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
+    DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
 
-	_glamor_trapezoids(op, src, dst, mask_format, x_src,
-	                   y_src, ntrap, traps, TRUE);
+    _glamor_trapezoids(op, src, dst, mask_format, x_src,
+                       y_src, ntrap, traps, TRUE);
 }
 
 Bool
 glamor_trapezoids_nf(CARD8 op,
-        PicturePtr src, PicturePtr dst,
-        PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-        int ntrap, xTrapezoid * traps)
+                     PicturePtr src, PicturePtr dst,
+                     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+                     int ntrap, xTrapezoid * traps)
 {
-	DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
+    DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
 
-	return _glamor_trapezoids(op, src, dst, mask_format, x_src,
-	        y_src, ntrap, traps, FALSE);
+    return _glamor_trapezoids(op, src, dst, mask_format, x_src,
+                              y_src, ntrap, traps, FALSE);
 }
 
-#endif				/* RENDER */
-
+#endif                          /* RENDER */
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index e0f4a97..693eef1 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -30,51 +30,48 @@
 
 static Bool
 _glamor_triangles(CARD8 op,
-		 PicturePtr pSrc,
-		 PicturePtr pDst,
-		 PictFormatPtr maskFormat,
-		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris, Bool fallback)
+                  PicturePtr pSrc,
+                  PicturePtr pDst,
+                  PictFormatPtr maskFormat,
+                  INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris,
+                  Bool fallback)
 {
-	if (!fallback
-	    && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
-	    && (!pSrc->pDrawable
-		|| glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
-		return FALSE;
+    if (!fallback && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
+        && (!pSrc->pDrawable
+            || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
+        return FALSE;
 
-	if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) {
-		if (glamor_prepare_access_picture(pSrc,
-						  GLAMOR_ACCESS_RO)) {
+    if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) {
+        if (glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
 
-			fbTriangles(op, pSrc, pDst, maskFormat, xSrc,
-				    ySrc, ntris, tris);
+            fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
 
-			glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO);
-		}
+            glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO);
+        }
 
-		glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW);
-	}
-	return TRUE;
+        glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW);
+    }
+    return TRUE;
 }
 
 void
 glamor_triangles(CARD8 op,
-		 PicturePtr pSrc,
-		 PicturePtr pDst,
-		 PictFormatPtr maskFormat,
-		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+                 PicturePtr pSrc,
+                 PicturePtr pDst,
+                 PictFormatPtr maskFormat,
+                 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
 {
-	_glamor_triangles(op, pSrc, pDst, maskFormat, 
-			  xSrc, ySrc, ntris, tris, TRUE);
+    _glamor_triangles(op, pSrc, pDst, maskFormat,
+                      xSrc, ySrc, ntris, tris, TRUE);
 }
 
 Bool
 glamor_triangles_nf(CARD8 op,
-		    PicturePtr pSrc,
-		    PicturePtr pDst,
-		    PictFormatPtr maskFormat,
-		    INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+                    PicturePtr pSrc,
+                    PicturePtr pDst,
+                    PictFormatPtr maskFormat,
+                    INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
 {
-	return _glamor_triangles(op, pSrc, pDst, maskFormat, 
-				 xSrc, ySrc, ntris, tris, FALSE);
+    return _glamor_triangles(op, pSrc, pDst, maskFormat,
+                             xSrc, ySrc, ntris, tris, FALSE);
 }
-
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d307838..b27c56c 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -254,7 +254,6 @@
 	}							\
    } while(0)
 
-
 /* _x1_ ... _y2_ may has fractional. */
 #define glamor_get_repeat_transform_coords(priv, repeat_type, tx1,	\
 					   ty1, _x1_, _y1_)		\
@@ -402,8 +401,6 @@
 						  2);			\
   } while (0)
 
-
-
 #define glamor_set_normalize_tri_tcoords(xscale,		\
 					 yscale,		\
 					 vtx,			\
@@ -475,7 +472,6 @@
    }									\
   } while (0)
 
-
 #define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
 							 repeat_type,	\
 							 matrix,	\
@@ -541,7 +537,6 @@
 				   x2, y2, yInverted, vertices, stride);\
  } while(0)
 
-
 #define glamor_set_normalize_tcoords(priv, xscale, yscale,		\
 				     x1, y1, x2, y2,			\
                                      yInverted, vertices)		\
@@ -577,7 +572,6 @@
 				   stride);				\
  } while(0)
 
-
 #define glamor_set_repeat_normalize_tcoords(priv, repeat_type,		\
 					    xscale, yscale,		\
 					    _x1_, _y1_, _x2_, _y2_,	\
@@ -721,7 +715,6 @@
     (vertices)[3 * stride + 1] = _t5_;					\
   } while(0)
 
-
 #define glamor_set_normalize_vcoords(priv, xscale, yscale,		\
 				     x1, y1, x2, y2,			\
                                      yInverted, vertices)		\
@@ -786,44 +779,46 @@
 inline static void
 glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
 {
-	int x_min, y_min;
-	int x_max, y_max;
-	int i;
-	x_min = y_min = MAXSHORT;
-	x_max = y_max = MINSHORT;
-	for (i = 0; i < nbox; i++) {
-		if (x_min > boxes[i].x1)
-			x_min = boxes[i].x1;
-		if (y_min > boxes[i].y1)
-			y_min = boxes[i].y1;
-
-		if (x_max < boxes[i].x2)
-			x_max = boxes[i].x2;
-		if (y_max < boxes[i].y2)
-			y_max = boxes[i].y2;
-	}
-	bound->x1 = x_min;
-	bound->y1 = y_min;
-	bound->x2 = x_max;
-	bound->y2 = y_max;
+    int x_min, y_min;
+    int x_max, y_max;
+    int i;
+
+    x_min = y_min = MAXSHORT;
+    x_max = y_max = MINSHORT;
+    for (i = 0; i < nbox; i++) {
+        if (x_min > boxes[i].x1)
+            x_min = boxes[i].x1;
+        if (y_min > boxes[i].y1)
+            y_min = boxes[i].y1;
+
+        if (x_max < boxes[i].x2)
+            x_max = boxes[i].x2;
+        if (y_max < boxes[i].y2)
+            y_max = boxes[i].y2;
+    }
+    bound->x1 = x_min;
+    bound->y1 = y_min;
+    bound->x2 = x_max;
+    bound->y2 = y_max;
 }
 
 inline static void
 glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 {
-	int i;
-	for (i = 0; i < nbox; i++) {
-		boxes[i].x1 += dx;
-		boxes[i].y1 += dy;
-		boxes[i].x2 += dx;
-		boxes[i].y2 += dy;
-	}
+    int i;
+
+    for (i = 0; i < nbox; i++) {
+        boxes[i].x1 += dx;
+        boxes[i].y1 += dy;
+        boxes[i].x2 += dx;
+        boxes[i].y2 += dy;
+    }
 }
 
 static inline Bool
-region_is_empty(pixman_region16_t *region)
+region_is_empty(pixman_region16_t * region)
 {
-	return region->data && region->data->numRects == 0;
+    return region->data && region->data->numRects == 0;
 }
 
 #ifndef ARRAY_SIZE
@@ -857,58 +852,58 @@ region_is_empty(pixman_region16_t *region)
 static inline CARD32
 format_for_depth(int depth)
 {
-	switch (depth) {
-	case 1:
-		return PICT_a1;
-	case 4:
-		return PICT_a4;
-	case 8:
-		return PICT_a8;
-	case 15:
-		return PICT_x1r5g5b5;
-	case 16:
-		return PICT_r5g6b5;
-	default:
-	case 24:
-		return PICT_x8r8g8b8;
+    switch (depth) {
+    case 1:
+        return PICT_a1;
+    case 4:
+        return PICT_a4;
+    case 8:
+        return PICT_a8;
+    case 15:
+        return PICT_x1r5g5b5;
+    case 16:
+        return PICT_r5g6b5;
+    default:
+    case 24:
+        return PICT_x8r8g8b8;
 #if XORG_VERSION_CURRENT >= 10699900
-	case 30:
-		return PICT_x2r10g10b10;
+    case 30:
+        return PICT_x2r10g10b10;
 #endif
-	case 32:
-		return PICT_a8r8g8b8;
-	}
+    case 32:
+        return PICT_a8r8g8b8;
+    }
 }
 
 static inline void
 gl_iformat_for_depth(int depth, GLenum * format)
 {
-	switch (depth) {
+    switch (depth) {
 #ifndef GLAMOR_GLES2
-	case 1:
-	case 8:
-		*format = GL_ALPHA;
-		break;
+    case 1:
+    case 8:
+        *format = GL_ALPHA;
+        break;
 #endif
-	default:
-		*format = GL_RGBA;
-		break;
-       }
+    default:
+        *format = GL_RGBA;
+        break;
+    }
 }
 
 static inline CARD32
 format_for_pixmap(PixmapPtr pixmap)
 {
-	glamor_pixmap_private *pixmap_priv;
-	PictFormatShort pict_format;
+    glamor_pixmap_private *pixmap_priv;
+    PictFormatShort pict_format;
 
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-		pict_format = pixmap_priv->base.picture->format;
-	else
-		pict_format = format_for_depth(pixmap->drawable.depth);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+        pict_format = pixmap_priv->base.picture->format;
+    else
+        pict_format = format_for_depth(pixmap->drawable.depth);
 
-	return pict_format;
+    return pict_format;
 }
 
 #define REVERT_NONE       		0
@@ -939,114 +934,112 @@ format_for_pixmap(PixmapPtr pixmap)
 #ifndef GLAMOR_GLES2
 static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum * tex_format,
-					   GLenum * tex_type,
-					   int *no_alpha,
-					   int *revert,
-					   int *swap_rb,
-					   int is_upload)
-
+                                           GLenum * tex_format,
+                                           GLenum * tex_type,
+                                           int *no_alpha,
+                                           int *revert,
+                                           int *swap_rb, int is_upload)
 {
-	*no_alpha = 0;
-	*revert = REVERT_NONE;
-	*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
-	switch (format) {
-	case PICT_a1:
-		*tex_format = GL_ALPHA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		*revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
-		break;
-	case PICT_b8g8r8x8:
-		*no_alpha = 1;
-	case PICT_b8g8r8a8:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_INT_8_8_8_8;
-		break;
-
-	case PICT_x8r8g8b8:
-		*no_alpha = 1;
-	case PICT_a8r8g8b8:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-		break;
-	case PICT_x8b8g8r8:
-		*no_alpha = 1;
-	case PICT_a8b8g8r8:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-		break;
-	case PICT_x2r10g10b10:
-		*no_alpha = 1;
-	case PICT_a2r10g10b10:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-		break;
-	case PICT_x2b10g10r10:
-		*no_alpha = 1;
-	case PICT_a2b10g10r10:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-		break;
-
-	case PICT_r5g6b5:
-		*tex_format = GL_RGB;
-		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
-		break;
-	case PICT_b5g6r5:
-		*tex_format = GL_RGB;
-		*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
-		break;
-	case PICT_x1b5g5r5:
-		*no_alpha = 1;
-	case PICT_a1b5g5r5:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		break;
-
-	case PICT_x1r5g5b5:
-		*no_alpha = 1;
-	case PICT_a1r5g5b5:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		break;
-	case PICT_a8:
-		*tex_format = GL_ALPHA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		break;
-	case PICT_x4r4g4b4:
-		*no_alpha = 1;
-	case PICT_a4r4g4b4:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		break;
-
-	case PICT_x4b4g4r4:
-		*no_alpha = 1;
-	case PICT_a4b4g4r4:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		break;
-
-	default:
-		LogMessageVerb(X_INFO, 0,
-			       "fail to get matched format for %x \n",
-			       format);
-		return -1;
-	}
-	return 0;
+    *no_alpha = 0;
+    *revert = REVERT_NONE;
+    *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+    switch (format) {
+    case PICT_a1:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        break;
+    case PICT_b8g8r8x8:
+        *no_alpha = 1;
+    case PICT_b8g8r8a8:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+        break;
+
+    case PICT_x8r8g8b8:
+        *no_alpha = 1;
+    case PICT_a8r8g8b8:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        break;
+    case PICT_x8b8g8r8:
+        *no_alpha = 1;
+    case PICT_a8b8g8r8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+        break;
+    case PICT_x2r10g10b10:
+        *no_alpha = 1;
+    case PICT_a2r10g10b10:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        break;
+    case PICT_x2b10g10r10:
+        *no_alpha = 1;
+    case PICT_a2b10g10r10:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+        break;
+
+    case PICT_r5g6b5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case PICT_b5g6r5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+        break;
+    case PICT_x1b5g5r5:
+        *no_alpha = 1;
+    case PICT_a1b5g5r5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        break;
+
+    case PICT_x1r5g5b5:
+        *no_alpha = 1;
+    case PICT_a1r5g5b5:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+        break;
+    case PICT_a8:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        break;
+    case PICT_x4r4g4b4:
+        *no_alpha = 1;
+    case PICT_a4r4g4b4:
+        *tex_format = GL_BGRA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        break;
+
+    case PICT_x4b4g4r4:
+        *no_alpha = 1;
+    case PICT_a4b4g4r4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+        break;
+
+    default:
+        LogMessageVerb(X_INFO, 0,
+                       "fail to get matched format for %x \n", format);
+        return -1;
+    }
+    return 0;
 }
 
 /* Currently, we use RGBA to represent all formats. */
-inline static int cache_format(GLenum format)
+inline static int
+cache_format(GLenum format)
 {
-	switch (format) {
-	case GL_ALPHA:
-		return 1;
-	case GL_RGBA:
-		return 0;
-	default:
-		return -1;
-	}
+    switch (format) {
+    case GL_ALPHA:
+        return 1;
+    case GL_RGBA:
+        return 0;
+    default:
+        return -1;
+    }
 }
 
 #else
@@ -1054,779 +1047,819 @@ inline static int cache_format(GLenum format)
 
 static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum * tex_format,
-					   GLenum * tex_type,
-					   int *no_alpha,
-					   int *revert,
-					   int *swap_rb,
-					   int is_upload)
+                                           GLenum * tex_format,
+                                           GLenum * tex_type,
+                                           int *no_alpha,
+                                           int *revert,
+                                           int *swap_rb, int is_upload)
 {
-	int need_swap_rb = 0;
-
-	*no_alpha = 0;
-	*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
-	switch (format) {
-	case PICT_b8g8r8x8:
-		*no_alpha = 1;
-	case PICT_b8g8r8a8:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		need_swap_rb = 1;
-		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-		break;
-
-	case PICT_x8r8g8b8:
-		*no_alpha = 1;
-	case PICT_a8r8g8b8:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		need_swap_rb = 1;
-		break;
-
-	case PICT_x8b8g8r8:
-		*no_alpha = 1;
-	case PICT_a8b8g8r8:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		break;
-
-	case PICT_x2r10g10b10:
-		*no_alpha = 1;
-	case PICT_a2r10g10b10:
-		*tex_format = GL_RGBA;
-		/* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
-		 * we have to use GL_UNSIGNED_BYTE and do the conversion in
-		 * shader latter.*/
-		*tex_type = GL_UNSIGNED_BYTE;
-		if (is_upload == 1) {
-			if (!IS_LITTLE_ENDIAN)
-				*revert = REVERT_UPLOADING_10_10_10_2;
-			else
-				*revert = REVERT_UPLOADING_2_10_10_10;
-		}
-		else {
-			if (!IS_LITTLE_ENDIAN) {
-				*revert = REVERT_DOWNLOADING_10_10_10_2;
-			}
-			else {
-				*revert = REVERT_DOWNLOADING_2_10_10_10;
-			}
-		}
-		need_swap_rb = 1;
-
-		break;
-
-	case PICT_x2b10g10r10:
-		*no_alpha = 1;
-	case PICT_a2b10g10r10:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		if (is_upload == 1) {
-			if (!IS_LITTLE_ENDIAN)
-				*revert = REVERT_UPLOADING_10_10_10_2;
-			else
-				*revert = REVERT_UPLOADING_2_10_10_10;
-		}
-		else {
-			if (!IS_LITTLE_ENDIAN) {
-				*revert = REVERT_DOWNLOADING_10_10_10_2;
-			}
-			else {
-				*revert = REVERT_DOWNLOADING_2_10_10_10;
-			}
-		}
-		break;
-
-	case PICT_r5g6b5:
-		*tex_format = GL_RGB;
-		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
-		*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
-		break;
-
-	case PICT_b5g6r5:
-		*tex_format = GL_RGB;
-		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
-		need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
-		break;
-
-	case PICT_x1b5g5r5:
-		*no_alpha = 1;
-	case PICT_a1b5g5r5:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-		if (IS_LITTLE_ENDIAN) {
-			*revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5;
-		} else
-			*revert = REVERT_NONE;
-		break;
-
-	case PICT_x1r5g5b5:
-		*no_alpha = 1;
-	case PICT_a1r5g5b5:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
-		if (IS_LITTLE_ENDIAN) {
-			*revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5;
-		} else
-			*revert = REVERT_NONE;
-		need_swap_rb = 1;
-		break;
-
-	case PICT_a1:
-		*tex_format = GL_ALPHA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		*revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
-		break;
-
-	case PICT_a8:
-		*tex_format = GL_ALPHA;
-		*tex_type = GL_UNSIGNED_BYTE;
-		*revert = REVERT_NONE;
-		break;
-
-	case PICT_x4r4g4b4:
-		*no_alpha = 1;
-	case PICT_a4r4g4b4:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-		need_swap_rb = 1;
-		break;
-
-	case PICT_x4b4g4r4:
-		*no_alpha = 1;
-	case PICT_a4b4g4r4:
-		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
-		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
-		break;
-
-	default:
-		LogMessageVerb(X_INFO, 0,
-			       "fail to get matched format for %x \n",
-			       format);
-		return -1;
-	}
-
-	if (need_swap_rb)
-		*swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
-	else
-		*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
-	return 0;
+    int need_swap_rb = 0;
+
+    *no_alpha = 0;
+    *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+    switch (format) {
+    case PICT_b8g8r8x8:
+        *no_alpha = 1;
+    case PICT_b8g8r8a8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        need_swap_rb = 1;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        break;
+
+    case PICT_x8r8g8b8:
+        *no_alpha = 1;
+    case PICT_a8r8g8b8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_x8b8g8r8:
+        *no_alpha = 1;
+    case PICT_a8b8g8r8:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        break;
+
+    case PICT_x2r10g10b10:
+        *no_alpha = 1;
+    case PICT_a2r10g10b10:
+        *tex_format = GL_RGBA;
+        /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
+         * we have to use GL_UNSIGNED_BYTE and do the conversion in
+         * shader latter.*/
+        *tex_type = GL_UNSIGNED_BYTE;
+        if (is_upload == 1) {
+            if (!IS_LITTLE_ENDIAN)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+        }
+        else {
+            if (!IS_LITTLE_ENDIAN) {
+                *revert = REVERT_DOWNLOADING_10_10_10_2;
+            }
+            else {
+                *revert = REVERT_DOWNLOADING_2_10_10_10;
+            }
+        }
+        need_swap_rb = 1;
+
+        break;
+
+    case PICT_x2b10g10r10:
+        *no_alpha = 1;
+    case PICT_a2b10g10r10:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        if (is_upload == 1) {
+            if (!IS_LITTLE_ENDIAN)
+                *revert = REVERT_UPLOADING_10_10_10_2;
+            else
+                *revert = REVERT_UPLOADING_2_10_10_10;
+        }
+        else {
+            if (!IS_LITTLE_ENDIAN) {
+                *revert = REVERT_DOWNLOADING_10_10_10_2;
+            }
+            else {
+                *revert = REVERT_DOWNLOADING_2_10_10_10;
+            }
+        }
+        break;
+
+    case PICT_r5g6b5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+        break;
+
+    case PICT_b5g6r5:
+        *tex_format = GL_RGB;
+        *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+        need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
+        break;
+
+    case PICT_x1b5g5r5:
+        *no_alpha = 1;
+    case PICT_a1b5g5r5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+        if (IS_LITTLE_ENDIAN) {
+            *revert =
+                is_upload ? REVERT_UPLOADING_1_5_5_5 :
+                REVERT_DOWNLOADING_1_5_5_5;
+        }
+        else
+            *revert = REVERT_NONE;
+        break;
+
+    case PICT_x1r5g5b5:
+        *no_alpha = 1;
+    case PICT_a1r5g5b5:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+        if (IS_LITTLE_ENDIAN) {
+            *revert =
+                is_upload ? REVERT_UPLOADING_1_5_5_5 :
+                REVERT_DOWNLOADING_1_5_5_5;
+        }
+        else
+            *revert = REVERT_NONE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_a1:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+        break;
+
+    case PICT_a8:
+        *tex_format = GL_ALPHA;
+        *tex_type = GL_UNSIGNED_BYTE;
+        *revert = REVERT_NONE;
+        break;
+
+    case PICT_x4r4g4b4:
+        *no_alpha = 1;
+    case PICT_a4r4g4b4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        need_swap_rb = 1;
+        break;
+
+    case PICT_x4b4g4r4:
+        *no_alpha = 1;
+    case PICT_a4b4g4r4:
+        *tex_format = GL_RGBA;
+        *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+        *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+        break;
+
+    default:
+        LogMessageVerb(X_INFO, 0,
+                       "fail to get matched format for %x \n", format);
+        return -1;
+    }
+
+    if (need_swap_rb)
+        *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
+    else
+        *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+    return 0;
 }
 
-inline static int cache_format(GLenum format)
+inline static int
+cache_format(GLenum format)
 {
-	switch (format) {
-	case GL_ALPHA:
-		return 2;
-	case GL_RGB:
-		return 1;
-	case GL_RGBA:
-		return 0;
-	default:
-		return -1;
-	}
+    switch (format) {
+    case GL_ALPHA:
+        return 2;
+    case GL_RGB:
+        return 1;
+    case GL_RGBA:
+        return 0;
+    default:
+        return -1;
+    }
 }
 
 #endif
 
-
 static inline int
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
-				       GLenum * format,
-				       GLenum * type,
-				       int *no_alpha,
-				       int *revert,
-				       int *swap_rb,
-				       int is_upload)
+                                       GLenum * format,
+                                       GLenum * type,
+                                       int *no_alpha,
+                                       int *revert, int *swap_rb, int is_upload)
 {
-	glamor_pixmap_private *pixmap_priv;
-	PictFormatShort pict_format;
-
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-		pict_format = pixmap_priv->base.picture->format;
-	else
-		pict_format = format_for_depth(pixmap->drawable.depth);
-
-	return glamor_get_tex_format_type_from_pictformat(pict_format,
-							  format, type,
-							  no_alpha,
-							  revert,
-							  swap_rb,
-							  is_upload);
+    glamor_pixmap_private *pixmap_priv;
+    PictFormatShort pict_format;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+        pict_format = pixmap_priv->base.picture->format;
+    else
+        pict_format = format_for_depth(pixmap->drawable.depth);
+
+    return glamor_get_tex_format_type_from_pictformat(pict_format,
+                                                      format, type,
+                                                      no_alpha,
+                                                      revert,
+                                                      swap_rb, is_upload);
 }
 
-
 /* borrowed from uxa */
 static inline Bool
 glamor_get_rgba_from_pixel(CARD32 pixel,
-			   float *red,
-			   float *green,
-			   float *blue, float *alpha, CARD32 format)
+                           float *red,
+                           float *green,
+                           float *blue, float *alpha, CARD32 format)
 {
-	int rbits, bbits, gbits, abits;
-	int rshift, bshift, gshift, ashift;
-
-	rbits = PICT_FORMAT_R(format);
-	gbits = PICT_FORMAT_G(format);
-	bbits = PICT_FORMAT_B(format);
-	abits = PICT_FORMAT_A(format);
-
-	if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
-		rshift = gshift = bshift = ashift = 0;
-	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
-		bshift = 0;
-		gshift = bbits;
-		rshift = gshift + gbits;
-		ashift = rshift + rbits;
-	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
-		rshift = 0;
-		gshift = rbits;
-		bshift = gshift + gbits;
-		ashift = bshift + bbits;
+    int rbits, bbits, gbits, abits;
+    int rshift, bshift, gshift, ashift;
+
+    rbits = PICT_FORMAT_R(format);
+    gbits = PICT_FORMAT_G(format);
+    bbits = PICT_FORMAT_B(format);
+    abits = PICT_FORMAT_A(format);
+
+    if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
+        rshift = gshift = bshift = ashift = 0;
+    }
+    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+        bshift = 0;
+        gshift = bbits;
+        rshift = gshift + gbits;
+        ashift = rshift + rbits;
+    }
+    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+        rshift = 0;
+        gshift = rbits;
+        bshift = gshift + gbits;
+        ashift = bshift + bbits;
 #if XORG_VERSION_CURRENT >= 10699900
-	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
-		ashift = 0;
-		rshift = abits;
-		if (abits == 0)
-			rshift = PICT_FORMAT_BPP(format) - (rbits + gbits +
-							    bbits);
-		gshift = rshift + rbits;
-		bshift = gshift + gbits;
+    }
+    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+        ashift = 0;
+        rshift = abits;
+        if (abits == 0)
+            rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits);
+        gshift = rshift + rbits;
+        bshift = gshift + gbits;
 #endif
-	} else {
-		return FALSE;
-	}
+    }
+    else {
+        return FALSE;
+    }
 #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
   *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
     / (float)((1<<(_bits_)) - 1)
 
-	if (rbits)
-		COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
-	else
-		*red = 0;
+    if (rbits)
+        COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
+    else
+        *red = 0;
 
-	if (gbits)
-		COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
-	else
-		*green = 0;
+    if (gbits)
+        COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
+    else
+        *green = 0;
 
-	if (bbits)
-		COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
-	else
-		*blue = 0;
+    if (bbits)
+        COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
+    else
+        *blue = 0;
 
-	if (abits)
-		COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
-	else
-		*alpha = 1;
+    if (abits)
+        COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
+    else
+        *alpha = 1;
 
-	return TRUE;
+    return TRUE;
 }
 
-inline static Bool glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth)
+inline static Bool
+glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth)
 {
-	GLenum iformat;
-
-	gl_iformat_for_depth(depth, &iformat);
-	switch (iformat) {
-		case GL_RGBA:
-			return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8);
-		case GL_ALPHA:
-			return (pict_format == PICT_a8);
-		default:
-			return FALSE;
-	}
+    GLenum iformat;
+
+    gl_iformat_for_depth(depth, &iformat);
+    switch (iformat) {
+    case GL_RGBA:
+        return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8);
+    case GL_ALPHA:
+        return (pict_format == PICT_a8);
+    default:
+        return FALSE;
+    }
 }
 
 /* return TRUE if we can access this pixmap at DDX driver. */
-inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
+inline static Bool
+glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
 {
-	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-	return (!pixmap_priv
-		|| (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-		    || pixmap_priv->type == GLAMOR_MEMORY
-		    || pixmap_priv->type == GLAMOR_DRM_ONLY));
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    return (!pixmap_priv
+            || (pixmap_priv->type == GLAMOR_TEXTURE_DRM
+                || pixmap_priv->type == GLAMOR_MEMORY
+                || pixmap_priv->type == GLAMOR_DRM_ONLY));
 }
 
-inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc)
+inline static Bool
+glamor_ddx_fallback_check_gc(GCPtr gc)
 {
-	PixmapPtr pixmap;
-	if (!gc)
-		return TRUE;
-        switch (gc->fillStyle) {
-        case FillStippled:
-        case FillOpaqueStippled:
-                pixmap = gc->stipple;
-                break;
-        case FillTiled:
-                pixmap = gc->tile.pixmap;
-                break;
-	default:
-		pixmap = NULL;
-        }
-	return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
+    PixmapPtr pixmap;
+
+    if (!gc)
+        return TRUE;
+    switch (gc->fillStyle) {
+    case FillStippled:
+    case FillOpaqueStippled:
+        pixmap = gc->stipple;
+        break;
+    case FillTiled:
+        pixmap = gc->tile.pixmap;
+        break;
+    default:
+        pixmap = NULL;
+    }
+    return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
 }
-inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap)
+
+inline static Bool
+glamor_is_large_pixmap(PixmapPtr pixmap)
 {
-	glamor_pixmap_private *priv;
+    glamor_pixmap_private *priv;
 
-	priv = glamor_get_pixmap_private(pixmap);
-	return (priv->type == GLAMOR_TEXTURE_LARGE);
+    priv = glamor_get_pixmap_private(pixmap);
+    return (priv->type == GLAMOR_TEXTURE_LARGE);
 }
 
-inline static Bool glamor_is_large_picture(PicturePtr picture)
+inline static Bool
+glamor_is_large_picture(PicturePtr picture)
 {
-	PixmapPtr pixmap;
+    PixmapPtr pixmap;
 
-	if (picture->pDrawable) {
-		pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-		return glamor_is_large_pixmap(pixmap);
-	}
-	return FALSE;
+    if (picture->pDrawable) {
+        pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+        return glamor_is_large_pixmap(pixmap);
+    }
+    return FALSE;
 }
 
-inline static Bool glamor_tex_format_is_readable(GLenum format)
+inline static Bool
+glamor_tex_format_is_readable(GLenum format)
 {
-	return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA));
+    return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA));
 
 }
 
-static inline void _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
+static inline void
+_glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-	int i,j;
-	unsigned char * p = pixmap->devPrivate.ptr;
-	int stride = pixmap->devKind;
-
-	p = p + y * stride + x;
-
-	for (i = 0; i < h; i++)
-	{
-		ErrorF("line %3d: ", i);
-		for(j = 0; j < w; j++)
-			ErrorF("%2d ", (p[j/8] & (1 << (j%8)))>>(j%8));
-		p += stride;
-		ErrorF("\n");
-	}
+    int i, j;
+    unsigned char *p = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind;
+
+    p = p + y * stride + x;
+
+    for (i = 0; i < h; i++) {
+        ErrorF("line %3d: ", i);
+        for (j = 0; j < w; j++)
+            ErrorF("%2d ", (p[j / 8] & (1 << (j % 8))) >> (j % 8));
+        p += stride;
+        ErrorF("\n");
+    }
 }
 
-static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
+static inline void
+_glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-	int i,j;
-	unsigned char * p = pixmap->devPrivate.ptr;
-	int stride = pixmap->devKind;
-
-	p = p + y * stride + x;
-
-	for (i = 0; i < h; i++)
-	{
-		ErrorF("line %3d: ", i);
-		for(j = 0; j < w; j++)
-			ErrorF("%2x ", p[j]);
-		p += stride;
-		ErrorF("\n");
-	}
+    int i, j;
+    unsigned char *p = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind;
+
+    p = p + y * stride + x;
+
+    for (i = 0; i < h; i++) {
+        ErrorF("line %3d: ", i);
+        for (j = 0; j < w; j++)
+            ErrorF("%2x ", p[j]);
+        p += stride;
+        ErrorF("\n");
+    }
 }
 
-static inline void _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
+static inline void
+_glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-	int i,j;
-	unsigned short * p = pixmap->devPrivate.ptr;
-	int stride = pixmap->devKind / 2;
-
-	p = p + y * stride + x;
-
-	for (i = 0; i < h; i++)
-	{
-		ErrorF("line %3d: ", i);
-		for(j = 0; j < w; j++)
-			ErrorF("%2x ", p[j]);
-		p += stride;
-		ErrorF("\n");
-	}
+    int i, j;
+    unsigned short *p = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind / 2;
+
+    p = p + y * stride + x;
+
+    for (i = 0; i < h; i++) {
+        ErrorF("line %3d: ", i);
+        for (j = 0; j < w; j++)
+            ErrorF("%2x ", p[j]);
+        p += stride;
+        ErrorF("\n");
+    }
 }
 
-static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
+static inline void
+_glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-	int i,j;
-	unsigned int * p = pixmap->devPrivate.ptr;
-	int stride = pixmap->devKind / 4;
-
-	p = p + y * stride + x;
-
-	for (i = 0; i < h; i++)
-	{
-		ErrorF("line %3d: ", i);
-		for(j = 0; j < w; j++)
-			ErrorF("%2x ", p[j]);
-		p += stride;
-		ErrorF("\n");
-	}
+    int i, j;
+    unsigned int *p = pixmap->devPrivate.ptr;
+    int stride = pixmap->devKind / 4;
+
+    p = p + y * stride + x;
+
+    for (i = 0; i < h; i++) {
+        ErrorF("line %3d: ", i);
+        for (j = 0; j < w; j++)
+            ErrorF("%2x ", p[j]);
+        p += stride;
+        ErrorF("\n");
+    }
 }
 
-static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
+static inline void
+glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
 {
-	w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
-	h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
-
-	glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
-	switch (pixmap->drawable.depth) {
-	case 8:
-		_glamor_dump_pixmap_byte(pixmap, x, y, w, h);
-		break;
-	case 15:
-	case 16:
-		_glamor_dump_pixmap_sword(pixmap, x, y, w, h);
-		break;
-
-	case 24:
-	case 32:
-		_glamor_dump_pixmap_word(pixmap, x, y, w, h);
-		break;
-	case 1:
-		_glamor_dump_pixmap_bits(pixmap, x, y, w, h);
-		break;
-	default:
-		ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
-	}
-	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+    w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
+    h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
+
+    glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+    switch (pixmap->drawable.depth) {
+    case 8:
+        _glamor_dump_pixmap_byte(pixmap, x, y, w, h);
+        break;
+    case 15:
+    case 16:
+        _glamor_dump_pixmap_sword(pixmap, x, y, w, h);
+        break;
+
+    case 24:
+    case 32:
+        _glamor_dump_pixmap_word(pixmap, x, y, w, h);
+        break;
+    case 1:
+        _glamor_dump_pixmap_bits(pixmap, x, y, w, h);
+        break;
+    default:
+        ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
+    }
+    glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 }
 
-static inline void _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
-                                           int x, int y, int w, int h,
-                                           PictFormatShort short_format,
-                                           int all, int diffs)
+static inline void
+_glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
+                        int x, int y, int w, int h,
+                        PictFormatShort short_format, int all, int diffs)
 {
-	int i, j;
-	unsigned char * p1 = pixmap1->devPrivate.ptr;
-	unsigned char * p2 = pixmap2->devPrivate.ptr;
-	int line_need_printed = 0;
-	int test_code = 0xAABBCCDD;
-	int little_endian = 0;
-	unsigned char *p_test;
-	int bpp = pixmap1->drawable.depth == 8 ? 1 : 4;
-	int stride = pixmap1->devKind;
-
-	assert(pixmap1->devKind == pixmap2->devKind);
-
-	ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h);
-
-	p1 = p1 + y * stride + x;
-	p2 = p2 + y * stride + x;
-
-	if (all) {
-		for (i = 0; i < h; i++) {
-			ErrorF("line %3d: ", i);
-
-			for (j = 0; j < stride; j++) {
-				if (j % bpp == 0)
-					ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
-				else
-					ErrorF("%2x:%2x ", p1[j], p2[j]);
-			}
-
-			p1 += stride;
-			p2 += stride;
-			ErrorF("\n");
-		}
-	} else {
-		if (short_format == PICT_a8r8g8b8) {
-			p_test = (unsigned char *) & test_code;
-			little_endian = (*p_test == 0xDD);
-			bpp = 4;
-
-			for (i = 0; i < h; i++) {
-				line_need_printed = 0;
-
-				for (j = 0; j < stride; j++) {
-					if (p1[j] != p2[j] && (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) {
-						if (line_need_printed) {
-							if (little_endian) {
-								switch (j % 4) {
-									case 2:
-										ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 1:
-										ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 0:
-										ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 3:
-										ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-								}
-							} else {
-								switch (j % 4) {
-									case 1:
-										ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 2:
-										ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 3:
-										ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-									case 0:
-										ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]);
-										break;
-								}
-							}
-						} else {
-							line_need_printed = 1;
-							j = -1;
-							ErrorF("line %3d: ", i);
-							continue;
-						}
-					}
-				}
-
-				p1 += stride;
-				p2 += stride;
-				ErrorF("\n");
-			}
-		} //more format can be added here.
-		else { // the default format, just print.
-			for (i = 0; i < h; i++) {
-				line_need_printed = 0;
-
-				for (j = 0; j < stride; j++) {
-					if (p1[j] != p2[j]) {
-						if (line_need_printed) {
-							ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
-						} else {
-							line_need_printed = 1;
-							j = -1;
-							ErrorF("line %3d: ", i);
-							continue;
-						}
-					}
-				}
-
-				p1 += stride;
-				p2 += stride;
-				ErrorF("\n");
-			}
-		}
-	}
+    int i, j;
+    unsigned char *p1 = pixmap1->devPrivate.ptr;
+    unsigned char *p2 = pixmap2->devPrivate.ptr;
+    int line_need_printed = 0;
+    int test_code = 0xAABBCCDD;
+    int little_endian = 0;
+    unsigned char *p_test;
+    int bpp = pixmap1->drawable.depth == 8 ? 1 : 4;
+    int stride = pixmap1->devKind;
+
+    assert(pixmap1->devKind == pixmap2->devKind);
+
+    ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h);
+
+    p1 = p1 + y * stride + x;
+    p2 = p2 + y * stride + x;
+
+    if (all) {
+        for (i = 0; i < h; i++) {
+            ErrorF("line %3d: ", i);
+
+            for (j = 0; j < stride; j++) {
+                if (j % bpp == 0)
+                    ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
+                else
+                    ErrorF("%2x:%2x ", p1[j], p2[j]);
+            }
+
+            p1 += stride;
+            p2 += stride;
+            ErrorF("\n");
+        }
+    }
+    else {
+        if (short_format == PICT_a8r8g8b8) {
+            p_test = (unsigned char *) &test_code;
+            little_endian = (*p_test == 0xDD);
+            bpp = 4;
+
+            for (i = 0; i < h; i++) {
+                line_need_printed = 0;
+
+                for (j = 0; j < stride; j++) {
+                    if (p1[j] != p2[j] &&
+                        (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) {
+                        if (line_need_printed) {
+                            if (little_endian) {
+                                switch (j % 4) {
+                                case 2:
+                                    ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 1:
+                                    ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 0:
+                                    ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 3:
+                                    ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                }
+                            }
+                            else {
+                                switch (j % 4) {
+                                case 1:
+                                    ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 2:
+                                    ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 3:
+                                    ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                case 0:
+                                    ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j],
+                                           p2[j]);
+                                    break;
+                                }
+                            }
+                        }
+                        else {
+                            line_need_printed = 1;
+                            j = -1;
+                            ErrorF("line %3d: ", i);
+                            continue;
+                        }
+                    }
+                }
+
+                p1 += stride;
+                p2 += stride;
+                ErrorF("\n");
+            }
+        }                       //more format can be added here.
+        else {                  // the default format, just print.
+            for (i = 0; i < h; i++) {
+                line_need_printed = 0;
+
+                for (j = 0; j < stride; j++) {
+                    if (p1[j] != p2[j]) {
+                        if (line_need_printed) {
+                            ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
+                        }
+                        else {
+                            line_need_printed = 1;
+                            j = -1;
+                            ErrorF("line %3d: ", i);
+                            continue;
+                        }
+                    }
+                }
+
+                p1 += stride;
+                p2 += stride;
+                ErrorF("\n");
+            }
+        }
+    }
 }
 
-static inline void glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
-                                          int x, int y, int w, int h, int all, int diffs)
+static inline void
+glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
+                       int x, int y, int w, int h, int all, int diffs)
 {
-	assert(pixmap1->drawable.depth == pixmap2->drawable.depth);
+    assert(pixmap1->drawable.depth == pixmap2->drawable.depth);
 
-	glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
-	glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
+    glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
+    glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
 
-	_glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
+    _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
 
-	glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
-	glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
+    glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
+    glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
 }
 
 /* This function is used to compare two pictures.
    If the picture has no drawable, we use fb functions to generate it. */
-static inline void glamor_compare_pictures( ScreenPtr screen,
-                                            PicturePtr fst_picture,
-                                            PicturePtr snd_picture,
-                                            int x_source, int y_source,
-                                            int width, int height,
-                                            int all, int diffs)
+static inline void
+glamor_compare_pictures(ScreenPtr screen,
+                        PicturePtr fst_picture,
+                        PicturePtr snd_picture,
+                        int x_source, int y_source,
+                        int width, int height, int all, int diffs)
 {
-	PixmapPtr fst_pixmap;
-	PixmapPtr snd_pixmap;
-	int fst_generated, snd_generated;
-	int error;
-	int fst_type = -1;
-	int snd_type = -1; // -1 represent has drawable.
-
-	if (fst_picture->format != snd_picture->format) {
-		ErrorF("Different picture format can not compare!\n");
-		return;
-	}
-
-	if (!fst_picture->pDrawable) {
-		fst_type = fst_picture->pSourcePict->type;
-	}
-
-	if (!snd_picture->pDrawable) {
-		snd_type = snd_picture->pSourcePict->type;
-	}
-
-	if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) {
-		ErrorF("Different picture type will never be same!\n");
-		return;
-	}
-
-	fst_generated = snd_generated = 0;
-
-	if (!fst_picture->pDrawable) {
-		PicturePtr pixman_pic;
-		PixmapPtr pixmap = NULL;
-		PictFormatShort format;
-
-		format = fst_picture->format;
-
-		pixmap = glamor_create_pixmap(screen,
-		                              width, height,
-		                              PIXMAN_FORMAT_DEPTH(format),
-		                              GLAMOR_CREATE_PIXMAP_CPU);
-
-		pixman_pic = CreatePicture(0,
-		                           &pixmap->drawable,
-		                           PictureMatchFormat(screen,
-		                               PIXMAN_FORMAT_DEPTH(format), format),
-		                           0, 0, serverClient, &error);
-
-		fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic,
-		            x_source, y_source,
-		            0, 0,
-		            0, 0,
-		            width, height);
-
-		glamor_destroy_pixmap(pixmap);
-
-		fst_picture = pixman_pic;
-		fst_generated = 1;
-	}
-
-	if (!snd_picture->pDrawable) {
-		PicturePtr pixman_pic;
-		PixmapPtr pixmap = NULL;
-		PictFormatShort format;
-
-		format = snd_picture->format;
-
-		pixmap = glamor_create_pixmap(screen,
-		                              width, height,
-		                              PIXMAN_FORMAT_DEPTH(format),
-		                              GLAMOR_CREATE_PIXMAP_CPU);
-
-		pixman_pic = CreatePicture(0,
-		                           &pixmap->drawable,
-		                           PictureMatchFormat(screen,
-		                               PIXMAN_FORMAT_DEPTH(format), format),
-		                           0, 0, serverClient, &error);
-
-		fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic,
-		            x_source, y_source,
-		            0, 0,
-		            0, 0,
-		            width, height);
-
-		glamor_destroy_pixmap(pixmap);
-
-		snd_picture = pixman_pic;
-		snd_generated = 1;
-	}
-
-	fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable);
-	snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable);
-
-	if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) {
-		if (fst_generated)
-			glamor_destroy_picture(fst_picture);
-		if (snd_generated)
-			glamor_destroy_picture(snd_picture);
-
-		ErrorF("Different pixmap depth can not compare!\n");
-		return;
-	}
-
-	glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
-	glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
-
-	if ((fst_type == SourcePictTypeLinear) ||
-	     (fst_type == SourcePictTypeRadial) ||
-	     (fst_type == SourcePictTypeConical) ||
-	     (snd_type == SourcePictTypeLinear) ||
-	     (snd_type == SourcePictTypeRadial) ||
-	     (snd_type == SourcePictTypeConical)) {
-		x_source = y_source = 0;
-	}
-
-	_glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
-	                        x_source, y_source,
-	                        width, height,
-	                        fst_picture->format, all, diffs);
-
-	glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
-	glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
-
-	if (fst_generated)
-		glamor_destroy_picture(fst_picture);
-	if (snd_generated)
-		glamor_destroy_picture(snd_picture);
-
-	return;
+    PixmapPtr fst_pixmap;
+    PixmapPtr snd_pixmap;
+    int fst_generated, snd_generated;
+    int error;
+    int fst_type = -1;
+    int snd_type = -1;          // -1 represent has drawable.
+
+    if (fst_picture->format != snd_picture->format) {
+        ErrorF("Different picture format can not compare!\n");
+        return;
+    }
+
+    if (!fst_picture->pDrawable) {
+        fst_type = fst_picture->pSourcePict->type;
+    }
+
+    if (!snd_picture->pDrawable) {
+        snd_type = snd_picture->pSourcePict->type;
+    }
+
+    if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) {
+        ErrorF("Different picture type will never be same!\n");
+        return;
+    }
+
+    fst_generated = snd_generated = 0;
+
+    if (!fst_picture->pDrawable) {
+        PicturePtr pixman_pic;
+        PixmapPtr pixmap = NULL;
+        PictFormatShort format;
+
+        format = fst_picture->format;
+
+        pixmap = glamor_create_pixmap(screen,
+                                      width, height,
+                                      PIXMAN_FORMAT_DEPTH(format),
+                                      GLAMOR_CREATE_PIXMAP_CPU);
+
+        pixman_pic = CreatePicture(0,
+                                   &pixmap->drawable,
+                                   PictureMatchFormat(screen,
+                                                      PIXMAN_FORMAT_DEPTH
+                                                      (format), format), 0, 0,
+                                   serverClient, &error);
+
+        fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic,
+                    x_source, y_source, 0, 0, 0, 0, width, height);
+
+        glamor_destroy_pixmap(pixmap);
+
+        fst_picture = pixman_pic;
+        fst_generated = 1;
+    }
+
+    if (!snd_picture->pDrawable) {
+        PicturePtr pixman_pic;
+        PixmapPtr pixmap = NULL;
+        PictFormatShort format;
+
+        format = snd_picture->format;
+
+        pixmap = glamor_create_pixmap(screen,
+                                      width, height,
+                                      PIXMAN_FORMAT_DEPTH(format),
+                                      GLAMOR_CREATE_PIXMAP_CPU);
+
+        pixman_pic = CreatePicture(0,
+                                   &pixmap->drawable,
+                                   PictureMatchFormat(screen,
+                                                      PIXMAN_FORMAT_DEPTH
+                                                      (format), format), 0, 0,
+                                   serverClient, &error);
+
+        fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic,
+                    x_source, y_source, 0, 0, 0, 0, width, height);
+
+        glamor_destroy_pixmap(pixmap);
+
+        snd_picture = pixman_pic;
+        snd_generated = 1;
+    }
+
+    fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable);
+    snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable);
+
+    if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) {
+        if (fst_generated)
+            glamor_destroy_picture(fst_picture);
+        if (snd_generated)
+            glamor_destroy_picture(snd_picture);
+
+        ErrorF("Different pixmap depth can not compare!\n");
+        return;
+    }
+
+    glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
+    glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
+
+    if ((fst_type == SourcePictTypeLinear) ||
+        (fst_type == SourcePictTypeRadial) ||
+        (fst_type == SourcePictTypeConical) ||
+        (snd_type == SourcePictTypeLinear) ||
+        (snd_type == SourcePictTypeRadial) ||
+        (snd_type == SourcePictTypeConical)) {
+        x_source = y_source = 0;
+    }
+
+    _glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
+                            x_source, y_source,
+                            width, height, fst_picture->format, all, diffs);
+
+    glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
+    glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
+
+    if (fst_generated)
+        glamor_destroy_picture(fst_picture);
+    if (snd_generated)
+        glamor_destroy_picture(snd_picture);
+
+    return;
 }
 
 #ifdef __i386__
-static inline unsigned long __fls(unsigned long x)
+static inline unsigned long
+__fls(unsigned long x)
 {
-        asm("bsr %1,%0"
-            : "=r" (x)
-            : "rm" (x));
-        return x;
+ asm("bsr %1,%0":"=r"(x)
+ :     "rm"(x));
+    return x;
 }
 #else
-static inline unsigned long __fls(unsigned long x)
+static inline unsigned long
+__fls(unsigned long x)
 {
-   int n;
-
-   if (x == 0) return(0);
-   n = 0;
-   if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
-   if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
-   if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
-   if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
-   if (x <= 0x7FFFFFFF) {n = n + 1;}
-   return 31 - n;
+    int n;
+
+    if (x == 0)
+        return (0);
+    n = 0;
+    if (x <= 0x0000FFFF) {
+        n = n + 16;
+        x = x << 16;
+    }
+    if (x <= 0x00FFFFFF) {
+        n = n + 8;
+        x = x << 8;
+    }
+    if (x <= 0x0FFFFFFF) {
+        n = n + 4;
+        x = x << 4;
+    }
+    if (x <= 0x3FFFFFFF) {
+        n = n + 2;
+        x = x << 2;
+    }
+    if (x <= 0x7FFFFFFF) {
+        n = n + 1;
+    }
+    return 31 - n;
 }
 #endif
 
-static inline void glamor_make_current(ScreenPtr screen)
+static inline void
+glamor_make_current(ScreenPtr screen)
 {
-	glamor_egl_make_current(screen);
+    glamor_egl_make_current(screen);
 }
 
-static inline void glamor_restore_current(ScreenPtr screen)
+static inline void
+glamor_restore_current(ScreenPtr screen)
 {
-	glamor_egl_restore_context(screen);
+    glamor_egl_restore_context(screen);
 }
 
 #ifdef GLX_USE_SHARED_DISPATCH
 static inline glamor_gl_dispatch *
-glamor_get_dispatch(glamor_screen_private *glamor_priv)
+glamor_get_dispatch(glamor_screen_private * glamor_priv)
 {
-	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
-		glamor_make_current(glamor_priv->screen);
+    if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
+        glamor_make_current(glamor_priv->screen);
 
-	return &glamor_priv->_dispatch;
+    return &glamor_priv->_dispatch;
 }
 
 static inline void
-glamor_put_dispatch(glamor_screen_private *glamor_priv)
+glamor_put_dispatch(glamor_screen_private * glamor_priv)
 {
-	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
-		glamor_restore_current(glamor_priv->screen);
+    if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
+        glamor_restore_current(glamor_priv->screen);
 }
 #else
 #warning "Indirect GLX may be broken, need to implement context switch."
 static inline glamor_gl_dispatch *
-glamor_get_dispatch(glamor_screen_private *glamor_priv)
+glamor_get_dispatch(glamor_screen_private * glamor_priv)
 {
-	return &glamor_priv->_dispatch;
+    return &glamor_priv->_dispatch;
 }
 
 static inline void
-glamor_put_dispatch(glamor_screen_private *glamor_priv)
+glamor_put_dispatch(glamor_screen_private * glamor_priv)
 {
 }
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
index b67c728..60647bf 100644
--- a/glamor/glamor_window.c
+++ b/glamor/glamor_window.c
@@ -28,76 +28,72 @@
  * Screen Change Window Attribute implementation.
  */
 
-
 static void
-glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr * ppPixmap)
+glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap)
 {
-	PixmapPtr pPixmap = *ppPixmap;
-	glamor_pixmap_private *pixmap_priv;
+    PixmapPtr pPixmap = *ppPixmap;
+    glamor_pixmap_private *pixmap_priv;
 
-	if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
-		pixmap_priv = glamor_get_pixmap_private(pPixmap);
-		if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-			glamor_fallback("pixmap %p has no fbo\n", pPixmap);
-			goto fail;
-		}
-		glamor_debug_output(GLAMOR_DEBUG_UNIMPL,
-				    "To be implemented.\n");
-	}
-	return;
+    if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
+        pixmap_priv = glamor_get_pixmap_private(pPixmap);
+        if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+            glamor_fallback("pixmap %p has no fbo\n", pPixmap);
+            goto fail;
+        }
+        glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n");
+    }
+    return;
 
-      fail:
-	GLAMOR_PANIC
-	    (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
-	     " is broken for glamor. \n");
+ fail:
+    GLAMOR_PANIC
+        (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
+         " is broken for glamor. \n");
 }
 
 Bool
 glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
 {
-	if (mask & CWBackPixmap) {
-		if (pWin->backgroundState == BackgroundPixmap)
-			glamor_fixup_window_pixmap(&pWin->drawable,
-						   &pWin->
-						   background.pixmap);
-	}
+    if (mask & CWBackPixmap) {
+        if (pWin->backgroundState == BackgroundPixmap)
+            glamor_fixup_window_pixmap(&pWin->drawable,
+                                       &pWin->background.pixmap);
+    }
 
-	if (mask & CWBorderPixmap) {
-		if (pWin->borderIsPixel == FALSE)
-			glamor_fixup_window_pixmap(&pWin->drawable,
-						   &pWin->border.pixmap);
-	}
-	return TRUE;
+    if (mask & CWBorderPixmap) {
+        if (pWin->borderIsPixel == FALSE)
+            glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap);
+    }
+    return TRUE;
 }
 
 void
 glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
 {
-	ScreenPtr screen = win->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-		glamor_get_screen_private(screen);
-	PixmapPtr old = screen->GetWindowPixmap(win);
+    ScreenPtr screen = win->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    PixmapPtr old = screen->GetWindowPixmap(win);
 
-	if (pPixmap != old) {
-		glamor_pixmap_private *pixmap_priv;
-		PicturePtr pic = NULL;
+    if (pPixmap != old) {
+        glamor_pixmap_private *pixmap_priv;
+        PicturePtr pic = NULL;
 
-		pixmap_priv = glamor_get_pixmap_private(old);
-		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) && pixmap_priv->base.picture->pDrawable == (DrawablePtr)win) {
-			pic = pixmap_priv->base.picture;
-			pixmap_priv->base.is_picture = 0;
-			pixmap_priv->base.picture = NULL;
-		}
+        pixmap_priv = glamor_get_pixmap_private(old);
+        if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) &&
+            pixmap_priv->base.picture->pDrawable == (DrawablePtr) win) {
+            pic = pixmap_priv->base.picture;
+            pixmap_priv->base.is_picture = 0;
+            pixmap_priv->base.picture = NULL;
+        }
 
-		pixmap_priv = glamor_get_pixmap_private(pPixmap);
-		if (pixmap_priv) {
-			pixmap_priv->base.is_picture = !!pic;
-			pixmap_priv->base.picture = pic;
-		}
-	}
+        pixmap_priv = glamor_get_pixmap_private(pPixmap);
+        if (pixmap_priv) {
+            pixmap_priv->base.is_picture = ! !pic;
+            pixmap_priv->base.picture = pic;
+        }
+    }
 
-	screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
-	(screen->SetWindowPixmap)(win, pPixmap);
-	glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
-	screen->SetWindowPixmap = glamor_set_window_pixmap;
+    screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
+    (screen->SetWindowPixmap) (win, pPixmap);
+    glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = glamor_set_window_pixmap;
 }
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index a89b4cd..237a272 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -39,15 +39,14 @@
 #include <X11/extensions/Xv.h>
 #include "fourcc.h"
 /* Reference color space transform data */
-typedef struct tagREF_TRANSFORM
-{
-	float   RefLuma;
-	float   RefRCb;
-	float   RefRCr;
-	float   RefGCb;
-	float   RefGCr;
-	float   RefBCb;
-	float   RefBCr;
+typedef struct tagREF_TRANSFORM {
+    float RefLuma;
+    float RefRCb;
+    float RefRCr;
+    float RefGCb;
+    float RefGCr;
+    float RefBCb;
+    float RefBCr;
 } REF_TRANSFORM;
 
 #define RTFSaturation(a)   (1.0 + ((a)*1.0)/1000.0)
@@ -56,590 +55,575 @@ typedef struct tagREF_TRANSFORM
 #define RTFContrast(a)   (1.0 + ((a)*1.0)/1000.0)
 #define RTFHue(a)   (((a)*3.1416)/1000.0)
 
-static const char *xv_vs= "attribute vec4 v_position;\n"
-	"attribute vec4 v_texcoord0;\n"
-	"varying vec2 tcs;\n"
-	"void main()\n" "{\n" "     gl_Position = v_position;\n"
-	"tcs = v_texcoord0.xy;\n"
-	"}\n";
+static const char *xv_vs = "attribute vec4 v_position;\n"
+    "attribute vec4 v_texcoord0;\n"
+    "varying vec2 tcs;\n"
+    "void main()\n" "{\n" "     gl_Position = v_position;\n"
+    "tcs = v_texcoord0.xy;\n" "}\n";
 
 static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
-	"uniform sampler2D y_sampler;\n"
-	"uniform sampler2D u_sampler;\n"
-	"uniform sampler2D v_sampler;\n"
-	"uniform vec4 offsetyco;\n"
-	"uniform vec4 ucogamma;\n"
-	"uniform vec4 vco;\n"
-	"varying vec2 tcs;\n"
-	"float sample;\n"
-	"vec4 temp1;\n"
-	"void main()\n" "{\n"
-	"sample = texture2D(y_sampler, tcs).w;\n"
-	"temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
-	"sample = texture2D(u_sampler, tcs).w;\n"
-	"temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
-	"sample = texture2D(v_sampler, tcs).w;\n"
-	"temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
-	"temp1.w = 1.0;\n"
-	"gl_FragColor = temp1;\n"
-	"}\n";
+    "uniform sampler2D y_sampler;\n"
+    "uniform sampler2D u_sampler;\n"
+    "uniform sampler2D v_sampler;\n"
+    "uniform vec4 offsetyco;\n"
+    "uniform vec4 ucogamma;\n"
+    "uniform vec4 vco;\n"
+    "varying vec2 tcs;\n"
+    "float sample;\n"
+    "vec4 temp1;\n"
+    "void main()\n" "{\n"
+    "sample = texture2D(y_sampler, tcs).w;\n"
+    "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
+    "sample = texture2D(u_sampler, tcs).w;\n"
+    "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
+    "sample = texture2D(v_sampler, tcs).w;\n"
+    "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
+    "temp1.w = 1.0;\n" "gl_FragColor = temp1;\n" "}\n";
 
 void
 glamor_init_xv_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	GLint fs_prog, vs_prog;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  glamor_get_dispatch(glamor_priv);
-	glamor_priv->xv_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs);
-	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps);
-	dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog);
-	dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog);
-
-	dispatch->glBindAttribLocation(glamor_priv->xv_prog,
-				       GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(glamor_priv->xv_prog,
-				       GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-	glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog);
-
-	glamor_put_dispatch(glamor_priv);
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
+    GLint fs_prog, vs_prog;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
+    glamor_priv->xv_prog = dispatch->glCreateProgram();
+
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps);
+    dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog);
+
+    dispatch->glBindAttribLocation(glamor_priv->xv_prog,
+                                   GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(glamor_priv->xv_prog,
+                                   GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog);
+
+    glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_fini_xv_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
+    glamor_screen_private *glamor_priv;
+    glamor_gl_dispatch *dispatch;
 
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  glamor_get_dispatch(glamor_priv);
+    glamor_priv = glamor_get_screen_private(screen);
+    dispatch = glamor_get_dispatch(glamor_priv);
 
-	dispatch->glDeleteProgram(glamor_priv->xv_prog);
-	glamor_put_dispatch(glamor_priv);
+    dispatch->glDeleteProgram(glamor_priv->xv_prog);
+    glamor_put_dispatch(glamor_priv);
 }
 
 #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
-static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace, xvGamma;
+static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace,
+    xvGamma;
 
 #define NUM_ATTRIBUTES 5
-static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES+1] =
-{
+static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = {
     {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
     {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
     {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
     {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
     {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
     {0, 0, 0, NULL}
-	    };
+};
 
 #define NUM_FORMATS 3
 
-static XF86VideoFormatRec Formats[NUM_FORMATS] =
-{
+static XF86VideoFormatRec Formats[NUM_FORMATS] = {
     {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
-	    };
+};
 
 #define NUM_IMAGES 2
 
-static XF86ImageRec Images[NUM_IMAGES] =
-{
-XVIMAGE_YV12,
-	XVIMAGE_I420,
-	};
+static XF86ImageRec Images[NUM_IMAGES] = {
+    XVIMAGE_YV12,
+    XVIMAGE_I420,
+};
 
 static void
 glamor_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
 {
-glamor_port_private *port_priv = (glamor_port_private *)data;
-int i;
-if (!cleanup)
-	return;
-
-for (i = 0; i < 3; i++) {
-if (port_priv->src_pix[i]) {
-glamor_destroy_pixmap(port_priv->src_pix[i]);
-port_priv->src_pix[i] = NULL;
-}
-}
+    glamor_port_private *port_priv = (glamor_port_private *) data;
+    int i;
+
+    if (!cleanup)
+        return;
+
+    for (i = 0; i < 3; i++) {
+        if (port_priv->src_pix[i]) {
+            glamor_destroy_pixmap(port_priv->src_pix[i]);
+            port_priv->src_pix[i] = NULL;
+        }
+    }
 }
 
 static int
-glamor_xv_set_port_attribute(ScrnInfoPtr  pScrn,
-				     Atom	    attribute,
-				     INT32	    value,
-				     pointer	    data)
+glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
+                             Atom attribute, INT32 value, pointer data)
 {
-glamor_port_private *port_priv = (glamor_port_private *)data;
-if (attribute == xvBrightness)
-	port_priv->brightness = ClipValue(value, -1000, 1000);
-else if (attribute == xvHue)
-	port_priv->hue = ClipValue(value, -1000, 1000);
-else if (attribute == xvContrast)
-	port_priv->contrast = ClipValue(value, -1000, 1000);
-else if (attribute == xvSaturation)
-	port_priv->saturation = ClipValue(value, -1000, 1000);
-else if (attribute == xvGamma)
-	port_priv->gamma = ClipValue (value, 100, 10000);
-else if(attribute == xvColorspace)
-	port_priv->transform_index = ClipValue (value, 0, 1);
-else
-	return BadMatch;
-return Success;
+    glamor_port_private *port_priv = (glamor_port_private *) data;
+
+    if (attribute == xvBrightness)
+        port_priv->brightness = ClipValue(value, -1000, 1000);
+    else if (attribute == xvHue)
+        port_priv->hue = ClipValue(value, -1000, 1000);
+    else if (attribute == xvContrast)
+        port_priv->contrast = ClipValue(value, -1000, 1000);
+    else if (attribute == xvSaturation)
+        port_priv->saturation = ClipValue(value, -1000, 1000);
+    else if (attribute == xvGamma)
+        port_priv->gamma = ClipValue(value, 100, 10000);
+    else if (attribute == xvColorspace)
+        port_priv->transform_index = ClipValue(value, 0, 1);
+    else
+        return BadMatch;
+    return Success;
 }
 
 static int
-glamor_xv_get_port_attribute(ScrnInfoPtr  pScrn,
-				     Atom	    attribute,
-				     INT32	    *value,
-				     pointer	    data)
+glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
+                             Atom attribute, INT32 *value, pointer data)
 {
-glamor_port_private *port_priv = (glamor_port_private *)data;
-if (attribute == xvBrightness)
-	*value = port_priv->brightness;
-else if (attribute == xvHue)
-	*value = port_priv->hue;
-else if (attribute == xvContrast)
-	*value = port_priv->contrast;
-else if (attribute == xvSaturation)
-	*value = port_priv->saturation;
-else if (attribute == xvGamma)
-	*value = port_priv->gamma;
-else if(attribute == xvColorspace)
-	*value = port_priv->transform_index;
-else
-	return BadMatch;
-
-return Success;
+    glamor_port_private *port_priv = (glamor_port_private *) data;
+
+    if (attribute == xvBrightness)
+        *value = port_priv->brightness;
+    else if (attribute == xvHue)
+        *value = port_priv->hue;
+    else if (attribute == xvContrast)
+        *value = port_priv->contrast;
+    else if (attribute == xvSaturation)
+        *value = port_priv->saturation;
+    else if (attribute == xvGamma)
+        *value = port_priv->gamma;
+    else if (attribute == xvColorspace)
+        *value = port_priv->transform_index;
+    else
+        return BadMatch;
+
+    return Success;
 }
 
 static void
 glamor_xv_query_best_size(ScrnInfoPtr pScrn,
-				  Bool motion,
-				  short vid_w, short vid_h,
-				  short drw_w, short drw_h,
-				  unsigned int *p_w, unsigned int *p_h,
-				  pointer data)
+                          Bool motion,
+                          short vid_w, short vid_h,
+                          short drw_w, short drw_h,
+                          unsigned int *p_w, unsigned int *p_h, pointer data)
 {
-*p_w = drw_w;
-*p_h = drw_h;
+    *p_w = drw_w;
+    *p_h = drw_h;
 }
 
 static int
 glamor_xv_query_image_attributes(ScrnInfoPtr pScrn,
-					 int id,
-					 unsigned short *w, unsigned short *h,
-					 int *pitches, int *offsets)
+                                 int id,
+                                 unsigned short *w, unsigned short *h,
+                                 int *pitches, int *offsets)
 {
-int size = 0, tmp;
-
-if (offsets) offsets[0] = 0;
-switch (id) {
-case FOURCC_YV12:
-case FOURCC_I420:
-*h = *h;
-*w = *w;
-size = *w;
-if (pitches) pitches[0] = size;
-size *= *h;
-if (offsets) offsets[1] = size;
-tmp = *w >> 1;
-if (pitches) pitches[1] = pitches[2] = tmp;
-tmp *= (*h >> 1);
-size += tmp;
-if (offsets) offsets[2] = size;
-size += tmp;
-break;
-}
-return size;
+    int size = 0, tmp;
+
+    if (offsets)
+        offsets[0] = 0;
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+        *h = *h;
+        *w = *w;
+        size = *w;
+        if (pitches)
+            pitches[0] = size;
+        size *= *h;
+        if (offsets)
+            offsets[1] = size;
+        tmp = *w >> 1;
+        if (pitches)
+            pitches[1] = pitches[2] = tmp;
+        tmp *= (*h >> 1);
+        size += tmp;
+        if (offsets)
+            offsets[2] = size;
+        size += tmp;
+        break;
+    }
+    return size;
 }
+
 /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces
    note the difference to the parameters used in overlay are due
    to 10bit vs. float calcs */
-static REF_TRANSFORM trans[2] =
-{
-    {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */
-    {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0}  /* BT.709 */
-	    };
+static REF_TRANSFORM trans[2] = {
+    {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0},       /* BT.601 */
+    {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0}        /* BT.709 */
+};
 
 static void
-glamor_display_textured_video(glamor_port_private *port_priv)
+glamor_display_textured_video(glamor_port_private * port_priv)
 {
-ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
-glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(screen);
-glamor_pixmap_private *pixmap_priv =
-	glamor_get_pixmap_private(port_priv->pPixmap);
-glamor_pixmap_private *src_pixmap_priv[3];
-glamor_gl_dispatch *dispatch;
-float vertices[32], texcoords[8];
-BoxPtr box = REGION_RECTS(&port_priv->clip);
-int nBox = REGION_NUM_RECTS(&port_priv->clip);
-int dst_x_off, dst_y_off;
-GLfloat dst_xscale, dst_yscale;
-GLfloat src_xscale[3], src_yscale[3];
-int i;
-const float Loff = -0.0627;
-const float Coff = -0.502;
-float uvcosf, uvsinf;
-float yco;
-float uco[3], vco[3], off[3];
-float bright, cont, gamma;
-int ref = port_priv->transform_index;
-GLint uloc, sampler_loc;
-
-cont = RTFContrast(port_priv->contrast);
-bright = RTFBrightness(port_priv->brightness);
-gamma = (float)port_priv->gamma / 1000.0;
-uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue));
-uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue));
+    ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *pixmap_priv =
+        glamor_get_pixmap_private(port_priv->pPixmap);
+    glamor_pixmap_private *src_pixmap_priv[3];
+    glamor_gl_dispatch *dispatch;
+    float vertices[32], texcoords[8];
+    BoxPtr box = REGION_RECTS(&port_priv->clip);
+    int nBox = REGION_NUM_RECTS(&port_priv->clip);
+    int dst_x_off, dst_y_off;
+    GLfloat dst_xscale, dst_yscale;
+    GLfloat src_xscale[3], src_yscale[3];
+    int i;
+    const float Loff = -0.0627;
+    const float Coff = -0.502;
+    float uvcosf, uvsinf;
+    float yco;
+    float uco[3], vco[3], off[3];
+    float bright, cont, gamma;
+    int ref = port_priv->transform_index;
+    GLint uloc, sampler_loc;
+
+    cont = RTFContrast(port_priv->contrast);
+    bright = RTFBrightness(port_priv->brightness);
+    gamma = (float) port_priv->gamma / 1000.0;
+    uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue));
+    uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue));
 /* overlay video also does pre-gamma contrast/sat adjust, should we? */
 
-yco = trans[ref].RefLuma * cont;
-uco[0] = -trans[ref].RefRCr * uvsinf;
-uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf;
-uco[2] = trans[ref].RefBCb * uvcosf;
-vco[0] = trans[ref].RefRCr * uvcosf;
-vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf;
-vco[2] = trans[ref].RefBCb * uvsinf;
-off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright;
-off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright;
-off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
-gamma = 1.0;
-
-pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
-glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
-				   &dst_y_off);
-glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-for (i = 0; i < 3; i++) {
-if (port_priv->src_pix[i]) {
-src_pixmap_priv[i] = glamor_get_pixmap_private(port_priv->src_pix[i]);
-pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], &src_yscale[i]);
-}
-}
-dispatch = glamor_get_dispatch(glamor_priv);
-dispatch->glUseProgram(glamor_priv->xv_prog);
-
-uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
-dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco);
-uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
-dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
-uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco");
-dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
-
-dispatch->glActiveTexture(GL_TEXTURE0);
-dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_S,
-				  GL_CLAMP_TO_EDGE);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_T,
-				  GL_CLAMP_TO_EDGE);
-
-dispatch->glActiveTexture(GL_TEXTURE1);
-dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_S,
-				  GL_CLAMP_TO_EDGE);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_T,
-				  GL_CLAMP_TO_EDGE);
-
-dispatch->glActiveTexture(GL_TEXTURE2);
-dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_LINEAR);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_S,
-				  GL_CLAMP_TO_EDGE);
-dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_WRAP_T,
-				  GL_CLAMP_TO_EDGE);
-
-sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
-dispatch->glUniform1i(sampler_loc, 0);
-sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
-dispatch->glUniform1i(sampler_loc, 1);
-sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
-dispatch->glUniform1i(sampler_loc, 2);
-
-dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-					GL_FLOAT, GL_FALSE,
-					2 * sizeof(float),
-					texcoords);
-dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-
-dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-for (i = 0; i < nBox; i++) {
-float off_x = box[i].x1 - port_priv->drw_x;
-float off_y = box[i].y1 - port_priv->drw_y;
-float diff_x = (float)port_priv->src_w / (float)port_priv->dst_w;
-float diff_y = (float)port_priv->src_h / (float)port_priv->dst_h;
-float srcx, srcy, srcw, srch;
-int dstx, dsty, dstw, dsth;
-
-
-dstx = box[i].x1 + dst_x_off;
-dsty = box[i].y1 + dst_y_off;
-dstw = box[i].x2 - box[i].x1;
-dsth = box[i].y2 - box[i].y1;
-
-srcx = port_priv->src_x + off_x * diff_x;
-srcy = port_priv->src_y + off_y * diff_y;
-srcw = (port_priv->src_w * dstw) / (float)port_priv->dst_w;
-srch = (port_priv->src_h * dsth) / (float)port_priv->dst_h;
-
-glamor_set_normalize_vcoords(pixmap_priv,
-				     dst_xscale, dst_yscale,
-			     dstx,
-			     dsty,
-			     dstx + dstw,
-			     dsty + dsth,
-			     glamor_priv->yInverted,
-			     vertices);
-
-glamor_set_normalize_tcoords(src_pixmap_priv[0],
-			     src_xscale[0],
-			     src_yscale[0],
-			     srcx,
-			     srcy,
-			     srcx + srcw,
-			     srcy + srch,
-			     glamor_priv->yInverted,
-			     texcoords);
-
-dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-}
-
-dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-dispatch->glUseProgram(0);
-glamor_put_dispatch(glamor_priv);
-DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
+    yco = trans[ref].RefLuma * cont;
+    uco[0] = -trans[ref].RefRCr * uvsinf;
+    uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf;
+    uco[2] = trans[ref].RefBCb * uvcosf;
+    vco[0] = trans[ref].RefRCr * uvcosf;
+    vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf;
+    vco[2] = trans[ref].RefBCb * uvsinf;
+    off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright;
+    off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright;
+    off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
+    gamma = 1.0;
+
+    pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+    glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
+                               &dst_y_off);
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+    for (i = 0; i < 3; i++) {
+        if (port_priv->src_pix[i]) {
+            src_pixmap_priv[i] =
+                glamor_get_pixmap_private(port_priv->src_pix[i]);
+            pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i],
+                                  &src_yscale[i]);
+        }
+    }
+    dispatch = glamor_get_dispatch(glamor_priv);
+    dispatch->glUseProgram(glamor_priv->xv_prog);
+
+    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
+    dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco);
+    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
+    dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
+    uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco");
+    dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
+
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    dispatch->glActiveTexture(GL_TEXTURE1);
+    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    dispatch->glActiveTexture(GL_TEXTURE2);
+    dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D,
+                              GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    sampler_loc =
+        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
+    dispatch->glUniform1i(sampler_loc, 0);
+    sampler_loc =
+        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
+    dispatch->glUniform1i(sampler_loc, 1);
+    sampler_loc =
+        dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
+    dispatch->glUniform1i(sampler_loc, 2);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+                                    GL_FLOAT, GL_FALSE,
+                                    2 * sizeof(float), texcoords);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+                                    GL_FALSE, 2 * sizeof(float), vertices);
+
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    for (i = 0; i < nBox; i++) {
+        float off_x = box[i].x1 - port_priv->drw_x;
+        float off_y = box[i].y1 - port_priv->drw_y;
+        float diff_x = (float) port_priv->src_w / (float) port_priv->dst_w;
+        float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h;
+        float srcx, srcy, srcw, srch;
+        int dstx, dsty, dstw, dsth;
+
+        dstx = box[i].x1 + dst_x_off;
+        dsty = box[i].y1 + dst_y_off;
+        dstw = box[i].x2 - box[i].x1;
+        dsth = box[i].y2 - box[i].y1;
+
+        srcx = port_priv->src_x + off_x * diff_x;
+        srcy = port_priv->src_y + off_y * diff_y;
+        srcw = (port_priv->src_w * dstw) / (float) port_priv->dst_w;
+        srch = (port_priv->src_h * dsth) / (float) port_priv->dst_h;
+
+        glamor_set_normalize_vcoords(pixmap_priv,
+                                     dst_xscale, dst_yscale,
+                                     dstx,
+                                     dsty,
+                                     dstx + dstw,
+                                     dsty + dsth,
+                                     glamor_priv->yInverted, vertices);
+
+        glamor_set_normalize_tcoords(src_pixmap_priv[0],
+                                     src_xscale[0],
+                                     src_yscale[0],
+                                     srcx,
+                                     srcy,
+                                     srcx + srcw,
+                                     srcy + srch,
+                                     glamor_priv->yInverted, texcoords);
+
+        dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    dispatch->glUseProgram(0);
+    glamor_put_dispatch(glamor_priv);
+    DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
 }
 
-static int glamor_xv_put_image(ScrnInfoPtr pScrn,
-			       short src_x, short src_y,
-			       short drw_x, short drw_y,
-			       short src_w, short src_h,
-			       short drw_w, short drw_h,
-			       int id,
-			       unsigned char *buf,
-			       short width,
-			       short height,
-			       Bool sync,
-			       RegionPtr clipBoxes,
-			       pointer data,
-			       DrawablePtr pDrawable)
+static int
+glamor_xv_put_image(ScrnInfoPtr pScrn,
+                    short src_x, short src_y,
+                    short drw_x, short drw_y,
+                    short src_w, short src_h,
+                    short drw_w, short drw_h,
+                    int id,
+                    unsigned char *buf,
+                    short width,
+                    short height,
+                    Bool sync,
+                    RegionPtr clipBoxes, pointer data, DrawablePtr pDrawable)
 {
-	ScreenPtr screen = xf86ScrnToScreen(pScrn);
-	glamor_port_private *port_priv = (glamor_port_private *)data;
-	INT32 x1, x2, y1, y2;
-	int srcPitch, srcPitch2;
-	BoxRec dstBox;
-	int top, nlines;
-	int s2offset, s3offset, tmp;
-
-	s2offset = s3offset = srcPitch2 = 0;
-
-	/* Clip */
-	x1 = src_x;
-	x2 = src_x + src_w;
-	y1 = src_y;
-	y2 = src_y + src_h;
-
-	dstBox.x1 = drw_x;
-	dstBox.x2 = drw_x + drw_w;
-	dstBox.y1 = drw_y;
-	dstBox.y2 = drw_y + drw_h;
-	if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
-		return Success;
-
-	if ((x1 >= x2) || (y1 >= y2))
-		return Success;
-
-	srcPitch = width;
-	srcPitch2 = width >> 1;
-
-	if (!port_priv->src_pix[0] || (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
-		int i;
-		for (i = 0; i < 3; i++)
-			if (port_priv->src_pix[i])
-				glamor_destroy_pixmap(port_priv->src_pix[i]);
-
-		port_priv->src_pix[0] = glamor_create_pixmap(screen, width, height, 8, 0);
-		port_priv->src_pix[1] = glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
-		port_priv->src_pix[2] = glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
-		port_priv->src_pix_w = width;
-		port_priv->src_pix_h = height;
-
-		if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || !port_priv->src_pix[2])
-			return BadAlloc;
-	}
-
-	top = (y1 >> 16) & ~1;
-	nlines = ((y2 + 0xffff) >> 16) - top;
-
-	switch (id) {
-	case FOURCC_YV12:
-	case FOURCC_I420:
-		s2offset = srcPitch * height;
-		s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1));
-		s2offset += ((top >> 1) * srcPitch2);
-		s3offset += ((top >> 1) * srcPitch2);
-		if (id == FOURCC_YV12) {
-			tmp = s2offset;
-			s2offset = s3offset;
-			s3offset = tmp;
-		}
-		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
-						    0, 0, srcPitch, nlines,
-						    port_priv->src_pix[0]->devKind,
-						    buf + (top * srcPitch), 0);
-
-		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
-						    0, 0, srcPitch2, (nlines + 1) >> 1,
-						    port_priv->src_pix[1]->devKind,
-						    buf + s2offset, 0);
-
-		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
-						    0, 0, srcPitch2, (nlines + 1) >> 1,
-						    port_priv->src_pix[2]->devKind,
-						    buf + s3offset, 0);
-		break;
-	default:
-		return BadMatch;
-	}
-
-	if (pDrawable->type == DRAWABLE_WINDOW)
-		port_priv->pPixmap = (*screen->GetWindowPixmap)((WindowPtr)pDrawable);
-	else
-		port_priv->pPixmap = (PixmapPtr)pDrawable;
-
-	if (!RegionEqual(&port_priv->clip, clipBoxes)) {
-		RegionCopy(&port_priv->clip, clipBoxes);
-	}
-
-	port_priv->src_x = src_x;
-	port_priv->src_y = src_y;
-	port_priv->src_w = src_w;
-	port_priv->src_h = src_h;
-	port_priv->dst_w = drw_w;
-	port_priv->dst_h = drw_h;
-	port_priv->drw_x = drw_x;
-	port_priv->drw_y = drw_y;
-	port_priv->w = width;
-	port_priv->h = height;
-	port_priv->pDraw = pDrawable;
-	glamor_display_textured_video(port_priv);
-	return Success;
+    ScreenPtr screen = xf86ScrnToScreen(pScrn);
+    glamor_port_private *port_priv = (glamor_port_private *) data;
+    INT32 x1, x2, y1, y2;
+    int srcPitch, srcPitch2;
+    BoxRec dstBox;
+    int top, nlines;
+    int s2offset, s3offset, tmp;
+
+    s2offset = s3offset = srcPitch2 = 0;
+
+    /* Clip */
+    x1 = src_x;
+    x2 = src_x + src_w;
+    y1 = src_y;
+    y2 = src_y + src_h;
+
+    dstBox.x1 = drw_x;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y1 = drw_y;
+    dstBox.y2 = drw_y + drw_h;
+    if (!xf86XVClipVideoHelper
+        (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
+        return Success;
+
+    if ((x1 >= x2) || (y1 >= y2))
+        return Success;
+
+    srcPitch = width;
+    srcPitch2 = width >> 1;
+
+    if (!port_priv->src_pix[0] ||
+        (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
+        int i;
+
+        for (i = 0; i < 3; i++)
+            if (port_priv->src_pix[i])
+                glamor_destroy_pixmap(port_priv->src_pix[i]);
+
+        port_priv->src_pix[0] =
+            glamor_create_pixmap(screen, width, height, 8, 0);
+        port_priv->src_pix[1] =
+            glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
+        port_priv->src_pix[2] =
+            glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
+        port_priv->src_pix_w = width;
+        port_priv->src_pix_h = height;
+
+        if (!port_priv->src_pix[0] || !port_priv->src_pix[1] ||
+            !port_priv->src_pix[2])
+            return BadAlloc;
+    }
+
+    top = (y1 >> 16) & ~1;
+    nlines = ((y2 + 0xffff) >> 16) - top;
+
+    switch (id) {
+    case FOURCC_YV12:
+    case FOURCC_I420:
+        s2offset = srcPitch * height;
+        s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1));
+        s2offset += ((top >> 1) * srcPitch2);
+        s3offset += ((top >> 1) * srcPitch2);
+        if (id == FOURCC_YV12) {
+            tmp = s2offset;
+            s2offset = s3offset;
+            s3offset = tmp;
+        }
+        glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
+                                            0, 0, srcPitch, nlines,
+                                            port_priv->src_pix[0]->devKind,
+                                            buf + (top * srcPitch), 0);
+
+        glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
+                                            0, 0, srcPitch2, (nlines + 1) >> 1,
+                                            port_priv->src_pix[1]->devKind,
+                                            buf + s2offset, 0);
+
+        glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
+                                            0, 0, srcPitch2, (nlines + 1) >> 1,
+                                            port_priv->src_pix[2]->devKind,
+                                            buf + s3offset, 0);
+        break;
+    default:
+        return BadMatch;
+    }
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+        port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable);
+    else
+        port_priv->pPixmap = (PixmapPtr) pDrawable;
+
+    if (!RegionEqual(&port_priv->clip, clipBoxes)) {
+        RegionCopy(&port_priv->clip, clipBoxes);
+    }
+
+    port_priv->src_x = src_x;
+    port_priv->src_y = src_y;
+    port_priv->src_w = src_w;
+    port_priv->src_h = src_h;
+    port_priv->dst_w = drw_w;
+    port_priv->dst_h = drw_h;
+    port_priv->drw_x = drw_x;
+    port_priv->drw_y = drw_y;
+    port_priv->w = width;
+    port_priv->h = height;
+    port_priv->pDraw = pDrawable;
+    glamor_display_textured_video(port_priv);
+    return Success;
 }
 
-static XF86VideoEncodingRec DummyEncodingGLAMOR[1] =
-{
-	{
-		0,
-		"XV_IMAGE",
-		8192, 8192,
-		{1, 1}
-	}
+static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
+    {
+     0,
+     "XV_IMAGE",
+     8192, 8192,
+     {1, 1}
+     }
 };
 
 XF86VideoAdaptorPtr
 glamor_xv_init(ScreenPtr screen, int num_texture_ports)
 {
-	glamor_port_private *port_priv;
-	XF86VideoAdaptorPtr adapt;
-	int i;
-
-	adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
-		       (sizeof(glamor_port_private) + sizeof(DevUnion)));
-	if (adapt == NULL)
-		return NULL;
-
-	xvBrightness      = MAKE_ATOM("XV_BRIGHTNESS");
-	xvContrast        = MAKE_ATOM("XV_CONTRAST");
-	xvSaturation      = MAKE_ATOM("XV_SATURATION");
-	xvHue             = MAKE_ATOM("XV_HUE");
-	xvGamma           = MAKE_ATOM("XV_GAMMA");
-	xvColorspace      = MAKE_ATOM("XV_COLORSPACE");
-
-	adapt->type = XvWindowMask | XvInputMask | XvImageMask;
-	adapt->flags = 0;
-	adapt->name = "GLAMOR Textured Video";
-	adapt->nEncodings = 1;
-	adapt->pEncodings = DummyEncodingGLAMOR;
-
-	adapt->nFormats = NUM_FORMATS;
-	adapt->pFormats = Formats;
-	adapt->nPorts = num_texture_ports;
-	adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
-
-	adapt->pAttributes = Attributes_glamor;
-	adapt->nAttributes = NUM_ATTRIBUTES;
-
-	port_priv = (glamor_port_private *)(&adapt->pPortPrivates[num_texture_ports]);
-	adapt->pImages = Images;
-	adapt->nImages = NUM_IMAGES;
-	adapt->PutVideo = NULL;
-	adapt->PutStill = NULL;
-	adapt->GetVideo = NULL;
-	adapt->GetStill = NULL;
-	adapt->StopVideo = glamor_xv_stop_video;
-	adapt->SetPortAttribute = glamor_xv_set_port_attribute;
-	adapt->GetPortAttribute = glamor_xv_get_port_attribute;
-	adapt->QueryBestSize = glamor_xv_query_best_size;
-	adapt->PutImage = glamor_xv_put_image;
-	adapt->ReputImage = NULL;
-	adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
-
-	for (i = 0; i < num_texture_ports; i++) {
-		glamor_port_private *pPriv = &port_priv[i];
-
-		pPriv->brightness = 0;
-		pPriv->contrast = 0;
-		pPriv->saturation = 0;
-		pPriv->hue = 0;
-		pPriv->gamma = 1000;
-		pPriv->transform_index = 0;
-
-		REGION_NULL(pScreen, &pPriv->clip);
-
-		adapt->pPortPrivates[i].ptr = (pointer)(pPriv);
-	}
-	return adapt;
+    glamor_port_private *port_priv;
+    XF86VideoAdaptorPtr adapt;
+    int i;
+
+    adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
+                   (sizeof(glamor_port_private) + sizeof(DevUnion)));
+    if (adapt == NULL)
+        return NULL;
+
+    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+    xvContrast = MAKE_ATOM("XV_CONTRAST");
+    xvSaturation = MAKE_ATOM("XV_SATURATION");
+    xvHue = MAKE_ATOM("XV_HUE");
+    xvGamma = MAKE_ATOM("XV_GAMMA");
+    xvColorspace = MAKE_ATOM("XV_COLORSPACE");
+
+    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+    adapt->flags = 0;
+    adapt->name = "GLAMOR Textured Video";
+    adapt->nEncodings = 1;
+    adapt->pEncodings = DummyEncodingGLAMOR;
+
+    adapt->nFormats = NUM_FORMATS;
+    adapt->pFormats = Formats;
+    adapt->nPorts = num_texture_ports;
+    adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
+
+    adapt->pAttributes = Attributes_glamor;
+    adapt->nAttributes = NUM_ATTRIBUTES;
+
+    port_priv =
+        (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
+    adapt->pImages = Images;
+    adapt->nImages = NUM_IMAGES;
+    adapt->PutVideo = NULL;
+    adapt->PutStill = NULL;
+    adapt->GetVideo = NULL;
+    adapt->GetStill = NULL;
+    adapt->StopVideo = glamor_xv_stop_video;
+    adapt->SetPortAttribute = glamor_xv_set_port_attribute;
+    adapt->GetPortAttribute = glamor_xv_get_port_attribute;
+    adapt->QueryBestSize = glamor_xv_query_best_size;
+    adapt->PutImage = glamor_xv_put_image;
+    adapt->ReputImage = NULL;
+    adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
+
+    for (i = 0; i < num_texture_ports; i++) {
+        glamor_port_private *pPriv = &port_priv[i];
+
+        pPriv->brightness = 0;
+        pPriv->contrast = 0;
+        pPriv->saturation = 0;
+        pPriv->hue = 0;
+        pPriv->gamma = 1000;
+        pPriv->transform_index = 0;
+
+        REGION_NULL(pScreen, &pPriv->clip);
+
+        adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
+    }
+    return adapt;
 }
 #else
 XF86VideoAdaptorPtr
 glamor_xv_init(ScreenPtr screen, int num_texture_ports)
 {
-	return NULL;
+    return NULL;
 }
 #endif
diff --git a/glamor/glapi.h b/glamor/glapi.h
index d510dac..481e4ba 100644
--- a/glamor/glapi.h
+++ b/glamor/glapi.h
@@ -22,7 +22,6 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-
 /**
  * \mainpage Mesa GL API Module
  *
@@ -63,59 +62,55 @@
 #define _glapi_Context _mglapi_Context
 #endif
 
-typedef void (*_glapi_proc)(void);
+typedef void (*_glapi_proc) (void);
 struct _glapi_table;
 
-
 #if defined (GLX_USE_TLS)
 
-extern __thread struct _glapi_table * _glapi_tls_Dispatch
-    __attribute__((tls_model("initial-exec")));
+extern __thread struct _glapi_table *_glapi_tls_Dispatch
+    __attribute__ ((tls_model("initial-exec")));
 
-extern __thread void * _glapi_tls_Context
-    __attribute__((tls_model("initial-exec")));
+extern __thread void *_glapi_tls_Context
+    __attribute__ ((tls_model("initial-exec")));
 
 extern const struct _glapi_table *_glapi_Dispatch;
 extern const void *_glapi_Context;
 
-# define GET_DISPATCH() _glapi_tls_Dispatch
-# define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_tls_Context
-# define SET_CURRENT_CONTEXT(C)  _glapi_tls_Context = (void*)C
+#define GET_DISPATCH() _glapi_tls_Dispatch
+#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_tls_Context
+#define SET_CURRENT_CONTEXT(C)  _glapi_tls_Context = (void*)C
 
 #else
 
 extern struct _glapi_table *_glapi_Dispatch;
 extern void *_glapi_Context;
 
-# ifdef THREADS
+#ifdef THREADS
 
-#  define GET_DISPATCH() \
+#define GET_DISPATCH() \
      (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
 
-#  define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) \
+#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) \
      (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context())
 
-
-# define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context))   \
+#define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context))   \
 					_glapi_Context = (void*)C; \
 				     else \
 					_glapi_set_context(C); } while(0)
 
-# else
-
-#  define GET_DISPATCH() _glapi_Dispatch
-#  define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_Context
-# define SET_CURRENT_CONTEXT(C)  _glapi_Context = (void*)C
+#else
 
-# endif
+#define GET_DISPATCH() _glapi_Dispatch
+#define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_Context
+#define SET_CURRENT_CONTEXT(C)  _glapi_Context = (void*)C
 
-#endif /* defined (GLX_USE_TLS) */
+#endif
 
+#endif                          /* defined (GLX_USE_TLS) */
 
 extern void
-_glapi_set_context(void *context);
+ _glapi_set_context(void *context);
 
-extern void *
-_glapi_get_context(void);
+extern void *_glapi_get_context(void);
 
 #endif
commit e8e9a54c47deedbc13b8969ed29e16463b0314a0
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:56:15 2013 -0800

    glamor: Touch up some code so indent doesn't get confused.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 84694ec..be7aa3d 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -248,7 +248,7 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 			  b_shift, b_bits,			\
 			  g_shift, g_bits,			\
 			  r_shift, r_bits)			\
-	{								\
+	do {								\
 		typeof(src) a,b,g,r;					\
 		typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
 		a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
@@ -270,7 +270,7 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 			(*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
 		else 												    \
 			(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
-	}
+	} while (0)
 
 static void *
 _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
@@ -293,7 +293,7 @@ _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, i
 			if (revert == REVERT_DOWNLOADING_2_10_10_10)
 				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
 						  24, 8, 16, 8, 8, 8, 0, 8,
-						  30, 2, 20, 10, 10, 10, 0, 10)
+						  30, 2, 20, 10, 10, 10, 0, 10);
 			else
 				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
 						  30, 2, 20, 10, 10, 10, 0, 10,
@@ -330,7 +330,7 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int
 			if (revert == REVERT_DOWNLOADING_1_5_5_5)
 				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
 						  0, 1, 1, 5, 6, 5, 11, 5,
-						  15, 1, 10, 5, 5, 5, 0, 5)
+						  15, 1, 10, 5, 5, 5, 0, 5);
 			else
 				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
 						  15, 1, 10, 5, 5, 5, 0, 5,
commit 9fc19168e7ca6308275bf8769d1ccb982f88465b
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jan 24 23:42:49 2014 -0800

    Check for calloc() failure in add_master()
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index e2f4b8a..9e36354 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -143,6 +143,10 @@ add_master(ClientPtr client, xXIAddMasterInfo * c, int flags[MAXDEVICES])
     int rc;
 
     name = calloc(c->name_len + 1, sizeof(char));
+    if (name == NULL) {
+        rc = BadAlloc;
+        goto unwind;
+    }
     strncpy(name, (char *) &c[1], c->name_len);
 
     rc = AllocDevicePair(client, name, &ptr, &keybd,
commit 76b3be75b62657e346731444736f7e4d200beb5b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 24 16:51:02 2014 +1000

    Xi: fix modifier offset in XIPassiveGrab swapping function
    
    The request is followed by mask_len 4-byte units, then followed by the actual
    modifiers.
    
    Also fix up the swapping test, which had the same issue.
    
    Reported-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index eccec0a..8aba977 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -63,7 +63,7 @@ SProcXIPassiveGrabDevice(ClientPtr client)
     swaps(&stuff->mask_len);
     swaps(&stuff->num_modifiers);
 
-    mods = (uint32_t *) &stuff[1];
+    mods = (uint32_t *) &stuff[1] + stuff->mask_len;
 
     for (i = 0; i < stuff->num_modifiers; i++, mods++) {
         swapl(mods);
diff --git a/test/xi2/protocol-xipassivegrabdevice.c b/test/xi2/protocol-xipassivegrabdevice.c
index 1e2341e..c747ddf 100644
--- a/test/xi2/protocol-xipassivegrabdevice.c
+++ b/test/xi2/protocol-xipassivegrabdevice.c
@@ -137,6 +137,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
 {
     int rc;
     int local_modifiers;
+    int mask_len;
 
     rc = ProcXIPassiveGrabDevice(&client_request);
     assert(rc == error);
@@ -153,10 +154,11 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
     swaps(&req->deviceid);
     local_modifiers = req->num_modifiers;
     swaps(&req->num_modifiers);
+    mask_len = req->mask_len;
     swaps(&req->mask_len);
 
     while (local_modifiers--) {
-        CARD32 *mod = ((CARD32 *) (req + 1)) + local_modifiers;
+        CARD32 *mod = (CARD32 *) (req + 1) + mask_len + local_modifiers;
 
         swapl(mod);
     }
@@ -228,6 +230,11 @@ test_XIPassiveGrabDevice(void)
     request->detail = XIAnyButton;
     request_XIPassiveGrabDevice(&client_request, request, Success, 0);
 
+    /* Set a few random masks to make sure we handle modifiers correctly */
+    SetBit(mask, XI_ButtonPress);
+    SetBit(mask, XI_KeyPress);
+    SetBit(mask, XI_Enter);
+
     /* some modifiers */
     request->num_modifiers = N_MODS;
     request->length += N_MODS;
commit c1ce807d9f18f215332d7eeb844e8c640f71c53c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:01:59 2014 -0800

    dix: Praise clients which haven't run for a while, rather than idle clients
    
    A client which is ready, but hasn't run for a while, should receive
    the same benefit as one which has simply been idle for a while. Use
    the smart_stop_tick to see how long it has been since a client has
    run instead of smart_check_tick, which got reset each time a client
    was ready, even if it didn't get to run.
    
    Reported-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Tested-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/dix/dispatch.c b/dix/dispatch.c
index e28270c..9a5658d 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -260,12 +260,11 @@ SmartScheduleClient(int *clientReady, int nready)
     for (i = 0; i < nready; i++) {
         client = clientReady[i];
         pClient = clients[client];
-        /* Praise clients which are idle */
-        if ((now - pClient->smart_check_tick) >= idle) {
+        /* Praise clients which haven't run in a while */
+        if ((now - pClient->smart_stop_tick) >= idle) {
             if (pClient->smart_priority < 0)
                 pClient->smart_priority++;
         }
-        pClient->smart_check_tick = now;
 
         /* check priority to select best client */
         robin =
@@ -3424,7 +3423,6 @@ InitClient(ClientPtr client, int i, void *ospriv)
     QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
     client->smart_start_tick = SmartScheduleTime;
     client->smart_stop_tick = SmartScheduleTime;
-    client->smart_check_tick = SmartScheduleTime;
     client->clientIds = NULL;
 }
 
diff --git a/include/dixstruct.h b/include/dixstruct.h
index a11729b..6c13895 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -106,7 +106,6 @@ typedef struct _Client {
 
     int smart_start_tick;
     int smart_stop_tick;
-    int smart_check_tick;
 
     DeviceIntPtr clientPtr;
     ClientIdPtr clientIds;
commit 76b275d7acbfd6b28cb9e74fa4862faa6d08217d
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 12 10:53:31 2014 -0800

    test/signal-formatting: Ignore compiler warnings
    
    The signal formatting tests intentionally include code which generates
    warnings with the current X server warning flags. Turn the compiler
    warnings off
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/test/signal-logging.c b/test/signal-logging.c
index 7bbd910..d894373 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -117,6 +117,8 @@ static void
 number_formatting(void)
 {
     int i;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Woverflow"
     long unsigned int unsigned_tests[] = { 0,/* Zero */
                                            5, /* Single digit number */
                                            12, /* Two digit decimal number */
@@ -139,6 +141,7 @@ number_formatting(void)
                                 -0x15D027BF211B37A, /* Large > 32 bit number */
                                 -0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
     } ;
+#pragma GCC diagnostic pop
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
         assert(check_number_format_test(unsigned_tests[i]));
@@ -152,6 +155,8 @@ number_formatting(void)
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wformat-security"
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
 static void logging_format(void)
 {
     const char *log_file_path = "/tmp/Xorg-logging-test.log";
@@ -220,14 +225,12 @@ static void logging_format(void)
     assert(strcmp(logmsg, "(EE) substituted string\n") == 0);
 
     /* Invalid format */
-#warning Ignore compiler warning below "lacks type at end of format".  This is intentional.
     LogMessageVerbSigSafe(X_ERROR, -1, "%4", 4);
     read_log_msg(logmsg);
     assert(strcmp(logmsg, "(EE) ") == 0);
     LogMessageVerbSigSafe(X_ERROR, -1, "\n");
     fseek(f, 0, SEEK_END);
 
-#warning Ignore compiler warning below "unknown conversion type character".  This is intentional.
     /* %hld is bogus */
     LogMessageVerbSigSafe(X_ERROR, -1, "%hld\n", 4);
     read_log_msg(logmsg);
commit 12ea81792868c10a89a06ce9a9e8f707be283569
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 12 10:44:22 2014 -0800

    test/hashtabletest: Clean up -Wshadow errors
    
    Declare 'XID id' local to each scope it is used in, rather than having
    the first use be a function-wide declaration.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/test/hashtabletest.c b/test/hashtabletest.c
index 6af14a8..ceadfa7 100644
--- a/test/hashtabletest.c
+++ b/test/hashtabletest.c
@@ -26,7 +26,6 @@ static int
 test1(void)
 {
     HashTable h;
-    XID id;
     int c;
     int ok = 1;
     const int numKeys = 420;
@@ -36,7 +35,7 @@ test1(void)
 
     for (c = 0; c < numKeys; ++c) {
       int *dest;
-      id = c;
+      XID id = c;
       dest = ht_add(h, &id);
       if (dest) {
         *dest = 2 * c;
@@ -85,7 +84,6 @@ static int
 test2(void)
 {
     HashTable h;
-    XID id;
     int c;
     int ok = 1;
     const int numKeys = 420;
@@ -94,7 +92,7 @@ test2(void)
     h = ht_create(sizeof(XID), 0, ht_resourceid_hash, ht_resourceid_compare, NULL);
 
     for (c = 0; c < numKeys; ++c) {
-      id = c;
+      XID id = c;
       ht_add(h, &id);
     }
 
commit 7104f0f338fa96824a463331d6099a76ee3c21ac
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 12 10:42:37 2014 -0800

    test/xi2: Clean up -Wshadow warnings
    
    protocol-common declares a bunch of pretty generic names; fix shadows
    of these names.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c
index e171115..9a429e4 100644
--- a/test/xi2/protocol-common.c
+++ b/test/xi2/protocol-common.c
@@ -41,7 +41,7 @@ WindowRec root;
 WindowRec window;
 static ClientRec server_client;
 
-void *userdata;
+void *global_userdata;
 
 static void
 fake_init_sprite(DeviceIntPtr dev)
@@ -136,34 +136,34 @@ struct devices
 init_devices(void)
 {
     ClientRec client;
-    struct devices devices;
+    struct devices local_devices;
 
     client = init_client(0, NULL);
 
-    AllocDevicePair(&client, "Virtual core", &devices.vcp, &devices.vck,
+    AllocDevicePair(&client, "Virtual core", &local_devices.vcp, &local_devices.vck,
                     CorePointerProc, CoreKeyboardProc, TRUE);
-    inputInfo.pointer = devices.vcp;
+    inputInfo.pointer = local_devices.vcp;
 
-    inputInfo.keyboard = devices.vck;
-    ActivateDevice(devices.vcp, FALSE);
-    ActivateDevice(devices.vck, FALSE);
-    EnableDevice(devices.vcp, FALSE);
-    EnableDevice(devices.vck, FALSE);
+    inputInfo.keyboard = local_devices.vck;
+    ActivateDevice(local_devices.vcp, FALSE);
+    ActivateDevice(local_devices.vck, FALSE);
+    EnableDevice(local_devices.vcp, FALSE);
+    EnableDevice(local_devices.vck, FALSE);
 
-    AllocDevicePair(&client, "", &devices.mouse, &devices.kbd,
+    AllocDevicePair(&client, "", &local_devices.mouse, &local_devices.kbd,
                     TestPointerProc, CoreKeyboardProc, FALSE);
-    ActivateDevice(devices.mouse, FALSE);
-    ActivateDevice(devices.kbd, FALSE);
-    EnableDevice(devices.mouse, FALSE);
-    EnableDevice(devices.kbd, FALSE);
+    ActivateDevice(local_devices.mouse, FALSE);
+    ActivateDevice(local_devices.kbd, FALSE);
+    EnableDevice(local_devices.mouse, FALSE);
+    EnableDevice(local_devices.kbd, FALSE);
 
-    devices.num_devices = 4;
-    devices.num_master_devices = 2;
+    local_devices.num_devices = 4;
+    local_devices.num_master_devices = 2;
 
-    fake_init_sprite(devices.mouse);
-    fake_init_sprite(devices.vcp);
+    fake_init_sprite(local_devices.mouse);
+    fake_init_sprite(local_devices.vcp);
 
-    return devices;
+    return local_devices;
 }
 
 /* Create minimal client, with the given buffer and len as request buffer */
@@ -187,20 +187,20 @@ init_client(int len, void *data)
 }
 
 void
-init_window(WindowPtr window, WindowPtr parent, int id)
+init_window(WindowPtr local_window, WindowPtr parent, int id)
 {
-    memset(window, 0, sizeof(*window));
+    memset(local_window, 0, sizeof(*local_window));
 
-    window->drawable.id = id;
+    local_window->drawable.id = id;
     if (parent) {
-        window->drawable.x = 30;
-        window->drawable.y = 50;
-        window->drawable.width = 100;
-        window->drawable.height = 200;
+        local_window->drawable.x = 30;
+        local_window->drawable.y = 50;
+        local_window->drawable.width = 100;
+        local_window->drawable.height = 200;
     }
-    window->parent = parent;
-    window->optional = calloc(1, sizeof(WindowOptRec));
-    assert(window->optional);
+    local_window->parent = parent;
+    local_window->optional = calloc(1, sizeof(WindowOptRec));
+    assert(local_window->optional);
 }
 
 extern DevPrivateKeyRec miPointerScreenKeyRec;
@@ -208,18 +208,18 @@ extern DevPrivateKeyRec miPointerPrivKeyRec;
 
 /* Needed for the screen setup, otherwise we crash during sprite initialization */
 static Bool
-device_cursor_init(DeviceIntPtr dev, ScreenPtr screen)
+device_cursor_init(DeviceIntPtr dev, ScreenPtr local_screen)
 {
     return TRUE;
 }
 
 static void
-device_cursor_cleanup(DeviceIntPtr dev, ScreenPtr screen)
+device_cursor_cleanup(DeviceIntPtr dev, ScreenPtr local_screen)
 {
 }
 
 static Bool
-set_cursor_pos(DeviceIntPtr dev, ScreenPtr screen, int x, int y, Bool event)
+set_cursor_pos(DeviceIntPtr dev, ScreenPtr local_screen, int x, int y, Bool event)
 {
     return TRUE;
 }
@@ -264,5 +264,5 @@ __wrap_WriteToClient(ClientPtr client, int len, void *data)
 {
     assert(reply_handler != NULL);
 
-    (*reply_handler) (client, len, data, userdata);
+    (*reply_handler) (client, len, data, global_userdata);
 }
diff --git a/test/xi2/protocol-common.h b/test/xi2/protocol-common.h
index d303068..f850478 100644
--- a/test/xi2/protocol-common.h
+++ b/test/xi2/protocol-common.h
@@ -91,7 +91,7 @@ extern struct devices devices;
 /**
  * test-specific userdata, passed into the reply handler.
  */
-extern void *userdata;
+extern void *global_userdata;
 
 /**
  * The reply handler called from WriteToClient. Set this handler if you need
diff --git a/test/xi2/protocol-xipassivegrabdevice.c b/test/xi2/protocol-xipassivegrabdevice.c
index 84b386b..1e2341e 100644
--- a/test/xi2/protocol-xipassivegrabdevice.c
+++ b/test/xi2/protocol-xipassivegrabdevice.c
@@ -136,7 +136,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
                             int error, int errval)
 {
     int rc;
-    int modifiers;
+    int local_modifiers;
 
     rc = ProcXIPassiveGrabDevice(&client_request);
     assert(rc == error);
@@ -151,12 +151,12 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
     swapl(&req->cursor);
     swapl(&req->detail);
     swaps(&req->deviceid);
-    modifiers = req->num_modifiers;
+    local_modifiers = req->num_modifiers;
     swaps(&req->num_modifiers);
     swaps(&req->mask_len);
 
-    while (modifiers--) {
-        CARD32 *mod = ((CARD32 *) (req + 1)) + modifiers;
+    while (local_modifiers--) {
+        CARD32 *mod = ((CARD32 *) (req + 1)) + local_modifiers;
 
         swapl(mod);
     }
diff --git a/test/xi2/protocol-xiquerydevice.c b/test/xi2/protocol-xiquerydevice.c
index c066daa..deef1f1 100644
--- a/test/xi2/protocol-xiquerydevice.c
+++ b/test/xi2/protocol-xiquerydevice.c
@@ -312,7 +312,7 @@ test_XIQueryDevice(void)
     struct test_data data;
 
     reply_handler = reply_XIQueryDevice;
-    userdata = &data;
+    global_userdata = &data;
     request_init(&request, XIQueryDevice);
 
     printf("Testing XIAllDevices.\n");
diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index ed75c89..3749b30 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -113,7 +113,7 @@ request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error)
 
     request_init(&request, XIQueryVersion);
     client = init_client(request.length, &request);
-    userdata = (void *) &versions;
+    global_userdata = (void *) &versions;
 
     /* Change the server to support smaj.smin */
     XIVersion.major_version = smaj;
@@ -206,7 +206,7 @@ test_XIQueryVersion_multiple(void)
     XIVersion.minor_version = 2;
 
     reply_handler = reply_XIQueryVersion_multiple;
-    userdata = (void *) &versions;
+    global_userdata = (void *) &versions;
 
     /* run 1 */
 
commit 92a9495800cf59b917c30d5fbaf4b7eca10d19cf
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 12 10:42:01 2014 -0800

    kdrive/ephyr: Remove extra 'i' variable in ProcXF86DRIGetDrawableInfo
    
    Just re-use the top-level one
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/kdrive/ephyr/ephyrdriext.c b/hw/kdrive/ephyr/ephyrdriext.c
index e2b33db..8368d12 100644
--- a/hw/kdrive/ephyr/ephyrdriext.c
+++ b/hw/kdrive/ephyr/ephyrdriext.c
@@ -1098,7 +1098,6 @@ ProcXF86DRIGetDrawableInfo(register ClientPtr client)
     if (rep.numClipRects) {
         if (clipRects) {
             ScreenPtr pScreen = screenInfo.screens[stuff->screen];
-            int i = 0;
 
             EPHYR_LOG("clip list of host gl drawable:\n");
             for (i = 0; i < rep.numClipRects; i++) {
commit 988877065486d0f25cc85be5be05f4523cc883c7
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:57:09 2013 -0800

    randr: Eliminate -Wshadow warnings
    
    Don't use rrScrPriv for nested screen private fetching.
    
    Eliminate a duplicate fetch of the randr screen private in rrCheckPixmapBounding.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index df1e3f1..6e181ba 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -475,21 +475,21 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
     }
 
     xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
-        rrScrPriv(slave);
-        for (c = 0; c < pScrPriv->numCrtcs; c++)
-            if (pScrPriv->crtcs[c] == rr_crtc) {
+        rrScrPrivPtr    slave_priv = rrGetScrPriv(slave);
+        for (c = 0; c < slave_priv->numCrtcs; c++)
+            if (slave_priv->crtcs[c] == rr_crtc) {
                 newbox.x1 = x;
                 newbox.x2 = x + w;
                 newbox.y1 = y;
                 newbox.y2 = y + h;
             }
             else {
-                if (!pScrPriv->crtcs[c]->mode)
+                if (!slave_priv->crtcs[c]->mode)
                     continue;
-                newbox.x1 = pScrPriv->crtcs[c]->x;
-                newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width;
-                newbox.y1 = pScrPriv->crtcs[c]->y;
-                newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height;
+                newbox.x1 = slave_priv->crtcs[c]->x;
+                newbox.x2 = slave_priv->crtcs[c]->x + slave_priv->crtcs[c]->mode->mode.width;
+                newbox.y1 = slave_priv->crtcs[c]->y;
+                newbox.y2 = slave_priv->crtcs[c]->y + slave_priv->crtcs[c]->mode->mode.height;
             }
         RegionInit(&new_crtc_region, &newbox, 1);
         RegionUnion(&total_region, &total_region, &new_crtc_region);
@@ -503,7 +503,6 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
         new_height == screen_pixmap->drawable.height) {
         ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2);
     } else {
-        rrScrPriv(pScreen);
         pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
     }
 
commit f46c487625e1ffbc78df5153128c68bd6bc41104
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:56:36 2013 -0800

    hw/xnest: Eliminate shadowed names
    
    Just rename stuff; nothing fancy here.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 447d5a7..3ff095b 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -64,15 +64,15 @@ SetTimeSinceLastInputEvent(void)
 }
 
 static Bool
-xnestExposurePredicate(Display * display, XEvent * event, char *args)
+xnestExposurePredicate(Display * dpy, XEvent * event, char *args)
 {
     return event->type == Expose || event->type == ProcessedExpose;
 }
 
 static Bool
-xnestNotExposurePredicate(Display * display, XEvent * event, char *args)
+xnestNotExposurePredicate(Display * dpy, XEvent * event, char *args)
 {
-    return !xnestExposurePredicate(display, event, args);
+    return !xnestExposurePredicate(dpy, event, args);
 }
 
 void
diff --git a/hw/xnest/GCOps.c b/hw/xnest/GCOps.c
index fa60231..e1cf9d6 100644
--- a/hw/xnest/GCOps.c
+++ b/hw/xnest/GCOps.c
@@ -95,7 +95,7 @@ xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 }
 
 static int
-xnestIgnoreErrorHandler (Display     *display,
+xnestIgnoreErrorHandler (Display     *dpy,
                          XErrorEvent *event)
 {
     return False; /* return value is ignored */
@@ -127,7 +127,7 @@ xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 }
 
 static Bool
-xnestBitBlitPredicate(Display * display, XEvent * event, char *args)
+xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
 {
     return event->type == GraphicsExpose || event->type == NoExpose;
 }
diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c
index 330b8ca..d9f490b 100644
--- a/hw/xnest/Init.c
+++ b/hw/xnest/Init.c
@@ -46,29 +46,29 @@ is" without express or implied warranty.
 Bool xnestDoFullGeneration = True;
 
 void
-InitOutput(ScreenInfo * screenInfo, int argc, char *argv[])
+InitOutput(ScreenInfo * screen_info, int argc, char *argv[])
 {
     int i, j;
 
     xnestOpenDisplay(argc, argv);
 
-    screenInfo->imageByteOrder = ImageByteOrder(xnestDisplay);
-    screenInfo->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
-    screenInfo->bitmapScanlinePad = BitmapPad(xnestDisplay);
-    screenInfo->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
+    screen_info->imageByteOrder = ImageByteOrder(xnestDisplay);
+    screen_info->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
+    screen_info->bitmapScanlinePad = BitmapPad(xnestDisplay);
+    screen_info->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
 
-    screenInfo->numPixmapFormats = 0;
+    screen_info->numPixmapFormats = 0;
     for (i = 0; i < xnestNumPixmapFormats; i++)
         for (j = 0; j < xnestNumDepths; j++)
             if ((xnestPixmapFormats[i].depth == 1) ||
                 (xnestPixmapFormats[i].depth == xnestDepths[j])) {
-                screenInfo->formats[screenInfo->numPixmapFormats].depth =
+                screen_info->formats[screen_info->numPixmapFormats].depth =
                     xnestPixmapFormats[i].depth;
-                screenInfo->formats[screenInfo->numPixmapFormats].bitsPerPixel =
+                screen_info->formats[screen_info->numPixmapFormats].bitsPerPixel =
                     xnestPixmapFormats[i].bits_per_pixel;
-                screenInfo->formats[screenInfo->numPixmapFormats].scanlinePad =
+                screen_info->formats[screen_info->numPixmapFormats].scanlinePad =
                     xnestPixmapFormats[i].scanline_pad;
-                screenInfo->numPixmapFormats++;
+                screen_info->numPixmapFormats++;
                 break;
             }
 
@@ -80,7 +80,7 @@ InitOutput(ScreenInfo * screenInfo, int argc, char *argv[])
     for (i = 0; i < xnestNumScreens; i++)
         AddScreen(xnestOpenScreen, argc, argv);
 
-    xnestNumScreens = screenInfo->numScreens;
+    xnestNumScreens = screen_info->numScreens;
 
     xnestDoFullGeneration = xnestFullGeneration;
 }
diff --git a/hw/xnest/Window.c b/hw/xnest/Window.c
index c33cbaa..fc87e82 100644
--- a/hw/xnest/Window.c
+++ b/hw/xnest/Window.c
@@ -380,7 +380,7 @@ xnestClipNotify(WindowPtr pWin, int dx, int dy)
 }
 
 static Bool
-xnestWindowExposurePredicate(Display * display, XEvent * event, XPointer ptr)
+xnestWindowExposurePredicate(Display * dpy, XEvent * event, XPointer ptr)
 {
     return (event->type == Expose && event->xexpose.window == *(Window *) ptr);
 }
commit 1f3676a81ef2c52699bdfcf1fb9da7e4e79b00b7
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:55:43 2013 -0800

    hw/vfb: Rename screenInfo parameter to screen_info
    
    Avoid shadowing the global screenInfo value.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index d102722..2175ac6 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -899,7 +899,7 @@ void vfbExtensionInit(void)
 }
 
 void
-InitOutput(ScreenInfo * screenInfo, int argc, char **argv)
+InitOutput(ScreenInfo * screen_info, int argc, char **argv)
 {
     int i;
     int NumFormats = 0;
@@ -935,18 +935,18 @@ InitOutput(ScreenInfo * screenInfo, int argc, char **argv)
         if (vfbPixmapDepths[i]) {
             if (NumFormats >= MAXFORMATS)
                 FatalError("MAXFORMATS is too small for this server\n");
-            screenInfo->formats[NumFormats].depth = i;
-            screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
-            screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
+            screen_info->formats[NumFormats].depth = i;
+            screen_info->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
+            screen_info->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
             NumFormats++;
         }
     }
 
-    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
-    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
-    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
-    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
-    screenInfo->numPixmapFormats = NumFormats;
+    screen_info->imageByteOrder = IMAGE_BYTE_ORDER;
+    screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+    screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+    screen_info->bitmapBitOrder = BITMAP_BIT_ORDER;
+    screen_info->numPixmapFormats = NumFormats;
 
     /* initialize screens */
 
commit 89c0fa3d6c8ae67084a30395085db6d872d9d6de
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:55:06 2013 -0800

    kdrive: Fix -Wshadow errors
    
    Just rename stuff to avoid conflicts.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 7d09e28..a539ca5 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -1940,7 +1940,7 @@ _KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z,
 }
 
 void
-KdBlockHandler(ScreenPtr pScreen, void *timeout, void *readmask)
+KdBlockHandler(ScreenPtr pScreen, void *timeo, void *readmask)
 {
     KdPointerInfo *pi;
     int myTimeout = 0;
@@ -1962,7 +1962,7 @@ KdBlockHandler(ScreenPtr pScreen, void *timeout, void *readmask)
         myTimeout = 20;
     }
     if (myTimeout > 0)
-        AdjustWaitForDelay(timeout, myTimeout);
+        AdjustWaitForDelay(timeo, myTimeout);
 }
 
 void
diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c
index 9e76ead..445eb60 100644
--- a/hw/kdrive/src/kxv.c
+++ b/hw/kdrive/src/kxv.c
@@ -1821,14 +1821,14 @@ KdXVCopyPlanarData(KdScreenInfo * screen, CARD8 *src, CARD8 *dst, int randr,
 
     w >>= 1;
     for (j = 0; j < h; j++) {
-        CARD32 *dst = (CARD32 *) dst1;
+        CARD32 *dst32 = (CARD32 *) dst1;
         CARD8 *s1l = src1;
         CARD8 *s1r = src1 + srcNext;
         CARD8 *s2 = src2;
         CARD8 *s3 = src3;
 
         for (i = 0; i < w; i++) {
-            *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
+            *dst32++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
             s1l += srcRight;
             s1r += srcRight;
             s2 += srcRight2;
commit 9c108b3ccdb4086002b83d9ad66f5619e9ec95bb
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:53:50 2013 -0800

    exa: Fix -Wshadow warnings
    
    In exa_accel, there was a duplicate fetch of a pixmap private field.
    
    exa_render just had a regular shadowed value.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 0e948f4..9c742bd 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1039,7 +1039,6 @@ exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
             pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
             pDrawable->width == 1 && pDrawable->height == 1 &&
             pDrawable->bitsPerPixel != 24) {
-            ExaPixmapPriv(pPixmap);
             RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
 
             switch (pDrawable->bitsPerPixel) {
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 172e2b5..c4edf40 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -915,7 +915,7 @@ exaComposite(CARD8 op,
             if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
                 (xSrc + width <= pSrc->pDrawable->width) &&
                 (ySrc + height <= pSrc->pDrawable->height)) {
-                Bool ret;
+                Bool suc;
 
                 xDst += pDst->pDrawable->x;
                 yDst += pDst->pDrawable->y;
@@ -927,7 +927,7 @@ exaComposite(CARD8 op,
                                               yDst, width, height))
                     goto done;
 
-                ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
+                suc = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
                                     RegionRects(&region),
                                     RegionNumRects(&region), xSrc - xDst,
                                     ySrc - yDst, FALSE, FALSE);
@@ -939,7 +939,7 @@ exaComposite(CARD8 op,
                 xSrc -= pSrc->pDrawable->x;
                 ySrc -= pSrc->pDrawable->y;
 
-                if (!ret)
+                if (!suc)
                     goto fallback;
 
                 goto done;
commit 04e320a4e4e1f46bf95e36078d93b4d18a0ef855
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:52:58 2013 -0800

    composite: Remove duplicate window pixmap fetch
    
    There's nothing between the previous fetch and this one that could
    cause the window pixmap to have changed.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/composite/compwindow.c b/composite/compwindow.c
index 8dce21d..6c24349 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -475,7 +475,6 @@ compCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
              * need to be copied to pNewPixmap.
              */
             RegionRec rgnDst;
-            PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
             GCPtr pGC;
 
             dx = ptOldOrg.x - pWin->drawable.x;
commit 07b03e721e4dbec1a640c9b3bb8a2d5902587e63
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:41:19 2013 -0800

    xfree86: Fix -Wshadow warnings
    
    Just rename variables to eliminate -Wshadow warnings.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 5be1693..258b22b 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1677,7 +1677,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
  */
 static Bool
 configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
-                    XF86ConfigPtr xf86configptr)
+                    XF86ConfigPtr conf_ptr)
 {
     MessageType from;
     XF86ConfScreenPtr s;
@@ -1722,7 +1722,7 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
 
     memset(&layout, 0, sizeof(layout));
     layout.lay_identifier = servlayoutp->id;
-    if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
+    if (xf86layoutAddInputDevices(conf_ptr, &layout) > 0) {
         if (!configInputDevices(&layout, servlayoutp))
             return FALSE;
         from = X_DEFAULT;
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 1348b27..30dc550 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -206,17 +206,17 @@ configureScreenSection(int screennum)
     ptr->scrn_device_str = tmp;
 
     for (i = 0; i < sizeof(depths) / sizeof(depths[0]); i++) {
-        XF86ConfDisplayPtr display;
+        XF86ConfDisplayPtr conf_display;
 
-        display = calloc(1, sizeof(XF86ConfDisplayRec));
-        display->disp_depth = depths[i];
-        display->disp_black.red = display->disp_white.red = -1;
-        display->disp_black.green = display->disp_white.green = -1;
-        display->disp_black.blue = display->disp_white.blue = -1;
+        conf_display = calloc(1, sizeof(XF86ConfDisplayRec));
+        conf_display->disp_depth = depths[i];
+        conf_display->disp_black.red = conf_display->disp_white.red = -1;
+        conf_display->disp_black.green = conf_display->disp_white.green = -1;
+        conf_display->disp_black.blue = conf_display->disp_white.blue = -1;
         ptr->scrn_display_lst = (XF86ConfDisplayPtr) xf86addListItem((glp) ptr->
                                                                      scrn_display_lst,
                                                                      (glp)
-                                                                     display);
+                                                                     conf_display);
     }
 
     return ptr;
@@ -375,7 +375,6 @@ configureLayoutSection(void)
             aptr->adj_refscreen = NULL;
         }
         else {
-            char *tmp;
             aptr->adj_where = CONF_ADJ_RIGHTOF;
             XNFasprintf(&tmp, "Screen%d", scrnum - 1);
             aptr->adj_refscreen = tmp;
@@ -586,24 +585,24 @@ DoConfigure(void)
 
     /* Add device, monitor and screen sections for detected devices */
     for (screennum = 0; screennum < nDevToConfig; screennum++) {
-        XF86ConfDevicePtr DevicePtr;
-        XF86ConfMonitorPtr MonitorPtr;
-        XF86ConfScreenPtr ScreenPtr;
+        XF86ConfDevicePtr device_ptr;
+        XF86ConfMonitorPtr monitor_ptr;
+        XF86ConfScreenPtr screen_ptr;
 
-        DevicePtr = configureDeviceSection(screennum);
+        device_ptr = configureDeviceSection(screennum);
         xf86config->conf_device_lst = (XF86ConfDevicePtr) xf86addListItem((glp)
                                                                           xf86config->
                                                                           conf_device_lst,
                                                                           (glp)
-                                                                          DevicePtr);
-        MonitorPtr = configureMonitorSection(screennum);
-        xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) MonitorPtr);
-        ScreenPtr = configureScreenSection(screennum);
+                                                                          device_ptr);
+        monitor_ptr = configureMonitorSection(screennum);
+        xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr);
+        screen_ptr = configureScreenSection(screennum);
         xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp)
                                                                           xf86config->
                                                                           conf_screen_lst,
                                                                           (glp)
-                                                                          ScreenPtr);
+                                                                          screen_ptr);
     }
 
     xf86config->conf_files = configureFilesSection();
@@ -714,27 +713,27 @@ DoConfigure(void)
     xf86freeScreenList(xf86config->conf_screen_lst);
     xf86config->conf_screen_lst = NULL;
     for (j = 0; j < xf86NumScreens; j++) {
-        XF86ConfMonitorPtr MonitorPtr;
-        XF86ConfScreenPtr ScreenPtr;
+        XF86ConfMonitorPtr monitor_ptr;
+        XF86ConfScreenPtr screen_ptr;
 
         ConfiguredMonitor = NULL;
 
         if ((*xf86Screens[dev2screen[j]]->PreInit) (xf86Screens[dev2screen[j]],
                                                     PROBE_DETECT) &&
             ConfiguredMonitor) {
-            MonitorPtr = configureDDCMonitorSection(j);
+            monitor_ptr = configureDDCMonitorSection(j);
         }
         else {
-            MonitorPtr = configureMonitorSection(j);
+            monitor_ptr = configureMonitorSection(j);
         }
-        ScreenPtr = configureScreenSection(j);
+        screen_ptr = configureScreenSection(j);
 
-        xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) MonitorPtr);
+        xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr);
         xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp)
                                                                           xf86config->
                                                                           conf_screen_lst,
                                                                           (glp)
-                                                                          ScreenPtr);
+                                                                          screen_ptr);
     }
 
     if (xf86writeConfigFile(filename, xf86config) == 0) {
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 0916dec..2c0629d 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -421,7 +421,6 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
              * Check for DefaultDepth and DefaultFbBpp options in the
              * Device sections.
              */
-            int i;
             GDevPtr device;
             Bool found = FALSE;
 
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 7c72aa9..9c8a86a 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -309,7 +309,7 @@ xf86CreateRootWindow(WindowPtr pWin)
     int err = Success;
     ScreenPtr pScreen = pWin->drawable.pScreen;
     RootWinPropPtr pProp;
-    CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
+    CreateWindowProcPtr create_window = (CreateWindowProcPtr)
         dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
 
     DebugF("xf86CreateRootWindow(%p)\n", pWin);
@@ -323,7 +323,7 @@ xf86CreateRootWindow(WindowPtr pWin)
     }
 
     /* Unhook this function ... */
-    pScreen->CreateWindow = CreateWindow;
+    pScreen->CreateWindow = create_window;
     dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
 
     /* ... and call the previous CreateWindow fuction, if any */
diff --git a/hw/xfree86/common/xf86fbman.c b/hw/xfree86/common/xf86fbman.c
index dafaad3..db715bd 100644
--- a/hw/xfree86/common/xf86fbman.c
+++ b/hw/xfree86/common/xf86fbman.c
@@ -1122,11 +1122,8 @@ localQueryLargestOffscreenLinear(ScreenPtr pScreen,
 
         if (localQueryLargestOffscreenArea(pScreen, &w, &h, gran,
                                            FAVOR_WIDTH_THEN_AREA, priority)) {
-            FBManagerPtr offman;
             BoxPtr extents;
 
-            offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates,
-                                                     xf86FBScreenKey);
             extents = RegionExtents(offman->InitialBoxes);
             if ((extents->x2 - extents->x1) == w)
                 *size = w * h;
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 38bfc1d..6033999 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -460,14 +460,14 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
         /* Add tags for reserved contexts */
         if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
                                                   &reserved_count))) {
-            int i;
+            int r;
             void *tag;
 
-            for (i = 0; i < reserved_count; i++) {
+            for (r = 0; r < reserved_count; r++) {
                 tag = DRICreateContextPrivFromHandle(pScreen,
-                                                     reserved[i],
+                                                     reserved[r],
                                                      DRI_CONTEXT_RESERVED);
-                drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+                drmAddContextTag(pDRIPriv->drmFD, reserved[r], tag);
             }
             drmFreeReservedContextList(reserved);
             DRIDrvMsg(pScreen->myNum, X_INFO,
@@ -684,9 +684,9 @@ DRICloseScreen(ScreenPtr pScreen)
                 pDRIPriv->wrap.ClipNotify = NULL;
             }
             if (pDRIInfo->wrap.AdjustFrame) {
-                ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+                ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
 
-                pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
+                scrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
                 pDRIPriv->wrap.AdjustFrame = NULL;
             }
 
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 42db8d7..87ba0b7 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -185,10 +185,10 @@ xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen)
     Bool has_none = FALSE;
     ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int c, o;
+    int icrtc, o;
 
-    for (c = 0; c < xf86_config->num_crtc; c++) {
-        xf86CrtcPtr crtc = xf86_config->crtc[c];
+    for (icrtc = 0; icrtc < xf86_config->num_crtc; icrtc++) {
+        xf86CrtcPtr crtc = xf86_config->crtc[icrtc];
 
         for (o = 0; o < xf86_config->num_output; o++) {
             xf86OutputPtr output = xf86_config->output[o];
@@ -216,20 +216,20 @@ xf86CrtcSetScreenSubpixelOrder(ScreenPtr pScreen)
                 SubPixelVerticalBGR,
             };
             int rotate;
-            int c;
+            int sc;
 
             for (rotate = 0; rotate < 4; rotate++)
                 if (crtc->rotation & (1 << rotate))
                     break;
-            for (c = 0; c < 4; c++)
-                if (circle[c] == subpixel_order)
+            for (sc = 0; sc < 4; sc++)
+                if (circle[sc] == subpixel_order)
                     break;
-            c = (c + rotate) & 0x3;
-            if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
-                c ^= 2;
-            if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
-                c ^= 2;
-            subpixel_order = circle[c];
+            sc = (sc + rotate) & 0x3;
+            if ((crtc->rotation & RR_Reflect_X) && !(sc & 1))
+                sc ^= 2;
+            if ((crtc->rotation & RR_Reflect_Y) && (sc & 1))
+                sc ^= 2;
+            subpixel_order = circle[sc];
             break;
         }
     }
@@ -2148,10 +2148,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
                 }
                 else {
                     for (mode = output->probed_modes; mode; mode = mode->next) {
-                        Rotation r = output->initial_rotation;
+                        Rotation ir = output->initial_rotation;
 
-                        if (xf86ModeWidth(mode, r) == pref_width &&
-                            xf86ModeHeight(mode, r) == pref_height) {
+                        if (xf86ModeWidth(mode, ir) == pref_width &&
+                            xf86ModeHeight(mode, ir) == pref_height) {
                             preferred[o] = mode;
                             match = TRUE;
                         }
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 4ee862d..a56f6ba 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -973,11 +973,11 @@ handle_cea_svd(struct cea_video_block *video, void *data)
 }
 
 static DisplayModePtr
-DDCModesFromCEAExtension(int scrnIndex, xf86MonPtr MonPtr)
+DDCModesFromCEAExtension(int scrnIndex, xf86MonPtr mon_ptr)
 {
     DisplayModePtr Modes = NULL;
 
-    xf86ForEachVideoBlock(MonPtr, handle_cea_svd, &Modes);
+    xf86ForEachVideoBlock(mon_ptr, handle_cea_svd, &Modes);
 
     return Modes;
 }
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index f7a7d44..66139dc 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1202,7 +1202,6 @@ xf86RandR12CrtcSet(ScreenPtr pScreen,
 
         if (randr_mode) {
             DisplayModeRec mode;
-            RRTransformPtr transform = RRCrtcGetTransform(randr_crtc);
 
             xf86RandRModeConvert(pScrn, randr_mode, &mode);
             if (!xf86CrtcSetModeTransform
diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index 62e5142..e853220 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -79,6 +79,8 @@ typedef struct {
     ParserNumType numType;      /* used to enforce correct number formatting */
 } LexRec, *LexPtr;
 
+extern LexRec xf86_lex_val;
+
 #ifndef TRUE
 #define TRUE 1
 #endif
diff --git a/hw/xfree86/parser/DRI.c b/hw/xfree86/parser/DRI.c
index e8d2625..ad053f7 100644
--- a/hw/xfree86/parser/DRI.c
+++ b/hw/xfree86/parser/DRI.c
@@ -35,7 +35,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec DRITab[] = {
     {ENDSECTION, "endsection"},
@@ -59,24 +58,24 @@ xf86parseDRISection(void)
         switch (token) {
         case GROUP:
             if ((token = xf86getSubToken(&(ptr->dri_comment))) == STRING)
-                ptr->dri_group_name = val.str;
+                ptr->dri_group_name = xf86_lex_val.str;
             else if (token == NUMBER)
-                ptr->dri_group = val.num;
+                ptr->dri_group = xf86_lex_val.num;
             else
                 Error(GROUP_MSG);
             break;
         case MODE:
             if (xf86getSubToken(&(ptr->dri_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Mode");
-            if (val.numType != PARSE_OCTAL)
-                Error(MUST_BE_OCTAL_MSG, val.num);
-            ptr->dri_mode = val.num;
+            if (xf86_lex_val.numType != PARSE_OCTAL)
+                Error(MUST_BE_OCTAL_MSG, xf86_lex_val.num);
+            ptr->dri_mode = xf86_lex_val.num;
             break;
         case EOF_TOKEN:
             Error(UNEXPECTED_EOF_MSG);
             break;
         case COMMENT:
-            ptr->dri_comment = xf86addComment(ptr->dri_comment, val.str);
+            ptr->dri_comment = xf86addComment(ptr->dri_comment, xf86_lex_val.str);
             break;
         default:
             Error(INVALID_KEYWORD_MSG, xf86tokenString());
diff --git a/hw/xfree86/parser/Device.c b/hw/xfree86/parser/Device.c
index bb1ba88..073171f 100644
--- a/hw/xfree86/parser/Device.c
+++ b/hw/xfree86/parser/Device.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static
 xf86ConfigSymTabRec DeviceTab[] = {
@@ -107,45 +106,45 @@ xf86parseDeviceSection(void)
     while ((token = xf86getToken(DeviceTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->dev_comment = xf86addComment(ptr->dev_comment, val.str);
+            ptr->dev_comment = xf86addComment(ptr->dev_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->dev_identifier = val.str;
+            ptr->dev_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case VENDOR:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Vendor");
-            ptr->dev_vendor = val.str;
+            ptr->dev_vendor = xf86_lex_val.str;
             break;
         case BOARD:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Board");
-            ptr->dev_board = val.str;
+            ptr->dev_board = xf86_lex_val.str;
             break;
         case CHIPSET:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Chipset");
-            ptr->dev_chipset = val.str;
+            ptr->dev_chipset = xf86_lex_val.str;
             break;
         case CARD:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Card");
-            ptr->dev_card = val.str;
+            ptr->dev_card = xf86_lex_val.str;
             break;
         case DRIVER:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            ptr->dev_driver = val.str;
+            ptr->dev_driver = xf86_lex_val.str;
             break;
         case RAMDAC:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "Ramdac");
-            ptr->dev_ramdac = val.str;
+            ptr->dev_ramdac = xf86_lex_val.str;
             break;
         case DACSPEED:
             for (i = 0; i < CONF_MAXDACSPEEDS; i++)
@@ -154,11 +153,11 @@ xf86parseDeviceSection(void)
                 Error(DACSPEED_MSG, CONF_MAXDACSPEEDS);
             }
             else {
-                ptr->dev_dacSpeeds[0] = (int) (val.realnum * 1000.0 + 0.5);
+                ptr->dev_dacSpeeds[0] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
                 for (i = 1; i < CONF_MAXDACSPEEDS; i++) {
                     if (xf86getSubToken(&(ptr->dev_comment)) == NUMBER)
                         ptr->dev_dacSpeeds[i] = (int)
-                            (val.realnum * 1000.0 + 0.5);
+                            (xf86_lex_val.realnum * 1000.0 + 0.5);
                     else {
                         xf86unGetToken(token);
                         break;
@@ -169,44 +168,44 @@ xf86parseDeviceSection(void)
         case VIDEORAM:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "VideoRam");
-            ptr->dev_videoram = val.num;
+            ptr->dev_videoram = xf86_lex_val.num;
             break;
         case BIOSBASE:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "BIOSBase");
-            ptr->dev_bios_base = val.num;
+            ptr->dev_bios_base = xf86_lex_val.num;
             break;
         case MEMBASE:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "MemBase");
-            ptr->dev_mem_base = val.num;
+            ptr->dev_mem_base = xf86_lex_val.num;
             break;
         case IOBASE:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "IOBase");
-            ptr->dev_io_base = val.num;
+            ptr->dev_io_base = xf86_lex_val.num;
             break;
         case CLOCKCHIP:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "ClockChip");
-            ptr->dev_clockchip = val.str;
+            ptr->dev_clockchip = xf86_lex_val.str;
             break;
         case CHIPID:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "ChipID");
-            ptr->dev_chipid = val.num;
+            ptr->dev_chipid = xf86_lex_val.num;
             break;
         case CHIPREV:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "ChipRev");
-            ptr->dev_chiprev = val.num;
+            ptr->dev_chiprev = xf86_lex_val.num;
             break;
 
         case CLOCKS:
             token = xf86getSubToken(&(ptr->dev_comment));
             for (i = ptr->dev_clocks;
                  token == NUMBER && i < CONF_MAXCLOCKS; i++) {
-                ptr->dev_clock[i] = (int) (val.realnum * 1000.0 + 0.5);
+                ptr->dev_clock[i] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
                 token = xf86getSubToken(&(ptr->dev_comment));
             }
             ptr->dev_clocks = i;
@@ -215,7 +214,7 @@ xf86parseDeviceSection(void)
         case TEXTCLOCKFRQ:
             if ((token = xf86getSubToken(&(ptr->dev_comment))) != NUMBER)
                 Error(NUMBER_MSG, "TextClockFreq");
-            ptr->dev_textclockfreq = (int) (val.realnum * 1000.0 + 0.5);
+            ptr->dev_textclockfreq = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
             break;
         case OPTION:
             ptr->dev_option_lst = xf86parseOption(ptr->dev_option_lst);
@@ -223,17 +222,17 @@ xf86parseDeviceSection(void)
         case BUSID:
             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
                 Error(QUOTE_MSG, "BusID");
-            ptr->dev_busid = val.str;
+            ptr->dev_busid = xf86_lex_val.str;
             break;
         case IRQ:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(QUOTE_MSG, "IRQ");
-            ptr->dev_irq = val.num;
+            ptr->dev_irq = xf86_lex_val.num;
             break;
         case SCREEN:
             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Screen");
-            ptr->dev_screen = val.num;
+            ptr->dev_screen = xf86_lex_val.num;
             break;
         case EOF_TOKEN:
             Error(UNEXPECTED_EOF_MSG);
diff --git a/hw/xfree86/parser/Extensions.c b/hw/xfree86/parser/Extensions.c
index ec0bda4..b5ba72e 100644
--- a/hw/xfree86/parser/Extensions.c
+++ b/hw/xfree86/parser/Extensions.c
@@ -39,7 +39,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec ExtensionsTab[] = {
     {ENDSECTION, "endsection"},
@@ -66,7 +65,7 @@ xf86parseExtensionsSection(void)
             break;
         case COMMENT:
             ptr->extensions_comment =
-                xf86addComment(ptr->extensions_comment, val.str);
+                xf86addComment(ptr->extensions_comment, xf86_lex_val.str);
             break;
         default:
             Error(INVALID_KEYWORD_MSG, xf86tokenString());
diff --git a/hw/xfree86/parser/Files.c b/hw/xfree86/parser/Files.c
index a6e18dd..24940a9 100644
--- a/hw/xfree86/parser/Files.c
+++ b/hw/xfree86/parser/Files.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec FilesTab[] = {
     {ENDSECTION, "endsection"},
@@ -89,13 +88,13 @@ xf86parseFilesSection(void)
         while ((token = xf86getToken(FilesTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->file_comment = xf86addComment(ptr->file_comment, val.str);
+            ptr->file_comment = xf86addComment(ptr->file_comment, xf86_lex_val.str);
             break;
         case FONTPATH:
             if (xf86getSubToken(&(ptr->file_comment)) != STRING)
                 Error(QUOTE_MSG, "FontPath");
             j = FALSE;
-            str = val.str;
+            str = xf86_lex_val.str;
             if (ptr->file_fontpath == NULL) {
                 ptr->file_fontpath = calloc(1, 1);
                 i = strlen(str) + 1;
@@ -112,13 +111,13 @@ xf86parseFilesSection(void)
                 strcat(ptr->file_fontpath, ",");
 
             strcat(ptr->file_fontpath, str);
-            free(val.str);
+            free(xf86_lex_val.str);
             break;
         case MODULEPATH:
             if (xf86getSubToken(&(ptr->file_comment)) != STRING)
                 Error(QUOTE_MSG, "ModulePath");
             l = FALSE;
-            str = val.str;
+            str = xf86_lex_val.str;
             if (ptr->file_modulepath == NULL) {
                 ptr->file_modulepath = malloc(1);
                 ptr->file_modulepath[0] = '\0';
@@ -137,17 +136,17 @@ xf86parseFilesSection(void)
                 strcat(ptr->file_modulepath, ",");
 
             strcat(ptr->file_modulepath, str);
-            free(val.str);
+            free(xf86_lex_val.str);
             break;
         case LOGFILEPATH:
             if (xf86getSubToken(&(ptr->file_comment)) != STRING)
                 Error(QUOTE_MSG, "LogFile");
-            ptr->file_logfile = val.str;
+            ptr->file_logfile = xf86_lex_val.str;
             break;
         case XKBDIR:
             if (xf86getSubToken(&(ptr->file_xkbdir)) != STRING)
                 Error(QUOTE_MSG, "XkbDir");
-            ptr->file_xkbdir = val.str;
+            ptr->file_xkbdir = xf86_lex_val.str;
             break;
         case EOF_TOKEN:
             Error(UNEXPECTED_EOF_MSG);
diff --git a/hw/xfree86/parser/Flags.c b/hw/xfree86/parser/Flags.c
index 326c6b7..71b50ac 100644
--- a/hw/xfree86/parser/Flags.c
+++ b/hw/xfree86/parser/Flags.c
@@ -62,7 +62,6 @@
 #include "Xprintf.h"
 #include "optionstr.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec ServerFlagsTab[] = {
     {ENDSECTION, "endsection"},
@@ -99,7 +98,7 @@ xf86parseFlagsSection(void)
 
         switch (token) {
         case COMMENT:
-            ptr->flg_comment = xf86addComment(ptr->flg_comment, val.str);
+            ptr->flg_comment = xf86addComment(ptr->flg_comment, xf86_lex_val.str);
             break;
             /* 
              * these old keywords are turned into standard generic options.
@@ -135,12 +134,12 @@ xf86parseFlagsSection(void)
                         if (strvalue) {
                             if (tokentype != STRING)
                                 Error(QUOTE_MSG, tmp);
-                            valstr = val.str;
+                            valstr = xf86_lex_val.str;
                         }
                         else {
                             if (tokentype != NUMBER)
                                 Error(NUMBER_MSG, tmp);
-                            if (asprintf(&valstr, "%d", val.num) == -1)
+                            if (asprintf(&valstr, "%d", xf86_lex_val.num) == -1)
                                 valstr = NULL;
                         }
                     }
@@ -435,12 +434,12 @@ xf86parseOption(XF86OptionPtr head)
         return head;
     }
 
-    name = val.str;
+    name = xf86_lex_val.str;
     if ((token = xf86getSubToken(&comment)) == STRING) {
-        option = xf86newOption(name, val.str);
+        option = xf86newOption(name, xf86_lex_val.str);
         option->opt_comment = comment;
         if ((token = xf86getToken(NULL)) == COMMENT)
-            option->opt_comment = xf86addComment(option->opt_comment, val.str);
+            option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str);
         else
             xf86unGetToken(token);
     }
@@ -448,7 +447,7 @@ xf86parseOption(XF86OptionPtr head)
         option = xf86newOption(name, NULL);
         option->opt_comment = comment;
         if (token == COMMENT)
-            option->opt_comment = xf86addComment(option->opt_comment, val.str);
+            option->opt_comment = xf86addComment(option->opt_comment, xf86_lex_val.str);
         else
             xf86unGetToken(token);
     }
diff --git a/hw/xfree86/parser/Input.c b/hw/xfree86/parser/Input.c
index ff2b9ac..1bfe5c1 100644
--- a/hw/xfree86/parser/Input.c
+++ b/hw/xfree86/parser/Input.c
@@ -61,7 +61,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static
 xf86ConfigSymTabRec InputTab[] = {
@@ -85,25 +84,25 @@ xf86parseInputSection(void)
         while ((token = xf86getToken(InputTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->inp_comment = xf86addComment(ptr->inp_comment, val.str);
+            ptr->inp_comment = xf86addComment(ptr->inp_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->inp_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->inp_identifier = val.str;
+            ptr->inp_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case DRIVER:
             if (xf86getSubToken(&(ptr->inp_comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            if (strcmp(val.str, "keyboard") == 0) {
+            if (strcmp(xf86_lex_val.str, "keyboard") == 0) {
                 ptr->inp_driver = strdup("kbd");
-                free(val.str);
+                free(xf86_lex_val.str);
             }
             else
-                ptr->inp_driver = val.str;
+                ptr->inp_driver = xf86_lex_val.str;
             break;
         case OPTION:
             ptr->inp_option_lst = xf86parseOption(ptr->inp_option_lst);
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index a7f573e..24a1246 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -33,7 +33,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static
 xf86ConfigSymTabRec InputClassTab[] = {
@@ -97,25 +96,25 @@ xf86parseInputClassSection(void)
     while ((token = xf86getToken(InputClassTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->comment = xf86addComment(ptr->comment, val.str);
+            ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->identifier = val.str;
+            ptr->identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            if (strcmp(val.str, "keyboard") == 0) {
+            if (strcmp(xf86_lex_val.str, "keyboard") == 0) {
                 ptr->driver = strdup("kbd");
-                free(val.str);
+                free(xf86_lex_val.str);
             }
             else
-                ptr->driver = val.str;
+                ptr->driver = xf86_lex_val.str;
             break;
         case OPTION:
             ptr->option_lst = xf86parseOption(ptr->option_lst);
@@ -124,69 +123,69 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchProduct");
             add_group_entry(&ptr->match_product,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_VENDOR:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchVendor");
             add_group_entry(&ptr->match_vendor,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_DEVICE_PATH:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDevicePath");
             add_group_entry(&ptr->match_device,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_OS:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchOS");
-            add_group_entry(&ptr->match_os, xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+            add_group_entry(&ptr->match_os, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_PNPID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchPnPID");
             add_group_entry(&ptr->match_pnpid,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_USBID:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchUSBID");
             add_group_entry(&ptr->match_usbid,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchDriver");
             add_group_entry(&ptr->match_driver,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_TAG:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchTag");
-            add_group_entry(&ptr->match_tag, xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+            add_group_entry(&ptr->match_tag, xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_LAYOUT:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchLayout");
             add_group_entry(&ptr->match_layout,
-                            xstrtokenize(val.str, TOKEN_SEP));
-            free(val.str);
+                            xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
+            free(xf86_lex_val.str);
             break;
         case MATCH_IS_KEYBOARD:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsKeyboard");
             ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val,
-                                                    val.str);
-            free(val.str);
+                                                    xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_keyboard.set)
                 Error(BOOL_MSG, "MatchIsKeyboard");
             break;
@@ -194,8 +193,8 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsPointer");
             ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val,
-                                                   val.str);
-            free(val.str);
+                                                   xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_pointer.set)
                 Error(BOOL_MSG, "MatchIsPointer");
             break;
@@ -203,16 +202,16 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsJoystick");
             ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val,
-                                                    val.str);
-            free(val.str);
+                                                    xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_joystick.set)
                 Error(BOOL_MSG, "MatchIsJoystick");
             break;
         case MATCH_IS_TABLET:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsTablet");
-            ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, val.str);
-            free(val.str);
+            ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_tablet.set)
                 Error(BOOL_MSG, "MatchIsTablet");
             break;
@@ -220,8 +219,8 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsTouchpad");
             ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val,
-                                                    val.str);
-            free(val.str);
+                                                    xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_touchpad.set)
                 Error(BOOL_MSG, "MatchIsTouchpad");
             break;
@@ -229,8 +228,8 @@ xf86parseInputClassSection(void)
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "MatchIsTouchscreen");
             ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val,
-                                                       val.str);
-            free(val.str);
+                                                       xf86_lex_val.str);
+            free(xf86_lex_val.str);
             if (!ptr->is_touchscreen.set)
                 Error(BOOL_MSG, "MatchIsTouchscreen");
             break;
diff --git a/hw/xfree86/parser/Layout.c b/hw/xfree86/parser/Layout.c
index cbd8d24..7be746f 100644
--- a/hw/xfree86/parser/Layout.c
+++ b/hw/xfree86/parser/Layout.c
@@ -65,7 +65,6 @@
 /* Needed for auto server layout */
 extern int xf86CheckBoolOption(void *optlist, const char *name, int deflt);
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec LayoutTab[] = {
     {ENDSECTION, "endsection"},
@@ -100,14 +99,14 @@ xf86parseLayoutSection(void)
         while ((token = xf86getToken(LayoutTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->lay_comment = xf86addComment(ptr->lay_comment, val.str);
+            ptr->lay_comment = xf86addComment(ptr->lay_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->lay_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->lay_identifier = val.str;
+            ptr->lay_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case INACTIVE:
@@ -120,7 +119,7 @@ xf86parseLayoutSection(void)
                 free(iptr);
                 Error(INACTIVE_MSG);
             }
-            iptr->inactive_device_str = val.str;
+            iptr->inactive_device_str = xf86_lex_val.str;
             ptr->lay_inactive_lst = (XF86ConfInactivePtr)
                 xf86addListItem((glp) ptr->lay_inactive_lst, (glp) iptr);
         }
@@ -138,7 +137,7 @@ xf86parseLayoutSection(void)
             aptr->adj_y = 0;
             aptr->adj_refscreen = NULL;
             if ((token = xf86getSubToken(&(ptr->lay_comment))) == NUMBER)
-                aptr->adj_scrnum = val.num;
+                aptr->adj_scrnum = xf86_lex_val.num;
             else
                 xf86unGetToken(token);
             token = xf86getSubToken(&(ptr->lay_comment));
@@ -146,7 +145,7 @@ xf86parseLayoutSection(void)
                 free(aptr);
                 Error(SCREEN_MSG);
             }
-            aptr->adj_screen_str = val.str;
+            aptr->adj_screen_str = xf86_lex_val.str;
 
             token = xf86getSubTokenWithTab(&(ptr->lay_comment), AdjTab);
             switch (token) {
@@ -186,13 +185,13 @@ xf86parseLayoutSection(void)
                 if (absKeyword)
                     token = xf86getSubToken(&(ptr->lay_comment));
                 if (token == NUMBER) {
-                    aptr->adj_x = val.num;
+                    aptr->adj_x = xf86_lex_val.num;
                     token = xf86getSubToken(&(ptr->lay_comment));
                     if (token != NUMBER) {
                         free(aptr);
                         Error(INVALID_SCR_MSG);
                     }
-                    aptr->adj_y = val.num;
+                    aptr->adj_y = xf86_lex_val.num;
                 }
                 else {
                     if (absKeyword) {
@@ -213,46 +212,46 @@ xf86parseLayoutSection(void)
                     free(aptr);
                     Error(INVALID_SCR_MSG);
                 }
-                aptr->adj_refscreen = val.str;
+                aptr->adj_refscreen = xf86_lex_val.str;
                 if (aptr->adj_where == CONF_ADJ_RELATIVE) {
                     token = xf86getSubToken(&(ptr->lay_comment));
                     if (token != NUMBER) {
                         free(aptr);
                         Error(INVALID_SCR_MSG);
                     }
-                    aptr->adj_x = val.num;
+                    aptr->adj_x = xf86_lex_val.num;
                     token = xf86getSubToken(&(ptr->lay_comment));
                     if (token != NUMBER) {
                         free(aptr);
                         Error(INVALID_SCR_MSG);
                     }
-                    aptr->adj_y = val.num;
+                    aptr->adj_y = xf86_lex_val.num;
                 }
                 break;
             case CONF_ADJ_OBSOLETE:
                 /* top */
-                aptr->adj_top_str = val.str;
+                aptr->adj_top_str = xf86_lex_val.str;
 
                 /* bottom */
                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
                     free(aptr);
                     Error(SCREEN_MSG);
                 }
-                aptr->adj_bottom_str = val.str;
+                aptr->adj_bottom_str = xf86_lex_val.str;
 
                 /* left */
                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
                     free(aptr);
                     Error(SCREEN_MSG);
                 }
-                aptr->adj_left_str = val.str;
+                aptr->adj_left_str = xf86_lex_val.str;
 
                 /* right */
                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
                     free(aptr);
                     Error(SCREEN_MSG);
                 }
-                aptr->adj_right_str = val.str;
+                aptr->adj_right_str = xf86_lex_val.str;
 
             }
             ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
@@ -270,10 +269,10 @@ xf86parseLayoutSection(void)
                 free(iptr);
                 Error(INPUTDEV_MSG);
             }
-            iptr->iref_inputdev_str = val.str;
+            iptr->iref_inputdev_str = xf86_lex_val.str;
             while ((token = xf86getSubToken(&(ptr->lay_comment))) == STRING) {
                 iptr->iref_option_lst =
-                    xf86addNewOption(iptr->iref_option_lst, val.str, NULL);
+                    xf86addNewOption(iptr->iref_option_lst, xf86_lex_val.str, NULL);
             }
             xf86unGetToken(token);
             ptr->lay_input_lst = (XF86ConfInputrefPtr)
diff --git a/hw/xfree86/parser/Module.c b/hw/xfree86/parser/Module.c
index 243ba91..e2d9120 100644
--- a/hw/xfree86/parser/Module.c
+++ b/hw/xfree86/parser/Module.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec SubModuleTab[] = {
     {ENDSUBSECTION, "endsubsection"},
@@ -95,7 +94,7 @@ xf86parseModuleSubSection(XF86LoadPtr head, char *name)
     while ((token = xf86getToken(SubModuleTab)) != ENDSUBSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->load_comment = xf86addComment(ptr->load_comment, val.str);
+            ptr->load_comment = xf86addComment(ptr->load_comment, xf86_lex_val.str);
             break;
         case OPTION:
             ptr->load_opt = xf86parseOption(ptr->load_opt);
@@ -126,34 +125,34 @@ xf86parseModuleSection(void)
         while ((token = xf86getToken(ModuleTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->mod_comment = xf86addComment(ptr->mod_comment, val.str);
+            ptr->mod_comment = xf86addComment(ptr->mod_comment, xf86_lex_val.str);
             break;
         case LOAD:
             if (xf86getSubToken(&(ptr->mod_comment)) != STRING)
                 Error(QUOTE_MSG, "Load");
             ptr->mod_load_lst =
-                xf86addNewLoadDirective(ptr->mod_load_lst, val.str,
+                xf86addNewLoadDirective(ptr->mod_load_lst, xf86_lex_val.str,
                                         XF86_LOAD_MODULE, NULL);
             break;
         case DISABLE:
             if (xf86getSubToken(&(ptr->mod_comment)) != STRING)
                 Error(QUOTE_MSG, "Disable");
             ptr->mod_disable_lst =
-                xf86addNewLoadDirective(ptr->mod_disable_lst, val.str,
+                xf86addNewLoadDirective(ptr->mod_disable_lst, xf86_lex_val.str,
                                         XF86_DISABLE_MODULE, NULL);
             break;
         case LOAD_DRIVER:
             if (xf86getSubToken(&(ptr->mod_comment)) != STRING)
                 Error(QUOTE_MSG, "LoadDriver");
             ptr->mod_load_lst =
-                xf86addNewLoadDirective(ptr->mod_load_lst, val.str,
+                xf86addNewLoadDirective(ptr->mod_load_lst, xf86_lex_val.str,
                                         XF86_LOAD_DRIVER, NULL);
             break;
         case SUBSECTION:
             if (xf86getSubToken(&(ptr->mod_comment)) != STRING)
                 Error(QUOTE_MSG, "SubSection");
             ptr->mod_load_lst =
-                xf86parseModuleSubSection(ptr->mod_load_lst, val.str);
+                xf86parseModuleSubSection(ptr->mod_load_lst, xf86_lex_val.str);
             break;
         case EOF_TOKEN:
             Error(UNEXPECTED_EOF_MSG);
@@ -232,7 +231,7 @@ xf86addNewLoadDirective(XF86LoadPtr head, const char *name, int type,
     new->list.next = NULL;
 
     if ((token = xf86getToken(NULL)) == COMMENT)
-        new->load_comment = xf86addComment(new->load_comment, val.str);
+        new->load_comment = xf86addComment(new->load_comment, xf86_lex_val.str);
     else
         xf86unGetToken(token);
 
diff --git a/hw/xfree86/parser/Monitor.c b/hw/xfree86/parser/Monitor.c
index 36b4ebe..8aebce0 100644
--- a/hw/xfree86/parser/Monitor.c
+++ b/hw/xfree86/parser/Monitor.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec MonitorTab[] = {
     {ENDSECTION, "endsection"},
@@ -140,52 +139,52 @@ xf86parseModeLine(void)
         /* Identifier */
         if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
         Error("ModeLine identifier expected");
-    ptr->ml_identifier = val.str;
+    ptr->ml_identifier = xf86_lex_val.str;
 
     /* DotClock */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine dotclock expected");
-    ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
+    ptr->ml_clock = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
 
     /* HDisplay */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine Hdisplay expected");
-    ptr->ml_hdisplay = val.num;
+    ptr->ml_hdisplay = xf86_lex_val.num;
 
     /* HSyncStart */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine HSyncStart expected");
-    ptr->ml_hsyncstart = val.num;
+    ptr->ml_hsyncstart = xf86_lex_val.num;
 
     /* HSyncEnd */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine HSyncEnd expected");
-    ptr->ml_hsyncend = val.num;
+    ptr->ml_hsyncend = xf86_lex_val.num;
 
     /* HTotal */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine HTotal expected");
-    ptr->ml_htotal = val.num;
+    ptr->ml_htotal = xf86_lex_val.num;
 
     /* VDisplay */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine Vdisplay expected");
-    ptr->ml_vdisplay = val.num;
+    ptr->ml_vdisplay = xf86_lex_val.num;
 
     /* VSyncStart */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine VSyncStart expected");
-    ptr->ml_vsyncstart = val.num;
+    ptr->ml_vsyncstart = xf86_lex_val.num;
 
     /* VSyncEnd */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine VSyncEnd expected");
-    ptr->ml_vsyncend = val.num;
+    ptr->ml_vsyncend = xf86_lex_val.num;
 
     /* VTotal */
     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
         Error("ModeLine VTotal expected");
-    ptr->ml_vtotal = val.num;
+    ptr->ml_vtotal = xf86_lex_val.num;
 
     token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab);
     while ((token == TT_INTERLACE) || (token == TT_PHSYNC) ||
@@ -226,7 +225,7 @@ xf86parseModeLine(void)
         case TT_HSKEW:
             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Hskew");
-            ptr->ml_hskew = val.num;
+            ptr->ml_hskew = xf86_lex_val.num;
             ptr->ml_flags |= XF86CONF_HSKEW;
             break;
         case TT_BCAST:
@@ -235,7 +234,7 @@ xf86parseModeLine(void)
         case TT_VSCAN:
             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Vscan");
-            ptr->ml_vscan = val.num;
+            ptr->ml_vscan = xf86_lex_val.num;
             ptr->ml_flags |= XF86CONF_VSCAN;
             break;
         case EOF_TOKEN:
@@ -265,58 +264,58 @@ xf86parseVerboseMode(void)
 
         if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
         Error("Mode name expected");
-    ptr->ml_identifier = val.str;
+    ptr->ml_identifier = xf86_lex_val.str;
     while ((token = xf86getToken(ModeTab)) != ENDMODE) {
         switch (token) {
         case COMMENT:
-            ptr->ml_comment = xf86addComment(ptr->ml_comment, val.str);
+            ptr->ml_comment = xf86addComment(ptr->ml_comment, xf86_lex_val.str);
             break;
         case DOTCLOCK:
             if ((token = xf86getSubToken(&(ptr->ml_comment))) != NUMBER)
                 Error(NUMBER_MSG, "DotClock");
-            ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
+            ptr->ml_clock = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
             had_dotclock = 1;
             break;
         case HTIMINGS:
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_hdisplay = val.num;
+                ptr->ml_hdisplay = xf86_lex_val.num;
             else
                 Error("Horizontal display expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_hsyncstart = val.num;
+                ptr->ml_hsyncstart = xf86_lex_val.num;
             else
                 Error("Horizontal sync start expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_hsyncend = val.num;
+                ptr->ml_hsyncend = xf86_lex_val.num;
             else
                 Error("Horizontal sync end expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_htotal = val.num;
+                ptr->ml_htotal = xf86_lex_val.num;
             else
                 Error("Horizontal total expected");
             had_htimings = 1;
             break;
         case VTIMINGS:
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_vdisplay = val.num;
+                ptr->ml_vdisplay = xf86_lex_val.num;
             else
                 Error("Vertical display expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_vsyncstart = val.num;
+                ptr->ml_vsyncstart = xf86_lex_val.num;
             else
                 Error("Vertical sync start expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_vsyncend = val.num;
+                ptr->ml_vsyncend = xf86_lex_val.num;
             else
                 Error("Vertical sync end expected");
 
             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
-                ptr->ml_vtotal = val.num;
+                ptr->ml_vtotal = xf86_lex_val.num;
             else
                 Error("Vertical total expected");
             had_vtimings = 1;
@@ -370,13 +369,13 @@ xf86parseVerboseMode(void)
             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
                 Error("Horizontal skew expected");
             ptr->ml_flags |= XF86CONF_HSKEW;
-            ptr->ml_hskew = val.num;
+            ptr->ml_hskew = xf86_lex_val.num;
             break;
         case VSCAN:
             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
                 Error("Vertical scan count expected");
             ptr->ml_flags |= XF86CONF_VSCAN;
-            ptr->ml_vscan = val.num;
+            ptr->ml_vscan = xf86_lex_val.num;
             break;
         case EOF_TOKEN:
             Error(UNEXPECTED_EOF_MSG);
@@ -413,25 +412,25 @@ xf86parseMonitorSection(void)
         while ((token = xf86getToken(MonitorTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->mon_comment = xf86addComment(ptr->mon_comment, val.str);
+            ptr->mon_comment = xf86addComment(ptr->mon_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->mon_identifier = val.str;
+            ptr->mon_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case VENDOR:
             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
                 Error(QUOTE_MSG, "Vendor");
-            ptr->mon_vendor = val.str;
+            ptr->mon_vendor = xf86_lex_val.str;
             break;
         case MODEL:
             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
                 Error(QUOTE_MSG, "ModelName");
-            ptr->mon_modelname = val.str;
+            ptr->mon_modelname = xf86_lex_val.str;
             break;
         case MODE:
             HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
@@ -444,10 +443,10 @@ xf86parseMonitorSection(void)
         case DISPLAYSIZE:
             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
                 Error(DISPLAYSIZE_MSG);
-            ptr->mon_width = val.realnum;
+            ptr->mon_width = xf86_lex_val.realnum;
             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
                 Error(DISPLAYSIZE_MSG);
-            ptr->mon_height = val.realnum;
+            ptr->mon_height = xf86_lex_val.realnum;
             break;
 
         case HORIZSYNC:
@@ -456,7 +455,7 @@ xf86parseMonitorSection(void)
             do {
                 if (ptr->mon_n_hsync >= CONF_MAX_HSYNC)
                     Error("Sorry. Too many horizontal sync intervals.");
-                ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum;
+                ptr->mon_hsync[ptr->mon_n_hsync].lo = xf86_lex_val.realnum;
                 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
                 case COMMA:
                     ptr->mon_hsync[ptr->mon_n_hsync].hi =
@@ -464,10 +463,10 @@ xf86parseMonitorSection(void)
                     break;
                 case DASH:
                     if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
-                        (float) val.realnum <
+                        (float) xf86_lex_val.realnum <
                         ptr->mon_hsync[ptr->mon_n_hsync].lo)
                         Error(HORIZSYNC_MSG);
-                    ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum;
+                    ptr->mon_hsync[ptr->mon_n_hsync].hi = xf86_lex_val.realnum;
                     if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
                         break;
                     ptr->mon_n_hsync++;
@@ -491,7 +490,7 @@ xf86parseMonitorSection(void)
             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
                 Error(VERTREFRESH_MSG);
             do {
-                ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum;
+                ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = xf86_lex_val.realnum;
                 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
                 case COMMA:
                     ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
@@ -499,10 +498,10 @@ xf86parseMonitorSection(void)
                     break;
                 case DASH:
                     if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
-                        (float) val.realnum <
+                        (float) xf86_lex_val.realnum <
                         ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo)
                         Error(VERTREFRESH_MSG);
-                    ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum;
+                    ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = xf86_lex_val.realnum;
                     if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
                         break;
                     ptr->mon_n_vrefresh++;
@@ -530,11 +529,11 @@ xf86parseMonitorSection(void)
             }
             else {
                 ptr->mon_gamma_red = ptr->mon_gamma_green =
-                    ptr->mon_gamma_blue = val.realnum;
+                    ptr->mon_gamma_blue = xf86_lex_val.realnum;
                 if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
-                    ptr->mon_gamma_green = val.realnum;
+                    ptr->mon_gamma_green = xf86_lex_val.realnum;
                     if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
-                        ptr->mon_gamma_blue = val.realnum;
+                        ptr->mon_gamma_blue = xf86_lex_val.realnum;
                     }
                     else {
                         Error(INVALID_GAMMA_MSG);
@@ -558,7 +557,7 @@ xf86parseMonitorSection(void)
                referenced here */
             mptr = calloc(1, sizeof(XF86ConfModesLinkRec));
             mptr->list.next = NULL;
-            mptr->ml_modes_str = val.str;
+            mptr->ml_modes_str = xf86_lex_val.str;
             mptr->ml_modes = NULL;
             ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
                 xf86addListItem((GenericListPtr) ptr->mon_modes_sect_lst,
@@ -599,14 +598,14 @@ xf86parseModesSection(void)
         while ((token = xf86getToken(ModesTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->modes_comment = xf86addComment(ptr->modes_comment, val.str);
+            ptr->modes_comment = xf86addComment(ptr->modes_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->modes_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->modes_identifier = val.str;
+            ptr->modes_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case MODE:
diff --git a/hw/xfree86/parser/Pointer.c b/hw/xfree86/parser/Pointer.c
index ff748d9..fe60d95 100644
--- a/hw/xfree86/parser/Pointer.c
+++ b/hw/xfree86/parser/Pointer.c
@@ -61,7 +61,6 @@
 #include "Configint.h"
 #include "Xprintf.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec PointerTab[] = {
     {PROTOCOL, "protocol"},
@@ -104,19 +103,19 @@ xf86parsePointerSection(void)
         while ((token = xf86getToken(PointerTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->inp_comment = xf86addComment(ptr->inp_comment, val.str);
+            ptr->inp_comment = xf86addComment(ptr->inp_comment, xf86_lex_val.str);
             break;
         case PROTOCOL:
             if (xf86getSubToken(&(ptr->inp_comment)) != STRING)
                 Error(QUOTE_MSG, "Protocol");
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
-                                                   strdup("Protocol"), val.str);
+                                                   strdup("Protocol"), xf86_lex_val.str);
             break;
         case PDEVICE:
             if (xf86getSubToken(&(ptr->inp_comment)) != STRING)
                 Error(QUOTE_MSG, "Device");
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
-                                                   strdup("Device"), val.str);
+                                                   strdup("Device"), xf86_lex_val.str);
             break;
         case EMULATE3:
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
@@ -124,9 +123,9 @@ xf86parsePointerSection(void)
                                                    NULL);
             break;
         case EM3TIMEOUT:
-            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || val.num < 0)
+            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || xf86_lex_val.num < 0)
                 Error(POSITIVE_INT_MSG, "Emulate3Timeout");
-            s = xf86uLongToString(val.num);
+            s = xf86uLongToString(xf86_lex_val.num);
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
                                                    strdup("Emulate3Timeout"),
                                                    s);
@@ -136,30 +135,30 @@ xf86parsePointerSection(void)
                                                    strdup("ChordMiddle"), NULL);
             break;
         case PBUTTONS:
-            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || val.num < 0)
+            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || xf86_lex_val.num < 0)
                 Error(POSITIVE_INT_MSG, "Buttons");
-            s = xf86uLongToString(val.num);
+            s = xf86uLongToString(xf86_lex_val.num);
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
                                                    strdup("Buttons"), s);
             break;
         case BAUDRATE:
-            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || val.num < 0)
+            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || xf86_lex_val.num < 0)
                 Error(POSITIVE_INT_MSG, "BaudRate");
-            s = xf86uLongToString(val.num);
+            s = xf86uLongToString(xf86_lex_val.num);
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
                                                    strdup("BaudRate"), s);
             break;
         case SAMPLERATE:
-            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || val.num < 0)
+            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || xf86_lex_val.num < 0)
                 Error(POSITIVE_INT_MSG, "SampleRate");
-            s = xf86uLongToString(val.num);
+            s = xf86uLongToString(xf86_lex_val.num);
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
                                                    strdup("SampleRate"), s);
             break;
         case PRESOLUTION:
-            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || val.num < 0)
+            if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER || xf86_lex_val.num < 0)
                 Error(POSITIVE_INT_MSG, "Resolution");
-            s = xf86uLongToString(val.num);
+            s = xf86uLongToString(xf86_lex_val.num);
             ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst,
                                                    strdup("Resolution"), s);
             break;
@@ -174,14 +173,14 @@ xf86parsePointerSection(void)
         case ZAXISMAPPING:
             switch (xf86getToken(ZMapTab)) {
             case NUMBER:
-                if (val.num < 0)
+                if (xf86_lex_val.num < 0)
                     Error(ZAXISMAPPING_MSG);
-                val1 = val.num;
+                val1 = xf86_lex_val.num;
                 if (xf86getSubToken(&(ptr->inp_comment)) != NUMBER ||
-                    val.num < 0) {
+                    xf86_lex_val.num < 0) {
                     Error(ZAXISMAPPING_MSG);
                 }
-                if (asprintf(&s, "%lu %u", val1, val.num) == -1)
+                if (asprintf(&s, "%lu %u", val1, xf86_lex_val.num) == -1)
                     s = NULL;
                 break;
             case XAXIS:
diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
index f294ec4..fecd57c 100644
--- a/hw/xfree86/parser/Screen.c
+++ b/hw/xfree86/parser/Screen.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec DisplayTab[] = {
     {ENDSUBSECTION, "endsubsection"},
@@ -92,71 +91,71 @@ xf86parseDisplaySubSection(void)
     while ((token = xf86getToken(DisplayTab)) != ENDSUBSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->disp_comment = xf86addComment(ptr->disp_comment, val.str);
+            ptr->disp_comment = xf86addComment(ptr->disp_comment, xf86_lex_val.str);
             break;
         case VIEWPORT:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(VIEWPORT_MSG);
-            ptr->disp_frameX0 = val.num;
+            ptr->disp_frameX0 = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(VIEWPORT_MSG);
-            ptr->disp_frameY0 = val.num;
+            ptr->disp_frameY0 = xf86_lex_val.num;
             break;
         case VIRTUAL:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(VIRTUAL_MSG);
-            ptr->disp_virtualX = val.num;
+            ptr->disp_virtualX = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(VIRTUAL_MSG);
-            ptr->disp_virtualY = val.num;
+            ptr->disp_virtualY = xf86_lex_val.num;
             break;
         case DEPTH:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Display");
-            ptr->disp_depth = val.num;
+            ptr->disp_depth = xf86_lex_val.num;
             break;
         case BPP:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(NUMBER_MSG, "Display");
-            ptr->disp_bpp = val.num;
+            ptr->disp_bpp = xf86_lex_val.num;
             break;
         case VISUAL:
             if (xf86getSubToken(&(ptr->disp_comment)) != STRING)
                 Error(QUOTE_MSG, "Display");
-            ptr->disp_visual = val.str;
+            ptr->disp_visual = xf86_lex_val.str;
             break;
         case WEIGHT:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WEIGHT_MSG);
-            ptr->disp_weight.red = val.num;
+            ptr->disp_weight.red = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WEIGHT_MSG);
-            ptr->disp_weight.green = val.num;
+            ptr->disp_weight.green = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WEIGHT_MSG);
-            ptr->disp_weight.blue = val.num;
+            ptr->disp_weight.blue = xf86_lex_val.num;
             break;
         case BLACK_TOK:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(BLACK_MSG);
-            ptr->disp_black.red = val.num;
+            ptr->disp_black.red = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(BLACK_MSG);
-            ptr->disp_black.green = val.num;
+            ptr->disp_black.green = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(BLACK_MSG);
-            ptr->disp_black.blue = val.num;
+            ptr->disp_black.blue = xf86_lex_val.num;
             break;
         case WHITE_TOK:
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WHITE_MSG);
-            ptr->disp_white.red = val.num;
+            ptr->disp_white.red = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WHITE_MSG);
-            ptr->disp_white.green = val.num;
+            ptr->disp_white.green = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
                 Error(WHITE_MSG);
-            ptr->disp_white.blue = val.num;
+            ptr->disp_white.blue = xf86_lex_val.num;
             break;
         case MODES:
         {
@@ -166,7 +165,7 @@ xf86parseDisplaySubSection(void)
                     xf86getSubTokenWithTab(&(ptr->disp_comment),
                                            DisplayTab)) == STRING) {
                 mptr = calloc(1, sizeof(XF86ModeRec));
-                mptr->mode_name = val.str;
+                mptr->mode_name = xf86_lex_val.str;
                 mptr->list.next = NULL;
                 ptr->disp_mode_lst = (XF86ModePtr)
                     xf86addListItem((glp) ptr->disp_mode_lst, (glp) mptr);
@@ -227,12 +226,12 @@ xf86parseScreenSection(void)
         while ((token = xf86getToken(ScreenTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->scrn_comment = xf86addComment(ptr->scrn_comment, val.str);
+            ptr->scrn_comment = xf86addComment(ptr->scrn_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
-            ptr->scrn_identifier = val.str;
+            ptr->scrn_identifier = xf86_lex_val.str;
             if (has_ident || has_driver)
                 Error(ONLY_ONE_MSG, "Identifier or Driver");
             has_ident = TRUE;
@@ -240,7 +239,7 @@ xf86parseScreenSection(void)
         case OBSDRIVER:
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            ptr->scrn_obso_driver = val.str;
+            ptr->scrn_obso_driver = xf86_lex_val.str;
             if (has_ident || has_driver)
                 Error(ONLY_ONE_MSG, "Identifier or Driver");
             has_driver = TRUE;
@@ -248,27 +247,27 @@ xf86parseScreenSection(void)
         case DEFAULTDEPTH:
             if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
                 Error(NUMBER_MSG, "DefaultDepth");
-            ptr->scrn_defaultdepth = val.num;
+            ptr->scrn_defaultdepth = xf86_lex_val.num;
             break;
         case DEFAULTBPP:
             if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
                 Error(NUMBER_MSG, "DefaultBPP");
-            ptr->scrn_defaultbpp = val.num;
+            ptr->scrn_defaultbpp = xf86_lex_val.num;
             break;
         case DEFAULTFBBPP:
             if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
                 Error(NUMBER_MSG, "DefaultFbBPP");
-            ptr->scrn_defaultfbbpp = val.num;
+            ptr->scrn_defaultfbbpp = xf86_lex_val.num;
             break;
         case MDEVICE:
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "Device");
-            ptr->scrn_device_str = val.str;
+            ptr->scrn_device_str = xf86_lex_val.str;
             break;
         case MONITOR:
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "Monitor");
-            ptr->scrn_monitor_str = val.str;
+            ptr->scrn_monitor_str = xf86_lex_val.str;
             break;
         case VIDEOADAPTOR:
         {
@@ -280,13 +279,13 @@ xf86parseScreenSection(void)
             /* Don't allow duplicates */
             for (aptr = ptr->scrn_adaptor_lst; aptr;
                  aptr = (XF86ConfAdaptorLinkPtr) aptr->list.next)
-                if (xf86nameCompare(val.str, aptr->al_adaptor_str) == 0)
+                if (xf86nameCompare(xf86_lex_val.str, aptr->al_adaptor_str) == 0)
                     break;
 
             if (aptr == NULL) {
                 aptr = calloc(1, sizeof(XF86ConfAdaptorLinkRec));
                 aptr->list.next = NULL;
-                aptr->al_adaptor_str = val.str;
+                aptr->al_adaptor_str = xf86_lex_val.str;
                 ptr->scrn_adaptor_lst = (XF86ConfAdaptorLinkPtr)
                     xf86addListItem((glp) ptr->scrn_adaptor_lst, (glp) aptr);
             }
@@ -295,10 +294,10 @@ xf86parseScreenSection(void)
         case VIRTUAL:
             if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
                 Error(VIRTUAL_MSG);
-            ptr->scrn_virtualX = val.num;
+            ptr->scrn_virtualX = xf86_lex_val.num;
             if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
                 Error(VIRTUAL_MSG);
-            ptr->scrn_virtualY = val.num;
+            ptr->scrn_virtualY = xf86_lex_val.num;
             break;
         case OPTION:
             ptr->scrn_option_lst = xf86parseOption(ptr->scrn_option_lst);
@@ -307,7 +306,7 @@ xf86parseScreenSection(void)
             if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
                 Error(QUOTE_MSG, "SubSection");
             {
-                free(val.str);
+                free(xf86_lex_val.str);
                 HANDLE_LIST(scrn_display_lst, xf86parseDisplaySubSection,
                             XF86ConfDisplayPtr);
             }
diff --git a/hw/xfree86/parser/Vendor.c b/hw/xfree86/parser/Vendor.c
index 9b7695c..2c870ae 100644
--- a/hw/xfree86/parser/Vendor.c
+++ b/hw/xfree86/parser/Vendor.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec VendorSubTab[] = {
     {ENDSUBSECTION, "endsubsection"},
@@ -82,14 +81,14 @@ xf86parseVendorSubSection(void)
         while ((token = xf86getToken(VendorSubTab)) != ENDSUBSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->vs_comment = xf86addComment(ptr->vs_comment, val.str);
+            ptr->vs_comment = xf86addComment(ptr->vs_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->vs_comment)))
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->vs_identifier = val.str;
+            ptr->vs_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case OPTION:
@@ -135,14 +134,14 @@ xf86parseVendorSection(void)
         while ((token = xf86getToken(VendorTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->vnd_comment = xf86addComment(ptr->vnd_comment, val.str);
+            ptr->vnd_comment = xf86addComment(ptr->vnd_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->vnd_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->vnd_identifier = val.str;
+            ptr->vnd_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case OPTION:
diff --git a/hw/xfree86/parser/Video.c b/hw/xfree86/parser/Video.c
index 68d611a..93209c4 100644
--- a/hw/xfree86/parser/Video.c
+++ b/hw/xfree86/parser/Video.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec VideoPortTab[] = {
     {ENDSUBSECTION, "endsubsection"},
@@ -97,14 +96,14 @@ xf86parseVideoPortSubSection(void)
         while ((token = xf86getToken(VideoPortTab)) != ENDSUBSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->vp_comment = xf86addComment(ptr->vp_comment, val.str);
+            ptr->vp_comment = xf86addComment(ptr->vp_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->vp_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
-            ptr->vp_identifier = val.str;
+            ptr->vp_identifier = xf86_lex_val.str;
             has_ident = TRUE;
             break;
         case OPTION:
@@ -154,12 +153,12 @@ xf86parseVideoAdaptorSection(void)
         while ((token = xf86getToken(VideoAdaptorTab)) != ENDSECTION) {
         switch (token) {
         case COMMENT:
-            ptr->va_comment = xf86addComment(ptr->va_comment, val.str);
+            ptr->va_comment = xf86addComment(ptr->va_comment, xf86_lex_val.str);
             break;
         case IDENTIFIER:
             if (xf86getSubToken(&(ptr->va_comment)) != STRING)
                 Error(QUOTE_MSG, "Identifier");
-            ptr->va_identifier = val.str;
+            ptr->va_identifier = xf86_lex_val.str;
             if (has_ident == TRUE)
                 Error(MULTIPLE_MSG, "Identifier");
             has_ident = TRUE;
@@ -167,22 +166,22 @@ xf86parseVideoAdaptorSection(void)
         case VENDOR:
             if (xf86getSubToken(&(ptr->va_comment)) != STRING)
                 Error(QUOTE_MSG, "Vendor");
-            ptr->va_vendor = val.str;
+            ptr->va_vendor = xf86_lex_val.str;
             break;
         case BOARD:
             if (xf86getSubToken(&(ptr->va_comment)) != STRING)
                 Error(QUOTE_MSG, "Board");
-            ptr->va_board = val.str;
+            ptr->va_board = xf86_lex_val.str;
             break;
         case BUSID:
             if (xf86getSubToken(&(ptr->va_comment)) != STRING)
                 Error(QUOTE_MSG, "BusID");
-            ptr->va_busid = val.str;
+            ptr->va_busid = xf86_lex_val.str;
             break;
         case DRIVER:
             if (xf86getSubToken(&(ptr->va_comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            ptr->va_driver = val.str;
+            ptr->va_driver = xf86_lex_val.str;
             break;
         case OPTION:
             ptr->va_option_lst = xf86parseOption(ptr->va_option_lst);
diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
index 6545bcd..2478b07 100644
--- a/hw/xfree86/parser/read.c
+++ b/hw/xfree86/parser/read.c
@@ -60,7 +60,6 @@
 #include "xf86tokens.h"
 #include "Configint.h"
 
-extern LexRec val;
 
 static xf86ConfigSymTabRec TopLevelTab[] = {
     {SECTION, "section"},
@@ -99,7 +98,7 @@ xf86readConfigFile(void)
     while ((token = xf86getToken(TopLevelTab)) != EOF_TOKEN) {
         switch (token) {
         case COMMENT:
-            ptr->conf_comment = xf86addComment(ptr->conf_comment, val.str);
+            ptr->conf_comment = xf86addComment(ptr->conf_comment, xf86_lex_val.str);
             break;
         case SECTION:
             if (xf86getSubToken(&(ptr->conf_comment)) != STRING) {
@@ -107,101 +106,101 @@ xf86readConfigFile(void)
                 CLEANUP(ptr);
                 return NULL;
             }
-            xf86setSection(val.str);
-            if (xf86nameCompare(val.str, "files") == 0) {
-                free(val.str);
-                val.str = NULL;
+            xf86setSection(xf86_lex_val.str);
+            if (xf86nameCompare(xf86_lex_val.str, "files") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_RETURN(conf_files, xf86parseFilesSection());
             }
-            else if (xf86nameCompare(val.str, "serverflags") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "serverflags") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_RETURN(conf_flags, xf86parseFlagsSection());
             }
-            else if (xf86nameCompare(val.str, "pointer") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "pointer") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_input_lst, xf86parsePointerSection,
                             XF86ConfInputPtr);
             }
-            else if (xf86nameCompare(val.str, "videoadaptor") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "videoadaptor") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_videoadaptor_lst, xf86parseVideoAdaptorSection,
                             XF86ConfVideoAdaptorPtr);
             }
-            else if (xf86nameCompare(val.str, "device") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "device") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_device_lst, xf86parseDeviceSection,
                             XF86ConfDevicePtr);
             }
-            else if (xf86nameCompare(val.str, "monitor") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "monitor") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_monitor_lst, xf86parseMonitorSection,
                             XF86ConfMonitorPtr);
             }
-            else if (xf86nameCompare(val.str, "modes") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "modes") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_modes_lst, xf86parseModesSection,
                             XF86ConfModesPtr);
             }
-            else if (xf86nameCompare(val.str, "screen") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "screen") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_screen_lst, xf86parseScreenSection,
                             XF86ConfScreenPtr);
             }
-            else if (xf86nameCompare(val.str, "inputdevice") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "inputdevice") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_input_lst, xf86parseInputSection,
                             XF86ConfInputPtr);
             }
-            else if (xf86nameCompare(val.str, "inputclass") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "inputclass") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_inputclass_lst,
                             xf86parseInputClassSection, XF86ConfInputClassPtr);
             }
-            else if (xf86nameCompare(val.str, "module") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "module") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_RETURN(conf_modules, xf86parseModuleSection());
             }
-            else if (xf86nameCompare(val.str, "serverlayout") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "serverlayout") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_layout_lst, xf86parseLayoutSection,
                             XF86ConfLayoutPtr);
             }
-            else if (xf86nameCompare(val.str, "vendor") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "vendor") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_LIST(conf_vendor_lst, xf86parseVendorSection,
                             XF86ConfVendorPtr);
             }
-            else if (xf86nameCompare(val.str, "dri") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "dri") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_RETURN(conf_dri, xf86parseDRISection());
             }
-            else if (xf86nameCompare(val.str, "extensions") == 0) {
-                free(val.str);
-                val.str = NULL;
+            else if (xf86nameCompare(xf86_lex_val.str, "extensions") == 0) {
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 HANDLE_RETURN(conf_extensions, xf86parseExtensionsSection());
             }
             else {
-                free(val.str);
-                val.str = NULL;
+                free(xf86_lex_val.str);
+                xf86_lex_val.str = NULL;
                 Error(INVALID_SECTION_MSG, xf86tokenString());
             }
             break;
         default:
-            free(val.str);
-            val.str = NULL;
+            free(xf86_lex_val.str);
+            xf86_lex_val.str = NULL;
             Error(INVALID_KEYWORD_MSG, xf86tokenString());
         }
     }
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index 55a8442..a6c1295 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -103,7 +103,7 @@ static int numFiles = 0;        /* number of config files */
 static int curFileIndex = 0;    /* index of current config file */
 static int pushToken = LOCK_TOKEN;
 static int eol_seen = 0;        /* private state to handle comments */
-LexRec val;
+LexRec xf86_lex_val;
 
 /*
  * xf86getNextLine --
@@ -332,7 +332,7 @@ xf86getToken(xf86ConfigSymTabRec * tab)
             /* XXX no private copy.
              * Use xf86addComment when setting a comment.
              */
-            val.str = configRBuf;
+            xf86_lex_val.str = configRBuf;
             return COMMENT;
         }
 
@@ -354,15 +354,15 @@ xf86getToken(xf86ConfigSymTabRec * tab)
                 if ((configBuf[configPos] == 'x') ||
                     (configBuf[configPos] == 'X')) {
                     base = 16;
-                    val.numType = PARSE_HEX;
+                    xf86_lex_val.numType = PARSE_HEX;
                 }
                 else {
                     base = 8;
-                    val.numType = PARSE_OCTAL;
+                    xf86_lex_val.numType = PARSE_OCTAL;
                 }
             else {
                 base = 10;
-                val.numType = PARSE_DECIMAL;
+                xf86_lex_val.numType = PARSE_DECIMAL;
             }
 
             configRBuf[0] = c;
@@ -374,8 +374,8 @@ xf86getToken(xf86ConfigSymTabRec * tab)
                 configRBuf[i++] = c;
             configPos--;        /* GJA -- one too far */
             configRBuf[i] = '\0';
-            val.num = strtoul(configRBuf, NULL, 0);
-            val.realnum = atof(configRBuf);
+            xf86_lex_val.num = strtoul(configRBuf, NULL, 0);
+            xf86_lex_val.realnum = atof(configRBuf);
             return NUMBER;
         }
 
@@ -389,8 +389,8 @@ xf86getToken(xf86ConfigSymTabRec * tab)
             }
             while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0'));
             configRBuf[i] = '\0';
-            val.str = malloc(strlen(configRBuf) + 1);
-            strcpy(val.str, configRBuf);        /* private copy ! */
+            xf86_lex_val.str = malloc(strlen(configRBuf) + 1);
+            strcpy(xf86_lex_val.str, configRBuf);        /* private copy ! */
             return STRING;
         }
 
@@ -452,7 +452,7 @@ xf86getSubToken(char **comment)
         token = xf86getToken(NULL);
         if (token == COMMENT) {
             if (comment)
-                *comment = xf86addComment(*comment, val.str);
+                *comment = xf86addComment(*comment, xf86_lex_val.str);
         }
         else
             return token;
@@ -468,7 +468,7 @@ xf86getSubTokenWithTab(char **comment, xf86ConfigSymTabRec * tab)
         token = xf86getToken(tab);
         if (token == COMMENT) {
             if (comment)
-                *comment = xf86addComment(*comment, val.str);
+                *comment = xf86addComment(*comment, xf86_lex_val.str);
         }
         else
             return token;
@@ -1025,7 +1025,7 @@ xf86setSection(const char *section)
 int
 xf86getStringToken(xf86ConfigSymTabRec * tab)
 {
-    return StringToToken(val.str, tab);
+    return StringToToken(xf86_lex_val.str, tab);
 }
 
 static int
diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index 8af1df4..b50badb 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -11705,38 +11705,38 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
         switch (rh) {
         case 0:                /* inc word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 1:                /* dec word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 2:                /* call word ptr ... */
@@ -11768,18 +11768,18 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             break;
         case 6:                /*  push word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                push_long(destval);
+                push_long(destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                push_word(destval);
+                push_word(destval16);
             }
             break;
         }
@@ -11790,38 +11790,38 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
         switch (rh) {
         case 0:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 1:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 2:                /* call word ptr ... */
@@ -11853,18 +11853,18 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             break;
         case 6:                /*  push word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                push_long(destval);
+                push_long(destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                push_word(destval);
+                push_word(destval16);
             }
             break;
         }
@@ -11875,38 +11875,38 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
         switch (rh) {
         case 0:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = inc_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 1:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_long(destval);
-                store_data_long(destoffset, destval);
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                destval = dec_word(destval);
-                store_data_word(destoffset, destval);
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
             }
             break;
         case 2:                /* call word ptr ... */
@@ -11938,18 +11938,18 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             break;
         case 6:                /*  push word ptr ... */
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 destval;
+                u32 destval32;
 
-                destval = fetch_data_long(destoffset);
+                destval32 = fetch_data_long(destoffset);
                 TRACE_AND_STEP();
-                push_long(destval);
+                push_long(destval32);
             }
             else {
-                u16 destval;
+                u16 destval16;
 
-                destval = fetch_data_word(destoffset);
+                destval16 = fetch_data_word(destoffset);
                 TRACE_AND_STEP();
-                push_word(destval);
+                push_word(destval16);
             }
             break;
         }
@@ -11958,38 +11958,38 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
         switch (rh) {
         case 0:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 *destreg;
+                u32 *destreg32;
 
-                destreg = DECODE_RM_LONG_REGISTER(rl);
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                *destreg = inc_long(*destreg);
+                *destreg32 = inc_long(*destreg32);
             }
             else {
-                u16 *destreg;
+                u16 *destreg16;
 
-                destreg = DECODE_RM_WORD_REGISTER(rl);
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                *destreg = inc_word(*destreg);
+                *destreg16 = inc_word(*destreg16);
             }
             break;
         case 1:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 *destreg;
+                u32 *destreg32;
 
-                destreg = DECODE_RM_LONG_REGISTER(rl);
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                *destreg = dec_long(*destreg);
+                *destreg32 = dec_long(*destreg32);
             }
             else {
-                u16 *destreg;
+                u16 *destreg16;
 
-                destreg = DECODE_RM_WORD_REGISTER(rl);
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                *destreg = dec_word(*destreg);
+                *destreg16 = dec_word(*destreg16);
             }
             break;
         case 2:                /* call word ptr ... */
@@ -12018,20 +12018,20 @@ x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
             break;
         case 6:
             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
-                u32 *destreg;
+                u32 *destreg32;
 
-                destreg = DECODE_RM_LONG_REGISTER(rl);
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                push_long(*destreg);
+                push_long(*destreg32);
             }
             else {
-                u16 *destreg;
+                u16 *destreg16;
 
-                destreg = DECODE_RM_WORD_REGISTER(rl);
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
                 DECODE_PRINTF("\n");
                 TRACE_AND_STEP();
-                push_word(*destreg);
+                push_word(*destreg16);
             }
             break;
         }
commit 3c94b89f149c2d63424faed0d44a6911393c3569
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:40:04 2013 -0800

    Xi: Use 'void *' instead of 'Pointer' (which is going away)
    
    There's no reason for XI to declare 'typedef char *Pointer' in a
    shared header file; assume it will eventually go away and stop using
    it here.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/Xi/grabdev.c b/Xi/grabdev.c
index 9c6c429..0900438 100644
--- a/Xi/grabdev.c
+++ b/Xi/grabdev.c
@@ -191,7 +191,7 @@ CreateMaskFromList(ClientPtr client, XEventClass * list, int count,
         for (j = 0; j < ExtEventIndex; j++)
             if (EventInfo[j].type == (*list & 0xff)) {
                 mask[device].mask |= EventInfo[j].mask;
-                mask[device].dev = (Pointer) tdev;
+                mask[device].dev = (void *) tdev;
                 break;
             }
     }
commit 08d0481e299c28b64a0db9bb0782ba2b551028fd
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:12:22 2013 -0800

    os: Fix -Wshadow errors
    
    Rename variables to avoid shadowing globals
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/os/xdmauth.c b/os/xdmauth.c
index 28584d2..f11cbb9 100644
--- a/os/xdmauth.c
+++ b/os/xdmauth.c
@@ -62,7 +62,7 @@ static XdmAuthKeyRec privateKey;
 static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
 
 #define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
-static XdmAuthKeyRec rho;
+static XdmAuthKeyRec global_rho;
 
 static Bool
 XdmAuthenticationValidator(ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
@@ -77,7 +77,7 @@ XdmAuthenticationValidator(ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
             return FALSE;
         incoming = (XdmAuthKeyPtr) incomingData->data;
         XdmcpDecrementKey(incoming);
-        return XdmcpCompareKeys(incoming, &rho);
+        return XdmcpCompareKeys(incoming, &global_rho);
     }
     return FALSE;
 }
@@ -90,7 +90,7 @@ XdmAuthenticationGenerator(ARRAY8Ptr privateData, ARRAY8Ptr outgoingData,
     outgoingData->data = 0;
     if (packet_type == REQUEST) {
         if (XdmcpAllocARRAY8(outgoingData, 8))
-            XdmcpWrap((unsigned char *) &rho, (unsigned char *) &privateKey,
+            XdmcpWrap((unsigned char *) &global_rho, (unsigned char *) &privateKey,
                       outgoingData->data, 8);
     }
     return TRUE;
@@ -150,10 +150,10 @@ XdmAuthenticationInit(const char *cookie, int cookie_len)
             cookie_len = 7;
         memmove(privateKey.data + 1, cookie, cookie_len);
     }
-    XdmcpGenerateKey(&rho);
+    XdmcpGenerateKey(&global_rho);
     XdmcpRegisterAuthentication(XdmAuthenticationName, XdmAuthenticationNameLen,
-                                (char *) &rho,
-                                sizeof(rho),
+                                (char *) &global_rho,
+                                sizeof(global_rho),
                                 (ValidatorFunc) XdmAuthenticationValidator,
                                 (GeneratorFunc) XdmAuthenticationGenerator,
                                 (AddAuthorFunc) XdmAuthenticationAddAuth);
@@ -328,7 +328,7 @@ XdmAddCookie(unsigned short data_length, const char *data, XID id)
         if (authFromXDMCP) {
             /* R5 xdm sent bogus authorization data in the accept packet,
              * but we can recover */
-            rho_bits = rho.data;
+            rho_bits = global_rho.data;
             key_bits = (unsigned char *) data;
             key_bits[0] = '\0';
         }
@@ -341,7 +341,7 @@ XdmAddCookie(unsigned short data_length, const char *data, XID id)
         break;
 #ifdef XDMCP
     case 8:                    /* auth from XDMCP is 8 bytes long */
-        rho_bits = rho.data;
+        rho_bits = global_rho.data;
         key_bits = (unsigned char *) data;
         break;
 #endif
@@ -466,7 +466,7 @@ XdmRemoveCookie(unsigned short data_length, const char *data)
         break;
 #ifdef XDMCP
     case 8:
-        rho_bits = ρ
+        rho_bits = &global_rho;
         key_bits = (XdmAuthKeyPtr) data;
         break;
 #endif
diff --git a/os/xdmcp.c b/os/xdmcp.c
index fd8ae58..99616d9 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -641,15 +641,15 @@ XdmcpCloseDisplay(int sock)
 XdmcpBlockHandler(void *data, /* unused */
                   struct timeval **wt, void *pReadmask)
 {
-    fd_set *LastSelectMask = (fd_set *) pReadmask;
+    fd_set *last_select_mask = (fd_set *) pReadmask;
     CARD32 millisToGo;
 
     if (state == XDM_OFF)
         return;
-    FD_SET(xdmcpSocket, LastSelectMask);
+    FD_SET(xdmcpSocket, last_select_mask);
 #if defined(IPv6) && defined(AF_INET6)
     if (xdmcpSocket6 >= 0)
-        FD_SET(xdmcpSocket6, LastSelectMask);
+        FD_SET(xdmcpSocket6, last_select_mask);
 #endif
     if (timeOutTime == 0)
         return;
@@ -669,23 +669,23 @@ XdmcpBlockHandler(void *data, /* unused */
 XdmcpWakeupHandler(void *data,        /* unused */
                    int i, void *pReadmask)
 {
-    fd_set *LastSelectMask = (fd_set *) pReadmask;
+    fd_set *last_select_mask = (fd_set *) pReadmask;
     fd_set devicesReadable;
 
     if (state == XDM_OFF)
         return;
     if (i > 0) {
-        if (FD_ISSET(xdmcpSocket, LastSelectMask)) {
+        if (FD_ISSET(xdmcpSocket, last_select_mask)) {
             receive_packet(xdmcpSocket);
-            FD_CLR(xdmcpSocket, LastSelectMask);
+            FD_CLR(xdmcpSocket, last_select_mask);
         }
 #if defined(IPv6) && defined(AF_INET6)
-        if (xdmcpSocket6 >= 0 && FD_ISSET(xdmcpSocket6, LastSelectMask)) {
+        if (xdmcpSocket6 >= 0 && FD_ISSET(xdmcpSocket6, last_select_mask)) {
             receive_packet(xdmcpSocket6);
-            FD_CLR(xdmcpSocket6, LastSelectMask);
+            FD_CLR(xdmcpSocket6, last_select_mask);
         }
 #endif
-        XFD_ANDSET(&devicesReadable, LastSelectMask, &EnabledDevices);
+        XFD_ANDSET(&devicesReadable, last_select_mask, &EnabledDevices);
         if (XFD_ANYSET(&devicesReadable)) {
             if (state == XDM_AWAIT_USER_INPUT)
                 restart();
@@ -712,12 +712,12 @@ XdmcpWakeupHandler(void *data,        /* unused */
 
 static void
 XdmcpSelectHost(const struct sockaddr *host_sockaddr,
-                int host_len, ARRAY8Ptr AuthenticationName)
+                int host_len, ARRAY8Ptr auth_name)
 {
     state = XDM_START_CONNECTION;
     memmove(&req_sockaddr, host_sockaddr, host_len);
     req_socklen = host_len;
-    XdmcpSetAuthentication(AuthenticationName);
+    XdmcpSetAuthentication(auth_name);
     send_packet();
 }
 
@@ -730,9 +730,9 @@ XdmcpSelectHost(const struct sockaddr *host_sockaddr,
  /*ARGSUSED*/ static void
 XdmcpAddHost(const struct sockaddr *from,
              int fromlen,
-             ARRAY8Ptr AuthenticationName, ARRAY8Ptr hostname, ARRAY8Ptr status)
+             ARRAY8Ptr auth_name, ARRAY8Ptr hostname, ARRAY8Ptr status)
 {
-    XdmcpSelectHost(from, fromlen, AuthenticationName);
+    XdmcpSelectHost(from, fromlen, auth_name);
 }
 
 /*
@@ -1058,8 +1058,6 @@ send_query_msg(void)
     XdmcpWriteHeader(&buffer, &header);
     XdmcpWriteARRAYofARRAY8(&buffer, &AuthenticationNames);
     if (broadcast) {
-        int i;
-
         for (i = 0; i < NumBroadcastAddresses; i++)
             XdmcpFlush(xdmcpSocket, &buffer,
                        (XdmcpNetaddr) &BroadcastAddresses[i],
commit 1487145b41390e689f8b03c1e8a2df70e00cf519
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 13 11:25:45 2013 -0800

    Add 'FONT_PATH_NAME_ELEMENT_CONST' to dix-config.h and xorg-server.h
    
    This signals to the fontsproto code that the X server has been fixed
    to allow the name member in a FontPathElement struct to be declared
    const to eliminate piles of warnings when assigning string constants
    to them.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 957257b..55cfe47 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -472,4 +472,7 @@
 /* Don't let Xdefs.h define 'pointer' */
 #define _XTYPEDEF_POINTER       1
 
+/* Ask fontsproto to make font path element names const */
+#define FONT_PATH_ELEMENT_NAME_CONST    1
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index 0c651bf..8bf9d38 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -224,4 +224,7 @@
 /* Use XTrans FD passing support */
 #undef XTRANS_SEND_FDS
 
+/* Ask fontsproto to make font path element names const */
+#define FONT_PATH_ELEMENT_NAME_CONST    1
+
 #endif /* _XORG_SERVER_H_ */
commit 1ad8d12e7fcd7d55a37099d7426e3290297ba6d3
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Dec 13 11:24:00 2013 -0800

    Ignore a couple of format-nonliteral warnings
    
    These are generated in code which uses sprintf as a convenient way to
    construct strings from various pieces.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index e2e8d08..46438e6 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -155,6 +155,7 @@ xf86OpenConsole(void)
 
         i = 0;
         while (vcs[i] != NULL) {
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
             snprintf(vtname, sizeof(vtname), vcs[i], xf86Info.vtno);    /* /dev/tty1-64 */
             if ((xf86Info.consoleFd = open(vtname, O_RDWR | O_NDELAY, 0)) >= 0)
                 break;
diff --git a/os/log.c b/os/log.c
index 792b79e..8deb810 100644
--- a/os/log.c
+++ b/os/log.c
@@ -195,6 +195,7 @@ LogInit(const char *fname, const char *backup)
     char *logFileName = NULL;
 
     if (fname && *fname) {
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
         if (asprintf(&logFileName, fname, display) == -1)
             FatalError("Cannot allocate space for the log file name\n");
 
@@ -205,6 +206,7 @@ LogInit(const char *fname, const char *backup)
                 char *suffix;
                 char *oldLog;
 
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
                 if ((asprintf(&suffix, backup, display) == -1) ||
                     (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1))
                     FatalError("Cannot allocate space for the log file name\n");
commit 9ef53e2267ea3dd60651961f66c65e8b00b7d823
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 11:55:37 2013 -0800

    include: GetClientResolutions is declared in font.h
    
    No need to have a duplicate definition here.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/include/dixfontstubs.h b/include/dixfontstubs.h
index 0454ffa..535d312 100644
--- a/include/dixfontstubs.h
+++ b/include/dixfontstubs.h
@@ -11,8 +11,6 @@ extern _X_EXPORT int client_auth_generation(ClientPtr client);
 
 extern _X_EXPORT void DeleteFontClientID(Font id);
 
-extern _X_EXPORT FontResolutionPtr GetClientResolutions(int *num);
-
 extern _X_EXPORT int GetDefaultPointSize(void);
 
 extern _X_EXPORT Font GetNewFontClientID(void);
commit 25ebb9dbc9df659dec2bf6c27654a5bad2d11f94
Merge: 409e8e2 71baa46
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:33:53 2014 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit 409e8e29fbe16122ba5a4249256fc56e2e68ea93
Merge: 457bc83 d6c8d75
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:32:35 2014 -0800

    Merge remote-tracking branch 'dlespiau/20131216-4k'

commit 457bc83549e58bb87de96bed02988db3275a7611
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Jan 4 00:09:45 2014 -0800

    If EAGAIN == EWOULDBLOCK, only need to check errno for one of them
    
    Solaris <sys/errno.h> has:
     #define EWOULDBLOCK       EAGAIN
    so checking (errno == EAGAIN || errno == EWOULDBLOCK) is overkill.
    
    This leads cppcheck 1.62 to complain:
    [xserver/os/io.c:365] -> [xserver/os/io.c:365]: (style) Same expression on both sides of '||'.
    [xserver/os/io.c:941] -> [xserver/os/io.c:941]: (style) Same expression on both sides of '||'.
    
    This quiets it, and reduces the number of calls Solaris Studio cc
    generates to the __errno() function to get the thread-specific errno value.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/io.c b/os/io.c
index cf5e8f9..8181a86 100644
--- a/os/io.c
+++ b/os/io.c
@@ -102,12 +102,17 @@ typedef struct _connectionOutput {
 static ConnectionInputPtr AllocateInputBuffer(void);
 static ConnectionOutputPtr AllocateOutputBuffer(void);
 
-/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+/* If EAGAIN and EWOULDBLOCK are distinct errno values, then we check errno
+ * for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
  * systems are broken and return EWOULDBLOCK when they should return EAGAIN
  */
 #ifndef WIN32
-#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
-#else                           /* WIN32 The socket errorcodes differ from the normal errors */
+# if (EAGAIN != EWOULDBLOCK)
+#  define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+# else
+#  define ETEST(err) (err == EAGAIN)
+# endif
+#else   /* WIN32 The socket errorcodes differ from the normal errors */
 #define ETEST(err) (err == EAGAIN || err == WSAEWOULDBLOCK)
 #endif
 
commit 044a6ef2ff5f2c83a80b11e747f62f48830b526b
Merge: 0b932cf 77df653
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:28:54 2014 -0800

    Merge remote-tracking branch 'jeremyhu/master'

commit 0b932cf47a4df8ea0f7488e285d218fe7c10dd77
Merge: 1d76b02 295d41f
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:27:36 2014 -0800

    Merge remote-tracking branch 'anholt/xserver-unifdef'

commit 1d76b02fac79c0360ae201e4d1a8ba0e9a00e810
Merge: 771f390 4dd62d7
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jan 22 11:22:35 2014 -0800

    Merge remote-tracking branch 'anholt/glamor-external-rebase'

commit 771f390efdf48cb7c44fe20857f06f8ffff3b2ce
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sat Dec 21 19:58:32 2013 -0500

    autoconf: fix warning by replacing AC_WARN with AC_MSG_WARN
    
    A warning about the macro generating the warnings to the user...
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 85ef4f0..560c460 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2413,7 +2413,7 @@ AC_SUBST([prefix])
 AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/sdksyms.dep])
 
 if test "x$CONFIG_HAL" = xno && test "x$CONFIG_UDEV" = xno; then
-    AC_WARN([
+    AC_MSG_WARN([
              ***********************************************
              Neither HAL nor udev backend will be enabled.
              Input device hotplugging will not be available!
commit c3819da87ff2e8c6292066f965c098704edc442c
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sat Dec 21 19:58:31 2013 -0500

    xorg-tls: fix warning, replace AC_TRY_COMPILE with AC_COMPILE_IFELSE
    
    The code produced in the configure script is identical.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/m4/xorg-tls.m4 b/m4/xorg-tls.m4
index e04f1ff..5768775 100644
--- a/m4/xorg-tls.m4
+++ b/m4/xorg-tls.m4
@@ -28,7 +28,7 @@ AC_DEFUN([XORG_TLS], [
         ac_cv_tls=none
         keywords="__thread __declspec(thread)"
         for kw in $keywords ; do
-            AC_TRY_COMPILE([int $kw test;], [], ac_cv_tls=$kw ; break ;)
+            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $kw test;]], [])], ac_cv_tls=$kw ; break ;)
         done
     ])
     AC_MSG_RESULT($ac_cv_tls)
@@ -38,7 +38,7 @@ AC_DEFUN([XORG_TLS], [
         AC_CACHE_VAL(ac_cv_tls_model, [
             save_CFLAGS="$CFLAGS"
             CFLAGS="$CFLAGS $STRICT_CFLAGS"
-            AC_TRY_COMPILE([int $ac_cv_tls __attribute__((tls_model("initial-exec"))) test;], [],
+            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $ac_cv_tls __attribute__((tls_model("initial-exec"))) test;]], [])],
                            ac_cv_tls_model=yes, ac_cv_tls_model=no)
             CFLAGS="$save_CFLAGS"
         ])
commit 02d866a088a2fc60c6aaebe23c48b372f6b6aa9b
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sat Dec 21 19:58:30 2013 -0500

    autoconf: fix warning, replace AC_TRY_COMPILE with AC_COMPILE_IFELSE
    
    The code produced in the configure script is identical.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 2a90287..85ef4f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1820,13 +1820,13 @@ if test "x$XORG" = xyes; then
 		save_CFLAGS="$CFLAGS"
 		proto_inc=`$PKG_CONFIG --cflags xproto`
 		CFLAGS="$CFLAGS $VISIBILITY_CFLAGS $proto_inc"
-		AC_TRY_COMPILE(
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
 		    [#include <X11/Xfuncproto.h>
 		     extern _X_HIDDEN int hidden_int;
 		     extern _X_EXPORT int public_int;
 		     extern _X_HIDDEN int hidden_int_func(void);
-		     extern _X_EXPORT int public_int_func(void);],
-		    [],
+		     extern _X_EXPORT int public_int_func(void);]],
+		    [])],
 		    have_visibility=yes,
 		    have_visibility=no)
 		CFLAGS=$save_CFLAGS
@@ -2386,12 +2386,12 @@ dnl though, thanks to the passing of some significant amount of time, the
 dnl above is probably a complete fallacy, and you should not rely on it.
 dnl but this is still actually better than imake, honest. -daniels
 
-AC_TRY_COMPILE([
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #include <features.h>
 #ifndef __GLIBC__
 #error not glibc
 #endif
-], [], [AC_DEFINE(_GNU_SOURCE, 1,
+]], [])], [AC_DEFINE(_GNU_SOURCE, 1,
 	[ Enable GNU and other extensions to the C environment for glibc])])
 
 AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix])
commit e38c98fe74394a138ebadb29b1cfe1d4ea7f7071
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sat Dec 21 19:58:29 2013 -0500

    autoconf: fix warning, replace AC_TRY_LINK with AC_LINK_IFELSE
    
    The code produced in the configure script is identical.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 5025718..2a90287 100644
--- a/configure.ac
+++ b/configure.ac
@@ -265,20 +265,20 @@ AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes])
 
 AC_CACHE_CHECK([for SYSV IPC],
 		ac_cv_sysv_ipc,
-		[AC_TRY_LINK([
+               [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/stat.h>
-],[
+]],[[
 { 
     int id;
     id = shmget(IPC_PRIVATE, 512, S_IRUSR | S_IWUSR);
     if (id < 0) return -1;
     return shmctl(id, IPC_RMID, 0);
-}],
-	[ac_cv_sysv_ipc=yes],
-	[ac_cv_sysv_ipc=no])])
+}]])],
+       [ac_cv_sysv_ipc=yes],
+       [ac_cv_sysv_ipc=no])])
 if test "x$ac_cv_sysv_ipc" = xyes; then
 	AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available])
 fi
commit 4993590c90b1289171a2ca0e74d9c4310f5318c7
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sat Dec 21 19:58:28 2013 -0500

    autoconf: fix warning by replacing deprecated AC_HELP_STRING
    
    We can also make do without the workaround introduced in 2005.
    The 2.60 autoconf minimum version covers that now.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 425dbae..5025718 100644
--- a/configure.ac
+++ b/configure.ac
@@ -437,8 +437,6 @@ VENDOR_NAME="The X.Org Foundation"
 VENDOR_NAME_SHORT="X.Org"
 VENDOR_WEB="http://wiki.x.org"
 
-m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
-
 dnl Build options.
 AC_ARG_ENABLE(werror,        AS_HELP_STRING([--enable-werror],
 		  [Obsolete - use --enable-strict-compilation instead]),
@@ -565,7 +563,7 @@ AC_ARG_ENABLE(install-libxf86config,
 				[Install libxf86config (default: disabled)]),
 				[INSTALL_LIBXF86CONFIG=$enableval],
 				[INSTALL_LIBXF86CONFIG=no])
-AC_ARG_ENABLE(visibility,     AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
+AC_ARG_ENABLE(visibility,     AS_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
 				[SYMBOL_VISIBILITY=$enableval],
 				[SYMBOL_VISIBILITY=auto])
 
@@ -627,8 +625,8 @@ AC_ARG_ENABLE(windowswm,      AS_HELP_STRING([--enable-windowswm], [Build XWin w
 AC_ARG_ENABLE(libdrm,         AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
 AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes])
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
-AC_ARG_ENABLE(linux_acpi, AC_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
-AC_ARG_ENABLE(linux_apm, AC_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
+AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
+AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
 
 dnl DDXes.
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
@@ -645,8 +643,8 @@ AC_ARG_ENABLE(xfake,          AS_HELP_STRING([--enable-xfake], [Build the kdrive
 AC_ARG_ENABLE(xfbdev,         AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
 dnl kdrive options
 AC_ARG_ENABLE(kdrive-kbd,     AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
-AC_ARG_ENABLE(kdrive-mouse,   AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
-AC_ARG_ENABLE(kdrive-evdev,   AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
+AC_ARG_ENABLE(kdrive-mouse,   AS_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
+AC_ARG_ENABLE(kdrive-evdev,   AS_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
 AC_ARG_ENABLE(libunwind,      AS_HELP_STRING([--enable-libunwind], [Use libunwind for backtracing (default: auto)]), [LIBUNWIND="$enableval"], [LIBUNWIND="auto"])
 
 
commit 1d4dbc2f2b4d2acca2691c3c7464a45aac59d73f
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Wed Dec 4 13:28:04 2013 -0500

    libtool: bump minimum required version to 2.2
    
    LT_PREREQ([2.2])
    LT_INIT
    
    AC_CONFIG_MACRO_DIR([m4]) is recommended to locate local macros,
    which is fully used starting automake 1.14.
    
    ACLOCAL_AMFLAGS in Makefile.am is deprecated since automake 1.14.
    The comment is to prevent developers from removing the statement
    as suggested in 1.14 which would break earlier versions.
    
    Automake 1.14 is already in use by many.
    This patch works on versions prior and post 1.14
    
    References:
    Building the X Window System from Source:
    http://www.x.org/wiki/Building_the_X_Window_System/#index2h3
    
    Discussion on xorg minimum autotools requirements:
    http://lists.x.org/archives/xorg-devel/2013-October/038325.html
    
    Tested with autoconf 2.60, automake 1.10.3 and libtool 2.2
    
    The same upgrade will be applied to libraries and drivers.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Makefile.am b/Makefile.am
index 5bf760b..add69d1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,6 @@
 AUTOMAKE_OPTIONS=nostdinc
+
+# Required for automake < 1.14
 ACLOCAL_AMFLAGS = -I m4
 
 if COMPOSITE
diff --git a/configure.ac b/configure.ac
index 234cf21..425dbae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,7 @@ AC_INIT([xorg-server], 1.15.99.900, [https://bugs.freedesktop.org/enter_bug.cgi?
 RELEASE_DATE="2014-01-09"
 RELEASE_NAME="Golden Gaytime"
 AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AC_USE_SYSTEM_EXTENSIONS
 
@@ -74,9 +75,8 @@ AC_CONFIG_HEADERS(include/version-config.h)
 
 AM_PROG_AS
 AC_PROG_LN_S
-AC_LIBTOOL_WIN32_DLL
-AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
+LT_PREREQ([2.2])
+LT_INIT([disable-static win32-dll])
 PKG_PROG_PKG_CONFIG
 AC_PROG_LEX
 AC_PROG_YACC
commit 71baa466b1f6b02fe503f9a3089b7b9d61aa0f80
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jan 13 17:00:23 2014 +1000

    os: restrict display names to digits
    
    We call atoi() on the server's display to get the socket but otherwise use the
    unmodified display for log file name, xkb paths, etc. This results in
    Xorg :banana being the equivalent of Xorg :0, except for the log files being
    in /var/log/Xorg.banana.log. I'm not sure there's a good use-case for this
    behaviour.
    
    Check the display for something that looks reasonable, i.e. digits only, but
    do allow for :0.0 (i.e. digits, followed by a period, followed by one or two
    digits).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/os/utils.c b/os/utils.c
index 608ee6a..3b20a5c 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -600,6 +600,10 @@ UseMsg(void)
 static int
 VerifyDisplayName(const char *d)
 {
+    int i;
+    int period_found = FALSE;
+    int after_period = 0;
+
     if (d == (char *) 0)
         return 0;               /*  null  */
     if (*d == '\0')
@@ -610,6 +614,29 @@ VerifyDisplayName(const char *d)
         return 0;               /*  must not equal "." or ".."  */
     if (strchr(d, '/') != (char *) 0)
         return 0;               /*  very important!!!  */
+
+    /* Since we run atoi() on the display later, only allow
+       for digits, or exception of :0.0 and similar (two decimal points max)
+       */
+    for (i = 0; i < strlen(d); i++) {
+        if (!isdigit(d[i])) {
+            if (d[i] != '.' || period_found)
+                return 0;
+            period_found = TRUE;
+        } else if (period_found)
+            after_period++;
+
+        if (after_period > 2)
+            return 0;
+    }
+
+    /* don't allow for :0. */
+    if (period_found && after_period == 0)
+        return 0;
+
+    if (atol(d) > INT_MAX)
+        return 0;
+
     return 1;
 }
 
commit 77df653ae3d8448be21221711851acde12c6bc1a
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 11:10:41 2014 -0800

    XQuartz: Avoid passing uninitialized pointers to X11ApplicationSetWindowMenu in AppleWMSetWindowMenu
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/applewm.c b/hw/xquartz/applewm.c
index 9ff0ff6..cc91c96 100644
--- a/hw/xquartz/applewm.c
+++ b/hw/xquartz/applewm.c
@@ -398,6 +398,15 @@ ProcAppleWMSetWindowMenu(register ClientPtr client)
                 break;
         }
     }
+
+    /* Check if we bailed out of the above loop due to a request that was too long */
+    if (j < nitems) {
+        free(items);
+        free(shortcuts);
+
+        return BadRequest;
+    }
+
     X11ApplicationSetWindowMenu(nitems, items, shortcuts);
     free(items);
     free(shortcuts);
commit 3bc608a361a01043b226fb9aaebf88f6fd852925
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 11:04:07 2014 -0800

    XQuartz: Check for allocated memory before using it in AppleWMSetWindowMenu
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/applewm.c b/hw/xquartz/applewm.c
index 4409d4b..9ff0ff6 100644
--- a/hw/xquartz/applewm.c
+++ b/hw/xquartz/applewm.c
@@ -378,6 +378,13 @@ ProcAppleWMSetWindowMenu(register ClientPtr client)
     items = malloc(sizeof(char *) * nitems);
     shortcuts = malloc(sizeof(char) * nitems);
 
+    if (!items || !shortcuts) {
+        free(items);
+        free(shortcuts);
+
+        return BadAlloc;
+    }
+
     max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
     bytes = (char *)&stuff[1];
 
commit 64327226ddfba8f0653615cd678d2d4336fb993d
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 11:00:40 2014 -0800

    XQuartz: Silence a clang static analysis warning about a memory leak
    
    It seems the alanyzer can't comprehend dixSetPrivate().
    
    quartz.c:119:12: warning: Potential leak of memory pointed to by 'displayInfo'
        return quartzProcs->AddScreen(index, pScreen);
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 5b977c7..bc6c8d0 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -109,11 +109,14 @@ Bool
 QuartzAddScreen(int index,
                 ScreenPtr pScreen)
 {
+    // The clang static analyzer thinks we leak displayInfo here
+#ifndef __clang_analyzer__
     // allocate space for private per screen Quartz specific storage
     QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1);
 
     // QUARTZ_PRIV(pScreen) = displayInfo;
     dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
+#endif /* __clang_analyzer__ */
 
     // do Quartz mode specific initialization
     return quartzProcs->AddScreen(index, pScreen);
commit b2f6b3497c33a4897afae80a2cf69c596b9f81e8
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 10:55:10 2014 -0800

    XQuartz: Silence a clang static analysis warning about a possible memory leak on exit
    
    stub.c:356:9: warning: Potential leak of memory pointed to by 'newargv'
            asl_log(aslc, NULL, ASL_LEVEL_ERR,
            ^~~~~~~
    stub.c:356:9: warning: Potential leak of memory pointed to by 'newenvp'
            asl_log(aslc, NULL, ASL_LEVEL_ERR,
            ^~~~~~~
    2 warnings generated.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index b5a3168..756e4ef 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -353,6 +353,10 @@ main(int argc, char **argv, char **envp)
     newenvp = (string_array_t)calloc((1 + envpc), sizeof(string_t));
 
     if (!newargv || !newenvp) {
+        /* Silence the clang static analyzer */
+        free(newargv);
+        free(newenvp);
+
         asl_log(aslc, NULL, ASL_LEVEL_ERR,
                 "Xquartz: Memory allocation failure");
         return EXIT_FAILURE;
commit a03f096a85537d9e881cedaa6cb71aca43a97086
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 10:47:52 2014 -0800

    XQuartz: Validate length in appledri before swapping
    
    Avoids potential memory corruption from bad requests
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c
index d7e9844..7757465 100644
--- a/hw/xquartz/xpr/appledri.c
+++ b/hw/xquartz/xpr/appledri.c
@@ -406,6 +406,7 @@ SProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)
 {
     REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq);
     swapl(&stuff->screen);
     return ProcAppleDRIQueryDirectRenderingCapable(client);
 }
@@ -415,6 +416,7 @@ SProcAppleDRIAuthConnection(register ClientPtr client)
 {
     REQUEST(xAppleDRIAuthConnectionReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq);
     swapl(&stuff->screen);
     swapl(&stuff->magic);
     return ProcAppleDRIAuthConnection(client);
@@ -425,6 +427,7 @@ SProcAppleDRICreateSurface(register ClientPtr client)
 {
     REQUEST(xAppleDRICreateSurfaceReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
     swapl(&stuff->screen);
     swapl(&stuff->drawable);
     swapl(&stuff->client_id);
@@ -436,6 +439,7 @@ SProcAppleDRIDestroySurface(register ClientPtr client)
 {
     REQUEST(xAppleDRIDestroySurfaceReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);
     swapl(&stuff->screen);
     swapl(&stuff->drawable);
     return ProcAppleDRIDestroySurface(client);
@@ -446,6 +450,7 @@ SProcAppleDRICreatePixmap(register ClientPtr client)
 {
     REQUEST(xAppleDRICreatePixmapReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
     swapl(&stuff->screen);
     swapl(&stuff->drawable);
     return ProcAppleDRICreatePixmap(client);
@@ -456,6 +461,7 @@ SProcAppleDRIDestroyPixmap(register ClientPtr client)
 {
     REQUEST(xAppleDRIDestroyPixmapReq);
     swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
     swapl(&stuff->drawable);
     return ProcAppleDRIDestroyPixmap(client);
 }
commit b3572c0d1ab7888ac26d6b2b8be6d1d19ed9af3f
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Wed Jan 1 10:39:56 2014 -0800

    XQuartz: Validate screen in AppleDRIQueryDirectRenderingCapable requests
    
    Return an error to the caller rather than crashing the server on
    invalid screens.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c
index 9aac072..d7e9844 100644
--- a/hw/xquartz/xpr/appledri.c
+++ b/hw/xquartz/xpr/appledri.c
@@ -123,6 +123,10 @@ ProcAppleDRIQueryDirectRenderingCapable(register ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
+    if (stuff->screen >= screenInfo.numScreens) {
+        return BadValue;
+    }
+
     if (!DRIQueryDirectRenderingCapable(screenInfo.screens[stuff->screen],
                                         &isCapable)) {
         return BadValue;
commit 959e8f23af7850fcaf40d6c67f5228241a36a9ab
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Dec 29 12:45:23 2013 -0800

    XQuartz: Simplify hook_run to quiet static analyzer
    
    x-hook.c:96:9: warning: Called function pointer is an uninitalized pointer value
            (*fun[i])(arg, data[i]);
            ^~~~~~~~~~~~~~~~~~~~~~~
    1 warning generated.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/x-hook.c b/hw/xquartz/xpr/x-hook.c
index b5d8ab9..3922bb8 100644
--- a/hw/xquartz/xpr/x-hook.c
+++ b/hw/xquartz/xpr/x-hook.c
@@ -70,34 +70,19 @@ X_PFX(hook_remove) (x_list * lst, x_hook_function * fun, void *data) {
 
 X_EXTERN void
 X_PFX(hook_run) (x_list * lst, void *arg) {
-    x_list *node, *cell;
-    x_hook_function **fun;
-    void **data;
-    int length, i;
+    x_list *node;
 
     if (!lst)
         return;
 
-    length = X_PFX(list_length) (lst);
-    fun = malloc(sizeof(x_hook_function *) * length);
-    data = malloc(sizeof(void *) * length);
-
-    if (!fun || !data) {
-        FatalError("Failed to allocate memory in %s\n", __func__);
-    }
+    for (node = lst; node != NULL; node = node->next) {
+        x_list *cell = node->data;
 
-    for (i = 0, node = lst; node != NULL; node = node->next, i++) {
-        cell = node->data;
-        fun[i] = CELL_FUN(cell);
-        data[i] = CELL_DATA(cell);
-    }
+        x_hook_function *fun = CELL_FUN(cell);
+        void *data = CELL_DATA(cell);
 
-    for (i = 0; i < length; i++) {
-        (*fun[i])(arg, data[i]);
+        (*fun)(arg, data);
     }
-
-    free(fun);
-    free(data);
 }
 
 X_EXTERN void
commit f79af1941776fd6f1ec26c50603fcc35ca7d514b
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Dec 29 12:41:18 2013 -0800

    XQuartz: Mark applicationWillTerminate: noreturn
    
    X11Controller.m:938:1: warning: method 'applicationWillTerminate:' could be declared with attribute 'noreturn'
          [-Wmissing-noreturn,Semantic Issue]
    {
    ^
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index 752bda3..5445c6f 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -934,7 +934,7 @@ extern char *bundle_id_prefix;
             == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel;
 }
 
-- (void) applicationWillTerminate:(NSNotification *)aNotification
+- (void) applicationWillTerminate:(NSNotification *)aNotification _X_NORETURN
 {
     int remain;
     [X11App prefs_synchronize];
commit ea80279e292e59a9fe9651489f03e9f2f39810d9
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Dec 29 12:36:51 2013 -0800

    XQuartz: Fix get_proc_address signature
    
    indirect.c:675:28: warning: incompatible pointer types passing 'glx_gpa_proc (*)(const char *)' to parameter of type
          'glx_gpa_proc' (aka 'glx_func_ptr (*)(const char *)') [-Wincompatible-pointer-types,Semantic Issue]
        __glXsetGetProcAddress(&get_proc_address);
                               ^~~~~~~~~~~~~~~~~
    ../../../glx/glxserver.h:122:42: note: passing argument to parameter 'get_proc_address' here [Semantic Issue]
    void __glXsetGetProcAddress(glx_gpa_proc get_proc_address);
                                             ^
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 8dabda1..19b7d86 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -643,10 +643,10 @@ __glFloorLog2(GLuint val)
 
 static void *opengl_framework_handle;
 
-static glx_gpa_proc
+static glx_func_ptr
 get_proc_address(const char *sym)
 {
-    return (glx_gpa_proc) dlsym(opengl_framework_handle, sym);
+    return (glx_func_ptr) dlsym(opengl_framework_handle, sym);
 }
 
 static void
commit 2e3ebec9520719a8e5c3c92390e83bcb5216f978
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Dec 29 12:31:23 2013 -0800

    XQuartz: Fix darwinfb.h header guard
    
    ./darwinfb.h:28:9: warning: '_DARWIN_FB_H' is used as a header guard here, followed by #define of a different macro
          [-Wheader-guard,Lexical or Preprocessor Issue]
            ^~~~~~~~~~~~
    ./darwinfb.h:29:9: note: '_DARWIN_DB_H' is defined here; did you mean '_DARWIN_FB_H'? [Lexical or Preprocessor Issue]
            ^~~~~~~~~~~~
            _DARWIN_FB_H
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/darwinfb.h b/hw/xquartz/darwinfb.h
index 5de360d..541128b 100644
--- a/hw/xquartz/darwinfb.h
+++ b/hw/xquartz/darwinfb.h
@@ -26,7 +26,7 @@
  */
 
 #ifndef _DARWIN_FB_H
-#define _DARWIN_DB_H
+#define _DARWIN_FB_H
 
 #include "scrnintstr.h"
 
commit 9da6c0918f40359f28fe8889d5b7cae7efcc8377
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sun Dec 29 12:22:55 2013 -0800

    XQuartz: Silence some static analyzer warnings by annotating referencing counts
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 1f9b05d..2efbd65 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -70,6 +70,18 @@ xpbproxy_run(void);
 static dispatch_queue_t eventTranslationQueue;
 #endif
 
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#ifndef CF_RETURNS_RETAINED
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#else
+#define CF_RETURNS_RETAINED
+#endif
+#endif
+
 extern Bool noTestExtensions;
 extern Bool noRenderExtension;
 extern BOOL serverRunning;
@@ -526,6 +538,7 @@ cfrelease(CFAllocatorRef a, const void *b)
     CFRelease(b);
 }
 
+CF_RETURNS_RETAINED
 static CFMutableArrayRef
 nsarray_to_cfarray(NSArray *in)
 {
commit 2d2d49dab5c5718989de97d7227aac793479745e
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 29 15:18:28 2013 -0800

    Clean up a few function prototypes to not place formals in /**/
    
    This just removes the comment markers from around the formals in
    several function prototypes near where pointer -> void * changes were
    made. There are plenty more of these to fix.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xext/saver.c b/Xext/saver.c
index 03f28bb..8e92fdf 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -107,9 +107,7 @@ typedef struct _ScreenSaverSuspension {
     int count;
 } ScreenSaverSuspensionRec;
 
-static int ScreenSaverFreeSuspend(void */*value */ ,
-                                  XID   /* id */
-    );
+static int ScreenSaverFreeSuspend(void *value, XID id);
 
 /*
  * each screen has a list of clients requesting
@@ -131,18 +129,14 @@ typedef struct _ScreenSaverEvent {
     CARD32 mask;
 } ScreenSaverEventRec;
 
-static int ScreenSaverFreeEvents(void * /* value */ ,
-                                 XID    /* id */
-    );
+static int ScreenSaverFreeEvents(void * value, XID id);
 
-static Bool setEventMask(ScreenPtr /* pScreen */ ,
-                         ClientPtr /* client */ ,
-                         unsigned long  /* mask */
-    );
+static Bool setEventMask(ScreenPtr      pScreen,
+                         ClientPtr      client,
+                         unsigned long  mask);
 
-static unsigned long getEventMask(ScreenPtr /* pScreen */ ,
-                                  ClientPtr     /* client */
-    );
+static unsigned long getEventMask(ScreenPtr     pScreen,
+                                  ClientPtr     client);
 
 /*
  * when a client sets the screen saver attributes, a resource is
@@ -168,21 +162,16 @@ typedef struct _ScreenSaverAttr {
     unsigned long *values;
 } ScreenSaverAttrRec, *ScreenSaverAttrPtr;
 
-static int ScreenSaverFreeAttr(void */* value */ ,
-                               XID      /* id */
-    );
+static int ScreenSaverFreeAttr(void *value, XID id);
 
-static void FreeAttrs(ScreenSaverAttrPtr        /* pAttr */
-    );
+static void FreeAttrs(ScreenSaverAttrPtr pAttr);
 
-static void FreeScreenAttr(ScreenSaverAttrPtr   /* pAttr */
-    );
+static void FreeScreenAttr(ScreenSaverAttrPtr pAttr);
 
 static void
- SendScreenSaverNotify(ScreenPtr /* pScreen */ ,
-                       int /* state */ ,
-                       Bool     /* forced */
-    );
+SendScreenSaverNotify(ScreenPtr pScreen,
+                      int       state,
+                      Bool      forced);
 
 typedef struct _ScreenSaverScreenPrivate {
     ScreenSaverEventPtr events;
@@ -191,8 +180,7 @@ typedef struct _ScreenSaverScreenPrivate {
     Colormap installedMap;
 } ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
 
-static ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr  /* pScreen */
-    );
+static ScreenSaverScreenPrivatePtr MakeScreenPrivate(ScreenPtr pScreen);
 
 static DevPrivateKeyRec ScreenPrivateKeyRec;
 
diff --git a/Xext/shm.c b/Xext/shm.c
index 34545ec..4dad8b6 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -99,14 +99,10 @@ typedef struct _ShmScrPrivateRec {
 } ShmScrPrivateRec;
 
 static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
-static int ShmDetachSegment(void */* value */ ,
-                            XID /* shmseg */
-    );
-static void ShmResetProc(ExtensionEntry *       /* extEntry */
-    );
-static void SShmCompletionEvent(xShmCompletionEvent * /* from */ ,
-                                xShmCompletionEvent *   /* to */
-    );
+static int ShmDetachSegment(void *value, XID shmseg);
+static void ShmResetProc(ExtensionEntry *extEntry);
+static void SShmCompletionEvent(xShmCompletionEvent *from,
+                                xShmCompletionEvent *to);
 
 static Bool ShmDestroyPixmap(PixmapPtr pPixmap);
 
diff --git a/dix/dixutils.c b/dix/dixutils.c
index 220040f..5de74c8 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -556,8 +556,7 @@ ProcessWorkQueueZombies(void)
 }
 
 Bool
-QueueWorkProc(Bool (*function)
-              (ClientPtr /* pClient */ , void */* closure */ ),
+QueueWorkProc(Bool (*function) (ClientPtr pClient, void *closure),
               ClientPtr client, void *closure)
 {
     WorkQueuePtr q;
diff --git a/mi/migc.h b/mi/migc.h
index fb9f35c..8d06a6f 100644
--- a/mi/migc.h
+++ b/mi/migc.h
@@ -26,31 +26,24 @@ from The Open Group.
 
 */
 
-extern _X_EXPORT void miChangeGC(GCPtr /*pGC */ ,
-                                 unsigned long  /*mask */
-    );
-
-extern _X_EXPORT void miDestroyGC(GCPtr /*pGC */
-    );
-
-extern _X_EXPORT void miDestroyClip(GCPtr       /*pGC */
-    );
-
-extern _X_EXPORT void miChangeClip(GCPtr /*pGC */ ,
-                                   int /*type */ ,
-                                   void */*pvalue */ ,
-                                   int  /*nrects */
-    );
-
-extern _X_EXPORT void miCopyClip(GCPtr /*pgcDst */ ,
-                                 GCPtr  /*pgcSrc */
-    );
-
-extern _X_EXPORT void miCopyGC(GCPtr /*pGCSrc */ ,
-                               unsigned long /*changes */ ,
-                               GCPtr    /*pGCDst */
-    );
-
-extern _X_EXPORT void miComputeCompositeClip(GCPtr /*pGC */ ,
-                                             DrawablePtr        /*pDrawable */
-    );
+extern _X_EXPORT void miChangeGC(GCPtr          pGC,
+                                 unsigned long  mask);
+
+extern _X_EXPORT void miDestroyGC(GCPtr         pGC);
+
+extern _X_EXPORT void miDestroyClip(GCPtr       pGC);
+
+extern _X_EXPORT void miChangeClip(GCPtr        pGC,
+                                   int          type,
+                                   void         *pvalue,
+                                   int          nrects);
+
+extern _X_EXPORT void miCopyClip(GCPtr          pgcDst,
+                                 GCPtr          pgcSrc);
+
+extern _X_EXPORT void miCopyGC(GCPtr            pGCSrc,
+                               unsigned long    changes,
+                               GCPtr            pGCDst);
+
+extern _X_EXPORT void miComputeCompositeClip(GCPtr              pGC,
+                                             DrawablePtr        pDrawable);
diff --git a/os/xdmcp.c b/os/xdmcp.c
index da509e4..fd8ae58 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -145,43 +145,46 @@ static void get_xdmcp_sock(void);
 
 static void send_query_msg(void);
 
-static void recv_willing_msg(struct sockaddr * /*from */ ,
-                             int /*fromlen */ ,
-                             unsigned /*length */ );
+static void recv_willing_msg(struct sockaddr    *from,
+                             int                fromlen,
+                             unsigned           length);
 
 static void send_request_msg(void);
 
-static void recv_accept_msg(unsigned /*length */ );
+static void recv_accept_msg(unsigned    length);
 
-static void recv_decline_msg(unsigned /*length */ );
+static void recv_decline_msg(unsigned   length);
 
 static void send_manage_msg(void);
 
-static void recv_refuse_msg(unsigned /*length */ );
+static void recv_refuse_msg(unsigned    length);
 
-static void recv_failed_msg(unsigned /*length */ );
+static void recv_failed_msg(unsigned    length);
 
 static void send_keepalive_msg(void);
 
-static void recv_alive_msg(unsigned /*length */ );
+static void recv_alive_msg(unsigned     length );
 
-static void XdmcpFatal(const char * /*type */ ,
-                       ARRAY8Ptr /*status */ );
+static void XdmcpFatal(const char       *type,
+                       ARRAY8Ptr        status);
 
-static void XdmcpWarning(const char * /*str */ );
+static void XdmcpWarning(const char     *str);
 
-static void get_manager_by_name(int /*argc */ ,
-                                char ** /*argv */ ,
-                                int /*i */ );
+static void get_manager_by_name(int     argc,
+                                char    **argv,
+                                int     i);
 
-static void get_fromaddr_by_name(int /*argc */ , char ** /*argv */ ,
-                                 int /*i */ );
+static void get_fromaddr_by_name(int    argc,
+                                 char   **argv,
+                                 int    i);
 
 #if defined(IPv6) && defined(AF_INET6)
-static int get_mcast_options(int /*argc */ , char ** /*argv */ , int /*i */ );
+static int get_mcast_options(int        argc,
+                             char       **argv,
+                             int        i);
 #endif
 
-static void receive_packet(int /*socketfd */ );
+static void receive_packet(int socketfd);
 
 static void send_packet(void);
 
@@ -189,13 +192,13 @@ static void timeout(void);
 
 static void restart(void);
 
-static void XdmcpBlockHandler(void */*data */ ,
-                              struct timeval ** /*wt */ ,
-                              void */*LastSelectMask */ );
+static void XdmcpBlockHandler(void              *data ,
+                              struct timeval    **wt,
+                              void              *LastSelectMask);
 
-static void XdmcpWakeupHandler(void */*data */ ,
-                               int /*i */ ,
-                               void */*LastSelectMask */ );
+static void XdmcpWakeupHandler(void             *data,
+                               int              i,
+                               void             *LastSelectMask);
 
 /*
  * Register the Manufacturer display ID
diff --git a/record/record.c b/record/record.c
index 8217a44..c900219 100644
--- a/record/record.c
+++ b/record/record.c
@@ -136,9 +136,8 @@ static int numEnabledRCAPs;
 	return rc; \
 }
 
-static int RecordDeleteContext(void */*value */ ,
-                               XID      /*id */
-    );
+static int RecordDeleteContext(void     *value,
+                               XID      id);
 
 /***************************************************************************/
 
commit 60014a4a98ff924ae7f6840781f768c1cc93bbab
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Dec 15 01:05:51 2013 -0800

    Replace 'pointer' type with 'void *'
    
    This lets us stop using the 'pointer' typedef in Xdefs.h as 'pointer'
    is used throughout the X server for other things, and having duplicate
    names generates compiler warnings.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/Xext/geext.c b/Xext/geext.c
index 1e5ae6f..aee68c4 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -150,7 +150,7 @@ SProcGEDispatch(ClientPtr client)
  * used in the furture for versioning support.
  */
 static void
-GEClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+GEClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
diff --git a/Xext/hashtable.c b/Xext/hashtable.c
index 76ebc6d..471ecca 100644
--- a/Xext/hashtable.c
+++ b/Xext/hashtable.c
@@ -23,7 +23,7 @@ struct HashTableRec {
     HashFunc        hash;
     HashCompareFunc compare;
 
-    pointer         cdata;
+    void            *cdata;
 };
 
 typedef struct {
@@ -37,7 +37,7 @@ ht_create(int             keySize,
           int             dataSize,
           HashFunc        hash,
           HashCompareFunc compare,
-          pointer         cdata)
+          void            *cdata)
 {
     int c;
     int numBuckets;
@@ -117,7 +117,7 @@ double_size(HashTable ht)
     }
 }
 
-pointer
+void *
 ht_add(HashTable ht, const void *key)
 {
     unsigned index = ht->hash(ht->cdata, key, ht->bucketBits);
@@ -182,7 +182,7 @@ ht_remove(HashTable ht, const void *key)
     }
 }
 
-pointer
+void *
 ht_find(HashTable ht, const void *key)
 {
     unsigned index = ht->hash(ht->cdata, key, ht->bucketBits);
diff --git a/Xext/hashtable.h b/Xext/hashtable.h
index 8a65732..a988af3 100644
--- a/Xext/hashtable.h
+++ b/Xext/hashtable.h
@@ -55,7 +55,7 @@ extern _X_EXPORT HashTable ht_create(int             keySize,
                                      int             dataSize,
                                      HashFunc        hash,
                                      HashCompareFunc compare,
-                                     pointer         cdata);
+                                     void            *cdata);
 /** @brief  HtDestruct deinitializes the structure. It does not free the
             memory allocated to HashTableRec
 */
@@ -75,7 +75,7 @@ extern _X_EXPORT void ht_destroy(HashTable ht);
          to avoid returning NULL. Obviously the data pointed cannot be
          modified, as implied by dataSize being 0.
 */
-extern _X_EXPORT pointer ht_add(HashTable ht, const void *key);
+extern _X_EXPORT void *ht_add(HashTable ht, const void *key);
 
 /** @brief  Removes a key from the hash table along with its
             associated data, which will be free'd.
@@ -93,7 +93,7 @@ extern _X_EXPORT void ht_remove(HashTable ht, const void *key);
           use HtMember instead to determine if a key has been
           inserted.
 */
-extern _X_EXPORT pointer ht_find(HashTable ht, const void *key);
+extern _X_EXPORT void *ht_find(HashTable ht, const void *key);
 
 /** @brief  A generic hash function */
 extern _X_EXPORT unsigned ht_generic_hash(void *cdata,
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 6f8939f..4d79c46 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -130,7 +130,7 @@ static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
 static void XineramaChangeGC(GCPtr, unsigned long);
 static void XineramaCopyGC(GCPtr, unsigned long, GCPtr);
 static void XineramaDestroyGC(GCPtr);
-static void XineramaChangeClip(GCPtr, int, pointer, int);
+static void XineramaChangeClip(GCPtr, int, void *, int);
 static void XineramaDestroyClip(GCPtr);
 static void XineramaCopyClip(GCPtr, GCPtr);
 
@@ -160,7 +160,7 @@ XineramaCloseScreen(ScreenPtr pScreen)
     if (pScreen->myNum == 0)
         RegionUninit(&PanoramiXScreenRegion);
 
-    free((pointer) pScreenPriv);
+    free(pScreenPriv);
 
     return (*pScreen->CloseScreen) (pScreen);
 }
@@ -294,7 +294,7 @@ XineramaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
 }
 
 static void
-XineramaChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+XineramaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     Xinerama_GC_FUNC_PROLOGUE(pGC);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
@@ -318,7 +318,7 @@ XineramaDestroyClip(GCPtr pGC)
 }
 
 int
-XineramaDeleteResource(pointer data, XID id)
+XineramaDeleteResource(void *data, XID id)
 {
     free(data);
     return 1;
@@ -330,7 +330,7 @@ typedef struct {
 } PanoramiXSearchData;
 
 static Bool
-XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata)
+XineramaFindIDByScrnum(void *resource, XID id, void *privdata)
 {
     PanoramiXRes *res = (PanoramiXRes *) resource;
     PanoramiXSearchData *data = (PanoramiXSearchData *) privdata;
@@ -342,7 +342,7 @@ PanoramiXRes *
 PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen)
 {
     PanoramiXSearchData data;
-    pointer val;
+    void *val;
 
     if (!screen) {
         dixLookupResourceByType(&val, id, type, serverClient, DixReadAccess);
@@ -691,9 +691,9 @@ PanoramiXCreateConnectionBlock(void)
     root->mmHeight *= height_mult;
 
     while (ConnectionCallbackList) {
-        pointer tmp;
+        void *tmp;
 
-        tmp = (pointer) ConnectionCallbackList;
+        tmp = (void *) ConnectionCallbackList;
         (*ConnectionCallbackList->func) ();
         ConnectionCallbackList = ConnectionCallbackList->next;
         free(tmp);
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 576844c..83a2e08 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -72,7 +72,7 @@ PanoramiXCreateWindow(ClientPtr client)
     if (Ones(stuff->mask) != len)
         return BadLength;
 
-    result = dixLookupResourceByType((pointer *) &parent, stuff->parent,
+    result = dixLookupResourceByType((void **) &parent, stuff->parent,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -87,7 +87,7 @@ PanoramiXCreateWindow(ClientPtr client)
         pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
         tmp = *((CARD32 *) &stuff[1] + pback_offset);
         if ((tmp != None) && (tmp != ParentRelative)) {
-            result = dixLookupResourceByType((pointer *) &backPix, tmp,
+            result = dixLookupResourceByType((void **) &backPix, tmp,
                                              XRT_PIXMAP, client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -97,7 +97,7 @@ PanoramiXCreateWindow(ClientPtr client)
         pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
         tmp = *((CARD32 *) &stuff[1] + pbord_offset);
         if (tmp != CopyFromParent) {
-            result = dixLookupResourceByType((pointer *) &bordPix, tmp,
+            result = dixLookupResourceByType((void **) &bordPix, tmp,
                                              XRT_PIXMAP, client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -107,7 +107,7 @@ PanoramiXCreateWindow(ClientPtr client)
         cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
         if ((tmp != CopyFromParent) && (tmp != None)) {
-            result = dixLookupResourceByType((pointer *) &cmap, tmp,
+            result = dixLookupResourceByType((void **) &cmap, tmp,
                                              XRT_COLORMAP, client,
                                              DixReadAccess);
             if (result != Success)
@@ -178,7 +178,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
     if (Ones(stuff->valueMask) != len)
         return BadLength;
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -191,7 +191,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
         pback_offset = Ones((Mask) stuff->valueMask & (CWBackPixmap - 1));
         tmp = *((CARD32 *) &stuff[1] + pback_offset);
         if ((tmp != None) && (tmp != ParentRelative)) {
-            result = dixLookupResourceByType((pointer *) &backPix, tmp,
+            result = dixLookupResourceByType((void **) &backPix, tmp,
                                              XRT_PIXMAP, client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -201,7 +201,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
         pbord_offset = Ones((Mask) stuff->valueMask & (CWBorderPixmap - 1));
         tmp = *((CARD32 *) &stuff[1] + pbord_offset);
         if (tmp != CopyFromParent) {
-            result = dixLookupResourceByType((pointer *) &bordPix, tmp,
+            result = dixLookupResourceByType((void **) &bordPix, tmp,
                                              XRT_PIXMAP, client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -211,7 +211,7 @@ PanoramiXChangeWindowAttributes(ClientPtr client)
         cmap_offset = Ones((Mask) stuff->valueMask & (CWColormap - 1));
         tmp = *((CARD32 *) &stuff[1] + cmap_offset);
         if ((tmp != CopyFromParent) && (tmp != None)) {
-            result = dixLookupResourceByType((pointer *) &cmap, tmp,
+            result = dixLookupResourceByType((void **) &cmap, tmp,
                                              XRT_COLORMAP, client,
                                              DixReadAccess);
             if (result != Success)
@@ -243,7 +243,7 @@ PanoramiXDestroyWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->id, XRT_WINDOW,
                                      client, DixDestroyAccess);
     if (result != Success)
         return result;
@@ -271,7 +271,7 @@ PanoramiXDestroySubwindows(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->id, XRT_WINDOW,
                                      client, DixDestroyAccess);
     if (result != Success)
         return result;
@@ -299,7 +299,7 @@ PanoramiXChangeSaveSet(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xChangeSaveSetReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -326,12 +326,12 @@ PanoramiXReparentWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xReparentWindowReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &parent, stuff->parent,
+    result = dixLookupResourceByType((void **) &parent, stuff->parent,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -365,7 +365,7 @@ PanoramiXMapWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id,
+    result = dixLookupResourceByType((void **) &win, stuff->id,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -390,7 +390,7 @@ PanoramiXMapSubwindows(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id,
+    result = dixLookupResourceByType((void **) &win, stuff->id,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -415,7 +415,7 @@ PanoramiXUnmapWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id,
+    result = dixLookupResourceByType((void **) &win, stuff->id,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -440,7 +440,7 @@ PanoramiXUnmapSubwindows(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->id,
+    result = dixLookupResourceByType((void **) &win, stuff->id,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -474,12 +474,12 @@ PanoramiXConfigureWindow(ClientPtr client)
         return BadLength;
 
     /* because we need the parent */
-    result = dixLookupResourceByType((pointer *) &pWin, stuff->window,
+    result = dixLookupResourceByType((void **) &pWin, stuff->window,
                                      RT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -489,7 +489,7 @@ PanoramiXConfigureWindow(ClientPtr client)
 
         sib_offset = Ones((Mask) stuff->mask & (CWSibling - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) {
-            result = dixLookupResourceByType((pointer *) &sib, tmp, XRT_WINDOW,
+            result = dixLookupResourceByType((void **) &sib, tmp, XRT_WINDOW,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -537,7 +537,7 @@ PanoramiXCirculateWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xCirculateWindowReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -687,7 +687,7 @@ PanoramiXCreatePixmap(ClientPtr client)
     REQUEST_SIZE_MATCH(xCreatePixmapReq);
     client->errorValue = stuff->pid;
 
-    result = dixLookupResourceByClass((pointer *) &refDraw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixReadAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -727,7 +727,7 @@ PanoramiXFreePixmap(ClientPtr client)
 
     client->errorValue = stuff->id;
 
-    result = dixLookupResourceByType((pointer *) &pix, stuff->id, XRT_PIXMAP,
+    result = dixLookupResourceByType((void **) &pix, stuff->id, XRT_PIXMAP,
                                      client, DixDestroyAccess);
     if (result != Success)
         return result;
@@ -766,7 +766,7 @@ PanoramiXCreateGC(ClientPtr client)
     if (Ones(stuff->mask) != len)
         return BadLength;
 
-    result = dixLookupResourceByClass((pointer *) &refDraw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixReadAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -774,7 +774,7 @@ PanoramiXCreateGC(ClientPtr client)
     if ((Mask) stuff->mask & GCTile) {
         tile_offset = Ones((Mask) stuff->mask & (GCTile - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
-            result = dixLookupResourceByType((pointer *) &tile, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &tile, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -783,7 +783,7 @@ PanoramiXCreateGC(ClientPtr client)
     if ((Mask) stuff->mask & GCStipple) {
         stip_offset = Ones((Mask) stuff->mask & (GCStipple - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
-            result = dixLookupResourceByType((pointer *) &stip, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &stip, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -792,7 +792,7 @@ PanoramiXCreateGC(ClientPtr client)
     if ((Mask) stuff->mask & GCClipMask) {
         clip_offset = Ones((Mask) stuff->mask & (GCClipMask - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
-            result = dixLookupResourceByType((pointer *) &clip, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &clip, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -846,7 +846,7 @@ PanoramiXChangeGC(ClientPtr client)
     if (Ones(stuff->mask) != len)
         return BadLength;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -854,7 +854,7 @@ PanoramiXChangeGC(ClientPtr client)
     if ((Mask) stuff->mask & GCTile) {
         tile_offset = Ones((Mask) stuff->mask & (GCTile - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
-            result = dixLookupResourceByType((pointer *) &tile, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &tile, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -863,7 +863,7 @@ PanoramiXChangeGC(ClientPtr client)
     if ((Mask) stuff->mask & GCStipple) {
         stip_offset = Ones((Mask) stuff->mask & (GCStipple - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
-            result = dixLookupResourceByType((pointer *) &stip, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &stip, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -872,7 +872,7 @@ PanoramiXChangeGC(ClientPtr client)
     if ((Mask) stuff->mask & GCClipMask) {
         clip_offset = Ones((Mask) stuff->mask & (GCClipMask - 1));
         if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
-            result = dixLookupResourceByType((pointer *) &clip, tmp, XRT_PIXMAP,
+            result = dixLookupResourceByType((void **) &clip, tmp, XRT_PIXMAP,
                                              client, DixReadAccess);
             if (result != Success)
                 return result;
@@ -905,12 +905,12 @@ PanoramiXCopyGC(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xCopyGCReq);
 
-    result = dixLookupResourceByType((pointer *) &srcGC, stuff->srcGC, XRT_GC,
+    result = dixLookupResourceByType((void **) &srcGC, stuff->srcGC, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &dstGC, stuff->dstGC, XRT_GC,
+    result = dixLookupResourceByType((void **) &dstGC, stuff->dstGC, XRT_GC,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -936,7 +936,7 @@ PanoramiXSetDashes(ClientPtr client)
 
     REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -961,7 +961,7 @@ PanoramiXSetClipRectangles(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -986,7 +986,7 @@ PanoramiXFreeGC(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->id, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->id, XRT_GC,
                                      client, DixDestroyAccess);
     if (result != Success)
         return result;
@@ -1015,7 +1015,7 @@ PanoramiXClearToBackground(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xClearAreaReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -1060,14 +1060,14 @@ PanoramiXCopyArea(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xCopyAreaReq);
 
-    result = dixLookupResourceByClass((pointer *) &src, stuff->srcDrawable,
+    result = dixLookupResourceByClass((void **) &src, stuff->srcDrawable,
                                       XRC_DRAWABLE, client, DixReadAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
     srcShared = IS_SHARED_PIXMAP(src);
 
-    result = dixLookupResourceByClass((pointer *) &dst, stuff->dstDrawable,
+    result = dixLookupResourceByClass((void **) &dst, stuff->dstDrawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1077,7 +1077,7 @@ PanoramiXCopyArea(ClientPtr client)
     if (dstShared && srcShared)
         return (*SavedProcVector[X_CopyArea]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1219,14 +1219,14 @@ PanoramiXCopyPlane(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xCopyPlaneReq);
 
-    rc = dixLookupResourceByClass((pointer *) &src, stuff->srcDrawable,
+    rc = dixLookupResourceByClass((void **) &src, stuff->srcDrawable,
                                   XRC_DRAWABLE, client, DixReadAccess);
     if (rc != Success)
         return (rc == BadValue) ? BadDrawable : rc;
 
     srcShared = IS_SHARED_PIXMAP(src);
 
-    rc = dixLookupResourceByClass((pointer *) &dst, stuff->dstDrawable,
+    rc = dixLookupResourceByClass((void **) &dst, stuff->dstDrawable,
                                   XRC_DRAWABLE, client, DixWriteAccess);
     if (rc != Success)
         return (rc == BadValue) ? BadDrawable : rc;
@@ -1236,7 +1236,7 @@ PanoramiXCopyPlane(ClientPtr client)
     if (dstShared && srcShared)
         return (*SavedProcVector[X_CopyPlane]) (client);
 
-    rc = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    rc = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                  client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -1327,7 +1327,7 @@ PanoramiXPolyPoint(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyPointReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1335,7 +1335,7 @@ PanoramiXPolyPoint(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyPoint]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1392,7 +1392,7 @@ PanoramiXPolyLine(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyLineReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1400,7 +1400,7 @@ PanoramiXPolyLine(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyLine]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1457,7 +1457,7 @@ PanoramiXPolySegment(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1465,7 +1465,7 @@ PanoramiXPolySegment(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolySegment]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1525,7 +1525,7 @@ PanoramiXPolyRectangle(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1533,7 +1533,7 @@ PanoramiXPolyRectangle(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyRectangle]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1592,7 +1592,7 @@ PanoramiXPolyArc(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyArcReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1600,7 +1600,7 @@ PanoramiXPolyArc(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyArc]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1657,7 +1657,7 @@ PanoramiXFillPoly(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xFillPolyReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1665,7 +1665,7 @@ PanoramiXFillPoly(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_FillPoly]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1723,7 +1723,7 @@ PanoramiXPolyFillRectangle(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1731,7 +1731,7 @@ PanoramiXPolyFillRectangle(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyFillRectangle]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1790,7 +1790,7 @@ PanoramiXPolyFillArc(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1798,7 +1798,7 @@ PanoramiXPolyFillArc(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyFillArc]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1855,7 +1855,7 @@ PanoramiXPutImage(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPutImageReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -1863,7 +1863,7 @@ PanoramiXPutImage(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PutImage]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1909,7 +1909,7 @@ PanoramiXGetImage(ClientPtr client)
         return BadValue;
     }
 
-    rc = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                   XRC_DRAWABLE, client, DixWriteAccess);
     if (rc != Success)
         return (rc == BadValue) ? BadDrawable : rc;
@@ -2055,7 +2055,7 @@ PanoramiXPolyText8(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyTextReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -2063,7 +2063,7 @@ PanoramiXPolyText8(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyText8]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2098,7 +2098,7 @@ PanoramiXPolyText16(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xPolyTextReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -2106,7 +2106,7 @@ PanoramiXPolyText16(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_PolyText16]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2141,7 +2141,7 @@ PanoramiXImageText8(ClientPtr client)
 
     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -2149,7 +2149,7 @@ PanoramiXImageText8(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_ImageText8]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2184,7 +2184,7 @@ PanoramiXImageText16(ClientPtr client)
 
     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
@@ -2192,7 +2192,7 @@ PanoramiXImageText16(ClientPtr client)
     if (IS_SHARED_PIXMAP(draw))
         return (*SavedProcVector[X_ImageText16]) (client);
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc, XRT_GC,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2225,7 +2225,7 @@ PanoramiXCreateColormap(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xCreateColormapReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->window,
+    result = dixLookupResourceByType((void **) &win, stuff->window,
                                      XRT_WINDOW, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2266,7 +2266,7 @@ PanoramiXFreeColormap(ClientPtr client)
 
     client->errorValue = stuff->id;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->id, XRT_COLORMAP,
+    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
                                      client, DixDestroyAccess);
     if (result != Success)
         return result;
@@ -2296,7 +2296,7 @@ PanoramiXCopyColormapAndFree(ClientPtr client)
 
     client->errorValue = stuff->srcCmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->srcCmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->srcCmap,
                                      XRT_COLORMAP, client,
                                      DixReadAccess | DixWriteAccess);
     if (result != Success)
@@ -2335,7 +2335,7 @@ PanoramiXInstallColormap(ClientPtr client)
 
     client->errorValue = stuff->id;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->id, XRT_COLORMAP,
+    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2360,7 +2360,7 @@ PanoramiXUninstallColormap(ClientPtr client)
 
     client->errorValue = stuff->id;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->id, XRT_COLORMAP,
+    result = dixLookupResourceByType((void **) &cmap, stuff->id, XRT_COLORMAP,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -2386,7 +2386,7 @@ PanoramiXAllocColor(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2412,7 +2412,7 @@ PanoramiXAllocNamedColor(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2438,7 +2438,7 @@ PanoramiXAllocColorCells(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2464,7 +2464,7 @@ PanoramiXAllocColorPlanes(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2490,7 +2490,7 @@ PanoramiXFreeColors(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2514,7 +2514,7 @@ PanoramiXStoreColors(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -2540,7 +2540,7 @@ PanoramiXStoreNamedColor(ClientPtr client)
 
     client->errorValue = stuff->cmap;
 
-    result = dixLookupResourceByType((pointer *) &cmap, stuff->cmap,
+    result = dixLookupResourceByType((void **) &cmap, stuff->cmap,
                                      XRT_COLORMAP, client, DixWriteAccess);
     if (result != Success)
         return result;
diff --git a/Xext/panoramiXsrv.h b/Xext/panoramiXsrv.h
index 0fcde4f..6d93eec 100644
--- a/Xext/panoramiXsrv.h
+++ b/Xext/panoramiXsrv.h
@@ -19,7 +19,7 @@ extern _X_EXPORT Bool PanoramiXCreateConnectionBlock(void);
 extern _X_EXPORT PanoramiXRes *PanoramiXFindIDByScrnum(RESTYPE, XID, int);
 extern _X_EXPORT Bool
 XineramaRegisterConnectionBlockCallback(void (*func) (void));
-extern _X_EXPORT int XineramaDeleteResource(pointer, XID);
+extern _X_EXPORT int XineramaDeleteResource(void *, XID);
 
 extern _X_EXPORT void XineramaReinitData(void);
 
diff --git a/Xext/saver.c b/Xext/saver.c
index e06f408..03f28bb 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -107,7 +107,7 @@ typedef struct _ScreenSaverSuspension {
     int count;
 } ScreenSaverSuspensionRec;
 
-static int ScreenSaverFreeSuspend(pointer /*value */ ,
+static int ScreenSaverFreeSuspend(void */*value */ ,
                                   XID   /* id */
     );
 
@@ -131,7 +131,7 @@ typedef struct _ScreenSaverEvent {
     CARD32 mask;
 } ScreenSaverEventRec;
 
-static int ScreenSaverFreeEvents(pointer /* value */ ,
+static int ScreenSaverFreeEvents(void * /* value */ ,
                                  XID    /* id */
     );
 
@@ -168,7 +168,7 @@ typedef struct _ScreenSaverAttr {
     unsigned long *values;
 } ScreenSaverAttrRec, *ScreenSaverAttrPtr;
 
-static int ScreenSaverFreeAttr(pointer /* value */ ,
+static int ScreenSaverFreeAttr(void */* value */ ,
                                XID      /* id */
     );
 
@@ -288,7 +288,7 @@ setEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
             pEv->client = client;
             pEv->screen = pScreen;
             pEv->resource = FakeClientID(client->index);
-            if (!AddResource(pEv->resource, SaverEventType, (pointer) pEv))
+            if (!AddResource(pEv->resource, SaverEventType, (void *) pEv))
                 return FALSE;
         }
         pEv->mask = mask;
@@ -319,7 +319,7 @@ FreeScreenAttr(ScreenSaverAttrPtr pAttr)
 }
 
 static int
-ScreenSaverFreeEvents(pointer value, XID id)
+ScreenSaverFreeEvents(void *value, XID id)
 {
     ScreenSaverEventPtr pOld = (ScreenSaverEventPtr) value;
     ScreenPtr pScreen = pOld->screen;
@@ -341,7 +341,7 @@ ScreenSaverFreeEvents(pointer value, XID id)
 }
 
 static int
-ScreenSaverFreeAttr(pointer value, XID id)
+ScreenSaverFreeAttr(void *value, XID id)
 {
     ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr) value;
     ScreenPtr pScreen = pOldAttr->screen;
@@ -363,7 +363,7 @@ ScreenSaverFreeAttr(pointer value, XID id)
 }
 
 static int
-ScreenSaverFreeSuspend(pointer value, XID id)
+ScreenSaverFreeSuspend(void *value, XID id)
 {
     ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
     ScreenSaverSuspensionPtr *prev, this;
@@ -460,7 +460,7 @@ UninstallSaverColormap(ScreenPtr pScreen)
     int rc;
 
     if (pPriv && pPriv->installedMap != None) {
-        rc = dixLookupResourceByType((pointer *) &pCmap, pPriv->installedMap,
+        rc = dixLookupResourceByType((void **) &pCmap, pPriv->installedMap,
                                      RT_COLORMAP, serverClient,
                                      DixUninstallAccess);
         if (rc == Success)
@@ -571,7 +571,7 @@ CreateSaverWindow(ScreenPtr pScreen)
     if (i < numInstalled)
         return TRUE;
 
-    result = dixLookupResourceByType((pointer *) &pCmap, wantMap, RT_COLORMAP,
+    result = dixLookupResourceByType((void **) &pCmap, wantMap, RT_COLORMAP,
                                      serverClient, DixInstallAccess);
     if (result != Success)
         return TRUE;
@@ -923,7 +923,7 @@ ScreenSaverSetAttributes(ClientPtr client)
             }
             else {
                 ret =
-                    dixLookupResourceByType((pointer *) &pPixmap, pixID,
+                    dixLookupResourceByType((void **) &pPixmap, pixID,
                                             RT_PIXMAP, client, DixReadAccess);
                 if (ret == Success) {
                     if ((pPixmap->drawable.depth != depth) ||
@@ -955,7 +955,7 @@ ScreenSaverSetAttributes(ClientPtr client)
             }
             else {
                 ret =
-                    dixLookupResourceByType((pointer *) &pPixmap, pixID,
+                    dixLookupResourceByType((void **) &pPixmap, pixID,
                                             RT_PIXMAP, client, DixReadAccess);
                 if (ret == Success) {
                     if ((pPixmap->drawable.depth != depth) ||
@@ -1039,7 +1039,7 @@ ScreenSaverSetAttributes(ClientPtr client)
             break;
         case CWColormap:
             cmap = (Colormap) * pVlist;
-            ret = dixLookupResourceByType((pointer *) &pCmap, cmap, RT_COLORMAP,
+            ret = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP,
                                           client, DixUseAccess);
             if (ret != Success) {
                 client->errorValue = cmap;
@@ -1058,7 +1058,7 @@ ScreenSaverSetAttributes(ClientPtr client)
                 *values++ = None;
             }
             else {
-                ret = dixLookupResourceByType((pointer *) &pCursor, cursorID,
+                ret = dixLookupResourceByType((void **) &pCursor, cursorID,
                                               RT_CURSOR, client, DixUseAccess);
                 if (ret != Success) {
                     client->errorValue = cursorID;
@@ -1079,7 +1079,7 @@ ScreenSaverSetAttributes(ClientPtr client)
         FreeScreenAttr(pPriv->attr);
     pPriv->attr = pAttr;
     pAttr->resource = FakeClientID(client->index);
-    if (!AddResource(pAttr->resource, AttrType, (pointer) pAttr))
+    if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
         return BadAlloc;
     return Success;
  PatchUp:
@@ -1131,7 +1131,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
 
         REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
 
-        status = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+        status = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                           XRC_DRAWABLE, client, DixWriteAccess);
         if (status != Success)
             return (status == BadValue) ? BadDrawable : status;
@@ -1146,7 +1146,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
             pback_offset = Ones((Mask) stuff->mask & (CWBackPixmap - 1));
             tmp = *((CARD32 *) &stuff[1] + pback_offset);
             if ((tmp != None) && (tmp != ParentRelative)) {
-                status = dixLookupResourceByType((pointer *) &backPix, tmp,
+                status = dixLookupResourceByType((void **) &backPix, tmp,
                                                  XRT_PIXMAP, client,
                                                  DixReadAccess);
                 if (status != Success)
@@ -1158,7 +1158,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
             pbord_offset = Ones((Mask) stuff->mask & (CWBorderPixmap - 1));
             tmp = *((CARD32 *) &stuff[1] + pbord_offset);
             if (tmp != CopyFromParent) {
-                status = dixLookupResourceByType((pointer *) &bordPix, tmp,
+                status = dixLookupResourceByType((void **) &bordPix, tmp,
                                                  XRT_PIXMAP, client,
                                                  DixReadAccess);
                 if (status != Success)
@@ -1170,7 +1170,7 @@ ProcScreenSaverSetAttributes(ClientPtr client)
             cmap_offset = Ones((Mask) stuff->mask & (CWColormap - 1));
             tmp = *((CARD32 *) &stuff[1] + cmap_offset);
             if ((tmp != CopyFromParent) && (tmp != None)) {
-                status = dixLookupResourceByType((pointer *) &cmap, tmp,
+                status = dixLookupResourceByType((void **) &cmap, tmp,
                                                  XRT_COLORMAP, client,
                                                  DixReadAccess);
                 if (status != Success)
@@ -1211,7 +1211,7 @@ ProcScreenSaverUnsetAttributes(ClientPtr client)
         PanoramiXRes *draw;
         int rc, i;
 
-        rc = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+        rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
         if (rc != Success)
             return (rc == BadValue) ? BadDrawable : rc;
@@ -1270,7 +1270,7 @@ ProcScreenSaverSuspend(ClientPtr client)
     this->count = 1;
     this->clientResource = FakeClientID(client->index);
 
-    if (!AddResource(this->clientResource, SuspendType, (pointer) this)) {
+    if (!AddResource(this->clientResource, SuspendType, (void *) this)) {
         free(this);
         return BadAlloc;
     }
diff --git a/Xext/security.c b/Xext/security.c
index 7bf6cc4..421b252 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -167,7 +167,7 @@ SecurityLookupRequestName(ClientPtr client)
  */
 
 static int
-SecurityDeleteAuthorization(pointer value, XID id)
+SecurityDeleteAuthorization(void *value, XID id)
 {
     SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr) value;
     unsigned short name_len, data_len;
@@ -221,7 +221,7 @@ SecurityDeleteAuthorization(pointer value, XID id)
 
 /* resource delete function for RTEventClient */
 static int
-SecurityDeleteAuthorizationEventClient(pointer value, XID id)
+SecurityDeleteAuthorizationEventClient(void *value, XID id)
 {
     OtherClientsPtr pEventClient, prev = NULL;
     SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr) value;
@@ -294,7 +294,7 @@ SecurityComputeAuthorizationTimeout(SecurityAuthorizationPtr pAuth,
  */
 
 static CARD32
-SecurityAuthorizationExpired(OsTimerPtr timer, CARD32 time, pointer pval)
+SecurityAuthorizationExpired(OsTimerPtr timer, CARD32 time, void *pval)
 {
     SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr) pval;
 
@@ -382,7 +382,7 @@ SecurityEventSelectForAuthorization(SecurityAuthorizationPtr pAuth,
     pEventClient->mask = mask;
     pEventClient->resource = FakeClientID(client->index);
     pEventClient->next = pAuth->eventClients;
-    if (!AddResource(pEventClient->resource, RTEventClient, (pointer) pAuth)) {
+    if (!AddResource(pEventClient->resource, RTEventClient, (void *) pAuth)) {
         free(pEventClient);
         return BadAlloc;
     }
@@ -454,7 +454,7 @@ ProcSecurityGenerateAuthorization(ClientPtr client)
 
             vgi.group = group;
             vgi.valid = FALSE;
-            CallCallbacks(&SecurityValidateGroupCallback, (pointer) &vgi);
+            CallCallbacks(&SecurityValidateGroupCallback, (void *) &vgi);
 
             /* if nobody said they recognized it, it's an error */
 
@@ -575,7 +575,7 @@ ProcSecurityRevokeAuthorization(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
 
-    rc = dixLookupResourceByType((pointer *) &pAuth, stuff->authId,
+    rc = dixLookupResourceByType((void **) &pAuth, stuff->authId,
                                  SecurityAuthorizationResType, client,
                                  DixDestroyAccess);
     if (rc != Success)
@@ -693,7 +693,7 @@ SwapSecurityAuthorizationRevokedEvent(xSecurityAuthorizationRevokedEvent * from,
  */
 
 static void
-SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityDevice(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceDeviceAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -737,7 +737,7 @@ SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
  */
 
 static void
-SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityResource(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceResourceAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -785,7 +785,7 @@ SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityExtension(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceExtAccessRec *rec = calldata;
     SecurityStateRec *subj;
@@ -808,7 +808,7 @@ SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityServer(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceServerAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -827,7 +827,7 @@ SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityClient(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceClientAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -846,7 +846,7 @@ SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityProperty(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XacePropertyAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -868,7 +868,7 @@ SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecuritySend(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceSendAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -900,7 +900,7 @@ SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SecurityReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityReceive(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceReceiveAccessRec *rec = calldata;
     SecurityStateRec *subj, *obj;
@@ -941,7 +941,7 @@ SecurityReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
  */
 
 static void
-SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SecurityClientState(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     NewClientInfoRec *pci = calldata;
     SecurityStateRec *state;
@@ -960,7 +960,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     case ClientStateRunning:
         state->authId = AuthorizationIDOfClient(pci->client);
-        rc = dixLookupResourceByType((pointer *) &pAuth, state->authId,
+        rc = dixLookupResourceByType((void **) &pAuth, state->authId,
                                      SecurityAuthorizationResType, serverClient,
                                      DixGetAttrAccess);
         if (rc == Success) {
@@ -976,7 +976,7 @@ SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     case ClientStateGone:
     case ClientStateRetained:
-        rc = dixLookupResourceByType((pointer *) &pAuth, state->authId,
+        rc = dixLookupResourceByType((void **) &pAuth, state->authId,
                                      SecurityAuthorizationResType, serverClient,
                                      DixGetAttrAccess);
         if (rc == Success && state->live) {
diff --git a/Xext/shape.c b/Xext/shape.c
index d36867c..bb479b1 100644
--- a/Xext/shape.c
+++ b/Xext/shape.c
@@ -50,11 +50,11 @@ in this Software without prior written authorization from The Open Group.
 typedef RegionPtr (*CreateDftPtr) (WindowPtr    /* pWin */
     );
 
-static int ShapeFreeClient(pointer /* data */ ,
-                           XID  /* id */
+static int ShapeFreeClient(void * /* data */ ,
+                           XID    /* id */
     );
-static int ShapeFreeEvents(pointer /* data */ ,
-                           XID  /* id */
+static int ShapeFreeEvents(void * /* data */ ,
+                           XID    /* id */
     );
 static void SShapeNotifyEvent(xShapeNotifyEvent * /* from */ ,
                               xShapeNotifyEvent *       /* to */
@@ -306,7 +306,7 @@ ProcPanoramiXShapeRectangles(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->dest, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->dest, XRT_WINDOW,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -361,7 +361,7 @@ ProcShapeMask(ClientPtr client)
     if (stuff->src == None)
         srcRgn = 0;
     else {
-        rc = dixLookupResourceByType((pointer *) &pPixmap, stuff->src,
+        rc = dixLookupResourceByType((void **) &pPixmap, stuff->src,
                                      RT_PIXMAP, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -404,13 +404,13 @@ ProcPanoramiXShapeMask(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xShapeMaskReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->dest, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->dest, XRT_WINDOW,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
 
     if (stuff->src != None) {
-        result = dixLookupResourceByType((pointer *) &pmap, stuff->src,
+        result = dixLookupResourceByType((void **) &pmap, stuff->src,
                                          XRT_PIXMAP, client, DixReadAccess);
         if (result != Success)
             return result;
@@ -532,12 +532,12 @@ ProcPanoramiXShapeCombine(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xShapeCombineReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->dest, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->dest, XRT_WINDOW,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &win2, stuff->src, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win2, stuff->src, XRT_WINDOW,
                                      client, DixReadAccess);
     if (result != Success)
         return result;
@@ -603,7 +603,7 @@ ProcPanoramiXShapeOffset(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xShapeOffsetReq);
 
-    result = dixLookupResourceByType((pointer *) &win, stuff->dest, XRT_WINDOW,
+    result = dixLookupResourceByType((void **) &win, stuff->dest, XRT_WINDOW,
                                      client, DixWriteAccess);
     if (result != Success)
         return result;
@@ -686,7 +686,7 @@ ProcShapeQueryExtents(ClientPtr client)
 }
 
  /*ARGSUSED*/ static int
-ShapeFreeClient(pointer data, XID id)
+ShapeFreeClient(void *data, XID id)
 {
     ShapeEventPtr pShapeEvent;
     WindowPtr pWin;
@@ -695,7 +695,7 @@ ShapeFreeClient(pointer data, XID id)
 
     pShapeEvent = (ShapeEventPtr) data;
     pWin = pShapeEvent->window;
-    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                                  ShapeEventType, serverClient, DixReadAccess);
     if (rc == Success) {
         pPrev = 0;
@@ -708,12 +708,12 @@ ShapeFreeClient(pointer data, XID id)
                 *pHead = pShapeEvent->next;
         }
     }
-    free((pointer) pShapeEvent);
+    free((void *) pShapeEvent);
     return 1;
 }
 
  /*ARGSUSED*/ static int
-ShapeFreeEvents(pointer data, XID id)
+ShapeFreeEvents(void *data, XID id)
 {
     ShapeEventPtr *pHead, pCur, pNext;
 
@@ -721,9 +721,9 @@ ShapeFreeEvents(pointer data, XID id)
     for (pCur = *pHead; pCur; pCur = pNext) {
         pNext = pCur->next;
         FreeResource(pCur->clientResource, ClientType);
-        free((pointer) pCur);
+        free((void *) pCur);
     }
-    free((pointer) pHead);
+    free((void *) pHead);
     return 1;
 }
 
@@ -740,7 +740,7 @@ ProcShapeSelectInput(ClientPtr client)
     rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
     if (rc != Success)
         return rc;
-    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                                  ShapeEventType, client, DixWriteAccess);
     if (rc != Success && rc != BadValue)
         return rc;
@@ -770,10 +770,10 @@ ProcShapeSelectInput(ClientPtr client)
          */
         clientResource = FakeClientID(client->index);
         pNewShapeEvent->clientResource = clientResource;
-        if (!AddResource(clientResource, ClientType, (pointer) pNewShapeEvent))
+        if (!AddResource(clientResource, ClientType, (void *) pNewShapeEvent))
             return BadAlloc;
         /*
-         * create a resource to contain a pointer to the list
+         * create a resource to contain a void *to the list
          * of clients selecting input.  This must be indirect as
          * the list may be arbitrarily rearranged which cannot be
          * done through the resource database.
@@ -782,7 +782,7 @@ ProcShapeSelectInput(ClientPtr client)
             pHead = malloc(sizeof(ShapeEventPtr));
             if (!pHead ||
                 !AddResource(pWin->drawable.id, ShapeEventType,
-                             (pointer) pHead)) {
+                             (void *) pHead)) {
                 FreeResource(clientResource, RT_NONE);
                 return BadAlloc;
             }
@@ -831,7 +831,7 @@ SendShapeNotify(WindowPtr pWin, int which)
     BYTE shaped;
     int rc;
 
-    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                                  ShapeEventType, serverClient, DixReadAccess);
     if (rc != Success)
         return;
@@ -910,7 +910,7 @@ ProcShapeInputSelected(ClientPtr client)
     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
     if (rc != Success)
         return rc;
-    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                                  ShapeEventType, client, DixReadAccess);
     if (rc != Success && rc != BadValue)
         return rc;
diff --git a/Xext/shm.c b/Xext/shm.c
index 1957a95..34545ec 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -99,7 +99,7 @@ typedef struct _ShmScrPrivateRec {
 } ShmScrPrivateRec;
 
 static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
-static int ShmDetachSegment(pointer /* value */ ,
+static int ShmDetachSegment(void */* value */ ,
                             XID /* shmseg */
     );
 static void ShmResetProc(ExtensionEntry *       /* extEntry */
@@ -130,7 +130,7 @@ static ShmFuncs fbFuncs = { fbShmCreatePixmap, NULL };
 #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
 { \
     int tmprc; \
-    tmprc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \
+    tmprc = dixLookupResourceByType((void **)&(shmdesc), shmseg, ShmSegType, \
                                     client, DixReadAccess); \
     if (tmprc != Success) \
 	return tmprc; \
@@ -260,7 +260,7 @@ ShmDestroyPixmap(PixmapPtr pPixmap)
         shmdesc = (ShmDescPtr) dixLookupPrivate(&pPixmap->devPrivates,
                                                 shmPixmapPrivateKey);
         if (shmdesc)
-            ShmDetachSegment((pointer) shmdesc, pPixmap->drawable.id);
+            ShmDetachSegment((void *) shmdesc, pPixmap->drawable.id);
     }
 
     pScreen->DestroyPixmap = screen_priv->destroyPixmap;
@@ -425,13 +425,13 @@ ProcShmAttach(ClientPtr client)
         shmdesc->next = Shmsegs;
         Shmsegs = shmdesc;
     }
-    if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc))
+    if (!AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc))
         return BadAlloc;
     return Success;
 }
 
  /*ARGSUSED*/ static int
-ShmDetachSegment(pointer value, /* must conform to DeleteType */
+ShmDetachSegment(void *value, /* must conform to DeleteType */
                  XID shmseg)
 {
     ShmDescPtr shmdesc = (ShmDescPtr) value;
@@ -729,12 +729,12 @@ ProcPanoramiXShmPutImage(ClientPtr client)
     REQUEST(xShmPutImageReq);
     REQUEST_SIZE_MATCH(xShmPutImageReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc,
                                      XRT_GC, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -783,7 +783,7 @@ ProcPanoramiXShmGetImage(ClientPtr client)
         return BadValue;
     }
 
-    rc = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                   XRC_DRAWABLE, client, DixWriteAccess);
     if (rc != Success)
         return (rc == BadValue) ? BadDrawable : rc;
@@ -980,7 +980,7 @@ ProcPanoramiXShmCreatePixmap(ClientPtr client)
             shmdesc->refcnt++;
             pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
             pMap->drawable.id = newPix->info[j].id;
-            if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer) pMap)) {
+            if (!AddResource(newPix->info[j].id, RT_PIXMAP, (void *) pMap)) {
                 result = BadAlloc;
                 break;
             }
@@ -1016,7 +1016,7 @@ fbShmCreatePixmap(ScreenPtr pScreen,
     if (!(*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth,
                                          BitsPerPixel(depth),
                                          PixmapBytePad(width, depth),
-                                         (pointer) addr)) {
+                                         (void *) addr)) {
         (*pScreen->DestroyPixmap) (pPixmap);
         return NullPixmap;
     }
@@ -1095,7 +1095,7 @@ ProcShmCreatePixmap(ClientPtr client)
         shmdesc->refcnt++;
         pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
         pMap->drawable.id = stuff->pid;
-        if (AddResource(stuff->pid, RT_PIXMAP, (pointer) pMap)) {
+        if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap)) {
             return Success;
         }
     }
@@ -1172,7 +1172,7 @@ ProcShmAttachFd(ClientPtr client)
     shmdesc->next = Shmsegs;
     Shmsegs = shmdesc;
 
-    if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc))
+    if (!AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc))
         return BadAlloc;
     return Success;
 }
@@ -1263,7 +1263,7 @@ ProcShmCreateSegment(ClientPtr client)
     shmdesc->next = Shmsegs;
     Shmsegs = shmdesc;
 
-    if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc)) {
+    if (!AddResource(stuff->shmseg, ShmSegType, (void *) shmdesc)) {
         close(fd);
         return BadAlloc;
     }
diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c
index 52e22b4..993c028 100644
--- a/Xext/sleepuntil.c
+++ b/Xext/sleepuntil.c
@@ -46,10 +46,10 @@ typedef struct _Sertafied {
     ClientPtr pClient;
     XID id;
     void (*notifyFunc) (ClientPtr /* client */ ,
-                        pointer /* closure */
+                        void *    /* closure */
         );
 
-    pointer closure;
+    void *closure;
 } SertafiedRec, *SertafiedPtr;
 
 static SertafiedPtr pPending;
@@ -58,24 +58,24 @@ static Bool BlockHandlerRegistered;
 static int SertafiedGeneration;
 
 static void ClientAwaken(ClientPtr /* client */ ,
-                         pointer        /* closure */
+                         void *    /* closure */
     );
-static int SertafiedDelete(pointer /* value */ ,
-                           XID  /* id */
+static int SertafiedDelete(void *  /* value */ ,
+                           XID     /* id */
     );
-static void SertafiedBlockHandler(pointer /* data */ ,
+static void SertafiedBlockHandler(void *    /* data */ ,
                                   OSTimePtr /* wt */ ,
-                                  pointer       /* LastSelectMask */
+                                  void *    /* LastSelectMask */
     );
-static void SertafiedWakeupHandler(pointer /* data */ ,
-                                   int /* i */ ,
-                                   pointer      /* LastSelectMask */
+static void SertafiedWakeupHandler(void *   /* data */ ,
+                                   int      /* i */ ,
+                                   void *   /* LastSelectMask */
     );
 
 int
 ClientSleepUntil(ClientPtr client,
                  TimeStamp *revive,
-                 void (*notifyFunc) (ClientPtr, pointer), pointer closure)
+                 void (*notifyFunc) (ClientPtr, void *), void *closure)
 {
     SertafiedPtr pRequest, pReq, pPrev;
 
@@ -97,14 +97,14 @@ ClientSleepUntil(ClientPtr client,
     if (!BlockHandlerRegistered) {
         if (!RegisterBlockAndWakeupHandlers(SertafiedBlockHandler,
                                             SertafiedWakeupHandler,
-                                            (pointer) 0)) {
+                                            (void *) 0)) {
             free(pRequest);
             return FALSE;
         }
         BlockHandlerRegistered = TRUE;
     }
     pRequest->notifyFunc = 0;
-    if (!AddResource(pRequest->id, SertafiedResType, (pointer) pRequest))
+    if (!AddResource(pRequest->id, SertafiedResType, (void *) pRequest))
         return FALSE;
     if (!notifyFunc)
         notifyFunc = ClientAwaken;
@@ -126,14 +126,14 @@ ClientSleepUntil(ClientPtr client,
 }
 
 static void
-ClientAwaken(ClientPtr client, pointer closure)
+ClientAwaken(ClientPtr client, void *closure)
 {
     if (!client->clientGone)
         AttendClient(client);
 }
 
 static int
-SertafiedDelete(pointer value, XID id)
+SertafiedDelete(void *value, XID id)
 {
     SertafiedPtr pRequest = (SertafiedPtr) value;
     SertafiedPtr pReq, pPrev;
@@ -154,7 +154,7 @@ SertafiedDelete(pointer value, XID id)
 }
 
 static void
-SertafiedBlockHandler(pointer data, OSTimePtr wt, pointer LastSelectMask)
+SertafiedBlockHandler(void *data, OSTimePtr wt, void *LastSelectMask)
 {
     SertafiedPtr pReq, pNext;
     unsigned long delay;
@@ -186,7 +186,7 @@ SertafiedBlockHandler(pointer data, OSTimePtr wt, pointer LastSelectMask)
 }
 
 static void
-SertafiedWakeupHandler(pointer data, int i, pointer LastSelectMask)
+SertafiedWakeupHandler(void *data, int i, void *LastSelectMask)
 {
     SertafiedPtr pReq, pNext;
     TimeStamp now;
@@ -203,7 +203,7 @@ SertafiedWakeupHandler(pointer data, int i, pointer LastSelectMask)
     }
     if (!pPending) {
         RemoveBlockAndWakeupHandlers(SertafiedBlockHandler,
-                                     SertafiedWakeupHandler, (pointer) 0);
+                                     SertafiedWakeupHandler, (void *) 0);
         BlockHandlerRegistered = FALSE;
     }
 }
diff --git a/Xext/sleepuntil.h b/Xext/sleepuntil.h
index 5c70848..e9b8388 100644
--- a/Xext/sleepuntil.h
+++ b/Xext/sleepuntil.h
@@ -36,7 +36,7 @@
 extern int ClientSleepUntil(ClientPtr client,
                             TimeStamp *revive,
                             void (*notifyFunc) (ClientPtr /* client */ ,
-                                                pointer /* closure */
-                            ), pointer Closure);
+                                                void *    /* closure */
+                            ), void *Closure);
 
 #endif
diff --git a/Xext/sync.c b/Xext/sync.c
index 2d58ea1..97c9d51 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -324,7 +324,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject,
     if (changes & XSyncCACounter) {
         if (syncObject == None)
             pSync = NULL;
-        else if (Success != (rc = dixLookupResourceByType((pointer *) &pSync,
+        else if (Success != (rc = dixLookupResourceByType((void **) &pSync,
                                                           syncObject, resType,
                                                           client,
                                                           DixReadAccess))) {
@@ -344,7 +344,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject,
         pCounter = (SyncCounter *) pSync;
 
         if (IsSystemCounter(pCounter)) {
-            (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter,
+            (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
                                                       &pCounter->value);
         }
     }
@@ -933,7 +933,7 @@ SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL
         return status;
     }
 
-    if (!AddResource(id, RTFence, (pointer) pFence))
+    if (!AddResource(id, RTFence, (void *) pFence))
         return BadAlloc;
 
     return Success;
@@ -963,7 +963,7 @@ SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue)
     pCounter->value = initialvalue;
     pCounter->pSysCounterInfo = NULL;
 
-    if (!AddResource(id, RTCounter, (pointer) pCounter))
+    if (!AddResource(id, RTCounter, (void *) pCounter))
         return NULL;
 
     return pCounter;
@@ -1023,7 +1023,7 @@ SyncCreateSystemCounter(const char *name,
 }
 
 void
-SyncDestroySystemCounter(pointer pSysCounter)
+SyncDestroySystemCounter(void *pSysCounter)
 {
     SyncCounter *pCounter = (SyncCounter *) pSysCounter;
 
@@ -1121,7 +1121,7 @@ SyncComputeBracketValues(SyncCounter * pCounter)
         }
     }                           /* end for each trigger */
 
-    (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
+    (*psci->BracketValues) ((void *) pCounter, pnewltval, pnewgtval);
 
 }
 
@@ -1431,7 +1431,7 @@ ProcSyncSetCounter(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncSetCounterReq);
 
-    rc = dixLookupResourceByType((pointer *) &pCounter, stuff->cid, RTCounter,
+    rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter,
                                  client, DixWriteAccess);
     if (rc != Success)
         return rc;
@@ -1460,7 +1460,7 @@ ProcSyncChangeCounter(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncChangeCounterReq);
 
-    rc = dixLookupResourceByType((pointer *) &pCounter, stuff->cid, RTCounter,
+    rc = dixLookupResourceByType((void **) &pCounter, stuff->cid, RTCounter,
                                  client, DixWriteAccess);
     if (rc != Success)
         return rc;
@@ -1493,7 +1493,7 @@ ProcSyncDestroyCounter(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncDestroyCounterReq);
 
-    rc = dixLookupResourceByType((pointer *) &pCounter, stuff->counter,
+    rc = dixLookupResourceByType((void **) &pCounter, stuff->counter,
                                  RTCounter, client, DixDestroyAccess);
     if (rc != Success)
         return rc;
@@ -1654,14 +1654,14 @@ ProcSyncQueryCounter(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncQueryCounterReq);
 
-    rc = dixLookupResourceByType((pointer *) &pCounter, stuff->counter,
+    rc = dixLookupResourceByType((void **) &pCounter, stuff->counter,
                                  RTCounter, client, DixReadAccess);
     if (rc != Success)
         return rc;
 
     /* if system counter, ask it what the current value is */
     if (IsSystemCounter(pCounter)) {
-        (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter,
+        (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
                                                   &pCounter->value);
     }
 
@@ -1780,7 +1780,7 @@ ProcSyncChangeAlarm(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq);
 
-    status = dixLookupResourceByType((pointer *) &pAlarm, stuff->alarm, RTAlarm,
+    status = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
                                      client, DixWriteAccess);
     if (status != Success)
         return status;
@@ -1821,7 +1821,7 @@ ProcSyncQueryAlarm(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncQueryAlarmReq);
 
-    rc = dixLookupResourceByType((pointer *) &pAlarm, stuff->alarm, RTAlarm,
+    rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
                                  client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -1879,7 +1879,7 @@ ProcSyncDestroyAlarm(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq);
 
-    rc = dixLookupResourceByType((pointer *) &pAlarm, stuff->alarm, RTAlarm,
+    rc = dixLookupResourceByType((void **) &pAlarm, stuff->alarm, RTAlarm,
                                  client, DixDestroyAccess);
     if (rc != Success)
         return rc;
@@ -1909,7 +1909,7 @@ ProcSyncCreateFence(ClientPtr client)
 
     miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered);
 
-    if (!AddResource(stuff->fid, RTFence, (pointer) pFence))
+    if (!AddResource(stuff->fid, RTFence, (void *) pFence))
         return BadAlloc;
 
     return client->noClientException;
@@ -1928,7 +1928,7 @@ FreeFence(void *obj, XID id)
 int
 SyncVerifyFence(SyncFence ** ppSyncFence, XID fid, ClientPtr client, Mask mode)
 {
-    int rc = dixLookupResourceByType((pointer *) ppSyncFence, fid, RTFence,
+    int rc = dixLookupResourceByType((void **) ppSyncFence, fid, RTFence,
                                      client, mode);
 
     if (rc != Success)
@@ -1946,7 +1946,7 @@ ProcSyncTriggerFence(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncTriggerFenceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pFence, stuff->fid, RTFence,
+    rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
                                  client, DixWriteAccess);
     if (rc != Success)
         return rc;
@@ -1965,7 +1965,7 @@ ProcSyncResetFence(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncResetFenceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pFence, stuff->fid, RTFence,
+    rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
                                  client, DixWriteAccess);
     if (rc != Success)
         return rc;
@@ -1987,7 +1987,7 @@ ProcSyncDestroyFence(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncDestroyFenceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pFence, stuff->fid, RTFence,
+    rc = dixLookupResourceByType((void **) &pFence, stuff->fid, RTFence,
                                  client, DixDestroyAccess);
     if (rc != Success)
         return rc;
@@ -2006,7 +2006,7 @@ ProcSyncQueryFence(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSyncQueryFenceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pFence, stuff->fid,
+    rc = dixLookupResourceByType((void **) &pFence, stuff->fid,
                                  RTFence, client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -2555,7 +2555,7 @@ SyncExtensionInit(void)
  * ***** SERVERTIME implementation - should go in its own file in OS directory?
  */
 
-static pointer ServertimeCounter;
+static void *ServertimeCounter;
 static XSyncValue Now;
 static XSyncValue *pnext_time;
 
@@ -2656,7 +2656,7 @@ typedef struct {
 } IdleCounterPriv;
 
 static void
-IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
+IdleTimeQueryValue(void *pCounter, CARD64 * pValue_return)
 {
     int deviceid;
     CARD32 idle;
@@ -2673,7 +2673,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
 }
 
 static void
-IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask)
+IdleTimeBlockHandler(void *pCounter, struct timeval **wt, void *LastSelectMask)
 {
     SyncCounter *counter = pCounter;
     IdleCounterPriv *priv = SysCounterGetPrivate(counter);
@@ -2769,7 +2769,7 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X
 }
 
 static void
-IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
+IdleTimeWakeupHandler(void *pCounter, int rc, void *LastSelectMask)
 {
     SyncCounter *counter = pCounter;
     IdleCounterPriv *priv = SysCounterGetPrivate(counter);
@@ -2803,7 +2803,7 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
 }
 
 static void
-IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
+IdleTimeBracketValues(void *pCounter, CARD64 * pbracket_less,
                       CARD64 * pbracket_greater)
 {
     SyncCounter *counter = pCounter;
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index 45fca04..8c2c00d 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -66,10 +66,10 @@ typedef enum {
     XSyncCounterUnrestricted
 } SyncCounterType;
 
-typedef void (*SyncSystemCounterQueryValue)(pointer counter,
+typedef void (*SyncSystemCounterQueryValue)(void *counter,
                                             CARD64 *value_return
     );
-typedef void (*SyncSystemCounterBracketValues)(pointer counter,
+typedef void (*SyncSystemCounterBracketValues)(void *counter,
                                                CARD64 *pbracket_less,
                                                CARD64 *pbracket_greater
     );
@@ -132,7 +132,7 @@ extern void SyncChangeCounter(SyncCounter *pCounter,
                               CARD64 new_value
     );
 
-extern void SyncDestroySystemCounter(pointer pCounter);
+extern void SyncDestroySystemCounter(void *pCounter);
 
 extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev);
 extern void SyncRemoveDeviceIdleTime(SyncCounter *counter);
diff --git a/Xext/xace.c b/Xext/xace.c
index 026d3c5..d77b312 100644
--- a/Xext/xace.c
+++ b/Xext/xace.c
@@ -122,9 +122,9 @@ XaceHook(int hook, ...)
         u.res.client = va_arg(ap, ClientPtr);
         u.res.id = va_arg(ap, XID);
         u.res.rtype = va_arg(ap, RESTYPE);
-        u.res.res = va_arg(ap, pointer);
+        u.res.res = va_arg(ap, void *);
         u.res.ptype = va_arg(ap, RESTYPE);
-        u.res.parent = va_arg(ap, pointer);
+        u.res.parent = va_arg(ap, void *);
         u.res.access_mode = va_arg(ap, Mask);
 
         u.res.status = Success; /* default allow */
@@ -288,7 +288,7 @@ XaceCensorImage(ClientPtr client,
 
         pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
                                       depth, bitsPerPixel,
-                                      widthBytesLine, (pointer) pBuf);
+                                      widthBytesLine, (void *) pBuf);
         if (!pPix) {
             failed = TRUE;
             goto failSafe;
diff --git a/Xext/xacestr.h b/Xext/xacestr.h
index 989b033..6fe8eec 100644
--- a/Xext/xacestr.h
+++ b/Xext/xacestr.h
@@ -40,9 +40,9 @@ typedef struct {
     ClientPtr client;
     XID id;
     RESTYPE rtype;
-    pointer res;
+    void *res;
     RESTYPE ptype;
-    pointer parent;
+    void *parent;
     Mask access_mode;
     int status;
 } XaceResourceAccessRec;
diff --git a/Xext/xres.c b/Xext/xres.c
index bdd49eb..b26cbb5 100644
--- a/Xext/xres.c
+++ b/Xext/xres.c
@@ -267,7 +267,7 @@ ProcXResQueryClients(ClientPtr client)
 }
 
 static void
-ResFindAllRes(pointer value, XID id, RESTYPE type, pointer cdata)
+ResFindAllRes(void *value, XID id, RESTYPE type, void *cdata)
 {
     int *counts = (int *) cdata;
 
@@ -365,7 +365,7 @@ ResGetApproxPixmapBytes(PixmapPtr pix)
 }
 
 static void
-ResFindResourcePixmaps(pointer value, XID id, RESTYPE type, pointer cdata)
+ResFindResourcePixmaps(void *value, XID id, RESTYPE type, void *cdata)
 {
     SizeType sizeFunc = GetResourceTypeSizeFunc(type);
     ResourceSizeRec size = { 0, 0, 0 };
@@ -376,7 +376,7 @@ ResFindResourcePixmaps(pointer value, XID id, RESTYPE type, pointer cdata)
 }
 
 static void 
-ResFindPixmaps(pointer value, XID id, pointer cdata)
+ResFindPixmaps(void *value, XID id, void *cdata)
 {
     unsigned long *bytes = (unsigned long *) cdata;
     PixmapPtr pix = (PixmapPtr) value;
@@ -385,7 +385,7 @@ ResFindPixmaps(pointer value, XID id, pointer cdata)
 }
 
 static void
-ResFindWindowPixmaps(pointer value, XID id, pointer cdata)
+ResFindWindowPixmaps(void *value, XID id, void *cdata)
 {
     unsigned long *bytes = (unsigned long *) cdata;
     WindowPtr pWin = (WindowPtr) value;
@@ -398,7 +398,7 @@ ResFindWindowPixmaps(pointer value, XID id, pointer cdata)
 }
 
 static void
-ResFindGCPixmaps(pointer value, XID id, pointer cdata)
+ResFindGCPixmaps(void *value, XID id, void *cdata)
 {
     unsigned long *bytes = (unsigned long *) cdata;
     GCPtr pGC = (GCPtr) value;
@@ -411,7 +411,7 @@ ResFindGCPixmaps(pointer value, XID id, pointer cdata)
 }
 
 static void
-ResFindPicturePixmaps(pointer value, XID id, pointer cdata)
+ResFindPicturePixmaps(void *value, XID id, void *cdata)
 {
 #ifdef RENDER
     ResFindResourcePixmaps(value, id, PictureType, cdata);
@@ -419,7 +419,7 @@ ResFindPicturePixmaps(pointer value, XID id, pointer cdata)
 }
 
 static void
-ResFindCompositeClientWindowPixmaps (pointer value, XID id, pointer cdata)
+ResFindCompositeClientWindowPixmaps (void *value, XID id, void *cdata)
 {
 #ifdef COMPOSITE
     ResFindResourcePixmaps(value, id, CompositeClientWindowType, cdata);
@@ -446,32 +446,32 @@ ProcXResQueryClientPixmapBytes(ClientPtr client)
     bytes = 0;
 
     FindClientResourcesByType(clients[clientID], RT_PIXMAP, ResFindPixmaps,
-                              (pointer) (&bytes));
+                              (void *) (&bytes));
 
     /* 
      * Make sure win background pixmaps also held to account. 
      */
     FindClientResourcesByType(clients[clientID], RT_WINDOW,
-                              ResFindWindowPixmaps, (pointer) (&bytes));
+                              ResFindWindowPixmaps, (void *) (&bytes));
 
     /* 
      * GC Tile & Stipple pixmaps too.
      */
     FindClientResourcesByType(clients[clientID], RT_GC,
-                              ResFindGCPixmaps, (pointer) (&bytes));
+                              ResFindGCPixmaps, (void *) (&bytes));
 
 #ifdef RENDER
     /* Render extension picture pixmaps. */
     FindClientResourcesByType(clients[clientID], PictureType,
                               ResFindPicturePixmaps,
-                              (pointer)(&bytes));
+                              (void *)(&bytes));
 #endif
 
 #ifdef COMPOSITE
     /* Composite extension client window pixmaps. */
     FindClientResourcesByType(clients[clientID], CompositeClientWindowType,
                               ResFindCompositeClientWindowPixmaps,
-                              (pointer)(&bytes));
+                              (void *)(&bytes));
 #endif
 
     rep = (xXResQueryClientPixmapBytesReply) {
@@ -753,10 +753,10 @@ SwapXResQueryResourceBytes(struct xorg_list *response)
                         FindRes
 */
 static void
-AddSubResourceSizeSpec(pointer value,
+AddSubResourceSizeSpec(void *value,
                        XID id,
                        RESTYPE type,
-                       pointer cdata)
+                       void *cdata)
 {
     ConstructResourceBytesCtx *ctx = cdata;
 
@@ -818,7 +818,7 @@ AddSubResourceSizeSpec(pointer value,
                         FindRes
 */
 static void
-AddResourceSizeValue(pointer ptr, XID id, RESTYPE type, pointer cdata)
+AddResourceSizeValue(void *ptr, XID id, RESTYPE type, void *cdata)
 {
     ConstructResourceBytesCtx *ctx = cdata;
     if (ctx->status == Success &&
@@ -888,7 +888,7 @@ AddResourceSizeValue(pointer ptr, XID id, RESTYPE type, pointer cdata)
    @param[in/out] cdata  The context object that contains the resource type
 */
 static void
-AddResourceSizeValueWithResType(pointer ptr, XID id, pointer cdata)
+AddResourceSizeValueWithResType(void *ptr, XID id, void *cdata)
 {
     ConstructResourceBytesCtx *ctx = cdata;
     AddResourceSizeValue(ptr, id, ctx->resType, cdata);
@@ -906,7 +906,7 @@ AddResourceSizeValueWithResType(pointer ptr, XID id, pointer cdata)
                          type FindAllRes
 */
 static void
-AddResourceSizeValueByResource(pointer ptr, XID id, RESTYPE type, pointer cdata)
+AddResourceSizeValueByResource(void *ptr, XID id, RESTYPE type, void *cdata)
 {
     ConstructResourceBytesCtx *ctx = cdata;
     xXResResourceIdSpec *spec = ctx->curSpec;
diff --git a/Xext/xselinux_ext.c b/Xext/xselinux_ext.c
index 3115f03..fb7b2d5 100644
--- a/Xext/xselinux_ext.c
+++ b/Xext/xselinux_ext.c
@@ -245,7 +245,7 @@ ProcSELinuxGetDrawableContext(ClientPtr client)
 }
 
 static int
-ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
+ProcSELinuxGetPropertyContext(ClientPtr client, void *privKey)
 {
     WindowPtr pWin;
     PropertyPtr pProp;
@@ -269,7 +269,7 @@ ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
 }
 
 static int
-ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
+ProcSELinuxGetSelectionContext(ClientPtr client, void *privKey)
 {
     Selection *pSel;
     SELinuxObjectRec *obj;
@@ -576,7 +576,7 @@ SProcSELinuxGetDrawableContext(ClientPtr client)
 }
 
 static int
-SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
+SProcSELinuxGetPropertyContext(ClientPtr client, void *privKey)
 {
     REQUEST(SELinuxGetPropertyContextReq);
 
@@ -587,7 +587,7 @@ SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
 }
 
 static int
-SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey)
+SProcSELinuxGetSelectionContext(ClientPtr client, void *privKey)
 {
     REQUEST(SELinuxGetContextReq);
 
diff --git a/Xext/xselinux_hooks.c b/Xext/xselinux_hooks.c
index e9c7e93..376d575 100644
--- a/Xext/xselinux_hooks.c
+++ b/Xext/xselinux_hooks.c
@@ -74,10 +74,10 @@ static Atom atom_client_ctx;
 static security_id_t unlabeled_sid;
 
 /* forward declarations */
-static void SELinuxScreen(CallbackListPtr *, pointer, pointer);
+static void SELinuxScreen(CallbackListPtr *, void *, void *);
 
 /* "true" pointer value for use as callback data */
-static pointer truep = (pointer) 1;
+static void *truep = (void *) 1;
 
 /*
  * Performs an SELinux permission check.
@@ -147,7 +147,7 @@ SELinuxLabelClient(ClientPtr client)
         strncpy(subj->command, cmdname, COMMAND_LEN - 1);
 
         if (!cached)
-            free((void *) cmdname);     /* const char * */
+            free(cmdname);     /* const char * */
     }
 
  finish:
@@ -171,7 +171,7 @@ SELinuxLabelInitial(void)
     SELinuxSubjectRec *subj;
     SELinuxObjectRec *obj;
     security_context_t ctx;
-    pointer unused;
+    void *unused;
 
     /* Do the serverClient */
     subj = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
@@ -326,7 +326,7 @@ SELinuxLog(int type, const char *fmt, ...)
  */
 
 static void
-SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxDevice(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceDeviceAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -363,7 +363,7 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxSend(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceSendAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -405,7 +405,7 @@ SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxReceive(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceReceiveAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -443,7 +443,7 @@ SELinuxReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxExtension(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceExtAccessRec *rec = calldata;
     SELinuxSubjectRec *subj, *serv;
@@ -484,7 +484,7 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxSelection(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceSelectionAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -544,7 +544,7 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxProperty(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XacePropertyAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -608,7 +608,7 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxResource(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceResourceAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -667,7 +667,7 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata)
+SELinuxScreen(CallbackListPtr *pcbl, void *is_saver, void *calldata)
 {
     XaceScreenAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -699,7 +699,7 @@ SELinuxScreen(CallbackListPtr *pcbl, pointer is_saver, pointer calldata)
 }
 
 static void
-SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxClient(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceClientAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -717,7 +717,7 @@ SELinuxClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxServer(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     XaceServerAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
@@ -739,7 +739,7 @@ SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
  */
 
 static void
-SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxClientState(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     NewClientInfoRec *pci = calldata;
 
@@ -754,7 +754,7 @@ SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
-SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
 {
     ResourceStateInfoRec *rec = calldata;
     SELinuxSubjectRec *subj;
diff --git a/Xext/xtest.c b/Xext/xtest.c
index 0a854f3..88df443 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -127,7 +127,7 @@ ProcXTestCompareCursor(ClientPtr client)
     else if (stuff->cursor == XTestCurrentCursor)
         pCursor = GetSpriteCursor(ptr);
     else {
-        rc = dixLookupResourceByType((pointer *) &pCursor, stuff->cursor,
+        rc = dixLookupResourceByType((void **) &pCursor, stuff->cursor,
                                      RT_CURSOR, client, DixReadAccess);
         if (rc != Success) {
             client->errorValue = stuff->cursor;
diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c
index 613867a..f2d49a2 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -994,7 +994,7 @@ ProcXvShmPutImage(ClientPtr client)
     if (!pImage)
         return BadMatch;
 
-    status = dixLookupResourceByType((pointer *) &shmdesc, stuff->shmseg,
+    status = dixLookupResourceByType((void **) &shmdesc, stuff->shmseg,
                                      ShmSegType, serverClient, DixReadAccess);
     if (status != Success)
         return status;
@@ -1512,12 +1512,12 @@ XineramaXvStopVideo(ClientPtr client)
     REQUEST(xvStopVideoReq);
     REQUEST_SIZE_MATCH(xvStopVideoReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1542,7 +1542,7 @@ XineramaXvSetPortAttribute(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1568,17 +1568,17 @@ XineramaXvShmPutImage(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xvShmPutImageReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc,
                                      XRT_GC, client, DixReadAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1620,17 +1620,17 @@ XineramaXvPutImage(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc,
                                      XRT_GC, client, DixReadAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1668,17 +1668,17 @@ XineramaXvPutVideo(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc,
                                      XRT_GC, client, DixReadAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
@@ -1716,17 +1716,17 @@ XineramaXvPutStill(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xvPutImageReq);
 
-    result = dixLookupResourceByClass((pointer *) &draw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
 
-    result = dixLookupResourceByType((pointer *) &gc, stuff->gc,
+    result = dixLookupResourceByType((void **) &gc, stuff->gc,
                                      XRT_GC, client, DixReadAccess);
     if (result != Success)
         return result;
 
-    result = dixLookupResourceByType((pointer *) &port, stuff->port,
+    result = dixLookupResourceByType((void **) &port, stuff->port,
                                      XvXRTPort, client, DixReadAccess);
     if (result != Success)
         return result;
diff --git a/Xext/xvdix.h b/Xext/xvdix.h
index 9c6160c..bb08cf4 100644
--- a/Xext/xvdix.h
+++ b/Xext/xvdix.h
@@ -200,7 +200,7 @@ typedef struct _XvPortRec {
 
 #define VALIDATE_XV_PORT(portID, pPort, mode)\
     {\
-	int rc = dixLookupResourceByType((pointer *)&(pPort), portID,\
+	int rc = dixLookupResourceByType((void **)&(pPort), portID,\
 	                                 XvRTPort, client, mode);\
 	if (rc != Success)\
 	    return rc;\
diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index 0c5dc9b..00b5179 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -134,12 +134,12 @@ static Bool XvCloseScreen(ScreenPtr);
 static Bool XvDestroyPixmap(PixmapPtr);
 static Bool XvDestroyWindow(WindowPtr);
 static void XvResetProc(ExtensionEntry *);
-static int XvdiDestroyGrab(pointer, XID);
-static int XvdiDestroyEncoding(pointer, XID);
-static int XvdiDestroyVideoNotify(pointer, XID);
-static int XvdiDestroyPortNotify(pointer, XID);
-static int XvdiDestroyVideoNotifyList(pointer, XID);
-static int XvdiDestroyPort(pointer, XID);
+static int XvdiDestroyGrab(void *, XID);
+static int XvdiDestroyEncoding(void *, XID);
+static int XvdiDestroyVideoNotify(void *, XID);
+static int XvdiDestroyPortNotify(void *, XID);
+static int XvdiDestroyVideoNotifyList(void *, XID);
+static int XvdiDestroyPort(void *, XID);
 static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int);
 
 /*
@@ -450,20 +450,20 @@ XvdiVideoStopped(XvPortPtr pPort, int reason)
 }
 
 static int
-XvdiDestroyPort(pointer pPort, XID id)
+XvdiDestroyPort(void *pPort, XID id)
 {
     return (*((XvPortPtr) pPort)->pAdaptor->ddFreePort) (pPort);
 }
 
 static int
-XvdiDestroyGrab(pointer pGrab, XID id)
+XvdiDestroyGrab(void *pGrab, XID id)
 {
     ((XvGrabPtr) pGrab)->client = NULL;
     return Success;
 }
 
 static int
-XvdiDestroyVideoNotify(pointer pn, XID id)
+XvdiDestroyVideoNotify(void *pn, XID id)
 {
     /* JUST CLEAR OUT THE client POINTER FIELD */
 
@@ -472,7 +472,7 @@ XvdiDestroyVideoNotify(pointer pn, XID id)
 }
 
 static int
-XvdiDestroyPortNotify(pointer pn, XID id)
+XvdiDestroyPortNotify(void *pn, XID id)
 {
     /* JUST CLEAR OUT THE client POINTER FIELD */
 
@@ -481,7 +481,7 @@ XvdiDestroyPortNotify(pointer pn, XID id)
 }
 
 static int
-XvdiDestroyVideoNotifyList(pointer pn, XID id)
+XvdiDestroyVideoNotifyList(void *pn, XID id)
 {
     XvVideoNotifyPtr npn, cpn;
 
@@ -500,7 +500,7 @@ XvdiDestroyVideoNotifyList(pointer pn, XID id)
 }
 
 static int
-XvdiDestroyEncoding(pointer value, XID id)
+XvdiDestroyEncoding(void *value, XID id)
 {
     return Success;
 }
@@ -510,7 +510,7 @@ XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason)
 {
     XvVideoNotifyPtr pn;
 
-    dixLookupResourceByType((pointer *) &pn, pDraw->id, XvRTVideoNotifyList,
+    dixLookupResourceByType((void **) &pn, pDraw->id, XvRTVideoNotifyList,
                             serverClient, DixReadAccess);
 
     while (pn) {
@@ -843,7 +843,7 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
 
     /* FIND VideoNotify LIST */
 
-    rc = dixLookupResourceByType((pointer *) &pn, pDraw->id,
+    rc = dixLookupResourceByType((void **) &pn, pDraw->id,
                                  XvRTVideoNotifyList, client, DixWriteAccess);
     if (rc != Success && rc != BadValue)
         return rc;
diff --git a/Xext/xvmc.c b/Xext/xvmc.c
index 2235fd5..64eda92 100644
--- a/Xext/xvmc.c
+++ b/Xext/xvmc.c
@@ -61,7 +61,7 @@ typedef struct {
     (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey))
 
 static int
-XvMCDestroyContextRes(pointer data, XID id)
+XvMCDestroyContextRes(void *data, XID id)
 {
     XvMCContextPtr pContext = (XvMCContextPtr) data;
 
@@ -78,7 +78,7 @@ XvMCDestroyContextRes(pointer data, XID id)
 }
 
 static int
-XvMCDestroySurfaceRes(pointer data, XID id)
+XvMCDestroySurfaceRes(void *data, XID id)
 {
     XvMCSurfacePtr pSurface = (XvMCSurfacePtr) data;
     XvMCContextPtr pContext = pSurface->context;
@@ -87,13 +87,13 @@ XvMCDestroySurfaceRes(pointer data, XID id)
     (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface) (pSurface);
     free(pSurface);
 
-    XvMCDestroyContextRes((pointer) pContext, pContext->context_id);
+    XvMCDestroyContextRes((void *) pContext, pContext->context_id);
 
     return Success;
 }
 
 static int
-XvMCDestroySubpictureRes(pointer data, XID id)
+XvMCDestroySubpictureRes(void *data, XID id)
 {
     XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr) data;
     XvMCContextPtr pContext = pSubpict->context;
@@ -102,7 +102,7 @@ XvMCDestroySubpictureRes(pointer data, XID id)
     (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture) (pSubpict);
     free(pSubpict);
 
-    XvMCDestroyContextRes((pointer) pContext, pContext->context_id);
+    XvMCDestroyContextRes((void *) pContext, pContext->context_id);
 
     return Success;
 }
@@ -276,7 +276,7 @@ ProcXvMCCreateContext(ClientPtr client)
 static int
 ProcXvMCDestroyContext(ClientPtr client)
 {
-    pointer val;
+    void *val;
     int rc;
 
     REQUEST(xvmcDestroyContextReq);
@@ -306,7 +306,7 @@ ProcXvMCCreateSurface(ClientPtr client)
     REQUEST(xvmcCreateSurfaceReq);
     REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
 
-    result = dixLookupResourceByType((pointer *) &pContext, stuff->context_id,
+    result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
                                      XvMCRTContext, client, DixUseAccess);
     if (result != Success)
         return result;
@@ -350,7 +350,7 @@ ProcXvMCCreateSurface(ClientPtr client)
 static int
 ProcXvMCDestroySurface(ClientPtr client)
 {
-    pointer val;
+    void *val;
     int rc;
 
     REQUEST(xvmcDestroySurfaceReq);
@@ -382,7 +382,7 @@ ProcXvMCCreateSubpicture(ClientPtr client)
     REQUEST(xvmcCreateSubpictureReq);
     REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
 
-    result = dixLookupResourceByType((pointer *) &pContext, stuff->context_id,
+    result = dixLookupResourceByType((void **) &pContext, stuff->context_id,
                                      XvMCRTContext, client, DixUseAccess);
     if (result != Success)
         return result;
@@ -474,7 +474,7 @@ ProcXvMCCreateSubpicture(ClientPtr client)
 static int
 ProcXvMCDestroySubpicture(ClientPtr client)
 {
-    pointer val;
+    void *val;
     int rc;
 
     REQUEST(xvmcDestroySubpictureReq);
diff --git a/Xext/xvmcext.h b/Xext/xvmcext.h
index 832e443..e8a6dae 100644
--- a/Xext/xvmcext.h
+++ b/Xext/xvmcext.h
@@ -31,15 +31,15 @@ typedef struct {
     unsigned short height;
     CARD32 flags;
     int refcnt;
-    pointer port_priv;
-    pointer driver_priv;
+    void *port_priv;
+    void *driver_priv;
 } XvMCContextRec, *XvMCContextPtr;
 
 typedef struct {
     XID surface_id;
     int surface_type_id;
     XvMCContextPtr context;
-    pointer driver_priv;
+    void *driver_priv;
 } XvMCSurfaceRec, *XvMCSurfacePtr;
 
 typedef struct {
@@ -51,7 +51,7 @@ typedef struct {
     int entry_bytes;
     char component_order[4];
     XvMCContextPtr context;
-    pointer driver_priv;
+    void *driver_priv;
 } XvMCSubpictureRec, *XvMCSubpicturePtr;
 
 typedef int (*XvMCCreateContextProcPtr) (XvPortPtr port,
diff --git a/Xi/devbell.c b/Xi/devbell.c
index 202c8de..07865d2 100644
--- a/Xi/devbell.c
+++ b/Xi/devbell.c
@@ -91,7 +91,7 @@ ProcXDeviceBell(ClientPtr client)
     int rc, base;
     int newpercent;
     CARD8 class;
-    pointer ctrl;
+    void *ctrl;
     BellProcPtr proc;
 
     REQUEST(xDeviceBellReq);
@@ -117,7 +117,7 @@ ProcXDeviceBell(ClientPtr client)
         }
         base = k->ctrl.bell;
         proc = k->BellProc;
-        ctrl = (pointer) &(k->ctrl);
+        ctrl = (void *) &(k->ctrl);
         class = KbdFeedbackClass;
     }
     else if (stuff->feedbackclass == BellFeedbackClass) {
@@ -130,7 +130,7 @@ ProcXDeviceBell(ClientPtr client)
         }
         base = b->ctrl.percent;
         proc = b->BellProc;
-        ctrl = (pointer) &(b->ctrl);
+        ctrl = (void *) &(b->ctrl);
         class = BellFeedbackClass;
     }
     else {
diff --git a/Xi/exevents.c b/Xi/exevents.c
index dff0a92..9d8416b 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1302,7 +1302,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
         *mask = (*grab)->xi2mask;
     }
     else {
-        rc = dixLookupResourceByType((pointer *) win, listener->listener,
+        rc = dixLookupResourceByType((void **) win, listener->listener,
                                      listener->resource_type,
                                      serverClient, DixSendAccess);
         if (rc != Success)
@@ -1735,7 +1735,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
 
         eventinfo.device = device;
         eventinfo.event = ev;
-        CallCallbacks(&DeviceEventCallback, (pointer) &eventinfo);
+        CallCallbacks(&DeviceEventCallback, (void *) &eventinfo);
     }
 
     grab = device->deviceGrab.grab;
@@ -2204,7 +2204,7 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
     if (param->cursor == None)
         cursor = NullCursor;
     else {
-        rc = dixLookupResourceByType((pointer *) &cursor, param->cursor,
+        rc = dixLookupResourceByType((void **) &cursor, param->cursor,
                                      RT_CURSOR, client, DixUseAccess);
         if (rc != Success) {
             client->errorValue = param->cursor;
@@ -2303,7 +2303,7 @@ GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
     if (param->cursor == None)
         cursor = NullCursor;
     else {
-        rc = dixLookupResourceByType((pointer *) &cursor, param->cursor,
+        rc = dixLookupResourceByType((void **) &cursor, param->cursor,
                                      RT_CURSOR, client, DixUseAccess);
         if (rc != Success) {
             client->errorValue = param->cursor;
@@ -2446,7 +2446,7 @@ AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx)
     others->resource = FakeClientID(client->index);
     others->next = pWin->optional->inputMasks->inputClients;
     pWin->optional->inputMasks->inputClients = others;
-    if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin))
+    if (!AddResource(others->resource, RT_INPUTCLIENT, (void *) pWin))
         goto bail;
     return Success;
 
@@ -2548,7 +2548,7 @@ InputClientGone(WindowPtr pWin, XID id)
                 else {
                     other->resource = FakeClientID(0);
                     if (!AddResource(other->resource, RT_INPUTCLIENT,
-                                     (pointer) pWin))
+                                     (void *) pWin))
                         return BadAlloc;
                 }
             }
diff --git a/Xi/extinit.c b/Xi/extinit.c
index c13bc47..9ebd733 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -381,7 +381,7 @@ DevPrivateKeyRec XIClientPrivateKeyRec;
  */
 
 static void
-XIClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+XIClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 6732ce9..a8b92cc 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -695,7 +695,7 @@ BarrierFreeBarrier(void *data, XID id)
     return Success;
 }
 
-static void add_master_func(pointer res, XID id, pointer devid)
+static void add_master_func(void *res, XID id, void *devid)
 {
     struct PointerBarrier *b;
     struct PointerBarrierClient *barrier;
@@ -712,7 +712,7 @@ static void add_master_func(pointer res, XID id, pointer devid)
     xorg_list_add(&pbd->entry, &barrier->per_device);
 }
 
-static void remove_master_func(pointer res, XID id, pointer devid)
+static void remove_master_func(void *res, XID id, void *devid)
 {
     struct PointerBarrierDevice *pbd;
     struct PointerBarrierClient *barrier;
diff --git a/Xi/xichangecursor.c b/Xi/xichangecursor.c
index 0be6bc0..7a1bb7a 100644
--- a/Xi/xichangecursor.c
+++ b/Xi/xichangecursor.c
@@ -96,7 +96,7 @@ ProcXIChangeCursor(ClientPtr client)
             pCursor = (CursorPtr) None;
     }
     else {
-        rc = dixLookupResourceByType((pointer *) &pCursor, stuff->cursor,
+        rc = dixLookupResourceByType((void **) &pCursor, stuff->cursor,
                                      RT_CURSOR, client, DixUseAccess);
         if (rc != Success)
             return rc;
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 796ba09..463607d 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -723,10 +723,10 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
         total_len = prop_value->size + len;
 
     if (mode == PropModeReplace || len > 0) {
-        pointer new_data = NULL, old_data = NULL;
+        void *new_data = NULL, *old_data = NULL;
 
         total_size = total_len * size_in_bytes;
-        new_value.data = (pointer) malloc(total_size);
+        new_value.data = (void *) malloc(total_size);
         if (!new_value.data && total_size) {
             if (add)
                 XIDestroyDeviceProperty(prop);
@@ -742,13 +742,13 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
             old_data = NULL;
             break;
         case PropModeAppend:
-            new_data = (pointer) (((char *) new_value.data) +
+            new_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             old_data = new_value.data;
             break;
         case PropModePrepend:
             new_data = new_value.data;
-            old_data = (pointer) (((char *) new_value.data) +
+            old_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             break;
         }
diff --git a/composite/compalloc.c b/composite/compalloc.c
index b7d731e..dfbff06 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -55,7 +55,7 @@ compScreenUpdate(ScreenPtr pScreen)
 }
 
 static void
-compBlockHandler(ScreenPtr pScreen, pointer pTimeout, pointer pReadmask)
+compBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
 {
     CompScreenPtr cs = GetCompScreen(pScreen);
 
diff --git a/composite/compext.c b/composite/compext.c
index e253f3c..a945f72 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -67,7 +67,7 @@ typedef struct _CompositeClient {
     dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
 
 static void
-CompositeClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+CompositeClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
@@ -78,7 +78,7 @@ CompositeClientCallback(CallbackListPtr *list, pointer closure, pointer data)
 }
 
 static int
-FreeCompositeClientWindow(pointer value, XID ccwid)
+FreeCompositeClientWindow(void *value, XID ccwid)
 {
     WindowPtr pWin = value;
 
@@ -87,7 +87,7 @@ FreeCompositeClientWindow(pointer value, XID ccwid)
 }
 
 static int
-FreeCompositeClientSubwindows(pointer value, XID ccwid)
+FreeCompositeClientSubwindows(void *value, XID ccwid)
 {
     WindowPtr pWin = value;
 
@@ -96,7 +96,7 @@ FreeCompositeClientSubwindows(pointer value, XID ccwid)
 }
 
 static int
-FreeCompositeClientOverlay(pointer value, XID ccwid)
+FreeCompositeClientOverlay(void *value, XID ccwid)
 {
     CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
 
@@ -140,7 +140,7 @@ ProcCompositeQueryVersion(ClientPtr client)
 #define VERIFY_WINDOW(pWindow, wid, client, mode)			\
     do {								\
 	int err;							\
-	err = dixLookupResourceByType((pointer *) &pWindow, wid,	\
+	err = dixLookupResourceByType((void **) &pWindow, wid,	\
 				      RT_WINDOW, client, mode);		\
 	if (err != Success) {						\
 	    client->errorValue = wid;					\
@@ -227,7 +227,7 @@ ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
         return BadAlloc;
     RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
 
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -267,7 +267,7 @@ ProcCompositeNameWindowPixmap(ClientPtr client)
 
     ++pPixmap->refcnt;
 
-    if (!AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
+    if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
         return BadAlloc;
 
     return Success;
@@ -500,7 +500,7 @@ SProcCompositeDispatch(ClientPtr client)
 
 /** @see GetDefaultBytes */
 static void
-GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size)
+GetCompositeClientWindowBytes(void *value, XID id, ResourceSizePtr size)
 {
     WindowPtr window = value;
 
@@ -754,13 +754,13 @@ PanoramiXCompositeNameWindowPixmap(ClientPtr client)
             return BadMatch;
         }
 
-        if (!AddResource(newPix->info[i].id, RT_PIXMAP, (pointer) pPixmap))
+        if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap))
             return BadAlloc;
 
         ++pPixmap->refcnt;
     }
 
-    if (!AddResource(stuff->pixmap, XRT_PIXMAP, (pointer) newPix))
+    if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix))
         return BadAlloc;
 
     return Success;
@@ -797,7 +797,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client)
     }
 
     FOR_NSCREENS_BACKWARD(i) {
-        rc = dixLookupResourceByType((pointer *) &pWin, win->info[i].id,
+        rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
                                      RT_WINDOW, client, DixGetAttrAccess);
         if (rc != Success) {
             client->errorValue = stuff->window;
diff --git a/composite/compinit.c b/composite/compinit.c
index 3c91091..1db9e0b 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -119,7 +119,7 @@ compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
         pScreen->backingStoreSupport != NotUseful) {
         if (pWin->backingStore != NotUseful && !pWin->backStorage) {
             compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
-            pWin->backStorage = (pointer) (intptr_t) 1;
+            pWin->backStorage = (void *) (intptr_t) 1;
         }
         else if (pWin->backingStore == NotUseful && pWin->backStorage) {
             compUnredirectWindow(serverClient, pWin,
diff --git a/composite/compint.h b/composite/compint.h
index 45b5824..12dc8b3 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -319,7 +319,7 @@ WindowPtr
  CompositeRealChildHead(WindowPtr pWin);
 
 int
- DeleteWindowNoInputDevices(pointer value, XID wid);
+ DeleteWindowNoInputDevices(void *value, XID wid);
 
 int
 
diff --git a/composite/compoverlay.c b/composite/compoverlay.c
index bf5434c..7932dda 100644
--- a/composite/compoverlay.c
+++ b/composite/compoverlay.c
@@ -114,7 +114,7 @@ compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
      * Create a resource for this element so it can be deleted
      * when the client goes away.
      */
-    if (!AddResource(pOc->resource, CompositeClientOverlayType, (pointer) pOc))
+    if (!AddResource(pOc->resource, CompositeClientOverlayType, (void *) pOc))
         return NULL;
 
     return pOc;
@@ -152,7 +152,7 @@ compCreateOverlayWindow(ScreenPtr pScreen)
     if (pWin == NULL)
         return FALSE;
 
-    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer) pWin))
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
         return FALSE;
 
     MapWindow(pWin, serverClient);
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 0be7a1b..8dce21d 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -53,7 +53,7 @@
 
 #ifdef COMPOSITE_DEBUG
 static int
-compCheckWindow(WindowPtr pWin, pointer data)
+compCheckWindow(WindowPtr pWin, void *data)
 {
     ScreenPtr pScreen = pWin->drawable.pScreen;
     PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
@@ -92,7 +92,7 @@ typedef struct _compPixmapVisit {
 } CompPixmapVisitRec, *CompPixmapVisitPtr;
 
 static Bool
-compRepaintBorder(ClientPtr pClient, pointer closure)
+compRepaintBorder(ClientPtr pClient, void *closure)
 {
     WindowPtr pWindow;
     int rc =
@@ -111,7 +111,7 @@ compRepaintBorder(ClientPtr pClient, pointer closure)
 }
 
 static int
-compSetPixmapVisitWindow(WindowPtr pWindow, pointer data)
+compSetPixmapVisitWindow(WindowPtr pWindow, void *data)
 {
     CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
     ScreenPtr pScreen = pWindow->drawable.pScreen;
@@ -128,7 +128,7 @@ compSetPixmapVisitWindow(WindowPtr pWindow, pointer data)
     SetBorderSize(pWindow);
     if (HasBorder(pWindow))
         QueueWorkProc(compRepaintBorder, serverClient,
-                      (pointer) (intptr_t) pWindow->drawable.id);
+                      (void *) (intptr_t) pWindow->drawable.id);
     return WT_WALKCHILDREN;
 }
 
@@ -139,7 +139,7 @@ compSetPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
 
     visitRec.pWindow = pWindow;
     visitRec.pPixmap = pPixmap;
-    TraverseTree(pWindow, compSetPixmapVisitWindow, (pointer) &visitRec);
+    TraverseTree(pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
     compCheckTree(pWindow->drawable.pScreen);
 }
 
diff --git a/config/dbus-core.c b/config/dbus-core.c
index 3242587..768a984 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -45,10 +45,10 @@ struct dbus_core_info {
 };
 static struct dbus_core_info bus_info;
 
-static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg);
+static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg);
 
 static void
-wakeup_handler(pointer data, int err, pointer read_mask)
+wakeup_handler(void *data, int err, void *read_mask)
 {
     struct dbus_core_info *info = data;
 
@@ -63,7 +63,7 @@ wakeup_handler(pointer data, int err, pointer read_mask)
 }
 
 static void
-block_handler(pointer data, struct timeval **tv, pointer read_mask)
+block_handler(void *data, struct timeval **tv, void *read_mask)
 {
 }
 
@@ -185,7 +185,7 @@ connect_to_bus(void)
 }
 
 static CARD32
-reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg)
+reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg)
 {
     if (connect_to_bus()) {
         TimerFree(bus_info.timer);
diff --git a/config/udev.c b/config/udev.c
index 23a53f4..436b8f0 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -291,7 +291,7 @@ device_removed(struct udev_device *device)
 }
 
 static void
-wakeup_handler(pointer data, int err, pointer read_mask)
+wakeup_handler(void *data, int err, void *read_mask)
 {
     int udev_fd = udev_monitor_get_fd(udev_monitor);
     struct udev_device *udev_device;
@@ -324,7 +324,7 @@ wakeup_handler(pointer data, int err, pointer read_mask)
 }
 
 static void
-block_handler(pointer data, struct timeval **tv, pointer read_mask)
+block_handler(void *data, struct timeval **tv, void *read_mask)
 {
 }
 
diff --git a/damageext/damageext.c b/damageext/damageext.c
index 5650953..886f56d 100644
--- a/damageext/damageext.c
+++ b/damageext/damageext.c
@@ -245,7 +245,7 @@ DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level,
         return NULL;
     }
 
-    if (!AddResource(id, DamageExtType, (pointer) pDamageExt))
+    if (!AddResource(id, DamageExtType, (void *) pDamageExt))
         return NULL;
 
     DamageExtRegister(pDrawable, pDamageExt->pDamage,
@@ -569,7 +569,7 @@ SProcDamageDispatch(ClientPtr client)
 }
 
 static void
-DamageClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+DamageClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
@@ -587,7 +587,7 @@ DamageResetProc(ExtensionEntry * extEntry)
 }
 
 static int
-FreeDamageExt(pointer value, XID did)
+FreeDamageExt(void *value, XID did)
 {
     DamageExtPtr pDamageExt = (DamageExtPtr) value;
 
diff --git a/damageext/damageextint.h b/damageext/damageextint.h
index e501495..7a7096d 100644
--- a/damageext/damageextint.h
+++ b/damageext/damageextint.h
@@ -58,7 +58,7 @@ typedef struct _DamageExt {
 } DamageExtRec, *DamageExtPtr;
 
 #define VERIFY_DAMAGEEXT(pDamageExt, rid, client, mode) { \
-    int rc = dixLookupResourceByType((pointer *)&(pDamageExt), rid, \
+    int rc = dixLookupResourceByType((void **)&(pDamageExt), rid, \
                                      DamageExtType, client, mode); \
     if (rc != Success) \
         return rc; \
diff --git a/dbe/dbe.c b/dbe/dbe.c
index 5524615..8896720 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -322,7 +322,7 @@ ProcDbeAllocateBackBufferName(ClientPtr client)
     if (status == Success) {
         pDbeWindowPriv->IDs[add_index] = stuff->buffer;
         if (!AddResource(stuff->buffer, dbeWindowPrivResType,
-                         (pointer) pDbeWindowPriv)) {
+                         (void *) pDbeWindowPriv)) {
             pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
 
             if (pDbeWindowPriv->nBufferIDs == 0) {
@@ -378,12 +378,12 @@ ProcDbeDeallocateBackBufferName(ClientPtr client)
     REQUEST(xDbeDeallocateBackBufferNameReq);
     DbeWindowPrivPtr pDbeWindowPriv;
     int rc, i;
-    pointer val;
+    void *val;
 
     REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
 
     /* Buffer name must be valid */
-    rc = dixLookupResourceByType((pointer *) &pDbeWindowPriv, stuff->buffer,
+    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
                                  dbeWindowPrivResType, client,
                                  DixDestroyAccess);
     if (rc != Success)
@@ -726,7 +726,7 @@ ProcDbeGetBackBufferAttributes(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
 
-    rc = dixLookupResourceByType((pointer *) &pDbeWindowPriv, stuff->buffer,
+    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
                                  dbeWindowPrivResType, client,
                                  DixGetAttrAccess);
     if (rc == Success) {
@@ -1125,7 +1125,7 @@ DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
  *
  *****************************************************************************/
 static int
-DbeDrawableDelete(pointer pDrawable, XID id)
+DbeDrawableDelete(void *pDrawable, XID id)
 {
     return Success;
 
@@ -1143,7 +1143,7 @@ DbeDrawableDelete(pointer pDrawable, XID id)
  *
  *****************************************************************************/
 static int
-DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
+DbeWindowPrivDelete(void *pDbeWinPriv, XID id)
 {
     DbeScreenPrivPtr pDbeScreenPriv;
     DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr) pDbeWinPriv;
diff --git a/dbe/midbe.c b/dbe/midbe.c
index 3663fdd..0479ecc 100644
--- a/dbe/midbe.c
+++ b/dbe/midbe.c
@@ -202,7 +202,7 @@ miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
 
         /* Associate the new ID with an existing pixmap. */
         if (!AddResource(bufId, dbeDrawableResType,
-                         (pointer) pDbeWindowPriv->pBackBuffer)) {
+                         (void *) pDbeWindowPriv->pBackBuffer)) {
             return BadAlloc;
         }
 
@@ -230,7 +230,7 @@ miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
 
     for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
         ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
-                            (pointer) pDbeWindowPriv->pBackBuffer);
+                            (void *) pDbeWindowPriv->pBackBuffer);
     }
 
 }                               /* miDbeAliasBuffers() */
diff --git a/dix/colormap.c b/dix/colormap.c
index 39fddc9..c1ff88e 100644
--- a/dix/colormap.c
+++ b/dix/colormap.c
@@ -367,7 +367,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
     }
     pmap->flags |= BeingCreated;
 
-    if (!AddResource(mid, RT_COLORMAP, (pointer) pmap))
+    if (!AddResource(mid, RT_COLORMAP, (void *) pmap))
         return BadAlloc;
 
     /*  
@@ -397,7 +397,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
  * \param value  must conform to DeleteType
  */
 int
-FreeColormap(pointer value, XID mid)
+FreeColormap(void *value, XID mid)
 {
     int i;
     EntryPtr pent;
@@ -405,7 +405,7 @@ FreeColormap(pointer value, XID mid)
 
     if (CLIENT_ID(mid) != SERVER_ID) {
         (*pmap->pScreen->UninstallColormap) (pmap);
-        WalkTree(pmap->pScreen, (VisitWindowProcPtr) TellNoMap, (pointer) &mid);
+        WalkTree(pmap->pScreen, (VisitWindowProcPtr) TellNoMap, (void *) &mid);
     }
 
     /* This is the device's chance to undo anything it needs to, especially
@@ -474,7 +474,7 @@ TellNoMap(WindowPtr pwin, Colormap * pmid)
 
 /* Tell window that pmid got uninstalled */
 int
-TellLostMap(WindowPtr pwin, pointer value)
+TellLostMap(WindowPtr pwin, void *value)
 {
     Colormap *pmid = (Colormap *) value;
 
@@ -499,7 +499,7 @@ TellLostMap(WindowPtr pwin, pointer value)
 
 /* Tell window that pmid got installed */
 int
-TellGainedMap(WindowPtr pwin, pointer value)
+TellGainedMap(WindowPtr pwin, void *value)
 {
     Colormap *pmid = (Colormap *) value;
 
@@ -845,7 +845,7 @@ AllocColor(ColormapPtr pmap,
             pmap->pVisual->vid == pmap->pScreen->rootVisual) {
             ColormapPtr prootmap;
 
-            dixLookupResourceByType((pointer *) &prootmap,
+            dixLookupResourceByType((void **) &prootmap,
                                     pmap->pScreen->defColormap, RT_COLORMAP,
                                     clients[client], DixReadAccess);
 
@@ -863,7 +863,7 @@ AllocColor(ColormapPtr pmap,
             pmap->pVisual->vid == pmap->pScreen->rootVisual) {
             ColormapPtr prootmap;
 
-            dixLookupResourceByType((pointer *) &prootmap,
+            dixLookupResourceByType((void **) &prootmap,
                                     pmap->pScreen->defColormap, RT_COLORMAP,
                                     clients[client], DixReadAccess);
 
@@ -917,7 +917,7 @@ AllocColor(ColormapPtr pmap,
         }
         pcr->mid = pmap->mid;
         pcr->client = client;
-        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer) pcr))
+        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr))
             return BadAlloc;
     }
     return Success;
@@ -1463,9 +1463,9 @@ FreePixels(ColormapPtr pmap, int client)
  *  \unused fakeid
  */
 int
-FreeClientPixels(pointer value, XID fakeid)
+FreeClientPixels(void *value, XID fakeid)
 {
-    pointer pmap;
+    void *pmap;
     colorResource *pcr = value;
     int rc;
 
@@ -1532,7 +1532,7 @@ AllocColorCells(int client, ColormapPtr pmap, int colors, int planes,
     if ((ok == Success) && pcr) {
         pcr->mid = pmap->mid;
         pcr->client = client;
-        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer) pcr))
+        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr))
             ok = BadAlloc;
     }
     else
@@ -1614,7 +1614,7 @@ AllocColorPlanes(int client, ColormapPtr pmap, int colors,
     if ((ok == Success) && pcr) {
         pcr->mid = pmap->mid;
         pcr->client = client;
-        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer) pcr))
+        if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *) pcr))
             ok = BadAlloc;
     }
     else
@@ -2492,7 +2492,7 @@ struct colormap_lookup_data {
 };
 
 static void
-_colormap_find_resource(pointer value, XID id, pointer cdata)
+_colormap_find_resource(void *value, XID id, void *cdata)
 {
     struct colormap_lookup_data *cmap_data = cdata;
     VisualPtr visuals = cmap_data->visuals;
diff --git a/dix/cursor.c b/dix/cursor.c
index 8cc54bd..56c5606 100644
--- a/dix/cursor.c
+++ b/dix/cursor.c
@@ -104,7 +104,7 @@ FreeCursorBits(CursorBitsPtr bits)
  *  \param value must conform to DeleteType
  */
 int
-FreeCursor(pointer value, XID cid)
+FreeCursor(void *value, XID cid)
 {
     int nscr;
     CursorPtr pCurs = (CursorPtr) value;
@@ -319,13 +319,13 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
     CursorPtr pCurs;
     GlyphSharePtr pShare;
 
-    rc = dixLookupResourceByType((pointer *) &sourcefont, source, RT_FONT,
+    rc = dixLookupResourceByType((void **) &sourcefont, source, RT_FONT,
                                  client, DixUseAccess);
     if (rc != Success) {
         client->errorValue = source;
         return rc;
     }
-    rc = dixLookupResourceByType((pointer *) &maskfont, mask, RT_FONT, client,
+    rc = dixLookupResourceByType((void **) &maskfont, mask, RT_FONT, client,
                                  DixUseAccess);
     if (rc != Success && mask != None) {
         client->errorValue = mask;
@@ -486,7 +486,7 @@ CreateRootCursor(char *unused1, unsigned int unused2)
     if (err != Success)
         return NullCursor;
 
-    err = dixLookupResourceByType((pointer *) &cursorfont, fontID, RT_FONT,
+    err = dixLookupResourceByType((void **) &cursorfont, fontID, RT_FONT,
                                   serverClient, DixReadAccess);
     if (err != Success)
         return NullCursor;
@@ -494,7 +494,7 @@ CreateRootCursor(char *unused1, unsigned int unused2)
                          &curs, serverClient, (XID) 0) != Success)
         return NullCursor;
 
-    if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer) curs))
+    if (!AddResource(FakeClientID(0), RT_CURSOR, (void *) curs))
         return NullCursor;
 
     return curs;
diff --git a/dix/devices.c b/dix/devices.c
index 3aecd1b..45de713 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -386,7 +386,7 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
         }
         else {
             if (dev->coreEvents)
-                other = (IsPointerDevice(dev)) ? inputInfo.pointer :
+                other = (IsPointerDevice(dev)) ? inputInfo.pointer:
                     inputInfo.keyboard;
             else
                 other = NULL;   /* auto-float non-core devices */
@@ -586,7 +586,7 @@ ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
  * The actual task of ringing the bell is the job of the DDX.
  */
 static void
-CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+CoreKeyboardBell(int volume, DeviceIntPtr pDev, void *arg, int something)
 {
     KeybdCtrl *ctrl = arg;
 
@@ -750,7 +750,7 @@ InitAndStartDevices(void)
  * Free the given device class and reset the pointer to NULL.
  */
 static void
-FreeDeviceClass(int type, pointer *class)
+FreeDeviceClass(int type, void **class)
 {
     if (!(*class))
         return;
@@ -818,7 +818,7 @@ FreeDeviceClass(int type, pointer *class)
 }
 
 static void
-FreeFeedbackClass(int type, pointer *class)
+FreeFeedbackClass(int type, void **class)
 {
     if (!(*class))
         return;
@@ -906,19 +906,19 @@ FreeAllDeviceClasses(ClassesPtr classes)
     if (!classes)
         return;
 
-    FreeDeviceClass(KeyClass, (pointer) &classes->key);
-    FreeDeviceClass(ValuatorClass, (pointer) &classes->valuator);
-    FreeDeviceClass(XITouchClass, (pointer) &classes->touch);
-    FreeDeviceClass(ButtonClass, (pointer) &classes->button);
-    FreeDeviceClass(FocusClass, (pointer) &classes->focus);
-    FreeDeviceClass(ProximityClass, (pointer) &classes->proximity);
-
-    FreeFeedbackClass(KbdFeedbackClass, (pointer) &classes->kbdfeed);
-    FreeFeedbackClass(PtrFeedbackClass, (pointer) &classes->ptrfeed);
-    FreeFeedbackClass(IntegerFeedbackClass, (pointer) &classes->intfeed);
-    FreeFeedbackClass(StringFeedbackClass, (pointer) &classes->stringfeed);
-    FreeFeedbackClass(BellFeedbackClass, (pointer) &classes->bell);
-    FreeFeedbackClass(LedFeedbackClass, (pointer) &classes->leds);
+    FreeDeviceClass(KeyClass, (void *) &classes->key);
+    FreeDeviceClass(ValuatorClass, (void *) &classes->valuator);
+    FreeDeviceClass(XITouchClass, (void *) &classes->touch);
+    FreeDeviceClass(ButtonClass, (void *) &classes->button);
+    FreeDeviceClass(FocusClass, (void *) &classes->focus);
+    FreeDeviceClass(ProximityClass, (void *) &classes->proximity);
+
+    FreeFeedbackClass(KbdFeedbackClass, (void *) &classes->kbdfeed);
+    FreeFeedbackClass(PtrFeedbackClass, (void *) &classes->ptrfeed);
+    FreeFeedbackClass(IntegerFeedbackClass, (void *) &classes->intfeed);
+    FreeFeedbackClass(StringFeedbackClass, (void *) &classes->stringfeed);
+    FreeFeedbackClass(BellFeedbackClass, (void *) &classes->bell);
+    FreeFeedbackClass(LedFeedbackClass, (void *) &classes->leds);
 
 }
 
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 64f8ef9..e28270c 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -652,7 +652,7 @@ ProcCreateWindow(ClientPtr client)
         Mask mask = pWin->eventMask;
 
         pWin->eventMask = 0;    /* subterfuge in case AddResource fails */
-        if (!AddResource(stuff->wid, RT_WINDOW, (pointer) pWin))
+        if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin))
             return BadAlloc;
         pWin->eventMask = mask;
     }
@@ -1069,7 +1069,7 @@ ProcGrabServer(ClientPtr client)
 
         grabinfo.client = client;
         grabinfo.grabstate = SERVER_GRABBED;
-        CallCallbacks(&ServerGrabCallback, (pointer) &grabinfo);
+        CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
     }
 
     return Success;
@@ -1096,7 +1096,7 @@ UngrabServer(ClientPtr client)
 
         grabinfo.client = client;
         grabinfo.grabstate = SERVER_UNGRABBED;
-        CallCallbacks(&ServerGrabCallback, (pointer) &grabinfo);
+        CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
     }
 }
 
@@ -1208,7 +1208,7 @@ ProcCloseFont(ClientPtr client)
     REQUEST(xResourceReq);
 
     REQUEST_SIZE_MATCH(xResourceReq);
-    rc = dixLookupResourceByType((pointer *) &pFont, stuff->id, RT_FONT,
+    rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT,
                                  client, DixDestroyAccess);
     if (rc == Success) {
         FreeResource(stuff->id, RT_NONE);
@@ -1335,7 +1335,7 @@ ProcListFontsWithInfo(ClientPtr client)
  *  \param value must conform to DeleteType
  */
 int
-dixDestroyPixmap(pointer value, XID pid)
+dixDestroyPixmap(void *value, XID pid)
 {
     PixmapPtr pPixmap = (PixmapPtr) value;
 
@@ -1402,7 +1402,7 @@ ProcCreatePixmap(ClientPtr client)
             (*pDraw->pScreen->DestroyPixmap) (pMap);
             return rc;
         }
-        if (AddResource(stuff->pid, RT_PIXMAP, (pointer) pMap))
+        if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap))
             return Success;
     }
     return BadAlloc;
@@ -1417,7 +1417,7 @@ ProcFreePixmap(ClientPtr client)
     REQUEST(xResourceReq);
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pMap, stuff->id, RT_PIXMAP,
+    rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP,
                                  client, DixDestroyAccess);
     if (rc == Success) {
         FreeResource(stuff->id, RT_NONE);
@@ -1454,7 +1454,7 @@ ProcCreateGC(ClientPtr client)
                           stuff->gc, client);
     if (error != Success)
         return error;
-    if (!AddResource(stuff->gc, RT_GC, (pointer) pGC))
+    if (!AddResource(stuff->gc, RT_GC, (void *) pGC))
         return BadAlloc;
     return Success;
 }
@@ -2121,7 +2121,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
                                          y + linesDone,
                                          width,
                                          nlines,
-                                         format, planemask, (pointer) pBuf);
+                                         format, planemask, (void *) pBuf);
             if (pVisibleRegion)
                 XaceCensorImage(client, pVisibleRegion, widthBytesLine,
                                 pDraw, x, y + linesDone, width,
@@ -2148,7 +2148,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
                                                  y + linesDone,
                                                  width,
                                                  nlines,
-                                                 format, plane, (pointer) pBuf);
+                                                 format, plane, (void *) pBuf);
                     if (pVisibleRegion)
                         XaceCensorImage(client, pVisibleRegion,
                                         widthBytesLine,
@@ -2308,7 +2308,7 @@ ProcFreeColormap(ClientPtr client)
     REQUEST(xResourceReq);
 
     REQUEST_SIZE_MATCH(xResourceReq);
-    rc = dixLookupResourceByType((pointer *) &pmap, stuff->id, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP,
                                  client, DixDestroyAccess);
     if (rc == Success) {
         /* Freeing a default colormap is a no-op */
@@ -2334,7 +2334,7 @@ ProcCopyColormapAndFree(ClientPtr client)
     REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
     mid = stuff->mid;
     LEGAL_NEW_RESOURCE(mid, client);
-    rc = dixLookupResourceByType((pointer *) &pSrcMap, stuff->srcCmap,
+    rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap,
                                  RT_COLORMAP, client,
                                  DixReadAccess | DixRemoveAccess);
     if (rc == Success)
@@ -2352,7 +2352,7 @@ ProcInstallColormap(ClientPtr client)
     REQUEST(xResourceReq);
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
                                  client, DixInstallAccess);
     if (rc != Success)
         goto out;
@@ -2381,7 +2381,7 @@ ProcUninstallColormap(ClientPtr client)
     REQUEST(xResourceReq);
     REQUEST_SIZE_MATCH(xResourceReq);
 
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
                                  client, DixUninstallAccess);
     if (rc != Success)
         goto out;
@@ -2449,7 +2449,7 @@ ProcAllocColor(ClientPtr client)
     REQUEST(xAllocColorReq);
 
     REQUEST_SIZE_MATCH(xAllocColorReq);
-    rc = dixLookupResourceByType((pointer *) &pmap, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP,
                                  client, DixAddAccess);
     if (rc == Success) {
         xAllocColorReply acr = {
@@ -2486,7 +2486,7 @@ ProcAllocNamedColor(ClientPtr client)
     REQUEST(xAllocNamedColorReq);
 
     REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixAddAccess);
     if (rc == Success) {
         xAllocNamedColorReply ancr = {
@@ -2531,7 +2531,7 @@ ProcAllocColorCells(ClientPtr client)
     REQUEST(xAllocColorCellsReq);
 
     REQUEST_SIZE_MATCH(xAllocColorCellsReq);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixAddAccess);
     if (rc == Success) {
         int npixels, nmasks;
@@ -2592,7 +2592,7 @@ ProcAllocColorPlanes(ClientPtr client)
     REQUEST(xAllocColorPlanesReq);
 
     REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixAddAccess);
     if (rc == Success) {
         xAllocColorPlanesReply acpr;
@@ -2654,7 +2654,7 @@ ProcFreeColors(ClientPtr client)
     REQUEST(xFreeColorsReq);
 
     REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixRemoveAccess);
     if (rc == Success) {
         int count;
@@ -2680,7 +2680,7 @@ ProcStoreColors(ClientPtr client)
     REQUEST(xStoreColorsReq);
 
     REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixWriteAccess);
     if (rc == Success) {
         int count;
@@ -2706,7 +2706,7 @@ ProcStoreNamedColor(ClientPtr client)
     REQUEST(xStoreNamedColorReq);
 
     REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixWriteAccess);
     if (rc == Success) {
         xColorItem def;
@@ -2734,7 +2734,7 @@ ProcQueryColors(ClientPtr client)
     REQUEST(xQueryColorsReq);
 
     REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixReadAccess);
     if (rc == Success) {
         int count;
@@ -2781,7 +2781,7 @@ ProcLookupColor(ClientPtr client)
     REQUEST(xLookupColorReq);
 
     REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
                                  client, DixReadAccess);
     if (rc == Success) {
         CARD16 exactRed, exactGreen, exactBlue;
@@ -2832,7 +2832,7 @@ ProcCreateCursor(ClientPtr client)
     REQUEST_SIZE_MATCH(xCreateCursorReq);
     LEGAL_NEW_RESOURCE(stuff->cid, client);
 
-    rc = dixLookupResourceByType((pointer *) &src, stuff->source, RT_PIXMAP,
+    rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP,
                                  client, DixReadAccess);
     if (rc != Success) {
         client->errorValue = stuff->source;
@@ -2844,7 +2844,7 @@ ProcCreateCursor(ClientPtr client)
 
     /* Find and validate cursor mask pixmap, if one is provided */
     if (stuff->mask != None) {
-        rc = dixLookupResourceByType((pointer *) &msk, stuff->mask, RT_PIXMAP,
+        rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP,
                                      client, DixReadAccess);
         if (rc != Success) {
             client->errorValue = stuff->mask;
@@ -2876,7 +2876,7 @@ ProcCreateCursor(ClientPtr client)
     }
 
     (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height,
-                                        XYPixmap, 1, (pointer) srcbits);
+                                        XYPixmap, 1, (void *) srcbits);
     if (msk == (PixmapPtr) NULL) {
         unsigned char *bits = mskbits;
 
@@ -2888,7 +2888,7 @@ ProcCreateCursor(ClientPtr client)
         memset((char *) mskbits, 0, n);
         (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width,
                                             height, XYPixmap, 1,
-                                            (pointer) mskbits);
+                                            (void *) mskbits);
     }
     cm.width = width;
     cm.height = height;
@@ -2901,7 +2901,7 @@ ProcCreateCursor(ClientPtr client)
 
     if (rc != Success)
         goto bail;
-    if (!AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor)) {
+    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
         rc = BadAlloc;
         goto bail;
     }
@@ -2931,7 +2931,7 @@ ProcCreateGlyphCursor(ClientPtr client)
                            &pCursor, client, stuff->cid);
     if (res != Success)
         return res;
-    if (AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor))
+    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
         return Success;
     return BadAlloc;
 }
@@ -2945,7 +2945,7 @@ ProcFreeCursor(ClientPtr client)
     REQUEST(xResourceReq);
 
     REQUEST_SIZE_MATCH(xResourceReq);
-    rc = dixLookupResourceByType((pointer *) &pCursor, stuff->id, RT_CURSOR,
+    rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR,
                                  client, DixDestroyAccess);
     if (rc == Success) {
         FreeResource(stuff->id, RT_NONE);
@@ -3094,10 +3094,10 @@ ProcChangeHosts(ClientPtr client)
 
     if (stuff->mode == HostInsert)
         return AddHost(client, (int) stuff->hostFamily,
-                       stuff->hostLength, (pointer) &stuff[1]);
+                       stuff->hostLength, (void *) &stuff[1]);
     if (stuff->mode == HostDelete)
         return RemoveHost(client, (int) stuff->hostFamily,
-                          stuff->hostLength, (pointer) &stuff[1]);
+                          stuff->hostLength, (void *) &stuff[1]);
     client->errorValue = stuff->mode;
     return BadValue;
 }
@@ -3108,7 +3108,7 @@ ProcListHosts(ClientPtr client)
     xListHostsReply reply;
     int len, nHosts, result;
     BOOL enabled;
-    pointer pdata;
+    void *pdata;
 
     /* REQUEST(xListHostsReq); */
 
@@ -3349,7 +3349,7 @@ CloseDownClient(ClientPtr client)
                 clientinfo.client = client;
                 clientinfo.prefix = (xConnSetupPrefix *) NULL;
                 clientinfo.setup = (xConnSetup *) NULL;
-                CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
+                CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
             }
         }
         client->clientGone = TRUE;      /* so events aren't sent to client */
@@ -3379,7 +3379,7 @@ CloseDownClient(ClientPtr client)
             clientinfo.client = client;
             clientinfo.prefix = (xConnSetupPrefix *) NULL;
             clientinfo.setup = (xConnSetup *) NULL;
-            CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
+            CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
         }
         TouchListenerGone(client->clientAsMask);
         FreeClientResources(client);
@@ -3414,7 +3414,7 @@ KillAllClients(void)
 }
 
 void
-InitClient(ClientPtr client, int i, pointer ospriv)
+InitClient(ClientPtr client, int i, void *ospriv)
 {
     client->index = i;
     client->clientAsMask = ((Mask) i) << CLIENTOFFSET;
@@ -3436,7 +3436,7 @@ InitClient(ClientPtr client, int i, pointer ospriv)
  *************************/
 
 ClientPtr
-NextAvailableClient(pointer ospriv)
+NextAvailableClient(void *ospriv)
 {
     int i;
     ClientPtr client;
@@ -3476,7 +3476,7 @@ NextAvailableClient(pointer ospriv)
         clientinfo.client = client;
         clientinfo.prefix = (xConnSetupPrefix *) NULL;
         clientinfo.setup = (xConnSetup *) NULL;
-        CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
+        CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
     }
     return client;
 }
@@ -3596,7 +3596,7 @@ SendConnSetup(ClientPtr client, const char *reason)
         clientinfo.client = client;
         clientinfo.prefix = lconnSetupPrefix;
         clientinfo.setup = (xConnSetup *) lConnectionInfo;
-        CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
+        CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
     }
     return Success;
 }
diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 57177ac..341ca3f 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -70,7 +70,7 @@ Equipment Corporation.
 #include "xf86bigfontsrv.h"
 #endif
 
-extern pointer fosNaturalParams;
+extern void *fosNaturalParams;
 extern FontPtr defaultFont;
 
 static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
@@ -139,7 +139,7 @@ SetDefaultFont(const char *defaultfontname)
                    (unsigned) strlen(defaultfontname), defaultfontname);
     if (err != Success)
         return FALSE;
-    err = dixLookupResourceByType((pointer *) &pf, fid, RT_FONT, serverClient,
+    err = dixLookupResourceByType((void **) &pf, fid, RT_FONT, serverClient,
                                   DixReadAccess);
     if (err != Success)
         return FALSE;
@@ -197,7 +197,7 @@ RemoveFontWakeup(FontPathElementPtr fpe)
 }
 
 void
-FontWakeup(pointer data, int count, pointer LastSelectMask)
+FontWakeup(void *data, int count, void *LastSelectMask)
 {
     int i;
     FontPathElementPtr fpe;
@@ -267,7 +267,7 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
     if (client->clientGone) {
         if (c->current_fpe < c->num_fpes) {
             fpe = c->fpe_list[c->current_fpe];
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
         }
         err = Successful;
         goto bail;
@@ -275,7 +275,7 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
     while (c->current_fpe < c->num_fpes) {
         fpe = c->fpe_list[c->current_fpe];
         err = (*fpe_functions[fpe->type].open_font)
-            ((pointer) client, fpe, c->flags,
+            ((void *) client, fpe, c->flags,
              c->fontname, c->fnamelen, FontFormat,
              BitmapFormatMaskByte |
              BitmapFormatMaskBit |
@@ -350,7 +350,7 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
             }
         }
     }
-    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+    if (!AddResource(c->fontid, RT_FONT, (void *) pfont)) {
         err = AllocError;
         goto bail;
     }
@@ -404,7 +404,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
 
         cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
         if (cached && cached->info.cachable) {
-            if (!AddResource(fid, RT_FONT, (pointer) cached))
+            if (!AddResource(fid, RT_FONT, (void *) cached))
                 return BadAlloc;
             cached->refcnt++;
             return Success;
@@ -453,7 +453,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
  *  \param value must conform to DeleteType
  */
 int
-CloseFont(pointer value, XID fid)
+CloseFont(void *value, XID fid)
 {
     int nscr;
     ScreenPtr pscr;
@@ -571,7 +571,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
     if (client->clientGone) {
         if (c->current.current_fpe < c->num_fpes) {
             fpe = c->fpe_list[c->current.current_fpe];
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
         }
         err = Successful;
         goto bail;
@@ -588,7 +588,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
             /* This FPE doesn't support/require list_fonts_and_aliases */
 
             err = (*fpe_functions[fpe->type].list_fonts)
-                ((pointer) c->client, fpe, c->current.pattern,
+                ((void *) c->client, fpe, c->current.pattern,
                  c->current.patlen, c->current.max_names - c->names->nnames,
                  c->names);
 
@@ -615,7 +615,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 
             if (!c->current.list_started) {
                 err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
-                    ((pointer) c->client, fpe, c->current.pattern,
+                    ((void *) c->client, fpe, c->current.pattern,
                      c->current.patlen, c->current.max_names - c->names->nnames,
                      &c->current.private);
                 if (err == Suspended) {
@@ -635,7 +635,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 
                 name = 0;
                 err = (*fpe_functions[fpe->type].list_next_font_or_alias)
-                    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+                    ((void *) c->client, fpe, &name, &namelen, &tmpname,
                      &resolvedlen, c->current.private);
                 if (err == Suspended) {
                     if (!ClientIsAsleep(client))
@@ -687,7 +687,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 
                     tmpname = 0;
                     (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
-                        ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+                        ((void *) c->client, fpe, &tmpname, &tmpnamelen,
                          &tmpname, &tmpnamelen, c->current.private);
                     if (--aliascount <= 0) {
                         err = BadFontName;
@@ -869,7 +869,7 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
     if (client->clientGone) {
         if (c->current.current_fpe < c->num_fpes) {
             fpe = c->fpe_list[c->current.current_fpe];
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
         }
         err = Successful;
         goto bail;
@@ -1118,12 +1118,12 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 
     if (client->clientGone) {
         fpe = c->pGC->font->fpe;
-        (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+        (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
 
         if (ClientIsAsleep(client)) {
             /* Client has died, but we cannot bail out right now.  We
                need to clean up after the work we did when going to
-               sleep.  Setting the drawable pointer to 0 makes this
+               sleep.  Setting the drawable poiner to 0 makes this
                happen without any attempts to render or perform other
                unnecessary activities.  */
             c->pDraw = (DrawablePtr) 0;
@@ -1144,7 +1144,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
                the FPE code to clean up after client and avoid further
                rendering while we clean up after ourself.  */
             fpe = c->pGC->font->fpe;
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
             c->pDraw = (DrawablePtr) 0;
         }
     }
@@ -1165,7 +1165,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
             fid = ((Font) *(c->pElt + 4))       /* big-endian */
                 |((Font) *(c->pElt + 3)) << 8
                 | ((Font) *(c->pElt + 2)) << 16 | ((Font) *(c->pElt + 1)) << 24;
-            err = dixLookupResourceByType((pointer *) &pFont, fid, RT_FONT,
+            err = dixLookupResourceByType((void **) &pFont, fid, RT_FONT,
                                           client, DixUseAccess);
             if (err != Success) {
                 /* restore pFont for step 4 (described below) */
@@ -1399,7 +1399,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
 
     if (client->clientGone) {
         fpe = c->pGC->font->fpe;
-        (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+        (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
         err = Success;
         goto bail;
     }
@@ -1413,7 +1413,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             /* Our drawable has disappeared.  Treat like client died... ask
                the FPE code to clean up after client. */
             fpe = c->pGC->font->fpe;
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
             err = Success;
             goto bail;
         }
@@ -1819,7 +1819,7 @@ DeleteClientFontStuff(ClientPtr client)
     for (i = 0; i < num_fpes; i++) {
         fpe = font_path_elements[i];
         if (fpe_functions[fpe->type].client_died)
-            (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+            (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
     }
 }
 
@@ -1937,7 +1937,7 @@ FreeFonts(void)
 FontPtr
 find_old_font(XID id)
 {
-    pointer pFont;
+    void *pFont;
 
     dixLookupResourceByType(&pFont, id, RT_NONE, serverClient, DixReadAccess);
     return (FontPtr) pFont;
@@ -1954,7 +1954,7 @@ _X_EXPORT
 int
 StoreFontClientFont(FontPtr pfont, Font id)
 {
-    return AddResource(id, RT_NONE, (pointer) pfont);
+    return AddResource(id, RT_NONE, (void *) pfont);
 }
 
 _X_EXPORT
@@ -1985,7 +1985,7 @@ init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
     }
     if (fs_handlers_installed == 0) {
         if (!RegisterBlockAndWakeupHandlers(block_handler,
-                                            FontWakeup, (pointer) 0))
+                                            FontWakeup, (void *) 0))
             return AllocError;
         fs_handlers_installed++;
     }
@@ -2002,7 +2002,7 @@ remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler,
         /* remove the handlers if no one else is using them */
         if (--fs_handlers_installed == 0) {
             RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
-                                         (pointer) 0);
+                                         (void *) 0);
         }
     }
     RemoveFontWakeup(fpe);
diff --git a/dix/dixutils.c b/dix/dixutils.c
index c250bb1..220040f 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -199,7 +199,7 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client,
 
     *pDraw = NULL;
 
-    rc = dixLookupResourceByClass((pointer *) &pTmp, id, RC_DRAWABLE, client,
+    rc = dixLookupResourceByClass((void **) &pTmp, id, RC_DRAWABLE, client,
                                   access);
 
     if (rc != Success)
@@ -236,7 +236,7 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
 int
 dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access)
 {
-    return dixLookupResourceByType((pointer *) pGC, id, RT_GC, client, access);
+    return dixLookupResourceByType((void **) pGC, id, RT_GC, client, access);
 }
 
 int
@@ -246,11 +246,11 @@ dixLookupFontable(FontPtr *pFont, XID id, ClientPtr client, Mask access)
     GC *pGC;
 
     client->errorValue = id;    /* EITHER font or gc */
-    rc = dixLookupResourceByType((pointer *) pFont, id, RT_FONT, client,
+    rc = dixLookupResourceByType((void **) pFont, id, RT_FONT, client,
                                  access);
     if (rc != BadFont)
         return rc;
-    rc = dixLookupResourceByType((pointer *) &pGC, id, RT_GC, client, access);
+    rc = dixLookupResourceByType((void **) &pGC, id, RT_GC, client, access);
     if (rc == BadGC)
         return BadFont;
     if (rc == Success)
@@ -261,7 +261,7 @@ dixLookupFontable(FontPtr *pFont, XID id, ClientPtr client, Mask access)
 int
 dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access)
 {
-    pointer pRes;
+    void *pRes;
     int rc = BadValue, clientIndex = CLIENT_ID(rid);
 
     if (!clientIndex || !clients[clientIndex] || (rid & SERVER_BIT))
@@ -296,7 +296,7 @@ AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
     j = 0;
     if (numnow) {
         pTmp = client->saveSet;
-        while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (pointer) pWin))
+        while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (void *) pWin))
             j++;
     }
     if (mode == SetModeInsert) {
@@ -362,7 +362,7 @@ NoopDDA(void)
 typedef struct _BlockHandler {
     BlockHandlerProcPtr BlockHandler;
     WakeupHandlerProcPtr WakeupHandler;
-    pointer blockData;
+    void *blockData;
     Bool deleted;
 } BlockHandlerRec, *BlockHandlerPtr;
 
@@ -378,7 +378,7 @@ static Bool handlerDeleted;
  *  \param pReadMask  nor how it represents the det of descriptors
  */
 void
-BlockHandler(pointer pTimeout, pointer pReadmask)
+BlockHandler(void *pTimeout, void *pReadmask)
 {
     int i, j;
 
@@ -413,7 +413,7 @@ BlockHandler(pointer pTimeout, pointer pReadmask)
  *  \param pReadmask the resulting descriptor mask
  */
 void
-WakeupHandler(int result, pointer pReadmask)
+WakeupHandler(int result, void *pReadmask)
 {
     int i, j;
 
@@ -449,7 +449,7 @@ WakeupHandler(int result, pointer pReadmask)
 Bool
 RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
                                WakeupHandlerProcPtr wakeupHandler,
-                               pointer blockData)
+                               void *blockData)
 {
     BlockHandlerPtr new;
 
@@ -472,7 +472,7 @@ RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
 void
 RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
                              WakeupHandlerProcPtr wakeupHandler,
-                             pointer blockData)
+                             void *blockData)
 {
     int i;
 
@@ -557,8 +557,8 @@ ProcessWorkQueueZombies(void)
 
 Bool
 QueueWorkProc(Bool (*function)
-              (ClientPtr /* pClient */ , pointer /* closure */ ),
-              ClientPtr client, pointer closure)
+              (ClientPtr /* pClient */ , void */* closure */ ),
+              ClientPtr client, void *closure)
 {
     WorkQueuePtr q;
 
@@ -586,13 +586,13 @@ typedef struct _SleepQueue {
     struct _SleepQueue *next;
     ClientPtr client;
     ClientSleepProcPtr function;
-    pointer closure;
+    void *closure;
 } SleepQueueRec, *SleepQueuePtr;
 
 static SleepQueuePtr sleepQueue = NULL;
 
 Bool
-ClientSleep(ClientPtr client, ClientSleepProcPtr function, pointer closure)
+ClientSleep(ClientPtr client, ClientSleepProcPtr function, void *closure)
 {
     SleepQueuePtr q;
 
@@ -666,7 +666,7 @@ static int numCallbackListsToCleanup = 0;
 static CallbackListPtr **listsToCleanup = NULL;
 
 static Bool
-_AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+_AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
 {
     CallbackPtr cbr;
 
@@ -682,7 +682,7 @@ _AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
 }
 
 static Bool
-_DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+_DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
 {
     CallbackListPtr cbl = *pcbl;
     CallbackPtr cbr, pcbr;
@@ -709,7 +709,7 @@ _DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
 }
 
 void
-_CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
+_CallCallbacks(CallbackListPtr *pcbl, void *call_data)
 {
     CallbackListPtr cbl = *pcbl;
     CallbackPtr cbr, pcbr;
@@ -821,7 +821,7 @@ CreateCallbackList(CallbackListPtr *pcbl)
 /* ===== Public Procedures ===== */
 
 Bool
-AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
 {
     if (!pcbl)
         return FALSE;
@@ -833,7 +833,7 @@ AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
 }
 
 Bool
-DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
+DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void *data)
 {
     if (!pcbl || !*pcbl)
         return FALSE;
diff --git a/dix/events.c b/dix/events.c
index e198112..ddbd4d2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -580,7 +580,7 @@ XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin)
         PanoramiXRes *win;
         int rc, i;
 
-        rc = dixLookupResourceByType((pointer *) &win, pWin->drawable.id,
+        rc = dixLookupResourceByType((void **) &win, pWin->drawable.id,
                                      XRT_WINDOW, serverClient, DixReadAccess);
         if (rc != Success)
             return FALSE;
@@ -1162,7 +1162,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
 
         eventinfo.event = ev;
         eventinfo.device = device;
-        CallCallbacks(&DeviceEventCallback, (pointer) &eventinfo);
+        CallCallbacks(&DeviceEventCallback, (void *) &eventinfo);
     }
 
     if (event->type == ET_Motion) {
@@ -4417,7 +4417,7 @@ RecalculateDeliverableEvents(WindowPtr pWin)
  *  \param value must conform to DeleteType
  */
 int
-OtherClientGone(pointer value, XID id)
+OtherClientGone(void *value, XID id)
 {
     OtherClientsPtr other, prev;
     WindowPtr pWin = (WindowPtr) value;
@@ -4498,7 +4498,7 @@ EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask)
         others->resource = FakeClientID(client->index);
         others->next = pWin->optional->otherClients;
         pWin->optional->otherClients = others;
-        if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer) pWin))
+        if (!AddResource(others->resource, RT_OTHERCLIENT, (void *) pWin))
             return BadAlloc;
     }
  maskSet:
@@ -4985,7 +4985,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
     if (stuff->cursor == None)
         newCursor = NullCursor;
     else {
-        int rc = dixLookupResourceByType((pointer *) &newCursor, stuff->cursor,
+        int rc = dixLookupResourceByType((void **) &newCursor, stuff->cursor,
                                          RT_CURSOR, client, DixUseAccess);
 
         if (rc != Success) {
@@ -5102,7 +5102,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     if (curs == None)
         cursor = NullCursor;
     else {
-        rc = dixLookupResourceByType((pointer *) &cursor, curs, RT_CURSOR,
+        rc = dixLookupResourceByType((void **) &cursor, curs, RT_CURSOR,
                                      client, DixUseAccess);
         if (rc != Success) {
             client->errorValue = curs;
@@ -5628,7 +5628,7 @@ ProcGrabButton(ClientPtr client)
     if (stuff->cursor == None)
         cursor = NullCursor;
     else {
-        rc = dixLookupResourceByType((pointer *) &cursor, stuff->cursor,
+        rc = dixLookupResourceByType((void **) &cursor, stuff->cursor,
                                      RT_CURSOR, client, DixUseAccess);
         if (rc != Success) {
             client->errorValue = stuff->cursor;
@@ -5882,7 +5882,7 @@ ProcRecolorCursor(ClientPtr client)
     REQUEST(xRecolorCursorReq);
 
     REQUEST_SIZE_MATCH(xRecolorCursorReq);
-    rc = dixLookupResourceByType((pointer *) &pCursor, stuff->cursor, RT_CURSOR,
+    rc = dixLookupResourceByType((void **) &pCursor, stuff->cursor, RT_CURSOR,
                                  client, DixWriteAccess);
     if (rc != Success) {
         client->errorValue = stuff->cursor;
@@ -5983,7 +5983,7 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
         eventinfo.client = pClient;
         eventinfo.events = events;
         eventinfo.count = count;
-        CallCallbacks(&EventCallback, (pointer) &eventinfo);
+        CallCallbacks(&EventCallback, (void *) &eventinfo);
     }
 #ifdef XSERVER_DTRACE
     if (XSERVER_SEND_EVENT_ENABLED()) {
diff --git a/dix/gc.c b/dix/gc.c
index f46e0dd..efe6d60 100644
--- a/dix/gc.c
+++ b/dix/gc.c
@@ -339,7 +339,7 @@ ChangeGC(ClientPtr client, GC * pGC, BITS32 mask, ChangeGCValPtr pUnion)
                 pPixmap->refcnt++;
             }
             (*pGC->funcs->ChangeClip) (pGC, pPixmap ? CT_PIXMAP : CT_NONE,
-                                       (pointer) pPixmap, 0);
+                                       (void *) pPixmap, 0);
             break;
         case GCDashOffset:
             NEXTVAL(INT16, pGC->dashOffset);
@@ -494,7 +494,7 @@ NewGCObject(ScreenPtr pScreen, int depth)
     pGC->clipOrg.x = 0;
     pGC->clipOrg.y = 0;
     pGC->clientClipType = CT_NONE;
-    pGC->clientClip = (pointer) NULL;
+    pGC->clientClip = (void *) NULL;
     pGC->numInDashList = 2;
     pGC->dash = DefaultDash;
     pGC->dashOffset = 0;
@@ -764,7 +764,7 @@ CopyGC(GC * pgcSrc, GC * pgcDst, BITS32 mask)
  *  \param value  must conform to DeleteType
  */
 int
-FreeGC(pointer value, XID gid)
+FreeGC(void *value, XID gid)
 {
     GCPtr pGC = (GCPtr) value;
 
@@ -1023,7 +1023,7 @@ SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
 
     if (size)
         memmove((char *) prectsNew, (char *) prects, size);
-    (*pGC->funcs->ChangeClip) (pGC, newct, (pointer) prectsNew, nrects);
+    (*pGC->funcs->ChangeClip) (pGC, newct, (void *) prectsNew, nrects);
     if (pGC->funcs->ChangeGC)
         (*pGC->funcs->ChangeGC) (pGC,
                                  GCClipXOrigin | GCClipYOrigin | GCClipMask);
diff --git a/dix/glyphcurs.c b/dix/glyphcurs.c
index 9004cb1..5404025 100644
--- a/dix/glyphcurs.c
+++ b/dix/glyphcurs.c
@@ -114,7 +114,7 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm,
     /* fill the pixmap with 0 */
     gcval[0].val = GXcopy;
     gcval[1].val = 0;
-    gcval[2].ptr = (pointer) pfont;
+    gcval[2].ptr = (void *) pfont;
     ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont, gcval);
     ValidateGC((DrawablePtr) ppix, pGC);
     (*pGC->ops->PolyFillRect) ((DrawablePtr) ppix, pGC, 1, &rect);
diff --git a/dix/grabs.c b/dix/grabs.c
index a03897a..5fd6820 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -317,7 +317,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
 }
 
 int
-DeletePassiveGrab(pointer value, XID id)
+DeletePassiveGrab(void *value, XID id)
 {
     GrabPtr g, prev;
     GrabPtr pGrab = (GrabPtr) value;
@@ -564,7 +564,7 @@ AddPassiveGrabToList(ClientPtr client, GrabPtr pGrab)
 
     pGrab->next = pGrab->window->optional->passiveGrabs;
     pGrab->window->optional->passiveGrabs = pGrab;
-    if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer) pGrab))
+    if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (void *) pGrab))
         return Success;
     return BadAlloc;
 }
@@ -662,7 +662,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
                 ok = FALSE;
             }
             else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB,
-                                  (pointer) pNewGrab))
+                                  (void *) pNewGrab))
                 ok = FALSE;
             else
                 adds[nadds++] = pNewGrab;
diff --git a/dix/main.c b/dix/main.c
index 05dcbed..fcc1ad3 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -168,7 +168,7 @@ dix_main(int argc, char *argv[], char *envp[])
             serverClient = calloc(sizeof(ClientRec), 1);
             if (!serverClient)
                 FatalError("couldn't create server client");
-            InitClient(serverClient, 0, (pointer) NULL);
+            InitClient(serverClient, 0, (void *) NULL);
         }
         else
             ResetWellKnownSockets();
diff --git a/dix/pixmap.c b/dix/pixmap.c
index d5dc383..4b880af 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -49,7 +49,7 @@ from The Open Group.
 /* callable by ddx */
 PixmapPtr
 GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
-                       int bitsPerPixel, int devKind, pointer pPixData)
+                       int bitsPerPixel, int devKind, void *pPixData)
 {
     PixmapPtr pPixmap = pScreen->pScratchPixmap;
 
diff --git a/dix/privates.c b/dix/privates.c
index 41b1a76..e03b225 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -259,7 +259,7 @@ fixupDefaultColormaps(FixupFunc fixup, unsigned bytes)
     for (s = 0; s < screenInfo.numScreens; s++) {
         ColormapPtr cmap;
 
-        dixLookupResourceByType((pointer *) &cmap,
+        dixLookupResourceByType((void **) &cmap,
                                 screenInfo.screens[s]->defColormap, RT_COLORMAP,
                                 serverClient, DixCreateAccess);
         if (cmap &&
@@ -348,7 +348,7 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
     if (size == 0)
         bytes = sizeof(void *);
 
-    /* align to void * size */
+    /* align to pointer size */
     bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
 
     /* Update offsets for all affected keys */
@@ -697,7 +697,7 @@ _dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
         privates_size = pScreen->screenSpecificPrivates[type].offset;
     else
         privates_size = global_keys[type].offset;
-    /* round up so that void * is aligned */
+    /* round up so that pointer is aligned */
     baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
     totalSize = baseSize + privates_size;
     object = malloc(totalSize);
diff --git a/dix/property.c b/dix/property.c
index dec4090..9f51cd0 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -242,7 +242,7 @@ ProcChangeProperty(ClientPtr client)
 int
 dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
                         Atom type, int format, int mode, unsigned long len,
-                        pointer value, Bool sendevent)
+                        void *value, Bool sendevent)
 {
     PropertyPtr pProp;
     PropertyRec savedProp;
@@ -356,7 +356,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
 
 int
 ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
-                     int mode, unsigned long len, pointer value, Bool sendevent)
+                     int mode, unsigned long len, void *value, Bool sendevent)
 {
     return dixChangeWindowProperty(serverClient, pWin, property, type, format,
                                    mode, len, value, sendevent);
diff --git a/dix/resource.c b/dix/resource.c
index 2aafa34..623d862 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -165,7 +165,7 @@ typedef struct _Resource {
     struct _Resource *next;
     XID id;
     RESTYPE type;
-    pointer value;
+    void *value;
 } ResourceRec, *ResourcePtr;
 
 typedef struct _ClientResource {
@@ -203,7 +203,7 @@ struct ResourceType {
  *                  resource can't be determined.
  */
 static void
-GetDefaultBytes(pointer value, XID id, ResourceSizePtr size)
+GetDefaultBytes(void *value, XID id, ResourceSizePtr size)
 {
     size->resourceSize = 0;
     size->pixmapRefSize = 0;
@@ -224,7 +224,7 @@ GetDefaultBytes(pointer value, XID id, ResourceSizePtr size)
  * @param[out] cdata Pointer to opaque data.
  */
 static void
-DefaultFindSubRes(pointer value, FindAllRes func, pointer cdata)
+DefaultFindSubRes(void *value, FindAllRes func, void *cdata)
 {
     /* do nothing */
 }
@@ -268,7 +268,7 @@ GetDrawableBytes(DrawablePtr drawable)
  *                  pixmap reference.
  */
 static void
-GetPixmapBytes(pointer value, XID id, ResourceSizePtr size)
+GetPixmapBytes(void *value, XID id, ResourceSizePtr size)
 {
     PixmapPtr pixmap = value;
 
@@ -297,7 +297,7 @@ GetPixmapBytes(pointer value, XID id, ResourceSizePtr size)
  *                  pixmap references of a window.
  */
 static void
-GetWindowBytes(pointer value, XID id, ResourceSizePtr size)
+GetWindowBytes(void *value, XID id, ResourceSizePtr size)
 {
     SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
     ResourceSizeRec pixmapSize = { 0, 0, 0 };
@@ -339,7 +339,7 @@ GetWindowBytes(pointer value, XID id, ResourceSizePtr size)
  * @param[out] cdata Pointer to opaque data
  */
 static void
-FindWindowSubRes(pointer value, FindAllRes func, pointer cdata)
+FindWindowSubRes(void *value, FindAllRes func, void *cdata)
 {
     WindowPtr window = value;
 
@@ -370,7 +370,7 @@ FindWindowSubRes(pointer value, FindAllRes func, pointer cdata)
  *                  pixmap references of a graphics context.
  */
 static void
-GetGcBytes(pointer value, XID id, ResourceSizePtr size)
+GetGcBytes(void *value, XID id, ResourceSizePtr size)
 {
     SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
     ResourceSizeRec pixmapSize = { 0, 0, 0 };
@@ -411,7 +411,7 @@ GetGcBytes(pointer value, XID id, ResourceSizePtr size)
  * @param[out] cdata Pointer to opaque data
  */
 static void
-FindGCSubRes(pointer value, FindAllRes func, pointer cdata)
+FindGCSubRes(void *value, FindAllRes func, void *cdata)
 {
     GCPtr gc = value;
 
@@ -743,7 +743,7 @@ GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
     unsigned int found = 0;
     XID rc, id = pClient->clientAsMask;
     XID maxid;
-    pointer val;
+    void *val;
 
     maxid = id | RESOURCE_ID_MASK;
     while ((found < count) && (id <= maxid)) {
@@ -787,7 +787,7 @@ FakeClientID(int client)
 }
 
 Bool
-AddResource(XID id, RESTYPE type, pointer value)
+AddResource(XID id, RESTYPE type, void *value)
 {
     int client;
     ClientResourceRec *rrec;
@@ -948,7 +948,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
  */
 
 Bool
-ChangeResourceValue(XID id, RESTYPE rtype, pointer value)
+ChangeResourceValue(XID id, RESTYPE rtype, void *value)
 {
     int cid;
     ResourcePtr res;
@@ -973,7 +973,7 @@ ChangeResourceValue(XID id, RESTYPE rtype, pointer value)
 
 void
 FindClientResourcesByType(ClientPtr client,
-                          RESTYPE type, FindResType func, pointer cdata)
+                          RESTYPE type, FindResType func, void *cdata)
 {
     ResourcePtr *resources;
     ResourcePtr this, next;
@@ -998,17 +998,17 @@ FindClientResourcesByType(ClientPtr client,
     }
 }
 
-void FindSubResources(pointer    resource,
+void FindSubResources(void *resource,
                       RESTYPE    type,
                       FindAllRes func,
-                      pointer    cdata)
+                      void *cdata)
 {
     struct ResourceType rtype = resourceTypes[type & TypeMask];
     rtype.findSubResFunc(resource, func, cdata);
 }
 
 void
-FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata)
+FindAllClientResources(ClientPtr client, FindAllRes func, void *cdata)
 {
     ResourcePtr *resources;
     ResourcePtr this, next;
@@ -1031,14 +1031,14 @@ FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata)
     }
 }
 
-pointer
+void *
 LookupClientResourceComplex(ClientPtr client,
                             RESTYPE type,
-                            FindComplexResType func, pointer cdata)
+                            FindComplexResType func, void *cdata)
 {
     ResourcePtr *resources;
     ResourcePtr this, next;
-    pointer value;
+    void *value;
     int i;
 
     if (!client)
@@ -1158,7 +1158,7 @@ FreeAllResources(void)
 Bool
 LegalNewID(XID id, ClientPtr client)
 {
-    pointer val;
+    void *val;
     int rc;
 
 #ifdef PANORAMIX
@@ -1181,7 +1181,7 @@ LegalNewID(XID id, ClientPtr client)
 }
 
 int
-dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype,
+dixLookupResourceByType(void **result, XID id, RESTYPE rtype,
                         ClientPtr client, Mask mode)
 {
     int cid = CLIENT_ID(id);
@@ -1216,7 +1216,7 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype,
 }
 
 int
-dixLookupResourceByClass(pointer *result, XID id, RESTYPE rclass,
+dixLookupResourceByClass(void **result, XID id, RESTYPE rclass,
                          ClientPtr client, Mask mode)
 {
     int cid = CLIENT_ID(id);
diff --git a/dix/touch.c b/dix/touch.c
index a7ea213..1eeed78 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -75,7 +75,7 @@ static unsigned char resize_waiting[(MAXDEVICES + 7) / 8];
  * anyway and re-executing this won't help.
  */
 static Bool
-TouchResizeQueue(ClientPtr client, pointer closure)
+TouchResizeQueue(ClientPtr client, void *closure)
 {
     int i;
 
diff --git a/dix/window.c b/dix/window.c
index fad57fa..f4acdc8 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -305,7 +305,7 @@ PrintWindowTree(void)
 }
 
 int
-TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, void *data)
 {
     int result;
     WindowPtr pChild;
@@ -338,7 +338,7 @@ TraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data)
  *****/
 
 int
-WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void *data)
 {
     return (TraverseTree(pScreen->root, func, data));
 }
@@ -363,7 +363,7 @@ SetWindowToDefaults(WindowPtr pWin)
 
     pWin->backingStore = NotUseful;
     pWin->DIXsaveUnder = FALSE;
-    pWin->backStorage = (pointer) NULL;
+    pWin->backStorage = (void *) NULL;
 
     pWin->mapped = FALSE;       /* off */
     pWin->realized = FALSE;     /* off */
@@ -524,7 +524,7 @@ CreateRootWindow(ScreenPtr pScreen)
                  RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess))
         return FALSE;
 
-    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer) pWin))
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
         return FALSE;
 
     if (disableBackingStore)
@@ -959,7 +959,7 @@ CrushTree(WindowPtr pWin)
  *****/
 
 int
-DeleteWindow(pointer value, XID wid)
+DeleteWindow(void *value, XID wid)
 {
     WindowPtr pParent;
     WindowPtr pWin = (WindowPtr) value;
@@ -1107,7 +1107,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
                  * incremented. */
             }
             else {
-                rc = dixLookupResourceByType((pointer *) &pPixmap, pixID,
+                rc = dixLookupResourceByType((void **) &pPixmap, pixID,
                                              RT_PIXMAP, client, DixReadAccess);
                 if (rc == Success) {
                     if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
@@ -1161,7 +1161,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
                     pixID = pWin->parent->border.pixmap->drawable.id;
                 }
             }
-            rc = dixLookupResourceByType((pointer *) &pPixmap, pixID, RT_PIXMAP,
+            rc = dixLookupResourceByType((void **) &pPixmap, pixID, RT_PIXMAP,
                                          client, DixReadAccess);
             if (rc == Success) {
                 if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
@@ -1308,7 +1308,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
                 error = BadMatch;
                 goto PatchUp;
             }
-            rc = dixLookupResourceByType((pointer *) &pCmap, cmap, RT_COLORMAP,
+            rc = dixLookupResourceByType((void **) &pCmap, cmap, RT_COLORMAP,
                                          client, DixUseAccess);
             if (rc != Success) {
                 error = rc;
@@ -1378,7 +1378,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
                     pCursor = (CursorPtr) None;
             }
             else {
-                rc = dixLookupResourceByType((pointer *) &pCursor, cursorID,
+                rc = dixLookupResourceByType((void **) &pCursor, cursorID,
                                              RT_CURSOR, client, DixUseAccess);
                 if (rc != Success) {
                     error = rc;
@@ -2377,7 +2377,7 @@ CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
 }
 
 static int
-CompareWIDs(WindowPtr pWin, pointer value)
+CompareWIDs(WindowPtr pWin, void *value)
 {                               /* must conform to VisitWindowProcPtr */
     Window *wid = (Window *) value;
 
@@ -2402,7 +2402,7 @@ ReparentWindow(WindowPtr pWin, WindowPtr pParent,
     ScreenPtr pScreen;
 
     pScreen = pWin->drawable.pScreen;
-    if (TraverseTree(pWin, CompareWIDs, (pointer) &pParent->drawable.id) ==
+    if (TraverseTree(pWin, CompareWIDs, (void *) &pParent->drawable.id) ==
         WT_STOPWALKING)
         return BadMatch;
     if (!MakeWindowOptional(pWin))
@@ -2688,7 +2688,7 @@ UnrealizeTree(WindowPtr pWin, Bool fromConfigure)
 #ifdef PANORAMIX
             if (!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
                 PanoramiXRes *win;
-                int rc = dixLookupResourceByType((pointer *) &win,
+                int rc = dixLookupResourceByType((void **) &win,
                                                  pChild->drawable.id,
                                                  XRT_WINDOW,
                                                  serverClient, DixWriteAccess);
@@ -3167,7 +3167,7 @@ TileScreenSaver(ScreenPtr pScreen, int kind)
                                  &cursor, serverClient, (XID) 0);
         if (cursor) {
             cursorID = FakeClientID(0);
-            if (AddResource(cursorID, RT_CURSOR, (pointer) cursor)) {
+            if (AddResource(cursorID, RT_CURSOR, (void *) cursor)) {
                 attributes[attri] = cursorID;
                 mask |= CWCursor;
             }
@@ -3196,7 +3196,7 @@ TileScreenSaver(ScreenPtr pScreen, int kind)
         return FALSE;
 
     if (!AddResource(pWin->drawable.id, RT_WINDOW,
-                     (pointer) pScreen->screensaver.pWindow))
+                     (void *) pScreen->screensaver.pWindow))
         return FALSE;
 
     if (mask & CWBackPixmap) {
diff --git a/dri3/dri3_event.c b/dri3/dri3_event.c
index 02f0f65..cb509a2 100644
--- a/dri3/dri3_event.c
+++ b/dri3/dri3_event.c
@@ -29,7 +29,7 @@
 RESTYPE dri3_event_type;
 
 static int
-dri3_free_event(pointer data, XID id)
+dri3_free_event(void *data, XID id)
 {
     dri3_event_ptr dri3_event = (dri3_event_ptr) data;
     dri3_window_priv_ptr window_priv = dri3_window_priv(dri3_event->window);
@@ -41,7 +41,7 @@ dri3_free_event(pointer data, XID id)
             break;
         }
     }
-    free((pointer) dri3_event);
+    free((void *) dri3_event);
     return 1;
 
 }
@@ -145,7 +145,7 @@ dri3_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
     event->next = window_priv->events;
     window_priv->events = event;
 
-    if (!AddResource(event->id, dri3_event_type, (pointer) event))
+    if (!AddResource(event->id, dri3_event_type, (void *) event))
         return BadAlloc;
 
     return Success;
diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c
index 4e1408f..31dce83 100644
--- a/dri3/dri3_request.c
+++ b/dri3/dri3_request.c
@@ -168,7 +168,7 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
         (*drawable->pScreen->DestroyPixmap) (pixmap);
         return rc;
     }
-    if (AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pixmap))
+    if (AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
         return Success;
 
     return Success;
@@ -189,7 +189,7 @@ proc_dri3_buffer_from_pixmap(ClientPtr client)
     PixmapPtr pixmap;
 
     REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
-    rc = dixLookupResourceByType((pointer *) &pixmap, stuff->pixmap, RT_PIXMAP,
+    rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
                                  client, DixWriteAccess);
     if (rc != Success) {
         client->errorValue = stuff->pixmap;
diff --git a/exa/exa.c b/exa/exa.c
index e961733..a2995db 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -475,7 +475,7 @@ static void
  exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
 
 static void
- exaChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+ exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects);
 
 static void
  exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
@@ -579,7 +579,7 @@ exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
 }
 
 static void
-exaChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+exaChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     ExaGCPriv(pGC);
     swap(pExaGC, pGC, funcs);
@@ -702,8 +702,8 @@ exaCreateScreenResources(ScreenPtr pScreen)
 }
 
 static void
-ExaBlockHandler(ScreenPtr pScreen, pointer pTimeout,
-                pointer pReadmask)
+ExaBlockHandler(ScreenPtr pScreen, void *pTimeout,
+                void *pReadmask)
 {
     ExaScreenPriv(pScreen);
 
@@ -733,7 +733,7 @@ ExaBlockHandler(ScreenPtr pScreen, pointer pTimeout,
 
 static void
 ExaWakeupHandler(ScreenPtr pScreen, unsigned long result,
-                 pointer pReadmask)
+                 void *pReadmask)
 {
     ExaScreenPriv(pScreen);
 
diff --git a/exa/exa.h b/exa/exa.h
index be022b2..98d094d 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -58,7 +58,7 @@ struct _ExaOffscreenArea {
     int offset;                 /* aligned offset */
     int size;                   /* total allocation size */
     unsigned last_use;
-    pointer privData;
+    void *privData;
 
     ExaOffscreenSaveProc save;
 
@@ -685,7 +685,7 @@ typedef struct _ExaDriver {
      */
     Bool (*ModifyPixmapHeader) (PixmapPtr pPixmap, int width, int height,
                                 int depth, int bitsPerPixel, int devKind,
-                                pointer pPixData);
+                                void *pPixData);
 
     /* hooks for drivers with tiling support:
      * driver MUST fill out new_fb_pitch with valid pitch of pixmap
@@ -784,7 +784,7 @@ extern _X_EXPORT ExaOffscreenArea *exaOffscreenAlloc(ScreenPtr pScreen,
                                                      int size, int align,
                                                      Bool locked,
                                                      ExaOffscreenSaveProc save,
-                                                     pointer privData);
+                                                     void *privData);
 
 extern _X_EXPORT ExaOffscreenArea *exaOffscreenFree(ScreenPtr pScreen,
                                                     ExaOffscreenArea * area);
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 0fa422f..a6a60e5 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -147,7 +147,7 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
 Bool
 exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
                               int depth, int bitsPerPixel, int devKind,
-                              pointer pPixData)
+                              void *pPixData)
 {
     ScreenPtr pScreen;
     ExaScreenPrivPtr pExaScr;
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index d467ca9..8799a79 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -130,7 +130,7 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
 Bool
 exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
                              int depth, int bitsPerPixel, int devKind,
-                             pointer pPixData)
+                             void *pPixData)
 {
     ScreenPtr pScreen;
     ExaScreenPrivPtr pExaScr;
@@ -218,7 +218,7 @@ exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap)
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
 
     ExaScreenPriv(pScreen);
-    pointer saved_ptr;
+    void *saved_ptr;
     Bool ret;
 
     saved_ptr = pPixmap->devPrivate.ptr;
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 71f750f..aa71b21 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -127,7 +127,7 @@ exaUnrealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
             continue;
 
         if (cache->picture) {
-            FreePicture((pointer) cache->picture, (XID) 0);
+            FreePicture((void *) cache->picture, (XID) 0);
             cache->picture = NULL;
         }
 
@@ -225,7 +225,7 @@ exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
     }
 
     /* Each cache references the picture individually */
-    FreePicture((pointer) pPicture, (XID) 0);
+    FreePicture((void *) pPicture, (XID) 0);
     return TRUE;
 
  bail:
@@ -737,7 +737,7 @@ exaGlyphs(CARD8 op,
 
             /* The driver can't seem to composite to a8, let's try argb (but
              * without component-alpha) */
-            FreePicture((pointer) pMask, (XID) 0);
+            FreePicture((void *) pMask, (XID) 0);
 
             argbFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
 
@@ -833,7 +833,7 @@ exaGlyphs(CARD8 op,
                          pDst,
                          xSrc + x - first_xOff,
                          ySrc + y - first_yOff, 0, 0, x, y, width, height);
-        FreePicture((pointer) pMask, (XID) 0);
+        FreePicture((void *) pMask, (XID) 0);
         (*pScreen->DestroyPixmap) (pMaskPixmap);
     }
 }
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index e890f67..f712e19 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -350,7 +350,7 @@ exaDoMoveInPixmap(ExaMigrationPtr migrate)
         pExaPixmap->area =
             exaOffscreenAlloc(pScreen, pExaPixmap->fb_size,
                               pExaScr->info->pixmapOffsetAlign, FALSE,
-                              exaPixmapSave, (pointer) pPixmap);
+                              exaPixmapSave, (void *) pPixmap);
         if (pExaPixmap->area == NULL)
             return;
 
@@ -465,12 +465,12 @@ exaMigrateTowardFb(ExaMigrationPtr migrate)
 
     if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
         DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
-                     (pointer) pPixmap));
+                     (void *) pPixmap));
         return;
     }
 
     DBG_MIGRATE(("UseScreen %p score %d\n",
-                 (pointer) pPixmap, pExaPixmap->score));
+                 (void *) pPixmap, pExaPixmap->score));
 
     if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
         exaDoMoveInPixmap(migrate);
@@ -504,7 +504,7 @@ exaMigrateTowardSys(ExaMigrationPtr migrate)
 
     ExaPixmapPriv(pPixmap);
 
-    DBG_MIGRATE(("UseMem: %p score %d\n", (pointer) pPixmap,
+    DBG_MIGRATE(("UseMem: %p score %d\n", (void *) pPixmap,
                  pExaPixmap->score));
 
     if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index b43dfec..f618a1e 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -125,7 +125,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
 
 Bool
 exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
-                            int bitsPerPixel, int devKind, pointer pPixData)
+                            int bitsPerPixel, int devKind, void *pPixData)
 {
     ScreenPtr pScreen;
     ExaScreenPrivPtr pExaScr;
@@ -282,7 +282,7 @@ exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap)
 
     ExaScreenPriv(pScreen);
     ExaPixmapPriv(pPixmap);
-    pointer saved_ptr;
+    void *saved_ptr;
     Bool ret;
 
     if (!pExaPixmap->driverPriv)
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 1f571cf..e287348 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -160,7 +160,7 @@ exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align)
  */
 ExaOffscreenArea *
 exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
-                  Bool locked, ExaOffscreenSaveProc save, pointer privData)
+                  Bool locked, ExaOffscreenSaveProc save, void *privData)
 {
     ExaOffscreenArea *area;
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index aba3934..61a1f4c 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -430,13 +430,13 @@ void
 
 ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                       int x, int y, unsigned int nglyph,
-                      CharInfoPtr * ppci, pointer pglyphBase);
+                      CharInfoPtr * ppci, void *pglyphBase);
 
 void
 
 ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                      int x, int y, unsigned int nglyph,
-                     CharInfoPtr * ppci, pointer pglyphBase);
+                     CharInfoPtr * ppci, void *pglyphBase);
 
 void
 
@@ -609,7 +609,7 @@ Bool
 
 exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
                               int depth, int bitsPerPixel, int devKind,
-                              pointer pPixData);
+                              void *pPixData);
 
 Bool
  exaDestroyPixmap_classic(PixmapPtr pPixmap);
@@ -627,7 +627,7 @@ Bool
 
 exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
                              int depth, int bitsPerPixel, int devKind,
-                             pointer pPixData);
+                             void *pPixData);
 
 Bool
  exaDestroyPixmap_driver(PixmapPtr pPixmap);
@@ -644,7 +644,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
 Bool
 
 exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
-                            int bitsPerPixel, int devKind, pointer pPixData);
+                            int bitsPerPixel, int devKind, void *pPixData);
 
 Bool
  exaDestroyPixmap_mixed(PixmapPtr pPixmap);
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index b0a0011..58262e0 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -319,7 +319,7 @@ ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
 void
 ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                       int x, int y, unsigned int nglyph,
-                      CharInfoPtr * ppci, pointer pglyphBase)
+                      CharInfoPtr * ppci, void *pglyphBase)
 {
     EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
@@ -334,7 +334,7 @@ ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
 void
 ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                      int x, int y, unsigned int nglyph,
-                     CharInfoPtr * ppci, pointer pglyphBase)
+                     CharInfoPtr * ppci, void *pglyphBase)
 {
     EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
diff --git a/fb/fb.h b/fb/fb.h
index 26957df..9057767 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -776,7 +776,7 @@ fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
                           int width,
                           int height,
                           int depth,
-                          int bitsPerPixel, int devKind, pointer pPixData);
+                          int bitsPerPixel, int devKind, void *pPixData);
 
 /*
  * fballpriv.c
@@ -1229,7 +1229,7 @@ fbPolyGlyphBlt(DrawablePtr pDrawable,
                GCPtr pGC,
                int x,
                int y,
-               unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase);
+               unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase);
 
 extern _X_EXPORT void
 
@@ -1237,7 +1237,7 @@ fbImageGlyphBlt(DrawablePtr pDrawable,
                 GCPtr pGC,
                 int x,
                 int y,
-                unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase);
+                unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase);
 
 /*
  * fbimage.c
@@ -1409,7 +1409,7 @@ extern _X_EXPORT void
  _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap);
 
 extern _X_EXPORT Bool
- fbSetupScreen(ScreenPtr pScreen, pointer pbits,        /* pointer to screen bitmap */
+ fbSetupScreen(ScreenPtr pScreen, void *pbits,        /* pointer to screen bitmap */
                int xsize,       /* in pixels */
                int ysize, int dpix,     /* dots per inch */
                int dpiy, int width,     /* pixel width of frame buffer */
@@ -1418,7 +1418,7 @@ extern _X_EXPORT Bool
 extern _X_EXPORT Bool
 
 wfbFinishScreenInit(ScreenPtr pScreen,
-                    pointer pbits,
+                    void *pbits,
                     int xsize,
                     int ysize,
                     int dpix,
@@ -1430,7 +1430,7 @@ wfbFinishScreenInit(ScreenPtr pScreen,
 extern _X_EXPORT Bool
 
 wfbScreenInit(ScreenPtr pScreen,
-              pointer pbits,
+              void *pbits,
               int xsize,
               int ysize,
               int dpix,
@@ -1442,14 +1442,14 @@ wfbScreenInit(ScreenPtr pScreen,
 extern _X_EXPORT Bool
 
 fbFinishScreenInit(ScreenPtr pScreen,
-                   pointer pbits,
+                   void *pbits,
                    int xsize,
                    int ysize, int dpix, int dpiy, int width, int bpp);
 
 extern _X_EXPORT Bool
 
 fbScreenInit(ScreenPtr pScreen,
-             pointer pbits,
+             void *pbits,
              int xsize, int ysize, int dpix, int dpiy, int width, int bpp);
 
 /*
diff --git a/fb/fb24_32.c b/fb/fb24_32.c
index 5eb81e8..ecb3951 100644
--- a/fb/fb24_32.c
+++ b/fb/fb24_32.c
@@ -495,7 +495,7 @@ fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
 }
 
 typedef struct {
-    pointer pbits;
+    void *pbits;
     int width;
 } miScreenInitParmsRec, *miScreenInitParmsPtr;
 
@@ -526,7 +526,7 @@ fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
                           int width,
                           int height,
                           int depth,
-                          int bitsPerPixel, int devKind, pointer pPixData)
+                          int bitsPerPixel, int devKind, void *pPixData)
 {
     int bpp, w;
 
diff --git a/fb/fb24_32.h b/fb/fb24_32.h
index 1bec00b..b357edf 100644
--- a/fb/fb24_32.h
+++ b/fb/fb24_32.h
@@ -31,14 +31,14 @@
 Bool
 
 fb24_32FinishScreenInit(ScreenPtr pScreen,
-                        pointer pbits,
+                        void *pbits,
                         int xsize,
                         int ysize, int dpix, int dpiy, int width, int bpp);
 
 Bool
 
 fb24_32ScreenInit(ScreenPtr pScreen,
-                  pointer pbits,
+                  void *pbits,
                   int xsize, int ysize, int dpix, int dpiy, int width, int bpp);
 
 #endif
diff --git a/fb/fbglyph.c b/fb/fbglyph.c
index 3080a77..4f2904c 100644
--- a/fb/fbglyph.c
+++ b/fb/fbglyph.c
@@ -241,7 +241,7 @@ fbPolyGlyphBlt(DrawablePtr pDrawable,
                GCPtr pGC,
                int x,
                int y,
-               unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase)
+               unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase)
 {
     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
     CharInfoPtr pci;
@@ -309,7 +309,7 @@ fbImageGlyphBlt(DrawablePtr pDrawable,
                 GCPtr pGC,
                 int x,
                 int y,
-                unsigned int nglyph, CharInfoPtr * ppciInit, pointer pglyphBase)
+                unsigned int nglyph, CharInfoPtr * ppciInit, void *pglyphBase)
 {
     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
     CharInfoPtr *ppci;
diff --git a/fb/fboverlay.c b/fb/fboverlay.c
index c6802e4..935bf1b 100644
--- a/fb/fboverlay.c
+++ b/fb/fboverlay.c
@@ -104,7 +104,7 @@ fbOverlayWindowLayer(WindowPtr pWin)
 
     for (i = 0; i < pScrPriv->nlayers; i++)
         if (dixLookupPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin)) ==
-            (pointer) pScrPriv->layer[i].u.run.pixmap)
+            (void *) pScrPriv->layer[i].u.run.pixmap)
             return i;
     return 0;
 }
@@ -115,7 +115,7 @@ fbOverlayCreateScreenResources(ScreenPtr pScreen)
     int i;
     FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
     PixmapPtr pPixmap;
-    pointer pbits;
+    void *pbits;
     int width;
     int depth;
     BoxRec box;
@@ -250,8 +250,8 @@ fbOverlayWindowExposures(WindowPtr pWin,
 
 Bool
 fbOverlaySetupScreen(ScreenPtr pScreen,
-                     pointer pbits1,
-                     pointer pbits2,
+                     void *pbits1,
+                     void *pbits2,
                      int xsize,
                      int ysize,
                      int dpix,
@@ -287,8 +287,8 @@ fb24_32OverlayCreateScreenResources(ScreenPtr pScreen)
 
 Bool
 fbOverlayFinishScreenInit(ScreenPtr pScreen,
-                          pointer pbits1,
-                          pointer pbits2,
+                          void *pbits1,
+                          void *pbits2,
                           int xsize,
                           int ysize,
                           int dpix,
diff --git a/fb/fboverlay.h b/fb/fboverlay.h
index 9a93457..57c9873 100644
--- a/fb/fboverlay.h
+++ b/fb/fboverlay.h
@@ -38,7 +38,7 @@ typedef void (*fbOverlayPaintKeyProc) (DrawablePtr, RegionPtr, CARD32, int);
 typedef struct _fbOverlayLayer {
     union {
         struct {
-            pointer pbits;
+            void *pbits;
             int width;
             int depth;
         } init;
@@ -89,8 +89,8 @@ fbOverlayWindowExposures(WindowPtr pWin,
 extern _X_EXPORT Bool
 
 fbOverlaySetupScreen(ScreenPtr pScreen,
-                     pointer pbits1,
-                     pointer pbits2,
+                     void *pbits1,
+                     void *pbits2,
                      int xsize,
                      int ysize,
                      int dpix,
@@ -99,8 +99,8 @@ fbOverlaySetupScreen(ScreenPtr pScreen,
 extern _X_EXPORT Bool
 
 fbOverlayFinishScreenInit(ScreenPtr pScreen,
-                          pointer pbits1,
-                          pointer pbits2,
+                          void *pbits1,
+                          void *pbits2,
                           int xsize,
                           int ysize,
                           int dpix,
diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
index 0824b64..677f28a 100644
--- a/fb/fbpixmap.c
+++ b/fb/fbpixmap.c
@@ -66,7 +66,7 @@ fbCreatePixmapBpp(ScreenPtr pScreen, int width, int height, int depth, int bpp,
     pPixmap->drawable.height = height;
     pPixmap->devKind = paddedWidth;
     pPixmap->refcnt = 1;
-    pPixmap->devPrivate.ptr = (pointer) ((char *) pPixmap + base + adjust);
+    pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap + base + adjust);
     pPixmap->master_pixmap = NULL;
 
 #ifdef FB_DEBUG
diff --git a/fb/fbscreen.c b/fb/fbscreen.c
index f9080a4..b2b9739 100644
--- a/fb/fbscreen.c
+++ b/fb/fbscreen.c
@@ -90,7 +90,7 @@ _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
 }
 
 Bool
-fbSetupScreen(ScreenPtr pScreen, pointer pbits, /* pointer to screen bitmap */
+fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */
               int xsize,        /* in pixels */
               int ysize, int dpix,      /* dots per inch */
               int dpiy, int width,      /* pixel width of frame buffer */
@@ -135,7 +135,7 @@ fbSetupScreen(ScreenPtr pScreen, pointer pbits, /* pointer to screen bitmap */
 #ifdef FB_ACCESS_WRAPPER
 Bool
 wfbFinishScreenInit(ScreenPtr pScreen,
-                    pointer pbits,
+                    void *pbits,
                     int xsize,
                     int ysize,
                     int dpix,
@@ -146,7 +146,7 @@ wfbFinishScreenInit(ScreenPtr pScreen,
 #else
 Bool
 fbFinishScreenInit(ScreenPtr pScreen,
-                   pointer pbits,
+                   void *pbits,
                    int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
 #endif
 {
@@ -224,7 +224,7 @@ fbFinishScreenInit(ScreenPtr pScreen,
 #ifdef FB_ACCESS_WRAPPER
 Bool
 wfbScreenInit(ScreenPtr pScreen,
-              pointer pbits,
+              void *pbits,
               int xsize,
               int ysize,
               int dpix,
@@ -242,7 +242,7 @@ wfbScreenInit(ScreenPtr pScreen,
 #else
 Bool
 fbScreenInit(ScreenPtr pScreen,
-             pointer pbits,
+             void *pbits,
              int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
 {
     if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index b8da048..187e426 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -133,7 +133,7 @@ _X_HIDDEN int
 validGlxContext(ClientPtr client, XID id, int access_mode,
                 __GLXcontext ** context, int *err)
 {
-    *err = dixLookupResourceByType((pointer *) context, id,
+    *err = dixLookupResourceByType((void **) context, id,
                                    __glXContextRes, client, access_mode);
     if (*err != Success || (*context)->idExists == GL_FALSE) {
         client->errorValue = id;
@@ -151,7 +151,7 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
 {
     int rc;
 
-    rc = dixLookupResourceByType((pointer *) drawable, id,
+    rc = dixLookupResourceByType((void **) drawable, id,
                                  __glXDrawableRes, client, access_mode);
     if (rc != Success && rc != BadValue) {
         *err = rc;
@@ -2507,7 +2507,7 @@ __glXpresentCompleteNotify(WindowPtr window, CARD8 present_mode, CARD32 serial,
     int glx_type;
     int rc;
 
-    rc = dixLookupResourceByType((pointer *) &drawable, window->drawable.id,
+    rc = dixLookupResourceByType((void **) &drawable, window->drawable.id,
                                  __glXDrawableRes, serverClient, DixGetAttrAccess);
 
     if (rc != Success)
diff --git a/glx/glxext.c b/glx/glxext.c
index 316b4f6..6a34ac2 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -164,7 +164,7 @@ __glXAddContext(__GLXcontext * cx)
 {
     /* Register this context as a resource.
      */
-    if (!AddResource(cx->id, __glXContextRes, (pointer)cx)) {
+    if (!AddResource(cx->id, __glXContextRes, (void *)cx)) {
 	return False;
     }
 
@@ -278,7 +278,7 @@ glxGetClient(ClientPtr pClient)
 }
 
 static void
-glxClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+glxClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
diff --git a/hw/dmx/dmx.c b/hw/dmx/dmx.c
index 0f7cb5c..99e970c 100644
--- a/hw/dmx/dmx.c
+++ b/hw/dmx/dmx.c
@@ -268,7 +268,7 @@ ProcDMXForceWindowCreation(ClientPtr client)
         PanoramiXRes *win;
         int i;
 
-        if (Success != dixLookupResourceByType((pointer *) &win,
+        if (Success != dixLookupResourceByType((void **) &win,
                                                stuff->window, XRT_WINDOW,
                                                client, DixReadAccess))
             return -1;          /* BadWindow */
@@ -556,7 +556,7 @@ dmxPopulatePanoramiX(ClientPtr client, Window window,
     int count = 0;
     DMXWindowAttributesRec attr;
 
-    if (Success != dixLookupResourceByType((pointer *) &win,
+    if (Success != dixLookupResourceByType((void **) &win,
                                            window, XRT_WINDOW,
                                            client, DixReadAccess))
         return -1;              /* BadWindow */
diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index c6c6a8e..fcc97e3 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -728,7 +728,7 @@ static Bool FoundPixImage;
  *  another screen with the same image.  If so, copy the pixmap image
  *  from the existing screen to the newly created pixmap. */
 static void
-dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type, pointer p)
+dmxBERestorePixmapImage(void *value, XID id, RESTYPE type, void *p)
 {
     if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) {
         PixmapPtr pDst = (PixmapPtr) p;
@@ -737,7 +737,7 @@ dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type, pointer p)
         PixmapPtr pPix;
         int i;
 
-        dixLookupResourceByType((pointer *) &pPix, pXinPix->info[idx].id,
+        dixLookupResourceByType((void **) &pPix, pXinPix->info[idx].id,
                                 RT_PIXMAP, NullClient, DixUnknownAccess);
         if (pPix != pDst)
             return;             /* Not a match.... Next! */
@@ -749,7 +749,7 @@ dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type, pointer p)
             if (i == idx)
                 continue;       /* Self replication is bad */
 
-            dixLookupResourceByType((pointer *) &pSrc, pXinPix->info[i].id,
+            dixLookupResourceByType((void **) &pSrc, pXinPix->info[i].id,
                                     RT_PIXMAP, NullClient, DixUnknownAccess);
             pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
             if (pSrcPriv->pixmap) {
@@ -828,7 +828,7 @@ dmxBERestorePixmap(PixmapPtr pPixmap)
     for (i = currentMaxClients; --i >= 0;)
         if (clients[i])
             FindAllClientResources(clients[i], dmxBERestorePixmapImage,
-                                   (pointer) pPixmap);
+                                   (void *) pPixmap);
 
     /* No corresponding pixmap image was found on other screens, so we
      * need to copy it from the saved image when the screen was detached
@@ -895,7 +895,7 @@ dmxBERestorePixmap(PixmapPtr pPixmap)
  *  number passed in as \a n and calls the appropriate DMX function to
  *  create the associated resource on the back-end server. */
 static void
-dmxBECreateResources(pointer value, XID id, RESTYPE type, pointer n)
+dmxBECreateResources(void *value, XID id, RESTYPE type, void *n)
 {
     int scrnNum = (uintptr_t) n;
     ScreenPtr pScreen = screenInfo.screens[scrnNum];
@@ -1121,7 +1121,7 @@ dmxCompareScreens(DMXScreenInfo * new, DMXScreenInfo * old)
 
 /** Restore Render's picture */
 static void
-dmxBERestoreRenderPict(pointer value, XID id, pointer n)
+dmxBERestoreRenderPict(void *value, XID id, void *n)
 {
     PicturePtr pPicture = value;        /* The picture */
     DrawablePtr pDraw = pPicture->pDrawable;    /* The picture's drawable */
@@ -1145,7 +1145,7 @@ dmxBERestoreRenderPict(pointer value, XID id, pointer n)
 
 /** Restore Render's glyphs */
 static void
-dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
+dmxBERestoreRenderGlyph(void *value, XID id, void *n)
 {
     GlyphSetPtr glyphSet = value;
     int scrnNum = (uintptr_t) n;
@@ -1340,7 +1340,7 @@ dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
     for (i = currentMaxClients; --i >= 0;)
         if (clients[i])
             FindAllClientResources(clients[i], dmxBECreateResources,
-                                   (pointer) (uintptr_t) idx);
+                                   (void *) (uintptr_t) idx);
 
     /* Create window hierarchy (top down) */
     dmxBECreateWindowTree(idx);
@@ -1350,14 +1350,14 @@ dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
         if (clients[i])
             FindClientResourcesByType(clients[i], PictureType,
                                       dmxBERestoreRenderPict,
-                                      (pointer) (uintptr_t) idx);
+                                      (void *) (uintptr_t) idx);
 
     /* Restore the glyph state for RENDER */
     for (i = currentMaxClients; --i >= 0;)
         if (clients[i])
             FindClientResourcesByType(clients[i], GlyphSetType,
                                       dmxBERestoreRenderGlyph,
-                                      (pointer) (uintptr_t) idx);
+                                      (void *) (uintptr_t) idx);
 
     /* Refresh screen by generating exposure events for all windows */
     dmxForceExposures(idx);
@@ -1425,7 +1425,7 @@ dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
 /** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs
  *  to have its image saved. */
 static void
-dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type, pointer p)
+dmxBEFindPixmapImage(void *value, XID id, RESTYPE type, void *p)
 {
     if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) {
         PixmapPtr pDst = (PixmapPtr) p;
@@ -1434,7 +1434,7 @@ dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type, pointer p)
         PixmapPtr pPix;
         int i;
 
-        dixLookupResourceByType((pointer *) &pPix, pXinPix->info[idx].id,
+        dixLookupResourceByType((void **) &pPix, pXinPix->info[idx].id,
                                 RT_PIXMAP, NullClient, DixUnknownAccess);
         if (pPix != pDst)
             return;             /* Not a match.... Next! */
@@ -1446,7 +1446,7 @@ dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type, pointer p)
             if (i == idx)
                 continue;       /* Self replication is bad */
 
-            dixLookupResourceByType((pointer *) &pSrc, pXinPix->info[i].id,
+            dixLookupResourceByType((void **) &pSrc, pXinPix->info[i].id,
                                     RT_PIXMAP, NullClient, DixUnknownAccess);
             pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
             if (pSrcPriv->pixmap) {
@@ -1482,7 +1482,7 @@ dmxBESavePixmap(PixmapPtr pPixmap)
     for (i = currentMaxClients; --i >= 0;)
         if (clients[i])
             FindAllClientResources(clients[i], dmxBEFindPixmapImage,
-                                   (pointer) pPixmap);
+                                   (void *) pPixmap);
 
     /* Save the image only if there is no other screens that have a
      * pixmap that corresponds to the one we are trying to save. */
@@ -1522,7 +1522,7 @@ dmxBESavePixmap(PixmapPtr pPixmap)
  *  number passed in as \a n and calls the appropriate DMX function to
  *  free the associated resource on the back-end server. */
 static void
-dmxBEDestroyResources(pointer value, XID id, RESTYPE type, pointer n)
+dmxBEDestroyResources(void *value, XID id, RESTYPE type, void *n)
 {
     int scrnNum = (uintptr_t) n;
     ScreenPtr pScreen = screenInfo.screens[scrnNum];
@@ -1683,7 +1683,7 @@ dmxDetachScreen(int idx)
     for (i = currentMaxClients; --i >= 0;)
         if (clients[i])
             FindAllClientResources(clients[i], dmxBEDestroyResources,
-                                   (pointer) (uintptr_t) idx);
+                                   (void *) (uintptr_t) idx);
 
     /* Free scratch GCs */
     dmxBEDestroyScratchGCs(idx);
diff --git a/hw/dmx/dmxfont.c b/hw/dmx/dmxfont.c
index 7ef7ad9..6b81826 100644
--- a/hw/dmx/dmxfont.c
+++ b/hw/dmx/dmxfont.c
@@ -460,7 +460,7 @@ dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
         pFontPriv->refcnt = 0;
     }
 
-    FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer) pFontPriv);
+    FontSetPrivate(pFont, dmxFontPrivateIndex, (void *) pFontPriv);
 
     if (dmxScreen->beDisplay) {
         if (!dmxBELoadFont(pScreen, pFont))
diff --git a/hw/dmx/dmxgc.c b/hw/dmx/dmxgc.c
index 703aeb3..2d61ea2 100644
--- a/hw/dmx/dmxgc.c
+++ b/hw/dmx/dmxgc.c
@@ -378,7 +378,7 @@ dmxDestroyGC(GCPtr pGC)
 
 /** Change the clip rects for a GC. */
 void
-dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     ScreenPtr pScreen = pGC->pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
diff --git a/hw/dmx/dmxgc.h b/hw/dmx/dmxgc.h
index 7b99d88..c8ecb53 100644
--- a/hw/dmx/dmxgc.h
+++ b/hw/dmx/dmxgc.h
@@ -55,7 +55,7 @@ extern void dmxValidateGC(GCPtr pGC, unsigned long changes,
 extern void dmxChangeGC(GCPtr pGC, unsigned long mask);
 extern void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst);
 extern void dmxDestroyGC(GCPtr pGC);
-extern void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+extern void dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects);
 extern void dmxDestroyClip(GCPtr pGC);
 extern void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
 
diff --git a/hw/dmx/dmxgcops.c b/hw/dmx/dmxgcops.c
index 1933066..aa7c8eb 100644
--- a/hw/dmx/dmxgcops.c
+++ b/hw/dmx/dmxgcops.c
@@ -508,7 +508,7 @@ dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
 void
 dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                  int x, int y, unsigned int nglyph,
-                 CharInfoPtr * ppci, pointer pglyphBase)
+                 CharInfoPtr * ppci, void *pglyphBase)
 {
     /* Error -- this should never happen! */
 }
@@ -517,7 +517,7 @@ dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
 void
 dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                 int x, int y, unsigned int nglyph,
-                CharInfoPtr * ppci, pointer pglyphBase)
+                CharInfoPtr * ppci, void *pglyphBase)
 {
     /* Error -- this should never happen! */
 }
@@ -551,7 +551,7 @@ dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
     if (pDrawable->type != DRAWABLE_PIXMAP)
         return NULL;
 
-    if (Success != dixLookupResourceByType((pointer *) &pXinPix,
+    if (Success != dixLookupResourceByType((void **) &pXinPix,
                                            pDrawable->id, XRT_PIXMAP,
                                            NullClient, DixUnknownAccess))
         return NULL;
@@ -562,7 +562,7 @@ dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
             PixmapPtr pSrc;
             dmxPixPrivPtr pSrcPriv;
 
-            dixLookupResourceByType((pointer *) &pSrc, pXinPix->info[i].id,
+            dixLookupResourceByType((void **) &pSrc, pXinPix->info[i].id,
                                     RT_PIXMAP, NullClient, DixUnknownAccess);
             pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
             if (pSrcPriv->pixmap) {
diff --git a/hw/dmx/dmxgcops.h b/hw/dmx/dmxgcops.h
index 4ba0ad5..529b6ff 100644
--- a/hw/dmx/dmxgcops.h
+++ b/hw/dmx/dmxgcops.h
@@ -78,10 +78,10 @@ extern void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
                            int x, int y, int count, unsigned short *chars);
 extern void dmxImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                              int x, int y, unsigned int nglyph,
-                             CharInfoPtr * ppci, pointer pglyphBase);
+                             CharInfoPtr * ppci, void *pglyphBase);
 extern void dmxPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                             int x, int y, unsigned int nglyph,
-                            CharInfoPtr * ppci, pointer pglyphBase);
+                            CharInfoPtr * ppci, void *pglyphBase);
 extern void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
                           int w, int h, int x, int y);
 
diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c
index c9762c2..64d0ae1 100644
--- a/hw/dmx/dmxpict.c
+++ b/hw/dmx/dmxpict.c
@@ -285,7 +285,7 @@ dmxProcRenderCreateGlyphSet(ClientPtr client)
         /* Store glyphsets from backends in glyphSet->devPrivate ????? */
         /* Make sure we handle all errors here!! */
 
-        dixLookupResourceByType((pointer *) &glyphSet,
+        dixLookupResourceByType((void **) &glyphSet,
                                 stuff->gsid, GlyphSetType,
                                 client, DixDestroyAccess);
 
@@ -332,7 +332,7 @@ dmxProcRenderFreeGlyphSet(ClientPtr client)
     REQUEST(xRenderFreeGlyphSetReq);
 
     REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
-    dixLookupResourceByType((pointer *) &glyphSet,
+    dixLookupResourceByType((void **) &glyphSet,
                             stuff->glyphset, GlyphSetType,
                             client, DixDestroyAccess);
 
@@ -378,7 +378,7 @@ dmxProcRenderAddGlyphs(ClientPtr client)
         CARD8 *bits;
         int nbytes;
 
-        dixLookupResourceByType((pointer *) &glyphSet,
+        dixLookupResourceByType((void **) &glyphSet,
                                 stuff->glyphset, GlyphSetType,
                                 client, DixReadAccess);
         glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
@@ -423,7 +423,7 @@ dmxProcRenderFreeGlyphs(ClientPtr client)
     REQUEST(xRenderFreeGlyphsReq);
 
     REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
-    dixLookupResourceByType((pointer *) &glyphSet,
+    dixLookupResourceByType((void **) &glyphSet,
                             stuff->glyphset, GlyphSetType,
                             client, DixWriteAccess);
 
@@ -498,14 +498,14 @@ dmxProcRenderCompositeGlyphs(ClientPtr client)
         GlyphSetPtr glyphSet;
         dmxGlyphPrivPtr glyphPriv;
 
-        dixLookupResourceByType((pointer *) &pSrc,
+        dixLookupResourceByType((void **) &pSrc,
                                 stuff->src, PictureType, client, DixReadAccess);
 
         pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
         if (!pSrcPriv->pict)
             return ret;
 
-        dixLookupResourceByType((pointer *) &pDst,
+        dixLookupResourceByType((void **) &pDst,
                                 stuff->dst, PictureType,
                                 client, DixWriteAccess);
 
@@ -524,7 +524,7 @@ dmxProcRenderCompositeGlyphs(ClientPtr client)
             return ret;
 
         if (stuff->maskFormat)
-            dixLookupResourceByType((pointer *) &pFmt,
+            dixLookupResourceByType((void **) &pFmt,
                                     stuff->maskFormat, PictFormatType,
                                     client, DixReadAccess);
         else
@@ -585,7 +585,7 @@ dmxProcRenderCompositeGlyphs(ClientPtr client)
         curGlyph = glyphs;
         curElt = elts;
 
-        dixLookupResourceByType((pointer *) &glyphSet,
+        dixLookupResourceByType((void **) &glyphSet,
                                 stuff->glyphset, GlyphSetType,
                                 client, DixReadAccess);
         glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
@@ -595,7 +595,7 @@ dmxProcRenderCompositeGlyphs(ClientPtr client)
             buffer += sizeof(xGlyphElt);
 
             if (elt->len == 0xff) {
-                dixLookupResourceByType((pointer *) &glyphSet,
+                dixLookupResourceByType((void **) &glyphSet,
                                         *((CARD32 *) buffer),
                                         GlyphSetType, client, DixReadAccess);
                 glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
@@ -894,7 +894,7 @@ dmxDestroyPicture(PicturePtr pPicture)
 
 /** Change the picture's list of clip rectangles. */
 int
-dmxChangePictureClip(PicturePtr pPicture, int clipType, pointer value, int n)
+dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n)
 {
     ScreenPtr pScreen = pPicture->pDrawable->pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
diff --git a/hw/dmx/dmxpict.h b/hw/dmx/dmxpict.h
index 6c37be9..080da3b 100644
--- a/hw/dmx/dmxpict.h
+++ b/hw/dmx/dmxpict.h
@@ -65,7 +65,7 @@ extern Bool dmxDestroyPictureList(WindowPtr pWindow);
 extern int dmxCreatePicture(PicturePtr pPicture);
 extern void dmxDestroyPicture(PicturePtr pPicture);
 extern int dmxChangePictureClip(PicturePtr pPicture, int clipType,
-                                pointer value, int n);
+                                void *value, int n);
 extern void dmxDestroyPictureClip(PicturePtr pPicture);
 extern void dmxChangePicture(PicturePtr pPicture, Mask mask);
 extern void dmxValidatePicture(PicturePtr pPicture, Mask mask);
diff --git a/hw/dmx/dmxstat.c b/hw/dmx/dmxstat.c
index 0d8c22a..0ae5107 100644
--- a/hw/dmx/dmxstat.c
+++ b/hw/dmx/dmxstat.c
@@ -175,7 +175,7 @@ dmxStatSync(DMXScreenInfo * dmxScreen,
 
 /* Actually do the work of printing out the human-readable message. */
 static CARD32
-dmxStatCallback(OsTimerPtr timer, CARD32 t, pointer arg)
+dmxStatCallback(OsTimerPtr timer, CARD32 t, void *arg)
 {
     int i, j;
     static int header = 0;
diff --git a/hw/dmx/dmxsync.c b/hw/dmx/dmxsync.c
index bf28584..81dbbc6 100644
--- a/hw/dmx/dmxsync.c
+++ b/hw/dmx/dmxsync.c
@@ -82,7 +82,7 @@ dmxDoSync(DMXScreenInfo * dmxScreen)
 }
 
 static CARD32
-dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
+dmxSyncCallback(OsTimerPtr timer, CARD32 time, void *arg)
 {
     int i;
 
@@ -99,13 +99,13 @@ dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
 }
 
 static void
-dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadMask)
+dmxSyncBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadMask)
 {
     TimerForce(dmxSyncTimer);
 }
 
 static void
-dmxSyncWakeupHandler(pointer blockData, int result, pointer pReadMask)
+dmxSyncWakeupHandler(void *blockData, int result, void *pReadMask)
 {
 }
 
diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index 9b8a384..1c23527 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -86,7 +86,7 @@ dmxCreateRootWindow(WindowPtr pWindow)
     parent = dmxScreen->scrnWin;        /* This is our "Screen" window */
     visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual;
 
-    dixLookupResourceByType((pointer *) &pCmap, wColormap(pWindow),
+    dixLookupResourceByType((void **) &pCmap, wColormap(pWindow),
                             RT_COLORMAP, NullClient, DixUnknownAccess);
     pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
 
@@ -192,7 +192,7 @@ dmxGetDefaultWindowAttributes(WindowPtr pWindow,
             ColormapPtr pCmap;
             dmxColormapPrivPtr pCmapPriv;
 
-            dixLookupResourceByType((pointer *) &pCmap, wColormap(pWindow),
+            dixLookupResourceByType((void **) &pCmap, wColormap(pWindow),
                                     RT_COLORMAP, NullClient, DixUnknownAccess);
             pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
             *cmap = pCmapPriv->cmap;
@@ -561,7 +561,7 @@ dmxDoChangeWindowAttributes(WindowPtr pWindow,
         ColormapPtr pCmap;
         dmxColormapPrivPtr pCmapPriv;
 
-        dixLookupResourceByType((pointer *) &pCmap, wColormap(pWindow),
+        dixLookupResourceByType((void **) &pCmap, wColormap(pWindow),
                                 RT_COLORMAP, NullClient, DixUnknownAccess);
         pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
         attribs->colormap = pCmapPriv->cmap;
diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c
index 190eeef..964db40 100644
--- a/hw/dmx/glxProxy/glxcmds.c
+++ b/hw/dmx/glxProxy/glxcmds.c
@@ -195,7 +195,7 @@ CreateContext(__GLXclientState * cl,
         shareglxc = NULL;
     }
     else {
-        dixLookupResourceByType((pointer *) &shareglxc, shareList,
+        dixLookupResourceByType((void **) &shareglxc, shareList,
                                 __glXContextRes, NullClient, DixUnknownAccess);
         if (!shareglxc) {
             client->errorValue = shareList;
@@ -425,7 +425,7 @@ CreateContext(__GLXclientState * cl,
     /*
      ** Register this context as a resource.
      */
-    if (!AddResource(gcId, __glXContextRes, (pointer) glxc)) {
+    if (!AddResource(gcId, __glXContextRes, (void *) glxc)) {
         free(glxc->real_ids);
         free(glxc->real_vids);
         free(glxc);
@@ -511,14 +511,14 @@ __glXBindSwapBarrierSGIX(__GLXclientState * cl, GLbyte * pc)
 
     rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
     if (rc != Success) {
-        dixLookupResourceByType((pointer *) &pGlxPixmap, req->drawable,
+        dixLookupResourceByType((void **) &pGlxPixmap, req->drawable,
                                 __glXPixmapRes, NullClient, DixUnknownAccess);
         if (pGlxPixmap)
             pDraw = pGlxPixmap->pDraw;
     }
 
     if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-        dixLookupResourceByType((pointer *) &pGlxWindow, req->drawable,
+        dixLookupResourceByType((void **) &pGlxWindow, req->drawable,
                                 __glXWindowRes, NullClient, DixUnknownAccess);
         if (pGlxWindow)
             pDraw = pGlxWindow->pDraw;
@@ -544,14 +544,14 @@ __glXJoinSwapGroupSGIX(__GLXclientState * cl, GLbyte * pc)
 
     rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
     if (rc != Success) {
-        dixLookupResourceByType((pointer *) &pGlxPixmap, req->drawable,
+        dixLookupResourceByType((void **) &pGlxPixmap, req->drawable,
                                 __glXPixmapRes, NullClient, DixUnknownAccess);
         if (pGlxPixmap)
             pDraw = pGlxPixmap->pDraw;
     }
 
     if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-        dixLookupResourceByType((pointer *) &pGlxWindow, req->drawable,
+        dixLookupResourceByType((void **) &pGlxWindow, req->drawable,
                                 __glXWindowRes, NullClient, DixUnknownAccess);
         if (pGlxWindow)
             pDraw = pGlxWindow->pDraw;
@@ -566,7 +566,7 @@ __glXJoinSwapGroupSGIX(__GLXclientState * cl, GLbyte * pc)
         rc = dixLookupDrawable(&pMember, req->member, client, 0,
                                DixGetAttrAccess);
         if (rc != Success) {
-            dixLookupResourceByType((pointer *) &pGlxPixmap, req->member,
+            dixLookupResourceByType((void **) &pGlxPixmap, req->member,
                                     __glXPixmapRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxPixmap)
@@ -574,7 +574,7 @@ __glXJoinSwapGroupSGIX(__GLXclientState * cl, GLbyte * pc)
         }
 
         if (!pMember && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-            dixLookupResourceByType((pointer *) &pGlxWindow, req->member,
+            dixLookupResourceByType((void **) &pGlxWindow, req->member,
                                     __glXWindowRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxWindow)
@@ -605,7 +605,7 @@ __glXDestroyContext(__GLXclientState * cl, GLbyte * pc)
     int to_screen = 0;
     int s;
 
-    dixLookupResourceByType((pointer *) &glxc, gcId, __glXContextRes,
+    dixLookupResourceByType((void **) &glxc, gcId, __glXContextRes,
                             NullClient, DixUnknownAccess);
     if (glxc) {
         /*
@@ -880,7 +880,7 @@ MakeCurrent(__GLXclientState * cl,
      ** Lookup new context.  It must not be current for someone else.
      */
     if (contextId != None) {
-        dixLookupResourceByType((pointer *) &glxc, contextId, __glXContextRes,
+        dixLookupResourceByType((void **) &glxc, contextId, __glXContextRes,
                                 NullClient, DixUnknownAccess);
         if (!glxc) {
             client->errorValue = contextId;
@@ -935,7 +935,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pDraw) {
-            dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
+            dixLookupResourceByType((void **) &pGlxPixmap, drawId,
                                     __glXPixmapRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxPixmap) {
@@ -960,7 +960,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-            dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
+            dixLookupResourceByType((void **) &pGlxWindow, drawId,
                                     __glXWindowRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxWindow) {
@@ -983,7 +983,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-            dixLookupResourceByType((pointer *) &pGlxPbuffer, drawId,
+            dixLookupResourceByType((void **) &pGlxPbuffer, drawId,
                                     __glXPbufferRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxPbuffer) {
@@ -1050,7 +1050,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pReadDraw) {
-            dixLookupResourceByType((pointer *) &pReadGlxPixmap, readId,
+            dixLookupResourceByType((void **) &pReadGlxPixmap, readId,
                                     __glXPixmapRes, NullClient,
                                     DixUnknownAccess);
             if (pReadGlxPixmap) {
@@ -1072,7 +1072,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-            dixLookupResourceByType((pointer *) &pGlxReadWindow, readId,
+            dixLookupResourceByType((void **) &pGlxReadWindow, readId,
                                     __glXWindowRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxReadWindow) {
@@ -1094,7 +1094,7 @@ MakeCurrent(__GLXclientState * cl,
         }
 
         if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-            dixLookupResourceByType((pointer *) &pGlxReadPbuffer, readId,
+            dixLookupResourceByType((void **) &pGlxReadPbuffer, readId,
                                     __glXPbufferRes, NullClient,
                                     DixUnknownAccess);
             if (pGlxReadPbuffer) {
@@ -1236,14 +1236,14 @@ MakeCurrent(__GLXclientState * cl,
         to_screen = screenInfo.numScreens - 1;
 
         if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
-            dixLookupResourceByClass((pointer *) &pXinDraw,
+            dixLookupResourceByClass((void **) &pXinDraw,
                                      pDraw->id, XRC_DRAWABLE,
                                      client, DixReadAccess);
         }
 
         if (pReadDraw && pReadDraw != pDraw &&
             new_reply.readType != GLX_PBUFFER_TYPE) {
-            dixLookupResourceByClass((pointer *) &pXinReadDraw,
+            dixLookupResourceByClass((void **) &pXinReadDraw,
                                      pReadDraw->id, XRC_DRAWABLE,
                                      client, DixReadAccess);
         }
@@ -1460,7 +1460,7 @@ __glXIsDirect(__GLXclientState * cl, GLbyte * pc)
     /*
      ** Find the GL context.
      */
-    dixLookupResourceByType((pointer *) &glxc, req->context, __glXContextRes,
+    dixLookupResourceByType((void **) &glxc, req->context, __glXContextRes,
                             NullClient, DixUnknownAccess);
     if (!glxc) {
         client->errorValue = req->context;
@@ -1619,13 +1619,13 @@ __glXCopyContext(__GLXclientState * cl, GLbyte * pc)
     /*
      ** Check that each context exists.
      */
-    dixLookupResourceByType((pointer *) &src, source, __glXContextRes,
+    dixLookupResourceByType((void **) &src, source, __glXContextRes,
                             NullClient, DixUnknownAccess);
     if (!src) {
         client->errorValue = source;
         return __glXBadContext;
     }
-    dixLookupResourceByType((pointer *) &dst, dest, __glXContextRes,
+    dixLookupResourceByType((void **) &dst, dest, __glXContextRes,
                             NullClient, DixUnknownAccess);
     if (!dst) {
         client->errorValue = dest;
@@ -1925,7 +1925,7 @@ CreateGLXPixmap(__GLXclientState * cl,
         from_screen = 0;
         to_screen = screenInfo.numScreens - 1;
 
-        dixLookupResourceByClass((pointer *) &pXinDraw,
+        dixLookupResourceByClass((void **) &pXinDraw,
                                  pDraw->id, XRC_DRAWABLE,
                                  client, DixReadAccess);
     }
@@ -2055,7 +2055,7 @@ __glXDestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc)
     /*
      ** Check if it's a valid GLX pixmap.
      */
-    dixLookupResourceByType((pointer *) &pGlxPixmap, glxpixmap,
+    dixLookupResourceByType((void **) &pGlxPixmap, glxpixmap,
                             __glXPixmapRes, NullClient, DixUnknownAccess);
     if (!pGlxPixmap) {
         client->errorValue = glxpixmap;
@@ -2141,7 +2141,7 @@ __glXDoSwapBuffers(__GLXclientState * cl, XID drawId, GLXContextTag tag)
     }
 
     if (!pDraw) {
-        dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
+        dixLookupResourceByType((void **) &pGlxPixmap, drawId,
                                 __glXPixmapRes, NullClient, DixUnknownAccess);
         if (pGlxPixmap) {
             /*
@@ -2153,7 +2153,7 @@ __glXDoSwapBuffers(__GLXclientState * cl, XID drawId, GLXContextTag tag)
     }
 
     if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-        dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
+        dixLookupResourceByType((void **) &pGlxWindow, drawId,
                                 __glXWindowRes, NullClient, DixUnknownAccess);
         if (pGlxWindow) {
             /*
@@ -2183,7 +2183,7 @@ __glXDoSwapBuffers(__GLXclientState * cl, XID drawId, GLXContextTag tag)
     if (!noPanoramiXExtension) {
         from_screen = 0;
         to_screen = screenInfo.numScreens - 1;
-        dixLookupResourceByClass((pointer *) &pXinDraw,
+        dixLookupResourceByClass((void **) &pXinDraw,
                                  pDraw->id, XRC_DRAWABLE,
                                  client, DixReadAccess);
     }
@@ -2291,7 +2291,7 @@ __glXSwapBuffers(__GLXclientState * cl, GLbyte * pc)
     }
 
     if (!pDraw) {
-        dixLookupResourceByType((pointer *) &pGlxPixmap, drawId,
+        dixLookupResourceByType((void **) &pGlxPixmap, drawId,
                                 __glXPixmapRes, NullClient, DixUnknownAccess);
         if (pGlxPixmap) {
             /*
@@ -2302,7 +2302,7 @@ __glXSwapBuffers(__GLXclientState * cl, GLbyte * pc)
     }
 
     if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1, 3)) {
-        dixLookupResourceByType((pointer *) &pGlxWindow, drawId,
+        dixLookupResourceByType((void **) &pGlxWindow, drawId,
                                 __glXWindowRes, NullClient, DixUnknownAccess);
         if (pGlxWindow) {
             /*
@@ -2817,12 +2817,12 @@ __glXUseXFont(__GLXclientState * cl, GLbyte * pc)
      ** Font can actually be either the ID of a font or the ID of a GC
      ** containing a font.
      */
-    dixLookupResourceByType((pointer *) &pFont, req->font, RT_FONT,
+    dixLookupResourceByType((void **) &pFont, req->font, RT_FONT,
                             NullClient, DixUnknownAccess);
     if (!pFont) {
         GC *pGC;
 
-        dixLookupResourceByType((pointer *) &pGC, req->font,
+        dixLookupResourceByType((void **) &pGC, req->font,
                                 RT_GC, NullClient, DixUnknownAccess);
         if (!pGC) {
             client->errorValue = req->font;
@@ -3082,7 +3082,7 @@ __glXCreateWindow(__GLXclientState * cl, GLbyte * pc)
     VisualPtr pVisual;
     VisualID visId;
     int i, rc;
-    pointer val;
+    void *val;
 
     /*
      ** Check if windowId is valid 
@@ -3184,7 +3184,7 @@ __glXDestroyWindow(__GLXclientState * cl, GLbyte * pc)
     ClientPtr client = cl->client;
     xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
     XID glxwindow = req->glxwindow;
-    pointer val;
+    void *val;
 
     /*
      ** Check if it's a valid GLX window.
@@ -3216,7 +3216,7 @@ __glXQueryContext(__GLXclientState * cl, GLbyte * pc)
     int nReplyBytes;
 
     req = (xGLXQueryContextReq *) pc;
-    dixLookupResourceByType((pointer *) &ctx, req->context, __glXContextRes,
+    dixLookupResourceByType((void **) &ctx, req->context, __glXContextRes,
                             NullClient, DixUnknownAccess);
     if (!ctx) {
         client->errorValue = req->context;
@@ -3266,7 +3266,7 @@ __glXQueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc)
     int nReplyBytes;
 
     req = (xGLXQueryContextInfoEXTReq *) pc;
-    dixLookupResourceByType((pointer *) &ctx,
+    dixLookupResourceByType((void **) &ctx,
                             req->context, __glXContextRes,
                             client, DixReadAccess);
 
@@ -3439,7 +3439,7 @@ __glXDestroyPbuffer(__GLXclientState * cl, GLbyte * pc)
     /*
      ** Check if it's a valid Pbuffer
      */
-    dixLookupResourceByType((pointer *) &pGlxPbuffer, pbuffer,
+    dixLookupResourceByType((void **) &pGlxPbuffer, pbuffer,
                             __glXPbufferRes, NullClient, DixUnknownAccess);
     if (!pGlxPbuffer) {
         client->errorValue = pbuffer;
@@ -3514,7 +3514,7 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __GLXpixmap *pGlxPixmap;
 
-            dixLookupResourceByType((pointer *) &pGlxPixmap,
+            dixLookupResourceByType((void **) &pGlxPixmap,
                                     drawId, __glXPixmapRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxPixmap) {
@@ -3527,7 +3527,7 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __glXWindow *pGlxWindow;
 
-            dixLookupResourceByType((pointer *) &pGlxWindow,
+            dixLookupResourceByType((void **) &pGlxWindow,
                                     drawId, __glXWindowRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxWindow) {
@@ -3540,7 +3540,7 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __glXPbuffer *pGlxPbuffer;
 
-            dixLookupResourceByType((pointer *) &pGlxPbuffer,
+            dixLookupResourceByType((void **) &pGlxPbuffer,
                                     drawId, __glXPbufferRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxPbuffer) {
@@ -3567,7 +3567,7 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
 
 #ifdef PANORAMIX
         if (!noPanoramiXExtension) {
-            if (Success != dixLookupResourceByClass((pointer *) &pXinDraw,
+            if (Success != dixLookupResourceByClass((void **) &pXinDraw,
                                                     pDraw->id, XRC_DRAWABLE,
                                                     client, DixReadAccess)) {
                 client->errorValue = drawId;
@@ -3676,7 +3676,7 @@ __glXChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __GLXpixmap *pGlxPixmap;
 
-            dixLookupResourceByType((pointer *) &pGlxPixmap,
+            dixLookupResourceByType((void **) &pGlxPixmap,
                                     drawId, __glXPixmapRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxPixmap) {
@@ -3689,7 +3689,7 @@ __glXChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __glXWindow *pGlxWindow;
 
-            dixLookupResourceByType((pointer *) &pGlxWindow,
+            dixLookupResourceByType((void **) &pGlxWindow,
                                     drawId, __glXWindowRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxWindow) {
@@ -3702,7 +3702,7 @@ __glXChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!pDraw) {
             __glXPbuffer *pGlxPbuffer;
 
-            dixLookupResourceByType((pointer *) &pGlxPbuffer,
+            dixLookupResourceByType((void **) &pGlxPbuffer,
                                     drawId, __glXPbufferRes,
                                     NullClient, DixUnknownAccess);
             if (pGlxPbuffer) {
@@ -3731,7 +3731,7 @@ __glXChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc)
         if (!noPanoramiXExtension) {
             PanoramiXRes *pXinDraw;
 
-            if (Success != dixLookupResourceByClass((pointer *) &pXinDraw,
+            if (Success != dixLookupResourceByClass((void **) &pXinDraw,
                                                     pDraw->id, XRC_DRAWABLE,
                                                     client, DixReadAccess)) {
                 client->errorValue = drawId;
diff --git a/hw/dmx/glxProxy/glxext.c b/hw/dmx/glxProxy/glxext.c
index b469708..3c5a14b 100644
--- a/hw/dmx/glxProxy/glxext.c
+++ b/hw/dmx/glxProxy/glxext.c
@@ -182,7 +182,7 @@ __glXFreeGLXWindow(__glXWindow * pGlxWindow)
         WindowPtr pWindow = (WindowPtr) pGlxWindow->pDraw;
         WindowPtr ret;
 
-        dixLookupResourceByType((pointer) &ret,
+        dixLookupResourceByType((void *) &ret,
                                 pWindow->drawable.id, RT_WINDOW,
                                 NullClient, DixUnknownAccess);
         if (ret == pWindow) {
@@ -414,7 +414,7 @@ __glXDispatch(ClientPtr client)
          */
         XID xid = FakeClientID(client->index);
 
-        if (!AddResource(xid, __glXClientRes, (pointer) (long) client->index)) {
+        if (!AddResource(xid, __glXClientRes, (void *) (long) client->index)) {
             return BadAlloc;
         }
         ResetClientState(client->index);
@@ -468,7 +468,7 @@ __glXSwapDispatch(ClientPtr client)
          */
         XID xid = FakeClientID(client->index);
 
-        if (!AddResource(xid, __glXClientRes, (pointer) (long) client->index)) {
+        if (!AddResource(xid, __glXClientRes, (void *) (long) client->index)) {
             return BadAlloc;
         }
         ResetClientState(client->index);
diff --git a/hw/dmx/glxProxy/glxswap.c b/hw/dmx/glxProxy/glxswap.c
index 87a7486..5f56501 100644
--- a/hw/dmx/glxProxy/glxswap.c
+++ b/hw/dmx/glxProxy/glxswap.c
@@ -110,7 +110,7 @@ SwapGroupIsReadyToSwap(SwapGroupPtr pSwap)
 }
 
 static Bool
-SGSwapCleanup(ClientPtr client, pointer closure)
+SGSwapCleanup(ClientPtr client, void *closure)
 {
     /* SwapGroupPtr  pSwap = (SwapGroupPtr)closure; */
 
@@ -154,7 +154,7 @@ SGSwapBuffers(__GLXclientState * cl, XID drawId, GLXContextTag tag,
     else {
         /* The swap group/barrier is not yet ready to swap, so put
          * client to sleep until the rest are ready to swap */
-        ClientSleep(cl->client, SGSwapCleanup, (pointer) pWin);
+        ClientSleep(cl->client, SGSwapCleanup, (void *) pWin);
         pCur->sleeping = TRUE;
     }
 
diff --git a/hw/dmx/input/dmxbackend.c b/hw/dmx/input/dmxbackend.c
index 807e023..56abe80 100644
--- a/hw/dmx/input/dmxbackend.c
+++ b/hw/dmx/input/dmxbackend.c
@@ -101,7 +101,7 @@ typedef struct _myPrivate {
 #endif
 
 /** Create and return a private data structure. */
-pointer
+void *
 dmxBackendCreatePrivate(DeviceIntPtr pDevice)
 {
     GETDMXLOCALFROMPDEVICE;
@@ -115,7 +115,7 @@ dmxBackendCreatePrivate(DeviceIntPtr pDevice)
  * verify that the structure was actually created by
  * #dmxBackendCreatePrivate. */
 void
-dmxBackendDestroyPrivate(pointer private)
+dmxBackendDestroyPrivate(void *private)
 {
     free(private);
 }
@@ -262,7 +262,7 @@ dmxBackendOffscreen(int screen, int x, int y)
 /** This routine is called from #dmxCoreMotion for each motion
  * event. \a x and \a y are global coordinants. */
 void
-dmxBackendUpdatePosition(pointer private, int x, int y)
+dmxBackendUpdatePosition(void *private, int x, int y)
 {
     GETPRIVFROMPRIVATE;
     int screen = miPointerGetScreen(inputInfo.pointer)->myNum;
@@ -500,7 +500,7 @@ dmxBackendCollectEvents(DevicePtr pDev,
  * event processing actually takes place here, but this is a convenient
  * place to update the pointer. */
 void
-dmxBackendProcessInput(pointer private)
+dmxBackendProcessInput(void *private)
 {
     GETPRIVFROMPRIVATE;
 
@@ -650,7 +650,7 @@ dmxBackendKbdGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
 /** Process #DMXFunctionType functions.  The only function handled here
  * is to acknowledge a pending server shutdown. */
 int
-dmxBackendFunctions(pointer private, DMXFunctionType function)
+dmxBackendFunctions(void *private, DMXFunctionType function)
 {
     switch (function) {
     case DMX_FUNCTION_TERMINATE:
diff --git a/hw/dmx/input/dmxbackend.h b/hw/dmx/input/dmxbackend.h
index 6a49a56..a608573 100644
--- a/hw/dmx/input/dmxbackend.h
+++ b/hw/dmx/input/dmxbackend.h
@@ -38,8 +38,8 @@
 #ifndef _DMXBACKEND_H_
 #define _DMXBACKEND_H_
 
-extern pointer dmxBackendCreatePrivate(DeviceIntPtr pDevice);
-extern void dmxBackendDestroyPrivate(pointer private);
+extern void *dmxBackendCreatePrivate(DeviceIntPtr pDevice);
+extern void dmxBackendDestroyPrivate(void *private);
 extern void dmxBackendInit(DevicePtr pDev);
 extern void dmxBackendLateReInit(DevicePtr pDev);
 extern void dmxBackendMouGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
@@ -49,8 +49,8 @@ extern void dmxBackendCollectEvents(DevicePtr pDev,
                                     dmxEnqueueProcPtr enqueue,
                                     dmxCheckSpecialProcPtr checkspecial,
                                     DMXBlockType block);
-extern void dmxBackendProcessInput(pointer private);
-extern int dmxBackendFunctions(pointer private, DMXFunctionType function);
-extern void dmxBackendUpdatePosition(pointer private, int x, int y);
+extern void dmxBackendProcessInput(void *private);
+extern int dmxBackendFunctions(void *private, DMXFunctionType function);
+extern void dmxBackendUpdatePosition(void *private, int x, int y);
 
 #endif
diff --git a/hw/dmx/input/dmxcommon.c b/hw/dmx/input/dmxcommon.c
index 6eb94b2..90154ef 100644
--- a/hw/dmx/input/dmxcommon.c
+++ b/hw/dmx/input/dmxcommon.c
@@ -558,7 +558,7 @@ dmxFindPointerScreen(int x, int y)
  * (e.g., when a keyboard and mouse form a pair that should share the
  * same private area).  If the requested private area cannot be located,
  * then NULL is returned. */
-pointer
+void *
 dmxCommonCopyPrivate(DeviceIntPtr pDevice)
 {
     GETDMXLOCALFROMPDEVICE;
@@ -583,7 +583,7 @@ dmxCommonCopyPrivate(DeviceIntPtr pDevice)
  * server startup and server shutdown).
  */
 void
-dmxCommonSaveState(pointer private)
+dmxCommonSaveState(void *private)
 {
     GETPRIVFROMPRIVATE;
     XKeyboardState ks;
@@ -641,7 +641,7 @@ dmxCommonSaveState(pointer private)
 
 /** This routine restores all the information saved by #dmxCommonSaveState. */
 void
-dmxCommonRestoreState(pointer private)
+dmxCommonRestoreState(void *private)
 {
     GETPRIVFROMPRIVATE;
     int retcode = -1;
diff --git a/hw/dmx/input/dmxcommon.h b/hw/dmx/input/dmxcommon.h
index d4f8d3c..ed04287 100644
--- a/hw/dmx/input/dmxcommon.h
+++ b/hw/dmx/input/dmxcommon.h
@@ -118,7 +118,7 @@ extern void dmxCommonOthOff(DevicePtr pDev);
 extern void dmxCommonOthGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
 
                                 /* helper functions */
-extern pointer dmxCommonCopyPrivate(DeviceIntPtr pDevice);
-extern void dmxCommonSaveState(pointer private);
-extern void dmxCommonRestoreState(pointer private);
+extern void *dmxCommonCopyPrivate(DeviceIntPtr pDevice);
+extern void dmxCommonSaveState(void *private);
+extern void dmxCommonRestoreState(void *private);
 #endif
diff --git a/hw/dmx/input/dmxconsole.c b/hw/dmx/input/dmxconsole.c
index cb80bd8..f33a0eb 100644
--- a/hw/dmx/input/dmxconsole.c
+++ b/hw/dmx/input/dmxconsole.c
@@ -141,7 +141,7 @@ unscaley(myPrivate * priv, int y)
 }
 
 /** Create the private area for \a pDevice. */
-pointer
+void *
 dmxConsoleCreatePrivate(DeviceIntPtr pDevice)
 {
     GETDMXLOCALFROMPDEVICE;
@@ -153,7 +153,7 @@ dmxConsoleCreatePrivate(DeviceIntPtr pDevice)
 
 /** If \a private is non-NULL, free its associated memory. */
 void
-dmxConsoleDestroyPrivate(pointer private)
+dmxConsoleDestroyPrivate(void *private)
 {
     free(private);
 }
@@ -193,7 +193,7 @@ dmxConsoleDrawFineCursor(myPrivate * priv, XRectangle * rect)
 }
 
 static void
-dmxConsoleDrawWindows(pointer private)
+dmxConsoleDrawWindows(void *private)
 {
     GETONLYPRIVFROMPRIVATE;
     Display *dpy = priv->display;
@@ -391,7 +391,7 @@ dmxConsoleUpdateFineCursor(myPrivate * priv)
  * fashion: the actual layout of the windows of the screen might not
  * have had any human-visible changes. */
 void
-dmxConsoleUpdateInfo(pointer private, DMXUpdateType type, WindowPtr pWindow)
+dmxConsoleUpdateInfo(void *private, DMXUpdateType type, WindowPtr pWindow)
 {
     GETONLYPRIVFROMPRIVATE;
     dmxConsoleDraw(priv, 1, 1);
@@ -436,7 +436,7 @@ dmxConsoleMoveRelative(myPrivate * priv, int x, int y,
  * allows the console's notion of the cursor postion to change when
  * another input device actually caused the change. */
 void
-dmxConsoleUpdatePosition(pointer private, int x, int y)
+dmxConsoleUpdatePosition(void *private, int x, int y)
 {
     GETONLYPRIVFROMPRIVATE;
     int tmpX, tmpY;
@@ -941,7 +941,7 @@ dmxConsoleKbdGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
 
 /** Handle special console-only keys. */
 int
-dmxConsoleFunctions(pointer private, DMXFunctionType function)
+dmxConsoleFunctions(void *private, DMXFunctionType function)
 {
     GETONLYPRIVFROMPRIVATE;
     XRectangle rect;
diff --git a/hw/dmx/input/dmxconsole.h b/hw/dmx/input/dmxconsole.h
index 1c52611..ea6033c 100644
--- a/hw/dmx/input/dmxconsole.h
+++ b/hw/dmx/input/dmxconsole.h
@@ -37,8 +37,8 @@
 #ifndef _DMXCONSOLE_H_
 #define _DMXCONSOLE_H_
 
-extern pointer dmxConsoleCreatePrivate(DeviceIntPtr pDevice);
-extern void dmxConsoleDestroyPrivate(pointer private);
+extern void *dmxConsoleCreatePrivate(DeviceIntPtr pDevice);
+extern void dmxConsoleDestroyPrivate(void *private);
 extern void dmxConsoleInit(DevicePtr pDev);
 extern void dmxConsoleReInit(DevicePtr pDev);
 extern void dmxConsoleMouGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
@@ -48,12 +48,12 @@ extern void dmxConsoleCollectEvents(DevicePtr pDev,
                                     dmxEnqueueProcPtr enqueue,
                                     dmxCheckSpecialProcPtr checkspecial,
                                     DMXBlockType block);
-extern int dmxConsoleFunctions(pointer private, DMXFunctionType function);
-extern void dmxConsoleUpdatePosition(pointer private, int x, int y);
-extern void dmxConsoleKbdSetCtrl(pointer private, KeybdCtrl * ctrl);
+extern int dmxConsoleFunctions(void *private, DMXFunctionType function);
+extern void dmxConsoleUpdatePosition(void *private, int x, int y);
+extern void dmxConsoleKbdSetCtrl(void *private, KeybdCtrl * ctrl);
 extern void dmxConsoleCapture(DMXInputInfo * dmxInput);
 extern void dmxConsoleUncapture(DMXInputInfo * dmxInput);
-extern void dmxConsoleUpdateInfo(pointer private,
+extern void dmxConsoleUpdateInfo(void *private,
                                  DMXUpdateType, WindowPtr pWindow);
 
 #endif
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index e06fc87..abb6a85 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -225,7 +225,7 @@ dmxKbdCtrl(DeviceIntPtr pDevice, KeybdCtrl * ctrl)
 
 /* taken from kdrive/src/kinput.c: */
 static void
-dmxBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+dmxBell(int volume, DeviceIntPtr pDev, void *arg, int something)
 {
 #if 0
     KeybdCtrl *ctrl = arg;
@@ -336,7 +336,7 @@ _dmxKeyboardBellProc(DMXLocalInputInfoPtr dmxLocal, int percent)
  * sound the bell on all of the devices that send core events. */
 void
 dmxKeyboardBellProc(int percent, DeviceIntPtr pDevice,
-                    pointer ctrl, int unknown)
+                    void *ctrl, int unknown)
 {
     GETDMXLOCALFROMPDEVICE;
     int i, j;
@@ -633,7 +633,7 @@ dmxCollectAll(DMXInputInfo * dmxInput)
 }
 
 static void
-dmxBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadMask)
+dmxBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadMask)
 {
     DMXInputInfo *dmxInput = &dmxInputs[(uintptr_t) blockData];
     static unsigned long generation = 0;
@@ -645,7 +645,7 @@ dmxBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadMask)
 }
 
 static void
-dmxSwitchReturn(pointer p)
+dmxSwitchReturn(void *p)
 {
     DMXInputInfo *dmxInput = p;
     int i;
@@ -662,7 +662,7 @@ dmxSwitchReturn(pointer p)
 }
 
 static void
-dmxWakeupHandler(pointer blockData, int result, pointer pReadMask)
+dmxWakeupHandler(void *blockData, int result, void *pReadMask)
 {
     DMXInputInfo *dmxInput = &dmxInputs[(uintptr_t) blockData];
     int i;
diff --git a/hw/dmx/input/dmxinputinit.h b/hw/dmx/input/dmxinputinit.h
index 94ec101..11af2ca 100644
--- a/hw/dmx/input/dmxinputinit.h
+++ b/hw/dmx/input/dmxinputinit.h
@@ -127,8 +127,8 @@ typedef struct _DMXLocalInitInfo {
     KeySym *symbols;                          /**< Key symbols */
 } DMXLocalInitInfo, *DMXLocalInitInfoPtr;
 
-typedef pointer (*dmxCreatePrivateProcPtr) (DeviceIntPtr);
-typedef void (*dmxDestroyPrivateProcPtr) (pointer);
+typedef void *(*dmxCreatePrivateProcPtr) (DeviceIntPtr);
+typedef void (*dmxDestroyPrivateProcPtr) (void *);
 
 typedef void (*dmxInitProcPtr) (DevicePtr);
 typedef void (*dmxReInitProcPtr) (DevicePtr);
@@ -136,13 +136,13 @@ typedef void (*dmxLateReInitProcPtr) (DevicePtr);
 typedef void (*dmxGetInfoProcPtr) (DevicePtr, DMXLocalInitInfoPtr);
 typedef int (*dmxOnProcPtr) (DevicePtr);
 typedef void (*dmxOffProcPtr) (DevicePtr);
-typedef void (*dmxUpdatePositionProcPtr) (pointer, int x, int y);
+typedef void (*dmxUpdatePositionProcPtr) (void *, int x, int y);
 
-typedef void (*dmxVTPreSwitchProcPtr) (pointer);        /* Turn I/O Off */
-typedef void (*dmxVTPostSwitchProcPtr) (pointer);       /* Turn I/O On */
-typedef void (*dmxVTSwitchReturnProcPtr) (pointer);
-typedef int (*dmxVTSwitchProcPtr) (pointer, int vt,
-                                   dmxVTSwitchReturnProcPtr, pointer);
+typedef void (*dmxVTPreSwitchProcPtr) (void *);        /* Turn I/O Off */
+typedef void (*dmxVTPostSwitchProcPtr) (void *);       /* Turn I/O On */
+typedef void (*dmxVTSwitchReturnProcPtr) (void *);
+typedef int (*dmxVTSwitchProcPtr) (void *, int vt,
+                                   dmxVTSwitchReturnProcPtr, void *);
 
 typedef void (*dmxMotionProcPtr) (DevicePtr,
                                   int *valuators,
@@ -157,9 +157,9 @@ typedef void (*dmxCollectEventsProcPtr) (DevicePtr,
                                          dmxMotionProcPtr,
                                          dmxEnqueueProcPtr,
                                          dmxCheckSpecialProcPtr, DMXBlockType);
-typedef void (*dmxProcessInputProcPtr) (pointer);
-typedef void (*dmxUpdateInfoProcPtr) (pointer, DMXUpdateType, WindowPtr);
-typedef int (*dmxFunctionsProcPtr) (pointer, DMXFunctionType);
+typedef void (*dmxProcessInputProcPtr) (void *);
+typedef void (*dmxUpdateInfoProcPtr) (void *, DMXUpdateType, WindowPtr);
+typedef int (*dmxFunctionsProcPtr) (void *, DMXFunctionType);
 
 typedef void (*dmxKBCtrlProcPtr) (DevicePtr, KeybdCtrl * ctrl);
 typedef void (*dmxMCtrlProcPtr) (DevicePtr, PtrCtrl * ctrl);
@@ -223,7 +223,7 @@ typedef struct _DMXLocalInputInfo {
     dmxKBCtrlProcPtr kCtrl;                   /**< Keyboard control */
     dmxKBBellProcPtr kBell;                   /**< Bell control */
 
-    pointer private;                          /**< Device-dependent private  */
+    void *private;                            /**< Device-dependent private  */
     int isCore;                               /**< Is a DMX core device  */
     int sendsCore;                            /**< Sends DMX core events */
     KeybdCtrl kctrl;                          /**< Keyboard control */
@@ -269,7 +269,7 @@ extern DMXLocalInputInfoPtr dmxInputCopyLocal(DMXInputInfo * dmxInput,
 extern void dmxChangePointerControl(DeviceIntPtr pDevice, PtrCtrl * ctrl);
 extern void dmxKeyboardKbdCtrlProc(DeviceIntPtr pDevice, KeybdCtrl * ctrl);
 extern void dmxKeyboardBellProc(int percent, DeviceIntPtr pDevice,
-                                pointer ctrl, int unknown);
+                                void *ctrl, int unknown);
 
 extern int dmxInputExtensionErrorHandler(Display * dsp, _Xconst char *name,
                                          _Xconst char *reason);
diff --git a/hw/dmx/input/lnx-keyboard.c b/hw/dmx/input/lnx-keyboard.c
index ecf4f59..1a4d01f 100644
--- a/hw/dmx/input/lnx-keyboard.c
+++ b/hw/dmx/input/lnx-keyboard.c
@@ -361,7 +361,7 @@ static unsigned char at2lnx[NUM_KEYCODES] = {
 };
 
 /** Create a private structure for use within this file. */
-pointer
+void *
 kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard)
 {
     myPrivate *priv = calloc(1, sizeof(*priv));
@@ -373,7 +373,7 @@ kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard)
 
 /** Destroy a private structure. */
 void
-kbdLinuxDestroyPrivate(pointer priv)
+kbdLinuxDestroyPrivate(void *priv)
 {
     free(priv);
 }
@@ -466,13 +466,13 @@ static int kbdLinuxActivate(int fd, int vtno, int setSig);
 
 /** Currently unused hook called prior to an VT switch. */
 void
-kbdLinuxVTPreSwitch(pointer p)
+kbdLinuxVTPreSwitch(void *p)
 {
 }
 
 /** Currently unused hook called after returning from a VT switch. */
 void
-kbdLinuxVTPostSwitch(pointer p)
+kbdLinuxVTPostSwitch(void *p)
 {
 }
 
@@ -481,8 +481,8 @@ kbdLinuxVTPostSwitch(pointer p)
  * switched back to the pre-switch VT (i.e., the user returns to the DMX
  * session). */
 int
-kbdLinuxVTSwitch(pointer p, int vt,
-                 void (*switch_return) (pointer), pointer switch_return_data)
+kbdLinuxVTSwitch(void *p, int vt,
+                 void (*switch_return) (void *), void *switch_return_data)
 {
     myPrivate *priv = p;
 
diff --git a/hw/dmx/input/lnx-keyboard.h b/hw/dmx/input/lnx-keyboard.h
index 891c6a9..857ea11 100644
--- a/hw/dmx/input/lnx-keyboard.h
+++ b/hw/dmx/input/lnx-keyboard.h
@@ -37,19 +37,19 @@
 #ifndef _LNX_KEYBOARD_H_
 #define _LNX_KEYBOARD_H_
 
-extern pointer kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard);
-extern void kbdLinuxDestroyPrivate(pointer private);
+extern void *kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard);
+extern void kbdLinuxDestroyPrivate(void *private);
 
 extern void kbdLinuxInit(DevicePtr pDev);
 extern void kbdLinuxGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
 extern int kbdLinuxOn(DevicePtr pDev);
 extern void kbdLinuxOff(DevicePtr pDev);
 
-extern void kbdLinuxVTPreSwitch(pointer p);
-extern void kbdLinuxVTPostSwitch(pointer p);
-extern int kbdLinuxVTSwitch(pointer p, int vt,
+extern void kbdLinuxVTPreSwitch(void *p);
+extern void kbdLinuxVTPostSwitch(void *p);
+extern int kbdLinuxVTSwitch(void *p, int vt,
                             dmxVTSwitchReturnProcPtr switch_return,
-                            pointer switch_return_data);
+                            void *switch_return_data);
 
 extern void kbdLinuxRead(DevicePtr pDev,
                          dmxMotionProcPtr motion,
diff --git a/hw/dmx/input/lnx-ms.c b/hw/dmx/input/lnx-ms.c
index 7e1acf4..210f6de 100644
--- a/hw/dmx/input/lnx-ms.c
+++ b/hw/dmx/input/lnx-ms.c
@@ -302,18 +302,18 @@ msLinuxGetMap(DevicePtr pDev, unsigned char *map, int *nButtons)
 
 /** Currently unused hook called prior to an VT switch. */
 void
-msLinuxVTPreSwitch(pointer p)
+msLinuxVTPreSwitch(void *p)
 {
 }
 
 /** Currently unused hook called after returning from a VT switch. */
 void
-msLinuxVTPostSwitch(pointer p)
+msLinuxVTPostSwitch(void *p)
 {
 }
 
 /** Create a private structure for use within this file. */
-pointer
+void *
 msLinuxCreatePrivate(DeviceIntPtr pMouse)
 {
     myPrivate *priv = calloc(1, sizeof(*priv));
@@ -325,7 +325,7 @@ msLinuxCreatePrivate(DeviceIntPtr pMouse)
 
 /** Destroy a private structure. */
 void
-msLinuxDestroyPrivate(pointer priv)
+msLinuxDestroyPrivate(void *priv)
 {
     free(priv);
 }
diff --git a/hw/dmx/input/lnx-ms.h b/hw/dmx/input/lnx-ms.h
index 28ed095..7f3ba4e 100644
--- a/hw/dmx/input/lnx-ms.h
+++ b/hw/dmx/input/lnx-ms.h
@@ -37,8 +37,8 @@
 #ifndef _LNX_MS_H_
 #define _LNX_MS_H_
 
-extern pointer msLinuxCreatePrivate(DeviceIntPtr pMouse);
-extern void msLinuxDestroyPrivate(pointer priv);
+extern void *msLinuxCreatePrivate(DeviceIntPtr pMouse);
+extern void msLinuxDestroyPrivate(void *priv);
 extern void msLinuxRead(DevicePtr pDev,
                         dmxMotionProcPtr motion,
                         dmxEnqueueProcPtr enqueue,
@@ -49,7 +49,7 @@ extern void msLinuxGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
 extern int msLinuxOn(DevicePtr pDev);
 extern void msLinuxOff(DevicePtr pDev);
 extern void msLinuxCtrl(DevicePtr pDev, PtrCtrl * ctrl);
-extern void msLinuxVTPreSwitch(pointer p);
-extern void msLinuxVTPostSwitch(pointer p);
+extern void msLinuxVTPreSwitch(void *p);
+extern void msLinuxVTPostSwitch(void *p);
 
 #endif
diff --git a/hw/dmx/input/lnx-ps2.c b/hw/dmx/input/lnx-ps2.c
index 67c73a0..dd70cb8 100644
--- a/hw/dmx/input/lnx-ps2.c
+++ b/hw/dmx/input/lnx-ps2.c
@@ -272,18 +272,18 @@ ps2LinuxGetMap(DevicePtr pDev, unsigned char *map, int *nButtons)
 
 /** Currently unused hook called prior to an VT switch. */
 void
-ps2LinuxVTPreSwitch(pointer p)
+ps2LinuxVTPreSwitch(void *p)
 {
 }
 
 /** Currently unused hook called after returning from a VT switch. */
 void
-ps2LinuxVTPostSwitch(pointer p)
+ps2LinuxVTPostSwitch(void *p)
 {
 }
 
 /** Create a private structure for use within this file. */
-pointer
+void *
 ps2LinuxCreatePrivate(DeviceIntPtr pMouse)
 {
     myPrivate *priv = calloc(1, sizeof(*priv));
@@ -295,7 +295,7 @@ ps2LinuxCreatePrivate(DeviceIntPtr pMouse)
 
 /** Destroy a private structure. */
 void
-ps2LinuxDestroyPrivate(pointer priv)
+ps2LinuxDestroyPrivate(void *priv)
 {
     free(priv);
 }
diff --git a/hw/dmx/input/lnx-ps2.h b/hw/dmx/input/lnx-ps2.h
index 93f0f02..339f353 100644
--- a/hw/dmx/input/lnx-ps2.h
+++ b/hw/dmx/input/lnx-ps2.h
@@ -37,8 +37,8 @@
 #ifndef _LNX_PS2_H_
 #define _LNX_PS2_H_
 
-extern pointer ps2LinuxCreatePrivate(DeviceIntPtr pMouse);
-extern void ps2LinuxDestroyPrivate(pointer priv);
+extern void *ps2LinuxCreatePrivate(DeviceIntPtr pMouse);
+extern void ps2LinuxDestroyPrivate(void *priv);
 extern void ps2LinuxRead(DevicePtr pDev,
                          dmxMotionProcPtr motion,
                          dmxEnqueueProcPtr enqueue,
@@ -49,7 +49,7 @@ extern void ps2LinuxGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info);
 extern int ps2LinuxOn(DevicePtr pDev);
 extern void ps2LinuxOff(DevicePtr pDev);
 extern void ps2LinuxCtrl(DevicePtr pDev, PtrCtrl * ctrl);
-extern void ps2LinuxVTPreSwitch(pointer p);
-extern void ps2LinuxVTPostSwitch(pointer p);
+extern void ps2LinuxVTPreSwitch(void *p);
+extern void ps2LinuxVTPostSwitch(void *p);
 
 #endif
diff --git a/hw/dmx/input/usb-common.c b/hw/dmx/input/usb-common.c
index c7c166c..67aa07e 100644
--- a/hw/dmx/input/usb-common.c
+++ b/hw/dmx/input/usb-common.c
@@ -474,7 +474,7 @@ usbOff(DevicePtr pDev)
 }
 
 /** Create a private structure for use within this file. */
-pointer
+void *
 usbCreatePrivate(DeviceIntPtr pDevice)
 {
     myPrivate *priv = calloc(1, sizeof(*priv));
@@ -486,7 +486,7 @@ usbCreatePrivate(DeviceIntPtr pDevice)
 
 /** Destroy a private structure. */
 void
-usbDestroyPrivate(pointer priv)
+usbDestroyPrivate(void *priv)
 {
     free(priv);
 }
diff --git a/hw/dmx/input/usb-common.h b/hw/dmx/input/usb-common.h
index eea98af..7159376 100644
--- a/hw/dmx/input/usb-common.h
+++ b/hw/dmx/input/usb-common.h
@@ -43,8 +43,8 @@ typedef enum {
     usbOther
 } usbType;
 
-extern pointer usbCreatePrivate(DeviceIntPtr pDevice);
-extern void usbDestroyPrivate(pointer priv);
+extern void *usbCreatePrivate(DeviceIntPtr pDevice);
+extern void usbDestroyPrivate(void *priv);
 extern void usbRead(DevicePtr pDev,
                     dmxMotionProcPtr motion,
                     dmxEnqueueProcPtr enqueue,
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index b2a7985..12c7086 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -341,7 +341,7 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen)
 }
 
 static void
-ephyrInternalDamageBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+ephyrInternalDamageBlockHandler(void *data, OSTimePtr pTimeout, void *pRead)
 {
     ScreenPtr pScreen = (ScreenPtr) data;
 
@@ -349,7 +349,7 @@ ephyrInternalDamageBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
 }
 
 static void
-ephyrInternalDamageWakeupHandler(pointer data, int i, pointer LastSelectMask)
+ephyrInternalDamageWakeupHandler(void *data, int i, void *LastSelectMask)
 {
     /* FIXME: Not needed ? */
 }
@@ -368,7 +368,7 @@ ephyrSetInternalDamage(ScreenPtr pScreen)
 
     if (!RegisterBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler,
                                         ephyrInternalDamageWakeupHandler,
-                                        (pointer) pScreen))
+                                        (void *) pScreen))
         return FALSE;
 
     pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
@@ -389,7 +389,7 @@ ephyrUnsetInternalDamage(ScreenPtr pScreen)
 
     RemoveBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler,
                                  ephyrInternalDamageWakeupHandler,
-                                 (pointer) pScreen);
+                                 (void *) pScreen);
 }
 
 #ifdef RANDR
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index 4a05721..c672835 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -84,15 +84,15 @@ static Bool ephyrXVPrivSaveImageToPortPriv(EphyrPortPriv * a_port_priv,
                                            int a_image_len);
 
 static void ephyrStopVideo(KdScreenInfo * a_info,
-                           pointer a_xv_priv, Bool a_exit);
+                           void *a_xv_priv, Bool a_exit);
 
 static int ephyrSetPortAttribute(KdScreenInfo * a_info,
                                  Atom a_attr_name,
-                                 int a_attr_value, pointer a_port_priv);
+                                 int a_attr_value, void *a_port_priv);
 
 static int ephyrGetPortAttribute(KdScreenInfo * a_screen_info,
                                  Atom a_attr_name,
-                                 int *a_attr_value, pointer a_port_priv);
+                                 int *a_attr_value, void *a_port_priv);
 
 static void ephyrQueryBestSize(KdScreenInfo * a_info,
                                Bool a_motion,
@@ -101,7 +101,7 @@ static void ephyrQueryBestSize(KdScreenInfo * a_info,
                                short a_drw_w,
                                short a_drw_h,
                                unsigned int *a_prefered_w,
-                               unsigned int *a_prefered_h, pointer a_port_priv);
+                               unsigned int *a_prefered_h, void *a_port_priv);
 
 static int ephyrPutImage(KdScreenInfo * a_info,
                          DrawablePtr a_drawable,
@@ -118,13 +118,13 @@ static int ephyrPutImage(KdScreenInfo * a_info,
                          short a_width,
                          short a_height,
                          Bool a_sync,
-                         RegionPtr a_clipping_region, pointer a_port_priv);
+                         RegionPtr a_clipping_region, void *a_port_priv);
 
 static int ephyrReputImage(KdScreenInfo * a_info,
                            DrawablePtr a_drawable,
                            short a_drw_x,
                            short a_drw_y,
-                           RegionPtr a_clipping_region, pointer a_port_priv);
+                           RegionPtr a_clipping_region, void *a_port_priv);
 
 static int ephyrPutVideo(KdScreenInfo * a_info,
                          DrawablePtr a_drawable,
@@ -132,7 +132,7 @@ static int ephyrPutVideo(KdScreenInfo * a_info,
                          short a_drw_x, short a_drw_y,
                          short a_vid_w, short a_vid_h,
                          short a_drw_w, short a_drw_h,
-                         RegionPtr a_clip_region, pointer a_port_priv);
+                         RegionPtr a_clip_region, void *a_port_priv);
 
 static int ephyrGetVideo(KdScreenInfo * a_info,
                          DrawablePtr a_drawable,
@@ -140,7 +140,7 @@ static int ephyrGetVideo(KdScreenInfo * a_info,
                          short a_drw_x, short a_drw_y,
                          short a_vid_w, short a_vid_h,
                          short a_drw_w, short a_drw_h,
-                         RegionPtr a_clip_region, pointer a_port_priv);
+                         RegionPtr a_clip_region, void *a_port_priv);
 
 static int ephyrPutStill(KdScreenInfo * a_info,
                          DrawablePtr a_drawable,
@@ -148,7 +148,7 @@ static int ephyrPutStill(KdScreenInfo * a_info,
                          short a_drw_x, short a_drw_y,
                          short a_vid_w, short a_vid_h,
                          short a_drw_w, short a_drw_h,
-                         RegionPtr a_clip_region, pointer a_port_priv);
+                         RegionPtr a_clip_region, void *a_port_priv);
 
 static int ephyrGetStill(KdScreenInfo * a_info,
                          DrawablePtr a_drawable,
@@ -156,7 +156,7 @@ static int ephyrGetStill(KdScreenInfo * a_info,
                          short a_drw_x, short a_drw_y,
                          short a_vid_w, short a_vid_h,
                          short a_drw_w, short a_drw_h,
-                         RegionPtr a_clip_region, pointer a_port_priv);
+                         RegionPtr a_clip_region, void *a_port_priv);
 
 static int ephyrQueryImageAttributes(KdScreenInfo * a_info,
                                      int a_id,
@@ -744,7 +744,7 @@ ephyrXVPrivSaveImageToPortPriv(EphyrPortPriv * a_port_priv,
 }
 
 static void
-ephyrStopVideo(KdScreenInfo * a_info, pointer a_port_priv, Bool a_exit)
+ephyrStopVideo(KdScreenInfo * a_info, void *a_port_priv, Bool a_exit)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
     EphyrPortPriv *port_priv = a_port_priv;
@@ -759,7 +759,7 @@ ephyrStopVideo(KdScreenInfo * a_info, pointer a_port_priv, Bool a_exit)
 
 static int
 ephyrSetPortAttribute(KdScreenInfo * a_info,
-                      Atom a_attr_name, int a_attr_value, pointer a_port_priv)
+                      Atom a_attr_name, int a_attr_value, void *a_port_priv)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
     int res = Success, host_atom = 0;
@@ -814,7 +814,7 @@ ephyrSetPortAttribute(KdScreenInfo * a_info,
 
 static int
 ephyrGetPortAttribute(KdScreenInfo * a_screen_info,
-                      Atom a_attr_name, int *a_attr_value, pointer a_port_priv)
+                      Atom a_attr_name, int *a_attr_value, void *a_port_priv)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
     int res = Success, host_atom = 0;
@@ -862,7 +862,7 @@ ephyrQueryBestSize(KdScreenInfo * a_info,
                    short a_drw_w,
                    short a_drw_h,
                    unsigned int *a_prefered_w,
-                   unsigned int *a_prefered_h, pointer a_port_priv)
+                   unsigned int *a_prefered_h, void *a_port_priv)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
     EphyrPortPriv *port_priv = a_port_priv;
@@ -992,7 +992,7 @@ ephyrPutImage(KdScreenInfo * a_info,
               unsigned char *a_buf,
               short a_width,
               short a_height,
-              Bool a_sync, RegionPtr a_clipping_region, pointer a_port_priv)
+              Bool a_sync, RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrPortPriv *port_priv = a_port_priv;
     Bool is_ok = FALSE;
@@ -1064,7 +1064,7 @@ static int
 ephyrReputImage(KdScreenInfo * a_info,
                 DrawablePtr a_drawable,
                 short a_drw_x,
-                short a_drw_y, RegionPtr a_clipping_region, pointer a_port_priv)
+                short a_drw_y, RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrPortPriv *port_priv = a_port_priv;
     int result = BadImplementation;
@@ -1107,7 +1107,7 @@ ephyrPutVideo(KdScreenInfo * a_info,
               short a_drw_x, short a_drw_y,
               short a_vid_w, short a_vid_h,
               short a_drw_w, short a_drw_h,
-              RegionPtr a_clipping_region, pointer a_port_priv)
+              RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrScrPriv *scrpriv = a_info->driver;
     xcb_connection_t *conn = hostx_get_xcbconn();
@@ -1138,7 +1138,7 @@ ephyrGetVideo(KdScreenInfo * a_info,
               short a_drw_x, short a_drw_y,
               short a_vid_w, short a_vid_h,
               short a_drw_w, short a_drw_h,
-              RegionPtr a_clipping_region, pointer a_port_priv)
+              RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrScrPriv *scrpriv = a_info->driver;
     xcb_connection_t *conn = hostx_get_xcbconn();
@@ -1170,7 +1170,7 @@ ephyrPutStill(KdScreenInfo * a_info,
               short a_drw_x, short a_drw_y,
               short a_vid_w, short a_vid_h,
               short a_drw_w, short a_drw_h,
-              RegionPtr a_clipping_region, pointer a_port_priv)
+              RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrScrPriv *scrpriv = a_info->driver;
     xcb_connection_t *conn = hostx_get_xcbconn();
@@ -1201,7 +1201,7 @@ ephyrGetStill(KdScreenInfo * a_info,
               short a_drw_x, short a_drw_y,
               short a_vid_w, short a_vid_h,
               short a_drw_w, short a_drw_h,
-              RegionPtr a_clipping_region, pointer a_port_priv)
+              RegionPtr a_clipping_region, void *a_port_priv)
 {
     EphyrScrPriv *scrpriv = a_info->driver;
     xcb_connection_t *conn = hostx_get_xcbconn();
diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c
index 00de2ae..6284de5 100644
--- a/hw/kdrive/linux/linux.c
+++ b/hw/kdrive/linux/linux.c
@@ -167,14 +167,14 @@ LinuxSetSwitchMode(int mode)
 }
 
 static void
-LinuxApmBlock(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+LinuxApmBlock(void *blockData, OSTimePtr pTimeout, void *pReadmask)
 {
 }
 
 static Bool LinuxApmRunning;
 
 static void
-LinuxApmWakeup(pointer blockData, int result, pointer pReadmask)
+LinuxApmWakeup(void *blockData, int result, void *pReadmask)
 {
     fd_set *readmask = (fd_set *) pReadmask;
 
diff --git a/hw/kdrive/src/kcmap.c b/hw/kdrive/src/kcmap.c
index c93c2f4..0970064 100644
--- a/hw/kdrive/src/kcmap.c
+++ b/hw/kdrive/src/kcmap.c
@@ -138,7 +138,7 @@ KdInstallColormap(ColormapPtr pCmap)
     /* Tell X clients that the installed colormap is going away. */
     if (pScreenPriv->pInstalledmap)
         WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
-                 (pointer) &(pScreenPriv->pInstalledmap->mid));
+                 (void *) &(pScreenPriv->pInstalledmap->mid));
 
     /* Take note of the new installed colorscreen-> */
     pScreenPriv->pInstalledmap = pCmap;
@@ -146,7 +146,7 @@ KdInstallColormap(ColormapPtr pCmap)
     KdSetColormap(pCmap->pScreen);
 
     /* Tell X clients of the new colormap */
-    WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
+    WalkTree(pCmap->pScreen, TellGainedMap, (void *) &(pCmap->mid));
 }
 
 /*
@@ -173,13 +173,13 @@ KdUninstallColormap(ColormapPtr pCmap)
         return;
 
     /* install default */
-    dixLookupResourceByType((pointer *) &defMap, defMapID, RT_COLORMAP,
+    dixLookupResourceByType((void **) &defMap, defMapID, RT_COLORMAP,
                             serverClient, DixInstallAccess);
     if (defMap)
         (*pCmap->pScreen->InstallColormap) (defMap);
     else {
         /* uninstall and clear colormap pointer */
-        WalkTree(pCmap->pScreen, TellLostMap, (pointer) &(pCmap->mid));
+        WalkTree(pCmap->pScreen, TellLostMap, (void *) &(pCmap->mid));
         pScreenPriv->pInstalledmap = 0;
     }
 }
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 3829684..8eb8cd0 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -665,7 +665,7 @@ KdCloseScreen(ScreenPtr pScreen)
 
     pScreenPriv->screen->pScreen = 0;
 
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
     return ret;
 }
 
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index 296d611..bec75cb 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -526,11 +526,11 @@ void
  KdSetLed(KdKeyboardInfo * ki, int led, Bool on);
 
 void
- KdSetPointerMatrix(KdPointerMatrix * pointer);
+ KdSetPointerMatrix(KdPointerMatrix *pointer);
 
 void
 
-KdComputePointerMatrix(KdPointerMatrix * pointer, Rotation randr, int width,
+KdComputePointerMatrix(KdPointerMatrix *pointer, Rotation randr, int width,
                        int height);
 
 void
@@ -538,11 +538,11 @@ void
 
 void
 
-KdBlockHandler(ScreenPtr pScreen, pointer timeout, pointer readmask);
+KdBlockHandler(ScreenPtr pScreen, void *timeout, void *readmask);
 
 void
 
-KdWakeupHandler(ScreenPtr pScreen, unsigned long result, pointer readmask);
+KdWakeupHandler(ScreenPtr pScreen, unsigned long result, void *readmask);
 
 void
  KdDisableInput(void);
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index a9a9fa5..7d09e28 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -533,7 +533,7 @@ LegalModifier(unsigned int key, DeviceIntPtr pDev)
 }
 
 static void
-KdBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+KdBell(int volume, DeviceIntPtr pDev, void *arg, int something)
 {
     KeybdCtrl *ctrl = arg;
     KdKeyboardInfo *ki = NULL;
@@ -1940,7 +1940,7 @@ _KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z,
 }
 
 void
-KdBlockHandler(ScreenPtr pScreen, pointer timeout, pointer readmask)
+KdBlockHandler(ScreenPtr pScreen, void *timeout, void *readmask)
 {
     KdPointerInfo *pi;
     int myTimeout = 0;
@@ -1966,7 +1966,7 @@ KdBlockHandler(ScreenPtr pScreen, pointer timeout, pointer readmask)
 }
 
 void
-KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, pointer readmask)
+KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, void *readmask)
 {
     int result = (int) lresult;
     fd_set *pReadmask = (fd_set *) readmask;
diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c
index 2263972..9e76ead 100644
--- a/hw/kdrive/src/kxv.c
+++ b/hw/kdrive/src/kxv.c
@@ -208,7 +208,7 @@ KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * adaptors, int num)
        sure that I appreciate that.  */
 
     ScreenPriv = malloc(sizeof(KdXVScreenRec));
-    pxvs->devPriv.ptr = (pointer) ScreenPriv;
+    pxvs->devPriv.ptr = (void *) ScreenPriv;
 
     if (!ScreenPriv)
         return FALSE;
@@ -487,7 +487,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
         adaptorPriv->PutImage = adaptorPtr->PutImage;
         adaptorPriv->ReputImage = adaptorPtr->ReputImage;
 
-        pa->devPriv.ptr = (pointer) adaptorPriv;
+        pa->devPriv.ptr = (void *) adaptorPriv;
 
         if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
             KdXVFreeAdaptor(pa);
@@ -874,7 +874,7 @@ KdXVReputImage(XvPortRecPrivatePtr portPriv)
 }
 
 static int
-KdXVReputAllVideo(WindowPtr pWin, pointer data)
+KdXVReputAllVideo(WindowPtr pWin, void *data)
 {
     KdXVWindowPtr WinPriv;
 
diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h
index 29118bc..4f644c2 100644
--- a/hw/kdrive/src/kxv.h
+++ b/hw/kdrive/src/kxv.h
@@ -98,41 +98,41 @@ typedef int (*PutVideoFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                 short vid_x, short vid_y, short drw_x,
                                 short drw_y, short vid_w, short vid_h,
                                 short drw_w, short drw_h, RegionPtr clipBoxes,
-                                pointer data);
+                                void *data);
 typedef int (*PutStillFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                 short vid_x, short vid_y, short drw_x,
                                 short drw_y, short vid_w, short vid_h,
                                 short drw_w, short drw_h, RegionPtr clipBoxes,
-                                pointer data);
+                                void *data);
 typedef int (*GetVideoFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                 short vid_x, short vid_y, short drw_x,
                                 short drw_y, short vid_w, short vid_h,
                                 short drw_w, short drw_h, RegionPtr clipBoxes,
-                                pointer data);
+                                void *data);
 typedef int (*GetStillFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                 short vid_x, short vid_y, short drw_x,
                                 short drw_y, short vid_w, short vid_h,
                                 short drw_w, short drw_h, RegionPtr clipBoxes,
-                                pointer data);
-typedef void (*StopVideoFuncPtr) (KdScreenInfo * screen, pointer data,
+                                void *data);
+typedef void (*StopVideoFuncPtr) (KdScreenInfo * screen, void *data,
                                   Bool Exit);
 typedef int (*SetPortAttributeFuncPtr) (KdScreenInfo * screen, Atom attribute,
-                                        int value, pointer data);
+                                        int value, void *data);
 typedef int (*GetPortAttributeFuncPtr) (KdScreenInfo * screen, Atom attribute,
-                                        int *value, pointer data);
+                                        int *value, void *data);
 typedef void (*QueryBestSizeFuncPtr) (KdScreenInfo * screen, Bool motion,
                                       short vid_w, short vid_h, short drw_w,
                                       short drw_h, unsigned int *p_w,
-                                      unsigned int *p_h, pointer data);
+                                      unsigned int *p_h, void *data);
 typedef int (*PutImageFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                 short src_x, short src_y, short drw_x,
                                 short drw_y, short src_w, short src_h,
                                 short drw_w, short drw_h, int image,
                                 unsigned char *buf, short width, short height,
-                                Bool Sync, RegionPtr clipBoxes, pointer data);
+                                Bool Sync, RegionPtr clipBoxes, void *data);
 typedef int (*ReputImageFuncPtr) (KdScreenInfo * screen, DrawablePtr pDraw,
                                   short drw_x, short drw_y, RegionPtr clipBoxes,
-                                  pointer data);
+                                  void *data);
 typedef int (*QueryImageAttributesFuncPtr) (KdScreenInfo * screen, int image,
                                             unsigned short *width,
                                             unsigned short *height,
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index ec3c47a..d102722 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -458,7 +458,7 @@ vfbUninstallColormap(ColormapPtr pmap)
 
     if (pmap == curpmap) {
         if (pmap->mid != pmap->pScreen->defColormap) {
-            dixLookupResourceByType((pointer *) &curpmap,
+            dixLookupResourceByType((void **) &curpmap,
                                     pmap->pScreen->defColormap,
                                     RT_COLORMAP, serverClient,
                                     DixInstallAccess);
@@ -506,7 +506,7 @@ vfbSaveScreen(ScreenPtr pScreen, int on)
 
 /* this flushes any changes to the screens out to the mmapped file */
 static void
-vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+vfbBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadmask)
 {
     int i;
 
@@ -527,7 +527,7 @@ vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
 }
 
 static void
-vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
+vfbWakeupHandler(void *blockData, int result, void *pReadmask)
 {
 }
 
diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index f547efd..cff340c 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -42,38 +42,38 @@ typedef union {
 extern Bool VidModeExtensionInit(ScreenPtr pScreen);
 
 extern _X_EXPORT Bool VidModeAvailable(int scrnIndex);
-extern _X_EXPORT Bool VidModeGetCurrentModeline(int scrnIndex, pointer *mode,
+extern _X_EXPORT Bool VidModeGetCurrentModeline(int scrnIndex, void **mode,
                                                 int *dotClock);
-extern _X_EXPORT Bool VidModeGetFirstModeline(int scrnIndex, pointer *mode,
+extern _X_EXPORT Bool VidModeGetFirstModeline(int scrnIndex, void **mode,
                                               int *dotClock);
-extern _X_EXPORT Bool VidModeGetNextModeline(int scrnIndex, pointer *mode,
+extern _X_EXPORT Bool VidModeGetNextModeline(int scrnIndex, void **mode,
                                              int *dotClock);
-extern _X_EXPORT Bool VidModeDeleteModeline(int scrnIndex, pointer mode);
+extern _X_EXPORT Bool VidModeDeleteModeline(int scrnIndex, void *mode);
 extern _X_EXPORT Bool VidModeZoomViewport(int scrnIndex, int zoom);
 extern _X_EXPORT Bool VidModeGetViewPort(int scrnIndex, int *x, int *y);
 extern _X_EXPORT Bool VidModeSetViewPort(int scrnIndex, int x, int y);
-extern _X_EXPORT Bool VidModeSwitchMode(int scrnIndex, pointer mode);
+extern _X_EXPORT Bool VidModeSwitchMode(int scrnIndex, void *mode);
 extern _X_EXPORT Bool VidModeLockZoom(int scrnIndex, Bool lock);
-extern _X_EXPORT Bool VidModeGetMonitor(int scrnIndex, pointer *monitor);
+extern _X_EXPORT Bool VidModeGetMonitor(int scrnIndex, void **monitor);
 extern _X_EXPORT int VidModeGetNumOfClocks(int scrnIndex, Bool *progClock);
 extern _X_EXPORT Bool VidModeGetClocks(int scrnIndex, int *Clocks);
 extern _X_EXPORT ModeStatus VidModeCheckModeForMonitor(int scrnIndex,
-                                                       pointer mode);
+                                                       void *mode);
 extern _X_EXPORT ModeStatus VidModeCheckModeForDriver(int scrnIndex,
-                                                      pointer mode);
-extern _X_EXPORT void VidModeSetCrtcForMode(int scrnIndex, pointer mode);
-extern _X_EXPORT Bool VidModeAddModeline(int scrnIndex, pointer mode);
+                                                      void *mode);
+extern _X_EXPORT void VidModeSetCrtcForMode(int scrnIndex, void *mode);
+extern _X_EXPORT Bool VidModeAddModeline(int scrnIndex, void *mode);
 extern _X_EXPORT int VidModeGetDotClock(int scrnIndex, int Clock);
 extern _X_EXPORT int VidModeGetNumOfModes(int scrnIndex);
 extern _X_EXPORT Bool VidModeSetGamma(int scrnIndex, float red, float green,
                                       float blue);
 extern _X_EXPORT Bool VidModeGetGamma(int scrnIndex, float *red, float *green,
                                       float *blue);
-extern _X_EXPORT pointer VidModeCreateMode(void);
-extern _X_EXPORT void VidModeCopyMode(pointer modefrom, pointer modeto);
-extern _X_EXPORT int VidModeGetModeValue(pointer mode, int valtyp);
-extern _X_EXPORT void VidModeSetModeValue(pointer mode, int valtyp, int val);
-extern _X_EXPORT vidMonitorValue VidModeGetMonitorValue(pointer monitor,
+extern _X_EXPORT void *VidModeCreateMode(void);
+extern _X_EXPORT void VidModeCopyMode(void *modefrom, void *modeto);
+extern _X_EXPORT int VidModeGetModeValue(void *mode, int valtyp);
+extern _X_EXPORT void VidModeSetModeValue(void *mode, int valtyp, int val);
+extern _X_EXPORT vidMonitorValue VidModeGetMonitorValue(void *monitor,
                                                         int valtyp, int indx);
 extern _X_EXPORT Bool VidModeSetGammaRamp(int, int, CARD16 *, CARD16 *,
                                           CARD16 *);
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 143be1e..89025fe 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -128,7 +128,7 @@ extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn,
                                                  void *dummy, EntityProc init,
                                                  EntityProc enter,
                                                  EntityProc leave,
-                                                 pointer private);
+                                                 void *private);
 /* Obsolete! don't use */
 extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
                                                 int entityIndex,
@@ -136,7 +136,7 @@ extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
                                                 void *dummy, EntityProc init,
                                                 EntityProc enter,
                                                 EntityProc leave,
-                                                pointer private);
+                                                void *private);
 #else
 #define xf86VGAarbiterInit() do {} while (0)
 #define xf86VGAarbiterFini() do {} while (0)
@@ -166,7 +166,7 @@ extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn,
 extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex);
 extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
                                          EntityProc enter, EntityProc leave,
-                                         pointer);
+                                         void *);
 extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex);
 extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex);
 
@@ -216,18 +216,18 @@ extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
 /* xf86Events.c */
 
 extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
-extern _X_EXPORT pointer xf86AddInputHandler(int fd, InputHandlerProc proc,
-                                             pointer data);
-extern _X_EXPORT int xf86RemoveInputHandler(pointer handler);
-extern _X_EXPORT void xf86DisableInputHandler(pointer handler);
-extern _X_EXPORT void xf86EnableInputHandler(pointer handler);
-extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc,
-                                               pointer data);
-extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
+extern _X_EXPORT void *xf86AddInputHandler(int fd, InputHandlerProc proc,
+                                             void *data);
+extern _X_EXPORT int xf86RemoveInputHandler(void *handler);
+extern _X_EXPORT void xf86DisableInputHandler(void *handler);
+extern _X_EXPORT void xf86EnableInputHandler(void *handler);
+extern _X_EXPORT void *xf86AddGeneralHandler(int fd, InputHandlerProc proc,
+                                               void *data);
+extern _X_EXPORT int xf86RemoveGeneralHandler(void *handler);
+extern _X_EXPORT void xf86DisableGeneralHandler(void *handler);
+extern _X_EXPORT void xf86EnableGeneralHandler(void *handler);
 extern _X_EXPORT InputHandlerProc xf86SetConsoleHandler(InputHandlerProc
-                                                        handler, pointer data);
+                                                        handler, void *data);
 extern _X_EXPORT void xf86InterceptSignals(int *signo);
 extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler) (void));
 extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
@@ -237,7 +237,7 @@ extern _X_EXPORT Bool xf86VTOwner(void);
 
 /* xf86Helper.c */
 
-extern _X_EXPORT void xf86AddDriver(DriverPtr driver, pointer module,
+extern _X_EXPORT void xf86AddDriver(DriverPtr driver, void *module,
                                     int flags);
 extern _X_EXPORT void xf86DeleteDriver(int drvIndex);
 extern _X_EXPORT ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags);
@@ -328,36 +328,36 @@ xf86DisableRandR(void);
 extern _X_EXPORT CARD32
 xorgGetVersion(void);
 extern _X_EXPORT CARD32
-xf86GetModuleVersion(pointer module);
-extern _X_EXPORT pointer
+xf86GetModuleVersion(void *module);
+extern _X_EXPORT void *
 xf86LoadDrvSubModule(DriverPtr drv, const char *name);
-extern _X_EXPORT pointer
+extern _X_EXPORT void *
 xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
-extern _X_EXPORT pointer
-xf86LoadOneModule(const char *name, pointer optlist);
+extern _X_EXPORT void *
+xf86LoadOneModule(const char *name, void *optlist);
 extern _X_EXPORT void
-xf86UnloadSubModule(pointer mod);
+xf86UnloadSubModule(void *mod);
 extern _X_EXPORT Bool
 xf86LoaderCheckSymbol(const char *name);
 extern _X_EXPORT void
 xf86SetBackingStore(ScreenPtr pScreen);
 extern _X_EXPORT void
 xf86SetSilkenMouse(ScreenPtr pScreen);
-extern _X_EXPORT pointer
+extern _X_EXPORT void *
 xf86FindXvOptions(ScrnInfoPtr pScrn, int adapt_index, const char *port_name,
-                  const char **adaptor_name, pointer *adaptor_options);
+                  const char **adaptor_name, void **adaptor_options);
 extern _X_EXPORT void
 xf86GetOS(const char **name, int *major, int *minor, int *teeny);
 extern _X_EXPORT ScrnInfoPtr
 xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
                    int entityIndex, EntityProc init,
-                   EntityProc enter, EntityProc leave, pointer private);
+                   EntityProc enter, EntityProc leave, void *private);
 
 extern _X_EXPORT Bool
 xf86IsScreenPrimary(ScrnInfoPtr pScrn);
 extern _X_EXPORT int
 xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
-                               int format, unsigned long len, pointer value);
+                               int format, unsigned long len, void *value);
 extern _X_EXPORT Bool
 xf86IsUnblank(int mode);
 
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index d463e91..507c57d 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -288,7 +288,7 @@ xf86IsEntityPrimary(int entityIndex)
 
 Bool
 xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
-                   EntityProc leave, pointer private)
+                   EntityProc leave, void *private)
 {
     if (entityIndex >= xf86NumEntities)
         return FALSE;
diff --git a/hw/xfree86/common/xf86Bus.h b/hw/xfree86/common/xf86Bus.h
index e83ba78..c59625d 100644
--- a/hw/xfree86/common/xf86Bus.h
+++ b/hw/xfree86/common/xf86Bus.h
@@ -51,7 +51,7 @@ typedef struct {
     EntityProc entityInit;
     EntityProc entityEnter;
     EntityProc entityLeave;
-    pointer private;
+    void *private;
     Bool active;
     Bool inUse;
     BusRec bus;
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index de50ec0..5be1693 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -237,7 +237,7 @@ xf86ValidateFontPath(char *path)
  * that we need at this point
  */
 const char **
-xf86ModulelistFromConfig(pointer **optlist)
+xf86ModulelistFromConfig(void ***optlist)
 {
     int count = 0, i = 0;
     const char **modulearray;
@@ -246,7 +246,7 @@ xf86ModulelistFromConfig(pointer **optlist)
         "freetype", "type1",
         NULL
     };
-    pointer *optarray;
+    void **optarray;
     XF86LoadPtr modp;
     Bool found;
 
@@ -352,7 +352,7 @@ xf86ModulelistFromConfig(pointer **optlist)
      * allocate the memory and walk the list again to fill in the pointers
      */
     modulearray = xnfalloc((count + 1) * sizeof(char *));
-    optarray = xnfalloc((count + 1) * sizeof(pointer));
+    optarray = xnfalloc((count + 1) * sizeof(void *));
     count = 0;
     if (xf86configptr->conf_modules) {
         modp = xf86configptr->conf_modules->mod_load_lst;
@@ -2446,7 +2446,7 @@ xf86HandleConfigFile(Bool autoconfig)
     else {
         if (xf86configptr->conf_flags != NULL) {
             char *dfltlayout = NULL;
-            pointer optlist = xf86configptr->conf_flags->flg_option_lst;
+            void *optlist = xf86configptr->conf_flags->flg_option_lst;
 
             if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
                 dfltlayout =
diff --git a/hw/xfree86/common/xf86Config.h b/hw/xfree86/common/xf86Config.h
index 84013e1..23fb383 100644
--- a/hw/xfree86/common/xf86Config.h
+++ b/hw/xfree86/common/xf86Config.h
@@ -59,7 +59,7 @@ typedef struct _ModuleDefault {
 /*
  * prototypes
  */
-const char **xf86ModulelistFromConfig(pointer **);
+const char **xf86ModulelistFromConfig(void ***);
 const char **xf86DriverlistFromConfig(void);
 const char **xf86DriverlistFromCompile(void);
 const char **xf86InputDriverlistFromConfig(void);
diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index 6a05ce5..b9e1e3f 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -450,7 +450,7 @@ xf86SetDGAMode(ScrnInfoPtr pScrn, int num, DGADevicePtr devRet)
                                             pMode->pixmapHeight, pMode->depth,
                                             pMode->bitsPerPixel,
                                             pMode->bytesPerScanline,
-                                            (pointer) (pMode->address));
+                                            (void *) (pMode->address));
         }
     }
 
@@ -1214,7 +1214,7 @@ DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 
 static void XDGAResetProc(ExtensionEntry * extEntry);
 
-static void DGAClientStateChange(CallbackListPtr *, pointer, pointer);
+static void DGAClientStateChange(CallbackListPtr *, void *, void *);
 
 static DevPrivateKeyRec DGAScreenPrivateKeyRec;
 
@@ -1404,7 +1404,7 @@ ProcXDGAQueryModes(ClientPtr client)
 }
 
 static void
-DGAClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+DGAClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata)
 {
     NewClientInfoRec *pci = (NewClientInfoRec *) calldata;
     ClientPtr client = NULL;
@@ -1484,7 +1484,7 @@ ProcXDGASetMode(ClientPtr client)
     DGA_SETCLIENT(stuff->screen, client);
 
     if (pPix) {
-        if (AddResource(stuff->pid, RT_PIXMAP, (pointer) (pPix))) {
+        if (AddResource(stuff->pid, RT_PIXMAP, (void *) (pPix))) {
             pPix->drawable.id = (int) stuff->pid;
             rep.flags = DGA_PIXMAP_AVAILABLE;
         }
@@ -1562,7 +1562,7 @@ ProcXDGAInstallColormap(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
 
-    rc = dixLookupResourceByType((pointer *) &cmap, stuff->cmap, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &cmap, stuff->cmap, RT_COLORMAP,
                                  client, DixInstallAccess);
     if (rc != Success)
         return rc;
@@ -1991,7 +1991,7 @@ ProcXF86DGAInstallColormap(ClientPtr client)
     if (!DGAActive(stuff->screen))
         return DGAErrorBase + XF86DGADirectNotActivated;
 
-    rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
+    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
                                  client, DixInstallAccess);
     if (rc == Success) {
         DGAInstallCmap(pcmp);
diff --git a/hw/xfree86/common/xf86DPMS.c b/hw/xfree86/common/xf86DPMS.c
index 881cb27..14d1f45 100644
--- a/hw/xfree86/common/xf86DPMS.c
+++ b/hw/xfree86/common/xf86DPMS.c
@@ -60,7 +60,7 @@ xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
 #ifdef DPMSExtension
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     DPMSPtr pDPMS;
-    pointer DPMSOpt;
+    void *DPMSOpt;
     MessageType enabled_from;
 
     DPMSKey = &DPMSKeyRec;
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index d0b1431..cae7873 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -114,7 +114,7 @@ static void xf86VTSwitch(void);
 typedef struct x_IHRec {
     int fd;
     InputHandlerProc ihproc;
-    pointer data;
+    void *data;
     Bool enabled;
     Bool is_input;
     struct x_IHRec *next;
@@ -243,7 +243,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 
 /* ARGSUSED */
 void
-xf86Wakeup(pointer blockData, int err, pointer pReadmask)
+xf86Wakeup(void *blockData, int err, void *pReadmask)
 {
     fd_set *LastSelectMask = (fd_set *) pReadmask;
     fd_set devicesWithInput;
@@ -583,8 +583,8 @@ xf86VTSwitch(void)
 
 /* Input handler registration */
 
-static pointer
-addInputHandler(int fd, InputHandlerProc proc, pointer data)
+static void *
+addInputHandler(int fd, InputHandlerProc proc, void *data)
 {
     IHPtr ih;
 
@@ -606,8 +606,8 @@ addInputHandler(int fd, InputHandlerProc proc, pointer data)
     return ih;
 }
 
-pointer
-xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data)
+void *
+xf86AddInputHandler(int fd, InputHandlerProc proc, void *data)
 {
     IHPtr ih = addInputHandler(fd, proc, data);
 
@@ -618,8 +618,8 @@ xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data)
     return ih;
 }
 
-pointer
-xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
+void *
+xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data)
 {
     IHPtr ih = addInputHandler(fd, proc, data);
 
@@ -634,7 +634,7 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
  * proc may be NULL if the server should not handle events on the console.
  */
 InputHandlerProc
-xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
+xf86SetConsoleHandler(InputHandlerProc proc, void *data)
 {
     static IHPtr handler = NULL;
     InputHandlerProc old_proc = NULL;
@@ -667,7 +667,7 @@ removeInputHandler(IHPtr ih)
 }
 
 int
-xf86RemoveInputHandler(pointer handler)
+xf86RemoveInputHandler(void *handler)
 {
     IHPtr ih;
     int fd;
@@ -686,7 +686,7 @@ xf86RemoveInputHandler(pointer handler)
 }
 
 int
-xf86RemoveGeneralHandler(pointer handler)
+xf86RemoveGeneralHandler(void *handler)
 {
     IHPtr ih;
     int fd;
@@ -705,7 +705,7 @@ xf86RemoveGeneralHandler(pointer handler)
 }
 
 void
-xf86DisableInputHandler(pointer handler)
+xf86DisableInputHandler(void *handler)
 {
     IHPtr ih;
 
@@ -719,7 +719,7 @@ xf86DisableInputHandler(pointer handler)
 }
 
 void
-xf86DisableGeneralHandler(pointer handler)
+xf86DisableGeneralHandler(void *handler)
 {
     IHPtr ih;
 
@@ -733,7 +733,7 @@ xf86DisableGeneralHandler(pointer handler)
 }
 
 void
-xf86EnableInputHandler(pointer handler)
+xf86EnableInputHandler(void *handler)
 {
     IHPtr ih;
 
@@ -747,7 +747,7 @@ xf86EnableInputHandler(pointer handler)
 }
 
 void
-xf86EnableGeneralHandler(pointer handler)
+xf86EnableGeneralHandler(void *handler)
 {
     IHPtr ih;
 
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index a59f4fc..0916dec 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -67,7 +67,7 @@ static int xf86ScrnInfoPrivateCount = 0;
 /* Add a pointer to a new DriverRec to xf86DriverList */
 
 void
-xf86AddDriver(DriverPtr driver, pointer module, int flags)
+xf86AddDriver(DriverPtr driver, void *module, int flags)
 {
     /* Don't add null entries */
     if (!driver)
@@ -107,7 +107,7 @@ xf86DeleteDriver(int drvIndex)
 /* Add a pointer to a new InputDriverRec to xf86InputDriverList */
 
 void
-xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
+xf86AddInputDriver(InputDriverPtr driver, void *module, int flags)
 {
     /* Don't add null entries */
     if (!driver)
@@ -1529,15 +1529,15 @@ xf86DisableRandR(void)
 }
 
 CARD32
-xf86GetModuleVersion(pointer module)
+xf86GetModuleVersion(void *module)
 {
     return (CARD32) LoaderGetModuleVersion(module);
 }
 
-pointer
+void *
 xf86LoadDrvSubModule(DriverPtr drv, const char *name)
 {
-    pointer ret;
+    void *ret;
     int errmaj = 0, errmin = 0;
 
     ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
@@ -1547,10 +1547,10 @@ xf86LoadDrvSubModule(DriverPtr drv, const char *name)
     return ret;
 }
 
-pointer
+void *
 xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
 {
-    pointer ret;
+    void *ret;
     int errmaj = 0, errmin = 0;
 
     ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
@@ -1563,12 +1563,12 @@ xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
 /*
  * xf86LoadOneModule loads a single module.
  */
-pointer
-xf86LoadOneModule(const char *name, pointer opt)
+void *
+xf86LoadOneModule(const char *name, void *opt)
 {
     int errmaj, errmin;
     char *Name;
-    pointer mod;
+    void *mod;
 
     if (!name)
         return NULL;
@@ -1592,7 +1592,7 @@ xf86LoadOneModule(const char *name, pointer opt)
 }
 
 void
-xf86UnloadSubModule(pointer mod)
+xf86UnloadSubModule(void *mod)
 {
     UnloadSubModule(mod);
 }
@@ -1695,9 +1695,9 @@ xf86SetSilkenMouse(ScreenPtr pScreen)
 
 /* Wrote this function for the PM2 Xv driver, preliminary. */
 
-pointer
+void *
 xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
-                  const char **adaptor_name, pointer *adaptor_options)
+                  const char **adaptor_name, void **adaptor_options)
 {
     confXvAdaptorPtr adaptor;
     int i;
@@ -1729,7 +1729,7 @@ xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
 
 static void
 xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
-                           EntityProc enter, EntityProc leave, pointer private)
+                           EntityProc enter, EntityProc leave, void *private)
 {
     ScrnInfoPtr pScrn;
 
@@ -1741,7 +1741,7 @@ xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
 ScrnInfoPtr
 xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
                    EntityProc init, EntityProc enter, EntityProc leave,
-                   pointer private)
+                   void *private)
 {
     EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
 
@@ -1783,7 +1783,7 @@ xf86IsScreenPrimary(ScrnInfoPtr pScrn)
 
 int
 xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
-                               int format, unsigned long len, pointer value)
+                               int format, unsigned long len, void *value)
 {
     RootWinPropPtr pNewProp = NULL, pRegProp;
     Bool existing = FALSE;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 6feedc8..7c72aa9 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -396,7 +396,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
 {
     int i, j, k, scr_index;
     const char **modulelist;
-    pointer *optionlist;
+    void **optionlist;
     Pix24Flags screenpix24, pix24;
     MessageType pix24From = X_DEFAULT;
     Bool pix24Fail = FALSE;
@@ -1538,10 +1538,10 @@ ddxUseMsg(void)
  * xf86LoadModules iterates over a list that is being passed in.
  */
 Bool
-xf86LoadModules(const char **list, pointer *optlist)
+xf86LoadModules(const char **list, void **optlist)
 {
     int errmaj, errmin;
-    pointer opt;
+    void *opt;
     int i;
     char *name;
     Bool failed = FALSE;
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 396f63c..b6ec19d 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -170,12 +170,12 @@ typedef struct {
 #define INITARGS void
 
 /* Prototypes for Loader functions that are exported to modules */
-extern _X_EXPORT pointer LoadSubModule(pointer, const char *, const char **,
-                                       const char **, pointer,
+extern _X_EXPORT void *LoadSubModule(void *, const char *, const char **,
+                                       const char **, void *,
                                        const XF86ModReqInfo *, int *, int *);
-extern _X_EXPORT void UnloadSubModule(pointer);
-extern _X_EXPORT void UnloadModule(pointer);
-extern _X_EXPORT pointer LoaderSymbol(const char *);
+extern _X_EXPORT void UnloadSubModule(void *);
+extern _X_EXPORT void UnloadModule(void *);
+extern _X_EXPORT void *LoaderSymbol(const char *);
 extern _X_EXPORT const char **LoaderListDirs(const char **, const char **);
 extern _X_EXPORT void LoaderFreeDirList(char **);
 extern _X_EXPORT void LoaderErrorMsg(const char *, const char *, int, int);
@@ -184,11 +184,11 @@ extern _X_EXPORT void LoaderGetOS(const char **name, int *major, int *minor,
 extern _X_EXPORT Bool LoaderShouldIgnoreABI(void);
 extern _X_EXPORT int LoaderGetABIVersion(const char *abiclass);
 
-typedef pointer (*ModuleSetupProc) (pointer, pointer, int *, int *);
-typedef void (*ModuleTearDownProc) (pointer);
+typedef void *(*ModuleSetupProc) (void *, void *, int *, int *);
+typedef void (*ModuleTearDownProc) (void *);
 
-#define MODULESETUPPROTO(func) pointer func(pointer, pointer, int*, int*)
-#define MODULETEARDOWNPROTO(func) void func(pointer)
+#define MODULESETUPPROTO(func) void *func(void *, void *, int*, int*)
+#define MODULETEARDOWNPROTO(func) void func(void *)
 
 typedef struct {
     XF86ModuleVersionInfo *vers;
diff --git a/hw/xfree86/common/xf86PM.c b/hw/xfree86/common/xf86PM.c
index 15257cb..9e49e8e 100644
--- a/hw/xfree86/common/xf86PM.c
+++ b/hw/xfree86/common/xf86PM.c
@@ -196,7 +196,7 @@ DoApmEvent(pmEvent event, Bool undo)
 #define MAX_NO_EVENTS 8
 
 void
-xf86HandlePMEvents(int fd, pointer data)
+xf86HandlePMEvents(int fd, void *data)
 {
     pmEvent events[MAX_NO_EVENTS];
     int i, n;
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 5239a6b..6e374eb 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -139,11 +139,11 @@ DoShowOptions(void)
 /* xf86Events.c */
 
 extern _X_EXPORT void
-xf86Wakeup(pointer blockData, int err, pointer pReadmask);
+xf86Wakeup(void *blockData, int err, void *pReadmask);
 extern _X_HIDDEN int
 xf86SigWrapper(int signo);
 extern _X_EXPORT void
-xf86HandlePMEvents(int fd, pointer data);
+xf86HandlePMEvents(int fd, void *data);
 extern _X_EXPORT int (*xf86PMGetEventFromOs) (int fd, pmEvent * events,
                                               int num);
 extern _X_EXPORT pmWait (*xf86PMConfirmEventToOs) (int fd, pmEvent event);
@@ -156,7 +156,7 @@ xf86CloseLog(enum ExitCode error);
 
 /* xf86Init.c */
 extern _X_EXPORT Bool
-xf86LoadModules(const char **list, pointer *optlist);
+xf86LoadModules(const char **list, void **optlist);
 extern _X_EXPORT int
 xf86SetVerbosity(int verb);
 extern _X_EXPORT int
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index ddcb3ca..f7a9c9f 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -140,7 +140,7 @@ typedef struct _RootWinProp {
     Atom type;
     short format;
     long size;
-    pointer data;
+    void *data;
 } RootWinProp, *RootWinPropPtr;
 
 /* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
diff --git a/hw/xfree86/common/xf86VGAarbiter.c b/hw/xfree86/common/xf86VGAarbiter.c
index 225fff0..5cc2429 100644
--- a/hw/xfree86/common/xf86VGAarbiter.c
+++ b/hw/xfree86/common/xf86VGAarbiter.c
@@ -257,7 +257,7 @@ VGAarbiterCloseScreen(ScreenPtr pScreen)
     UNWRAP_SCREEN_INFO(FreeScreen);
     UNWRAP_SPRITE;
 
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
     xf86VGAarbiterLock(xf86ScreenToScrn(pScreen));
     val = (*pScreen->CloseScreen) (pScreen);
     xf86VGAarbiterUnlock(xf86ScreenToScrn(pScreen));
@@ -266,7 +266,7 @@ VGAarbiterCloseScreen(ScreenPtr pScreen)
 
 static void
 VGAarbiterBlockHandler(ScreenPtr pScreen,
-                       pointer pTimeout, pointer pReadmask)
+                       void *pTimeout, void *pReadmask)
 {
     SCREEN_PROLOG(BlockHandler);
     VGAGet(pScreen);
@@ -277,7 +277,7 @@ VGAarbiterBlockHandler(ScreenPtr pScreen,
 
 static void
 VGAarbiterWakeupHandler(ScreenPtr pScreen, unsigned long result,
-                        pointer pReadmask)
+                        void *pReadmask)
 {
     SCREEN_PROLOG(WakeupHandler);
     VGAGet(pScreen);
@@ -586,7 +586,7 @@ VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
 }
 
 static void
-VGAarbiterChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+VGAarbiterChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     GC_UNWRAP(pGC);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
@@ -860,7 +860,7 @@ VGAarbiterImageGlyphBlt(DrawablePtr pDraw,
                         GCPtr pGC,
                         int xInit, int yInit,
                         unsigned int nglyph,
-                        CharInfoPtr * ppci, pointer pglyphBase)
+                        CharInfoPtr * ppci, void *pglyphBase)
 {
     ScreenPtr pScreen = pGC->pScreen;
 
@@ -877,7 +877,7 @@ VGAarbiterPolyGlyphBlt(DrawablePtr pDraw,
                        GCPtr pGC,
                        int xInit, int yInit,
                        unsigned int nglyph,
-                       CharInfoPtr * ppci, pointer pglyphBase)
+                       CharInfoPtr * ppci, void *pglyphBase)
 {
     ScreenPtr pScreen = pGC->pScreen;
 
diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h
index f91de0c..ec21bc2 100644
--- a/hw/xfree86/common/xf86VGAarbiterPriv.h
+++ b/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -142,10 +142,10 @@ typedef struct _VGAarbiterGC {
 } VGAarbiterGCRec, *VGAarbiterGCPtr;
 
 /* Screen funcs */
-static void VGAarbiterBlockHandler(ScreenPtr pScreen, pointer pTimeout,
-                                   pointer pReadmask);
+static void VGAarbiterBlockHandler(ScreenPtr pScreen, void *pTimeout,
+                                   void *pReadmask);
 static void VGAarbiterWakeupHandler(ScreenPtr pScreen,
-                                    unsigned long result, pointer pReadmask);
+                                    unsigned long result, void *pReadmask);
 static Bool VGAarbiterCloseScreen(ScreenPtr pScreen);
 static void VGAarbiterGetImage(DrawablePtr pDrawable, int sx, int sy, int w,
                                int h, unsigned int format,
@@ -188,7 +188,7 @@ static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes,
 static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask);
 static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
 static void VGAarbiterDestroyGC(GCPtr pGC);
-static void VGAarbiterChangeClip(GCPtr pGC, int type, pointer pvalue,
+static void VGAarbiterChangeClip(GCPtr pGC, int type, void *pvalue,
                                  int nrects);
 static void VGAarbiterDestroyClip(GCPtr pGC);
 static void VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
@@ -236,10 +236,10 @@ static void VGAarbiterImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
                                   int count, unsigned short *chars);
 static void VGAarbiterImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
                                     int yInit, unsigned int nglyph,
-                                    CharInfoPtr * ppci, pointer pglyphBase);
+                                    CharInfoPtr * ppci, void *pglyphBase);
 static void VGAarbiterPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
                                    int yInit, unsigned int nglyph,
-                                   CharInfoPtr * ppci, pointer pglyphBase);
+                                   CharInfoPtr * ppci, void *pglyphBase);
 static void VGAarbiterPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr
                                  pDraw, int dx, int dy, int xOrg, int yOrg);
 
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index a7d1c25..e708b27 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -138,7 +138,7 @@ VidModeAvailable(int scrnIndex)
 }
 
 Bool
-VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
+VidModeGetCurrentModeline(int scrnIndex, void **mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
 
@@ -148,7 +148,7 @@ VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
     pScrn = xf86Screens[scrnIndex];
 
     if (pScrn->currentMode) {
-        *mode = (pointer) (pScrn->currentMode);
+        *mode = (void *) (pScrn->currentMode);
         *dotClock = pScrn->currentMode->Clock;
 
         return TRUE;
@@ -211,7 +211,7 @@ VidModeGetClocks(int scrnIndex, int *Clocks)
 }
 
 Bool
-VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
+VidModeGetFirstModeline(int scrnIndex, void **mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
@@ -228,7 +228,7 @@ VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
     pVidMode->Next = pVidMode->First->next;
 
     if (pVidMode->First->status == MODE_OK) {
-        *mode = (pointer) (pVidMode->First);
+        *mode = (void *) (pVidMode->First);
         *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
         return TRUE;
     }
@@ -237,7 +237,7 @@ VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
 }
 
 Bool
-VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
+VidModeGetNextModeline(int scrnIndex, void **mode, int *dotClock)
 {
     ScrnInfoPtr pScrn;
     VidModePtr pVidMode;
@@ -252,7 +252,7 @@ VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
     for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
         if (p->status == MODE_OK) {
             pVidMode->Next = p->next;
-            *mode = (pointer) p;
+            *mode = (void *) p;
             *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
             return TRUE;
         }
@@ -262,7 +262,7 @@ VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
 }
 
 Bool
-VidModeDeleteModeline(int scrnIndex, pointer mode)
+VidModeDeleteModeline(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -323,7 +323,7 @@ VidModeGetViewPort(int scrnIndex, int *x, int *y)
 }
 
 Bool
-VidModeSwitchMode(int scrnIndex, pointer mode)
+VidModeSwitchMode(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr pTmpMode;
@@ -362,7 +362,7 @@ VidModeLockZoom(int scrnIndex, Bool lock)
 }
 
 Bool
-VidModeGetMonitor(int scrnIndex, pointer *monitor)
+VidModeGetMonitor(int scrnIndex, void **monitor)
 {
     ScrnInfoPtr pScrn;
 
@@ -370,13 +370,13 @@ VidModeGetMonitor(int scrnIndex, pointer *monitor)
         return FALSE;
 
     pScrn = xf86Screens[scrnIndex];
-    *monitor = (pointer) (pScrn->monitor);
+    *monitor = (void *) (pScrn->monitor);
 
     return TRUE;
 }
 
 ModeStatus
-VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
+VidModeCheckModeForMonitor(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -389,7 +389,7 @@ VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
 }
 
 ModeStatus
-VidModeCheckModeForDriver(int scrnIndex, pointer mode)
+VidModeCheckModeForDriver(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -402,7 +402,7 @@ VidModeCheckModeForDriver(int scrnIndex, pointer mode)
 }
 
 void
-VidModeSetCrtcForMode(int scrnIndex, pointer mode)
+VidModeSetCrtcForMode(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
     DisplayModePtr ScreenModes;
@@ -421,7 +421,7 @@ VidModeSetCrtcForMode(int scrnIndex, pointer mode)
 }
 
 Bool
-VidModeAddModeline(int scrnIndex, pointer mode)
+VidModeAddModeline(int scrnIndex, void *mode)
 {
     ScrnInfoPtr pScrn;
 
@@ -444,7 +444,7 @@ VidModeAddModeline(int scrnIndex, pointer mode)
 int
 VidModeGetNumOfModes(int scrnIndex)
 {
-    pointer mode = NULL;
+    void *mode = NULL;
     int dotClock = 0, nummodes = 0;
 
     if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
@@ -526,7 +526,7 @@ VidModeGetGammaRampSize(int scrnIndex)
     return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
 }
 
-pointer
+void *
 VidModeCreateMode(void)
 {
     DisplayModePtr mode;
@@ -543,13 +543,13 @@ VidModeCreateMode(void)
 }
 
 void
-VidModeCopyMode(pointer modefrom, pointer modeto)
+VidModeCopyMode(void *modefrom, void *modeto)
 {
     memcpy(modeto, modefrom, sizeof(DisplayModeRec));
 }
 
 int
-VidModeGetModeValue(pointer mode, int valtyp)
+VidModeGetModeValue(void *mode, int valtyp)
 {
     int ret = 0;
 
@@ -592,7 +592,7 @@ VidModeGetModeValue(pointer mode, int valtyp)
 }
 
 void
-VidModeSetModeValue(pointer mode, int valtyp, int val)
+VidModeSetModeValue(void *mode, int valtyp, int val)
 {
     switch (valtyp) {
     case VIDMODE_H_DISPLAY:
@@ -633,7 +633,7 @@ VidModeSetModeValue(pointer mode, int valtyp, int val)
 }
 
 vidMonitorValue
-VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
+VidModeGetMonitorValue(void *monitor, int valtyp, int indx)
 {
     vidMonitorValue ret = { NULL, };
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 5b0b6a1..3a01513 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -107,7 +107,7 @@ static int
  * Eval config and modify DeviceVelocityRec accordingly
  */
 static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, const char *devname, pointer list,
+ProcessVelocityConfiguration(DeviceIntPtr pDev, const char *devname, void *list,
                              DeviceVelocityPtr s)
 {
     int tempi;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index b95fbe5..f94261a 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -74,7 +74,7 @@ typedef struct _InputDriverRec {
                     struct _InputInfoRec * pInfo, int flags);
     void (*UnInit) (struct _InputDriverRec * drv,
                     struct _InputInfoRec * pInfo, int flags);
-    pointer module;
+    void *module;
     const char **default_options;
 } InputDriverRec, *InputDriverPtr;
 
@@ -97,10 +97,10 @@ typedef struct _InputInfoRec {
 
     int fd;
     DeviceIntPtr dev;
-    pointer private;
+    void *private;
     const char *type_name;
     InputDriverPtr drv;
-    pointer module;
+    void *module;
     XF86OptionPtr options;
     InputAttributes *attrs;
 } *InputInfoPtr;
@@ -178,7 +178,7 @@ int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
 InputInfoPtr xf86AllocateInput(void);
 
 /* xf86Helper.c */
-extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module,
+extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, void *module,
                                          int flags);
 extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex);
 extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index 85f35f8..3f9c880 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -224,7 +224,7 @@ xf86HandleColormaps(ScreenPtr pScreen,
     ComputeGamma(pScreenPriv);
 
     /* get the default map */
-    dixLookupResourceByType((pointer *) &pDefMap, pScreen->defColormap,
+    dixLookupResourceByType((void **) &pDefMap, pScreen->defColormap,
                             RT_COLORMAP, serverClient, DixInstallAccess);
 
     if (!CMapAllocateColormapPrivate(pDefMap)) {
diff --git a/hw/xfree86/common/xf86fbman.c b/hw/xfree86/common/xf86fbman.c
index 4da6af2..dafaad3 100644
--- a/hw/xfree86/common/xf86fbman.c
+++ b/hw/xfree86/common/xf86fbman.c
@@ -74,7 +74,7 @@ xf86FBManagerRunning(ScreenPtr pScreen)
 Bool
 xf86RegisterFreeBoxCallback(ScreenPtr pScreen,
                             FreeBoxCallbackProcPtr FreeBoxCallback,
-                            pointer devPriv)
+                            void *devPriv)
 {
     FBManagerFuncsPtr funcs;
 
@@ -93,7 +93,7 @@ xf86AllocateOffscreenArea(ScreenPtr pScreen,
                           int w, int h,
                           int gran,
                           MoveAreaCallbackProcPtr moveCB,
-                          RemoveAreaCallbackProcPtr removeCB, pointer privData)
+                          RemoveAreaCallbackProcPtr removeCB, void *privData)
 {
     FBManagerFuncsPtr funcs;
 
@@ -113,7 +113,7 @@ xf86AllocateOffscreenLinear(ScreenPtr pScreen,
                             int gran,
                             MoveLinearCallbackProcPtr moveCB,
                             RemoveLinearCallbackProcPtr removeCB,
-                            pointer privData)
+                            void *privData)
 {
     FBManagerFuncsPtr funcs;
 
@@ -309,7 +309,7 @@ SendCallFreeBoxCallbacks(FBManagerPtr offman)
 static Bool
 localRegisterFreeBoxCallback(ScreenPtr pScreen,
                              FreeBoxCallbackProcPtr FreeBoxCallback,
-                             pointer devPriv)
+                             void *devPriv)
 {
     FBManagerPtr offman;
     FreeBoxCallbackProcPtr *newCallbacks;
@@ -346,7 +346,7 @@ AllocateArea(FBManagerPtr offman,
              int w, int h,
              int granularity,
              MoveAreaCallbackProcPtr moveCB,
-             RemoveAreaCallbackProcPtr removeCB, pointer privData)
+             RemoveAreaCallbackProcPtr removeCB, void *privData)
 {
     ScreenPtr pScreen = offman->pScreen;
     FBLinkPtr link = NULL;
@@ -436,7 +436,7 @@ localAllocateOffscreenArea(ScreenPtr pScreen,
                            int w, int h,
                            int gran,
                            MoveAreaCallbackProcPtr moveCB,
-                           RemoveAreaCallbackProcPtr removeCB, pointer privData)
+                           RemoveAreaCallbackProcPtr removeCB, void *privData)
 {
     FBManagerPtr offman;
     FBAreaPtr area = NULL;
@@ -824,7 +824,7 @@ DumpDebug(FBLinearLinkPtr pLink)
 }
 
 static FBLinearPtr
-AllocateLinear(FBManagerPtr offman, int size, int granularity, pointer privData)
+AllocateLinear(FBManagerPtr offman, int size, int granularity, void *privData)
 {
     ScreenPtr pScreen = offman->pScreen;
     FBLinearLinkPtr linear = NULL;
@@ -903,7 +903,7 @@ localAllocateOffscreenLinear(ScreenPtr pScreen,
                              int gran,
                              MoveLinearCallbackProcPtr moveCB,
                              RemoveLinearCallbackProcPtr removeCB,
-                             pointer privData)
+                             void *privData)
 {
     FBManagerPtr offman;
     FBLinearLinkPtr link;
@@ -1394,7 +1394,7 @@ xf86AllocateLinearOffscreenArea(ScreenPtr pScreen,
                                 int gran,
                                 MoveAreaCallbackProcPtr moveCB,
                                 RemoveAreaCallbackProcPtr removeCB,
-                                pointer privData)
+                                void *privData)
 {
     FBManagerFuncsPtr funcs;
     FBManagerPtr offman;
diff --git a/hw/xfree86/common/xf86fbman.h b/hw/xfree86/common/xf86fbman.h
index 99bf991..092c2e2 100644
--- a/hw/xfree86/common/xf86fbman.h
+++ b/hw/xfree86/common/xf86fbman.h
@@ -60,7 +60,7 @@ typedef struct _FBLinear {
     DevUnion devPrivate;
 } FBLinear, *FBLinearPtr;
 
-typedef void (*FreeBoxCallbackProcPtr) (ScreenPtr, RegionPtr, pointer);
+typedef void (*FreeBoxCallbackProcPtr) (ScreenPtr, RegionPtr, void *);
 typedef void (*MoveAreaCallbackProcPtr) (FBAreaPtr, FBAreaPtr);
 typedef void (*RemoveAreaCallbackProcPtr) (FBAreaPtr);
 
@@ -73,7 +73,7 @@ typedef struct {
                                        int granularity,
                                        MoveAreaCallbackProcPtr moveCB,
                                        RemoveAreaCallbackProcPtr removeCB,
-                                       pointer privData);
+                                       void *privData);
     void (*FreeOffscreenArea) (FBAreaPtr area);
     Bool (*ResizeOffscreenArea) (FBAreaPtr area, int w, int h);
     Bool (*QueryLargestOffscreenArea) (ScreenPtr pScreen,
@@ -82,14 +82,14 @@ typedef struct {
                                        int preferences, int priority);
     Bool (*RegisterFreeBoxCallback) (ScreenPtr pScreen,
                                      FreeBoxCallbackProcPtr FreeBoxCallback,
-                                     pointer devPriv);
+                                     void *devPriv);
 /* linear functions */
      FBLinearPtr(*AllocateOffscreenLinear) (ScreenPtr pScreen,
                                             int size,
                                             int granularity,
                                             MoveLinearCallbackProcPtr moveCB,
                                             RemoveLinearCallbackProcPtr
-                                            removeCB, pointer privData);
+                                            removeCB, void *privData);
     void (*FreeOffscreenLinear) (FBLinearPtr area);
     Bool (*ResizeOffscreenLinear) (FBLinearPtr area, int size);
     Bool (*QueryLargestOffscreenLinear) (ScreenPtr pScreen,
@@ -121,7 +121,7 @@ xf86AllocateOffscreenArea(ScreenPtr pScreen,
                           int w, int h,
                           int granularity,
                           MoveAreaCallbackProcPtr moveCB,
-                          RemoveAreaCallbackProcPtr removeCB, pointer privData);
+                          RemoveAreaCallbackProcPtr removeCB, void *privData);
 
 extern _X_EXPORT FBAreaPtr
 xf86AllocateLinearOffscreenArea(ScreenPtr pScreen,
@@ -129,7 +129,7 @@ xf86AllocateLinearOffscreenArea(ScreenPtr pScreen,
                                 int granularity,
                                 MoveAreaCallbackProcPtr moveCB,
                                 RemoveAreaCallbackProcPtr removeCB,
-                                pointer privData);
+                                void *privData);
 
 extern _X_EXPORT FBLinearPtr
 xf86AllocateOffscreenLinear(ScreenPtr pScreen,
@@ -137,7 +137,7 @@ xf86AllocateOffscreenLinear(ScreenPtr pScreen,
                             int granularity,
                             MoveLinearCallbackProcPtr moveCB,
                             RemoveLinearCallbackProcPtr removeCB,
-                            pointer privData);
+                            void *privData);
 
 extern _X_EXPORT void xf86FreeOffscreenArea(FBAreaPtr area);
 extern _X_EXPORT void xf86FreeOffscreenLinear(FBLinearPtr area);
@@ -152,7 +152,7 @@ extern _X_EXPORT Bool
 
 xf86RegisterFreeBoxCallback(ScreenPtr pScreen,
                             FreeBoxCallbackProcPtr FreeBoxCallback,
-                            pointer devPriv);
+                            void *devPriv);
 
 extern _X_EXPORT Bool
  xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen);
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 2704766..0f76a03 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1013,7 +1013,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
 static void
 xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets * p_chip,
                             EntityProc init, EntityProc enter,
-                            EntityProc leave, pointer private)
+                            EntityProc leave, void *private)
 {
     ScrnInfoPtr pScrn;
 
@@ -1027,7 +1027,7 @@ xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets * p_chip,
 ScrnInfoPtr
 xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
                     PciChipsets * p_chip, void *dummy, EntityProc init,
-                    EntityProc enter, EntityProc leave, pointer private)
+                    EntityProc enter, EntityProc leave, void *private)
 {
     EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
 
@@ -1068,7 +1068,7 @@ xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
 Bool
 xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
                           PciChipsets * p_chip, void *dummy, EntityProc init,
-                          EntityProc enter, EntityProc leave, pointer private)
+                          EntityProc enter, EntityProc leave, void *private)
 {
     EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
 
diff --git a/hw/xfree86/common/xf86sbusBus.h b/hw/xfree86/common/xf86sbusBus.h
index 5ebdf25..9cfcbc5 100644
--- a/hw/xfree86/common/xf86sbusBus.h
+++ b/hw/xfree86/common/xf86sbusBus.h
@@ -76,10 +76,10 @@ extern _X_EXPORT sbusDevicePtr xf86GetSbusInfoForEntity(int entityIndex);
 extern _X_EXPORT int xf86GetEntityForSbusInfo(sbusDevicePtr psdp);
 extern _X_EXPORT void xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn,
                                              sbusDevicePtr psdp);
-extern _X_EXPORT pointer xf86MapSbusMem(sbusDevicePtr psdp,
+extern _X_EXPORT void *xf86MapSbusMem(sbusDevicePtr psdp,
                                         unsigned long offset,
                                         unsigned long size);
-extern _X_EXPORT void xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr,
+extern _X_EXPORT void xf86UnmapSbusMem(sbusDevicePtr psdp, void *addr,
                                        unsigned long size);
 extern _X_EXPORT void xf86SbusHideOsHwCursor(sbusDevicePtr psdp);
 extern _X_EXPORT void xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg,
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index fe13816..b164b7f 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -224,8 +224,8 @@ typedef struct {
     Gamma gamma;                /* Gamma of the monitor */
     int widthmm;
     int heightmm;
-    pointer options;
-    pointer DDC;
+    void *options;
+    void *DDC;
     Bool reducedblanking;       /* Allow CVT reduced blanking modes? */
     int maxPixClock;            /* in kHz, like mode->Clock */
 } MonRec, *MonPtr;
@@ -259,7 +259,7 @@ typedef enum {
     GET_REQUIRED_HW_INTERFACES = 10
 } xorgDriverFuncOp;
 
-typedef Bool xorgDriverFuncProc(ScrnInfoPtr, xorgDriverFuncOp, pointer);
+typedef Bool xorgDriverFuncProc(ScrnInfoPtr, xorgDriverFuncOp, void *);
 
 /* RR_GET_INFO, RR_SET_CONFIG */
 typedef struct {
@@ -303,7 +303,7 @@ typedef struct {
     void (*Identify) (int flags);
     Bool (*Probe) (struct _DriverRec * drv, int flags);
     const OptionInfoRec *(*AvailableOptions) (int chipid, int bustype);
-    pointer module;
+    void *module;
     int refCount;
 } DriverRec1;
 
@@ -319,7 +319,7 @@ typedef struct _DriverRec {
     void (*Identify) (int flags);
     Bool (*Probe) (struct _DriverRec * drv, int flags);
     const OptionInfoRec *(*AvailableOptions) (int chipid, int bustype);
-    pointer module;
+    void *module;
     int refCount;
     xorgDriverFuncProc *driverFunc;
 
@@ -408,7 +408,7 @@ typedef struct {
     unsigned long IOBase;
     int chipID;
     int chipRev;
-    pointer options;
+    void *options;
     int irq;
     int screen;                 /* For multi-CRTC cards */
 } GDevRec, *GDevPtr;
@@ -425,19 +425,19 @@ typedef struct {
     rgb whiteColour;
     int defaultVisual;
     const char **modes;
-    pointer options;
+    void *options;
 } DispRec, *DispPtr;
 
 typedef struct _confxvportrec {
     const char *identifier;
-    pointer options;
+    void *options;
 } confXvPortRec, *confXvPortPtr;
 
 typedef struct _confxvadaptrec {
     const char *identifier;
     int numports;
     confXvPortPtr ports;
-    pointer options;
+    void *options;
 } confXvAdaptorRec, *confXvAdaptorPtr;
 
 typedef struct _confscreenrec {
@@ -452,7 +452,7 @@ typedef struct _confscreenrec {
     DispPtr displays;
     int numxvadaptors;
     confXvAdaptorPtr xvadaptors;
-    pointer options;
+    void *options;
 } confScreenRec, *confScreenPtr;
 
 typedef enum {
@@ -489,7 +489,7 @@ typedef struct _serverlayoutrec {
     screenLayoutPtr screens;
     GDevPtr inactives;
     InputInfoRec **inputs;      /* NULL terminated */
-    pointer options;
+    void *options;
 } serverLayoutRec, *serverLayoutPtr;
 
 typedef struct _confdribufferrec {
@@ -512,7 +512,7 @@ typedef struct _confdrirec {
 #define NUM_RESERVED_POINTERS		14
 #define NUM_RESERVED_FUNCS		10
 
-typedef pointer (*funcPointer) (void);
+typedef void *(*funcPointer) (void);
 
 /* flags for depth 24 pixmap options */
 typedef enum {
@@ -581,7 +581,7 @@ typedef struct _PciChipsets {
 } PciChipsets;
 
 /* Entity properties */
-typedef void (*EntityProc) (int entityIndex, pointer private);
+typedef void (*EntityProc) (int entityIndex, void *private);
 
 typedef struct _entityInfo {
     int index;
@@ -731,11 +731,11 @@ typedef struct _ScrnInfoRec {
     int xDpi;                   /* width DPI */
     int yDpi;                   /* height DPI */
     const char *name;           /* Name to prefix messages */
-    pointer driverPrivate;      /* Driver private area */
+    void *driverPrivate;        /* Driver private area */
     DevUnion *privates;         /* Other privates can hook in
                                  * here */
     DriverPtr drv;              /* xf86DriverList[] entry */
-    pointer module;             /* Pointer to module head */
+    void *module;               /* Pointer to module head */
     int colorKey;
     int overlayFlags;
 
@@ -754,7 +754,7 @@ typedef struct _ScrnInfoRec {
     int memClk;                 /* memory clock */
     int textClockFreq;          /* clock of text mode */
     Bool flipPixels;            /* swap default black/white */
-    pointer options;
+    void *options;
 
     int chipID;
     int chipRev;
@@ -779,7 +779,7 @@ typedef struct _ScrnInfoRec {
     int *entityInstanceList;
     struct pci_device *vgaDev;
 
-    pointer reservedPtr[NUM_RESERVED_POINTERS];
+    void *reservedPtr[NUM_RESERVED_POINTERS];
 
     /*
      * Driver entry points.
@@ -864,7 +864,7 @@ typedef enum {
 typedef void (*DPMSSetProcPtr) (ScrnInfoPtr, int, int);
 
 /* Input handler proc */
-typedef void (*InputHandlerProc) (int fd, pointer data);
+typedef void (*InputHandlerProc) (int fd, void *data);
 
 /* These are used by xf86GetClocks */
 #define CLK_REG_SAVE		-1
diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c
index cad0e6a..2b07833 100644
--- a/hw/xfree86/common/xf86vmode.c
+++ b/hw/xfree86/common/xf86vmode.c
@@ -216,7 +216,7 @@ setEventMask(ScreenPtr pScreen, ClientPtr client, unsigned long mask)
 }
 
 static int
-XF86VidModeFreeEvents(pointer value, XID id)
+XF86VidModeFreeEvents(void *value, XID id)
 {
     XF86VidModeEventPtr pOld = (XF86VidModeEventPtr) value;
     ScreenPtr pScreen = pOld->screen;
@@ -314,7 +314,7 @@ ProcXF86VidModeGetModeLine(ClientPtr client)
         .type = X_Reply,
         .sequenceNumber = client->sequence
     };
-    pointer mode;
+    void *mode;
     int dotClock;
     int ver;
 
@@ -413,7 +413,7 @@ ProcXF86VidModeGetAllModeLines(ClientPtr client)
 {
     REQUEST(xXF86VidModeGetAllModeLinesReq);
     xXF86VidModeGetAllModeLinesReply rep;
-    pointer mode;
+    void *mode;
     int modecount, dotClock;
     int ver;
 
@@ -524,7 +524,7 @@ ProcXF86VidModeAddModeLine(ClientPtr client)
     xXF86OldVidModeAddModeLineReq *oldstuff =
         (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
     xXF86VidModeAddModeLineReq newstuff;
-    pointer mode;
+    void *mode;
     int len;
     int dotClock;
     int ver;
@@ -688,7 +688,7 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client)
     xXF86OldVidModeDeleteModeLineReq *oldstuff =
         (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
     xXF86VidModeDeleteModeLineReq newstuff;
-    pointer mode;
+    void *mode;
     int len, dotClock;
     int ver;
 
@@ -813,7 +813,7 @@ ProcXF86VidModeModModeLine(ClientPtr client)
     xXF86OldVidModeModModeLineReq *oldstuff =
         (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
     xXF86VidModeModModeLineReq newstuff;
-    pointer mode, modetmp;
+    void *mode, *modetmp;
     int len, dotClock;
     int ver;
 
@@ -942,7 +942,7 @@ ProcXF86VidModeValidateModeLine(ClientPtr client)
         (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
     xXF86VidModeValidateModeLineReq newstuff;
     xXF86VidModeValidateModeLineReply rep;
-    pointer mode, modetmp = NULL;
+    void *mode, *modetmp = NULL;
     int len, status, dotClock;
     int ver;
 
@@ -1080,7 +1080,7 @@ ProcXF86VidModeSwitchToMode(ClientPtr client)
     xXF86OldVidModeSwitchToModeReq *oldstuff =
         (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
     xXF86VidModeSwitchToModeReq newstuff;
-    pointer mode;
+    void *mode;
     int len, dotClock;
     int ver;
 
@@ -1205,7 +1205,7 @@ ProcXF86VidModeGetMonitor(ClientPtr client)
     };
     CARD32 *hsyncdata, *vsyncdata;
     int i, nHsync, nVrefresh;
-    pointer monitor;
+    void *monitor;
 
     DEBUG_P("XF86VidModeGetMonitor");
 
diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 92d0f6d..b16cb5d 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -261,7 +261,7 @@ xf86XVScreenInit(ScreenPtr pScreen, XF86VideoAdaptorPtr * adaptors, int num)
        sure that I appreciate that.  */
 
     ScreenPriv = malloc(sizeof(XF86XVScreenRec));
-    pxvs->devPriv.ptr = (pointer) ScreenPriv;
+    pxvs->devPriv.ptr = (void *) ScreenPriv;
 
     if (!ScreenPriv)
         return FALSE;
@@ -551,7 +551,7 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
         adaptorPriv->PutImage = adaptorPtr->PutImage;
         adaptorPriv->ReputImage = adaptorPtr->ReputImage;       /* image/still */
 
-        pa->devPriv.ptr = (pointer) adaptorPriv;
+        pa->devPriv.ptr = (void *) adaptorPriv;
 
         if (!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
             xf86XVFreeAdaptor(pa);
@@ -957,7 +957,7 @@ xf86XVReputImage(XvPortRecPrivatePtr portPriv)
 }
 
 static int
-xf86XVReputAllVideo(WindowPtr pWin, pointer data)
+xf86XVReputAllVideo(WindowPtr pWin, void *data)
 {
     XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
 
@@ -1922,7 +1922,7 @@ xf86XVFillKeyHelper(ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
 }
 
 void
-xf86XVFillKeyHelperPort(DrawablePtr pDraw, pointer data, CARD32 key,
+xf86XVFillKeyHelperPort(DrawablePtr pDraw, void *data, CARD32 key,
                         RegionPtr clipboxes, Bool fillEverything)
 {
     WindowPtr pWin = (WindowPtr) pDraw;
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index f393369..8986e2e 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -84,47 +84,47 @@ typedef int (*PutVideoFuncPtr) (ScrnInfoPtr pScrn,
                                 short vid_x, short vid_y, short drw_x,
                                 short drw_y, short vid_w, short vid_h,
                                 short drw_w, short drw_h, RegionPtr clipBoxes,
-                                pointer data, DrawablePtr pDraw);
+                                void *data, DrawablePtr pDraw);
 typedef int (*PutStillFuncPtr) (ScrnInfoPtr pScrn, short vid_x, short vid_y,
                                 short drw_x, short drw_y, short vid_w,
                                 short vid_h, short drw_w, short drw_h,
-                                RegionPtr clipBoxes, pointer data,
+                                RegionPtr clipBoxes, void *data,
                                 DrawablePtr pDraw);
 typedef int (*GetVideoFuncPtr) (ScrnInfoPtr pScrn, short vid_x, short vid_y,
                                 short drw_x, short drw_y, short vid_w,
                                 short vid_h, short drw_w, short drw_h,
-                                RegionPtr clipBoxes, pointer data,
+                                RegionPtr clipBoxes, void *data,
                                 DrawablePtr pDraw);
 typedef int (*GetStillFuncPtr) (ScrnInfoPtr pScrn, short vid_x, short vid_y,
                                 short drw_x, short drw_y, short vid_w,
                                 short vid_h, short drw_w, short drw_h,
-                                RegionPtr clipBoxes, pointer data,
+                                RegionPtr clipBoxes, void *data,
                                 DrawablePtr pDraw);
-typedef void (*StopVideoFuncPtr) (ScrnInfoPtr pScrn, pointer data, Bool Exit);
+typedef void (*StopVideoFuncPtr) (ScrnInfoPtr pScrn, void *data, Bool Exit);
 typedef int (*SetPortAttributeFuncPtr) (ScrnInfoPtr pScrn, Atom attribute,
-                                        INT32 value, pointer data);
+                                        INT32 value, void *data);
 typedef int (*GetPortAttributeFuncPtr) (ScrnInfoPtr pScrn, Atom attribute,
-                                        INT32 *value, pointer data);
+                                        INT32 *value, void *data);
 typedef void (*QueryBestSizeFuncPtr) (ScrnInfoPtr pScrn, Bool motion,
                                       short vid_w, short vid_h, short drw_w,
                                       short drw_h, unsigned int *p_w,
-                                      unsigned int *p_h, pointer data);
+                                      unsigned int *p_h, void *data);
 typedef int (*PutImageFuncPtr) (ScrnInfoPtr pScrn, short src_x, short src_y,
                                 short drw_x, short drw_y, short src_w,
                                 short src_h, short drw_w, short drw_h,
                                 int image, unsigned char *buf, short width,
                                 short height, Bool Sync, RegionPtr clipBoxes,
-                                pointer data, DrawablePtr pDraw);
+                                void *data, DrawablePtr pDraw);
 typedef int (*ReputImageFuncPtr) (ScrnInfoPtr pScrn, short src_x, short src_y,
                                   short drw_x, short drw_y, short src_w,
                                   short src_h, short drw_w, short drw_h,
-                                  RegionPtr clipBoxes, pointer data,
+                                  RegionPtr clipBoxes, void *data,
                                   DrawablePtr pDraw);
 typedef int (*QueryImageAttributesFuncPtr) (ScrnInfoPtr pScrn, int image,
                                             unsigned short *width,
                                             unsigned short *height,
                                             int *pitches, int *offsets);
-typedef void (*ClipNotifyFuncPtr) (ScrnInfoPtr pScrn, pointer data,
+typedef void (*ClipNotifyFuncPtr) (ScrnInfoPtr pScrn, void *data,
                                    WindowPtr window, int dx, int dy);
 
 typedef enum {
@@ -238,7 +238,7 @@ xf86XVFillKeyHelperDrawable(DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
 
 extern _X_EXPORT void
 
-xf86XVFillKeyHelperPort(DrawablePtr pDraw, pointer data, CARD32 key,
+xf86XVFillKeyHelperPort(DrawablePtr pDraw, void *data, CARD32 key,
                         RegionPtr clipboxes, Bool fillEverything);
 
 extern _X_EXPORT Bool
diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c
index 133a2a6..bf7d182 100644
--- a/hw/xfree86/dixmods/glxmodule.c
+++ b/hw/xfree86/dixmods/glxmodule.c
@@ -68,8 +68,8 @@ static XF86ModuleVersionInfo VersRec = {
 
 _X_EXPORT XF86ModuleData glxModuleData = { &VersRec, glxSetup, NULL };
 
-static pointer
-glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+static void *
+glxSetup(void *module, void *opts, int *errmaj, int *errmin)
 {
     static Bool setupDone = FALSE;
     __GLXprovider *provider;
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index bfa3e36..38bfc1d 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -1052,7 +1052,7 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
     }
 
     /* track this in case the client dies before cleanup */
-    AddResource(context, DRIContextPrivResType, (pointer) pDRIContextPriv);
+    AddResource(context, DRIContextPrivResType, (void *) pDRIContextPriv);
 
     return TRUE;
 }
@@ -1067,7 +1067,7 @@ DRIDestroyContext(ScreenPtr pScreen, XID context)
 
 /* DRIContextPrivDelete is called by the resource manager. */
 Bool
-DRIContextPrivDelete(pointer pResource, XID id)
+DRIContextPrivDelete(void *pResource, XID id)
 {
     DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr) pResource;
     DRIScreenPrivPtr pDRIPriv;
@@ -1150,7 +1150,7 @@ DRITransitionTo2d(ScreenPtr pScreen)
 }
 
 static int
-DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
+DRIDCNTreeTraversal(WindowPtr pWin, void *data)
 {
     DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
 
@@ -1189,7 +1189,7 @@ DRIDriverClipNotify(ScreenPtr pScreen)
         if (pDRIPriv->nrWindows > 0) {
             pDRIPriv->nrWalked = 0;
             TraverseTree(pScreen->root, DRIDCNTreeTraversal,
-                         (pointer) pDRIWindows);
+                         (void *) pDRIWindows);
         }
 
         pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
@@ -1284,7 +1284,7 @@ DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
 
         /* track this in case the client dies */
         AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
-                    (pointer) (intptr_t) pDrawable->id);
+                    (void *) (intptr_t) pDrawable->id);
 
         if (pDRIDrawablePriv->hwDrawable) {
             drmUpdateDrawableInfo(pDRIPriv->drmFD,
@@ -1337,7 +1337,7 @@ DRIDrawablePrivDestroy(WindowPtr pWin)
 }
 
 static Bool
-DRIDestroyDrawableCB(pointer value, XID id, pointer data)
+DRIDestroyDrawableCB(void *value, XID id, void *data)
 {
     if (value == data) {
         /* This calls back DRIDrawablePrivDelete which frees private area */
@@ -1355,7 +1355,7 @@ DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
     if (pDrawable->type == DRAWABLE_WINDOW) {
         LookupClientResourceComplex(client, DRIDrawablePrivResType,
                                     DRIDestroyDrawableCB,
-                                    (pointer) (intptr_t) pDrawable->id);
+                                    (void *) (intptr_t) pDrawable->id);
     }
     else {                      /* pixmap (or for GLX 1.3, a PBuffer) */
         /* NOT_DONE */
@@ -1366,7 +1366,7 @@ DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
 }
 
 Bool
-DRIDrawablePrivDelete(pointer pResource, XID id)
+DRIDrawablePrivDelete(void *pResource, XID id)
 {
     WindowPtr pWin;
     int rc;
@@ -1625,7 +1625,7 @@ DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
 }
 
 void
-DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
+DRIWakeupHandler(void *wakeupData, int result, void *pReadmask)
 {
     int i;
 
@@ -1640,7 +1640,7 @@ DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
 }
 
 void
-DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+DRIBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadmask)
 {
     int i;
 
@@ -1656,7 +1656,7 @@ DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
 
 void
 DRIDoWakeupHandler(ScreenPtr pScreen,
-                   unsigned long result, pointer pReadmask)
+                   unsigned long result, void *pReadmask)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
 
@@ -1674,7 +1674,7 @@ DRIDoWakeupHandler(ScreenPtr pScreen,
 
 void
 DRIDoBlockHandler(ScreenPtr pScreen,
-                  pointer pTimeout, pointer pReadmask)
+                  void *pTimeout, void *pReadmask)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
 
@@ -1877,7 +1877,7 @@ DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
 }
 
 static int
-DRITreeTraversal(WindowPtr pWin, pointer data)
+DRITreeTraversal(WindowPtr pWin, void *data)
 {
     DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
 
@@ -1937,7 +1937,7 @@ DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 
         RegionNull(&reg);
         pDRIPriv->nrWalked = 0;
-        TraverseTree(pWin, DRITreeTraversal, (pointer) (&reg));
+        TraverseTree(pWin, DRITreeTraversal, (void *) (&reg));
 
         if (RegionNotEmpty(&reg)) {
             RegionTranslate(&reg, ptOldOrg.x - pWin->drawable.x,
diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h
index 4bfaf16..64cd7c9 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -151,7 +151,7 @@ typedef struct {
     int ddxDriverMajorVersion;
     int ddxDriverMinorVersion;
     int ddxDriverPatchVersion;
-    pointer frameBufferPhysicalAddress;
+    void *frameBufferPhysicalAddress;
     long frameBufferSize;
     long frameBufferStride;
     long SAREASize;
@@ -224,7 +224,7 @@ extern _X_EXPORT Bool DRICreateContext(ScreenPtr pScreen,
 
 extern _X_EXPORT Bool DRIDestroyContext(ScreenPtr pScreen, XID context);
 
-extern _X_EXPORT Bool DRIContextPrivDelete(pointer pResource, XID id);
+extern _X_EXPORT Bool DRIContextPrivDelete(void *pResource, XID id);
 
 extern _X_EXPORT Bool DRICreateDrawable(ScreenPtr pScreen,
                                         ClientPtr client,
@@ -235,7 +235,7 @@ extern _X_EXPORT Bool DRIDestroyDrawable(ScreenPtr pScreen,
                                          ClientPtr client,
                                          DrawablePtr pDrawable);
 
-extern _X_EXPORT Bool DRIDrawablePrivDelete(pointer pResource, XID id);
+extern _X_EXPORT Bool DRIDrawablePrivDelete(void *pResource, XID id);
 
 extern _X_EXPORT Bool DRIGetDrawableInfo(ScreenPtr pScreen,
                                          DrawablePtr pDrawable,
@@ -265,18 +265,18 @@ extern _X_EXPORT void DRIDestroyInfoRec(DRIInfoPtr DRIInfo);
 
 extern _X_EXPORT Bool DRIFinishScreenInit(ScreenPtr pScreen);
 
-extern _X_EXPORT void DRIWakeupHandler(pointer wakeupData,
-                                       int result, pointer pReadmask);
+extern _X_EXPORT void DRIWakeupHandler(void *wakeupData,
+                                       int result, void *pReadmask);
 
-extern _X_EXPORT void DRIBlockHandler(pointer blockData,
-                                      OSTimePtr pTimeout, pointer pReadmask);
+extern _X_EXPORT void DRIBlockHandler(void *blockData,
+                                      OSTimePtr pTimeout, void *pReadmask);
 
 extern _X_EXPORT void DRIDoWakeupHandler(ScreenPtr pScreen,
                                          unsigned long result,
-                                         pointer pReadmask);
+                                         void *pReadmask);
 
 extern _X_EXPORT void DRIDoBlockHandler(ScreenPtr pScreen,
-                                        pointer pTimeout, pointer pReadmask);
+                                        void *pTimeout, void *pReadmask);
 
 extern _X_EXPORT void DRISwapContext(int drmFD, void *oldctx, void *newctx);
 
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 34cc02f..729a323 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -354,7 +354,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
 }
 
 static int
-DRI2DrawableGone(pointer p, XID id)
+DRI2DrawableGone(void *p, XID id)
 {
     DRI2DrawablePtr pPriv = p;
     DRI2DrawableRefPtr ref, next;
@@ -754,7 +754,7 @@ static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
  * pixmap
  */
 static int
-DRI2InvalidateWalk(WindowPtr pWin, pointer data)
+DRI2InvalidateWalk(WindowPtr pWin, void *data)
 {
     if (pWin->drawable.pScreen->GetWindowPixmap(pWin) != data)
         return WT_DONTWALKCHILDREN;
diff --git a/hw/xfree86/i2c/fi1236.c b/hw/xfree86/i2c/fi1236.c
index 2eb27ba..ebd1454 100644
--- a/hw/xfree86/i2c/fi1236.c
+++ b/hw/xfree86/i2c/fi1236.c
@@ -545,7 +545,7 @@ FI1236_set_tuner_type(FI1236Ptr f, int type)
 }
 
 static CARD32
-AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data)
+AFC_TimerCallback(OsTimerPtr timer, CARD32 time, void *data)
 {
     FI1236Ptr f = (FI1236Ptr) data;
 
diff --git a/hw/xfree86/int10/generic.c b/hw/xfree86/int10/generic.c
index 41e348c..abbd36f 100644
--- a/hw/xfree86/int10/generic.c
+++ b/hw/xfree86/int10/generic.c
@@ -87,8 +87,8 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     if (!xf86Int10ExecSetup(pInt))
         goto error0;
     pInt->mem = &genericMem;
-    pInt->private = (pointer) xnfcalloc(1, sizeof(genericInt10Priv));
-    INTPriv(pInt)->alloc = (pointer) xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
+    pInt->private = (void *) xnfcalloc(1, sizeof(genericInt10Priv));
+    INTPriv(pInt)->alloc = (void *) xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
     pInt->pScrn = pScrn;
     base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
 
@@ -343,10 +343,10 @@ xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
 	   : *(uint8_t*) V_ADDR(addr)
 #define V_ADDR_RW(addr) \
 	(VRAM(addr)) ? MMIO_IN16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr)) \
-	   : ldw_u((pointer)V_ADDR(addr))
+	   : ldw_u((void *)V_ADDR(addr))
 #define V_ADDR_RL(addr) \
 	(VRAM(addr)) ? MMIO_IN32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr)) \
-	   : ldl_u((pointer)V_ADDR(addr))
+	   : ldl_u((void *)V_ADDR(addr))
 
 #define V_ADDR_WB(addr,val) \
 	if(VRAM(addr)) \
@@ -357,13 +357,13 @@ xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
 	if(VRAM(addr)) \
 	    MMIO_OUT16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
 	else \
-	    stw_u((val),(pointer)(V_ADDR(addr)));
+	    stw_u((val),(void *)(V_ADDR(addr)));
 
 #define V_ADDR_WL(addr,val) \
 	if (VRAM(addr)) \
 	    MMIO_OUT32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
 	else \
-	    stl_u(val,(pointer)(V_ADDR(addr)));
+	    stl_u(val,(void *)(V_ADDR(addr)));
 
 static uint8_t
 read_b(xf86Int10InfoPtr pInt, int addr)
@@ -425,7 +425,7 @@ write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val)
     V_ADDR_WB(addr + 3, val >> 24);
 }
 
-pointer
+void *
 xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr)
 {
     return V_ADDR(addr);
diff --git a/hw/xfree86/int10/helper_mem.c b/hw/xfree86/int10/helper_mem.c
index 160c5ae..1b5960e 100644
--- a/hw/xfree86/int10/helper_mem.c
+++ b/hw/xfree86/int10/helper_mem.c
@@ -199,7 +199,7 @@ xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
     OptionInfoPtr options = NULL;
 
     if (pEnt->device) {
-        pointer configOptions = NULL;
+        void *configOptions = NULL;
 
         /* Check if xf86CollectOptions() has already been called */
         if (((pEnt->index < 0) ||
diff --git a/hw/xfree86/int10/stub.c b/hw/xfree86/int10/stub.c
index 8fd0790..40e0ba7 100644
--- a/hw/xfree86/int10/stub.c
+++ b/hw/xfree86/int10/stub.c
@@ -62,7 +62,7 @@ xf86ExecX86int10(xf86Int10InfoPtr pInt)
     return;
 }
 
-pointer
+void *
 xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
 {
     return 0;
diff --git a/hw/xfree86/int10/xf86int10.h b/hw/xfree86/int10/xf86int10.h
index 94040c5..83bab7e 100644
--- a/hw/xfree86/int10/xf86int10.h
+++ b/hw/xfree86/int10/xf86int10.h
@@ -24,10 +24,10 @@ typedef struct {
     uint16_t BIOSseg;
     uint16_t inb40time;
     ScrnInfoPtr pScrn;
-    pointer cpuRegs;
+    void *cpuRegs;
     char *BIOSScratch;
     int Flags;
-    pointer private;
+    void *private;
     struct _int10Mem *mem;
     int num;
     int ax;
@@ -69,7 +69,7 @@ extern _X_EXPORT void *xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num,
                                            int *off);
 extern _X_EXPORT void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase,
                                          int num);
-extern _X_EXPORT pointer xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr);
+extern _X_EXPORT void *xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr);
 
 /* x86 executor related functions */
 extern _X_EXPORT void xf86ExecX86int10(xf86Int10InfoPtr pInt);
diff --git a/hw/xfree86/loader/loaderProcs.h b/hw/xfree86/loader/loaderProcs.h
index 8b4b53f..cfc4d80 100644
--- a/hw/xfree86/loader/loaderProcs.h
+++ b/hw/xfree86/loader/loaderProcs.h
@@ -72,10 +72,10 @@ typedef struct module_desc {
 
 void LoaderInit(void);
 
-ModuleDescPtr LoadDriver(const char *, const char *, int, pointer, int *,
+ModuleDescPtr LoadDriver(const char *, const char *, int, void *, int *,
                          int *);
 ModuleDescPtr LoadModule(const char *, const char *, const char **,
-                         const char **, pointer, const XF86ModReqInfo *,
+                         const char **, void *, const XF86ModReqInfo *,
                          int *, int *);
 ModuleDescPtr DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent);
 void UnloadDriver(ModuleDescPtr);
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index d70ba28..092bf57 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -81,7 +81,7 @@ static void UnloadModuleOrDriver(ModuleDescPtr mod);
 static char *LoaderGetCanonicalName(const char *, PatternPtr);
 static void RemoveChild(ModuleDescPtr);
 static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
-                                  const char **, pointer,
+                                  const char **, void *,
                                   const XF86ModReqInfo *, int *, int *);
 
 const ModuleVersions LoaderVersionInfo = {
@@ -761,10 +761,10 @@ AddSibling(ModuleDescPtr head, ModuleDescPtr new)
     return new;
 }
 
-pointer
-LoadSubModule(pointer _parent, const char *module,
+void *
+LoadSubModule(void *_parent, const char *module,
               const char **subdirlist, const char **patternlist,
-              pointer options, const XF86ModReqInfo * modreq,
+              void *options, const XF86ModReqInfo * modreq,
               int *errmaj, int *errmin)
 {
     ModuleDescPtr submod;
@@ -843,7 +843,7 @@ static const char *compiled_in_modules[] = {
 
 static ModuleDescPtr
 doLoadModule(const char *module, const char *path, const char **subdirlist,
-             const char **patternlist, pointer options,
+             const char **patternlist, void *options,
              const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
 {
     XF86ModuleData *initdata = NULL;
@@ -1071,7 +1071,7 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
  */
 ModuleDescPtr
 LoadModule(const char *module, const char *path, const char **subdirlist,
-           const char **patternlist, pointer options,
+           const char **patternlist, void *options,
            const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
 {
     return doLoadModule(module, path, subdirlist, patternlist, options,
@@ -1079,7 +1079,7 @@ LoadModule(const char *module, const char *path, const char **subdirlist,
 }
 
 void
-UnloadModule(pointer mod)
+UnloadModule(void *mod)
 {
     UnloadModuleOrDriver((ModuleDescPtr) mod);
 }
@@ -1115,7 +1115,7 @@ UnloadModuleOrDriver(ModuleDescPtr mod)
 }
 
 void
-UnloadSubModule(pointer _mod)
+UnloadSubModule(void *_mod)
 {
     ModuleDescPtr mod = (ModuleDescPtr) _mod;
 
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 2c9c31b..0ddd840 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -229,7 +229,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 
 static void
 xf86RotateBlockHandler(ScreenPtr pScreen,
-                       pointer pTimeout, pointer pReadmask)
+                       void *pTimeout, void *pReadmask)
 {
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
diff --git a/hw/xfree86/os-support/bsd/alpha_video.c b/hw/xfree86/os-support/bsd/alpha_video.c
index 91f9fc8..95bd059 100644
--- a/hw/xfree86/os-support/bsd/alpha_video.c
+++ b/hw/xfree86/os-support/bsd/alpha_video.c
@@ -189,10 +189,10 @@ static int devMemFd = -1;
 #define DEV_APERTURE "/dev/xf86"
 #endif
 
-static pointer mapVidMem(int, unsigned long, unsigned long, int);
-static void unmapVidMem(int, pointer, unsigned long);
-static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
-static void unmapVidMemSparse(int, pointer, unsigned long);
+static void *mapVidMem(int, unsigned long, unsigned long, int);
+static void unmapVidMem(int, void *, unsigned long);
+static void *mapVidMemSparse(int, unsigned long, unsigned long, int);
+static void unmapVidMemSparse(int, void *, unsigned long);
 
 /*
  * Check if /dev/mem can be mmap'd.  If it can't print a warning when
@@ -203,7 +203,7 @@ checkDevMem(Bool warn)
 {
     static Bool devMemChecked = FALSE;
     int fd;
-    pointer base;
+    void *base;
 
     if (devMemChecked)
         return;
@@ -295,10 +295,10 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
     pVidMem->initialised = TRUE;
 }
 
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
-    pointer base;
+    void *base;
 
     checkDevMem(FALSE);
     Base = Base & ((1L << 32) - 1);
@@ -336,7 +336,7 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 }
 
 static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     munmap((caddr_t) Base, Size);
 }
@@ -424,40 +424,40 @@ xf86DisableIO()
 
 #define vuip    volatile unsigned int *
 
-static pointer memSBase = 0;
-static pointer memBase = 0;
+static void *memSBase = 0;
+static void *memBase = 0;
 
-extern int readDense8(pointer Base, register unsigned long Offset);
-extern int readDense16(pointer Base, register unsigned long Offset);
-extern int readDense32(pointer Base, register unsigned long Offset);
+extern int readDense8(void *Base, register unsigned long Offset);
+extern int readDense16(void *Base, register unsigned long Offset);
+extern int readDense32(void *Base, register unsigned long Offset);
 extern void
- writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB8(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB16(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB32(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense8(int Value, pointer Base, register unsigned long Offset);
+ writeDense8(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense16(int Value, pointer Base, register unsigned long Offset);
+ writeDense16(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense32(int Value, pointer Base, register unsigned long Offset);
+ writeDense32(int Value, void *Base, register unsigned long Offset);
 
-static int readSparse8(pointer Base, register unsigned long Offset);
-static int readSparse16(pointer Base, register unsigned long Offset);
-static int readSparse32(pointer Base, register unsigned long Offset);
+static int readSparse8(void *Base, register unsigned long Offset);
+static int readSparse16(void *Base, register unsigned long Offset);
+static int readSparse32(void *Base, register unsigned long Offset);
 static void
- writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB8(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB16(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB32(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse8(int Value, pointer Base, register unsigned long Offset);
+ writeSparse8(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse16(int Value, pointer Base, register unsigned long Offset);
+ writeSparse16(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse32(int Value, pointer Base, register unsigned long Offset);
+ writeSparse32(int Value, void *Base, register unsigned long Offset);
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 extern int sysarch(int, void *);
@@ -481,7 +481,7 @@ sethae(u_int64_t hae)
 }
 #endif
 
-static pointer
+static void *
 mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size,
                 int flags)
 {
@@ -514,16 +514,16 @@ mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size,
                        strerror(errno));
         }
     }
-    return (pointer) ((unsigned long) memBase + Base);
+    return (void *) ((unsigned long) memBase + Base);
 }
 
 static void
-unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMemSparse(int ScreenNum, void *Base, unsigned long Size)
 {
 }
 
 static int
-readSparse8(pointer Base, register unsigned long Offset)
+readSparse8(void *Base, register unsigned long Offset)
 {
     register unsigned long result, shift;
     register unsigned long msb;
@@ -544,7 +544,7 @@ readSparse8(pointer Base, register unsigned long Offset)
 }
 
 static int
-readSparse16(pointer Base, register unsigned long Offset)
+readSparse16(void *Base, register unsigned long Offset)
 {
     register unsigned long result, shift;
     register unsigned long msb;
@@ -566,14 +566,14 @@ readSparse16(pointer Base, register unsigned long Offset)
 }
 
 static int
-readSparse32(pointer Base, register unsigned long Offset)
+readSparse32(void *Base, register unsigned long Offset)
 {
     mem_barrier();
     return *(vuip) ((unsigned long) Base + (Offset));
 }
 
 static void
-writeSparse8(int Value, pointer Base, register unsigned long Offset)
+writeSparse8(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int b = Value & 0xffU;
@@ -591,7 +591,7 @@ writeSparse8(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparse16(int Value, pointer Base, register unsigned long Offset)
+writeSparse16(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int w = Value & 0xffffU;
@@ -611,7 +611,7 @@ writeSparse16(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparse32(int Value, pointer Base, register unsigned long Offset)
+writeSparse32(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
     *(vuip) ((unsigned long) Base + (Offset)) = Value;
@@ -619,7 +619,7 @@ writeSparse32(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB8(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int b = Value & 0xffU;
@@ -636,7 +636,7 @@ writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB16(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int w = Value & 0xffffU;
@@ -654,27 +654,27 @@ writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB32(int Value, void *Base, register unsigned long Offset)
 {
     *(vuip) ((unsigned long) Base + (Offset)) = Value;
     return;
 }
 
-void (*xf86WriteMmio8) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset)
     = writeDense8;
-void (*xf86WriteMmio16) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset)
     = writeDense16;
-void (*xf86WriteMmio32) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset)
     = writeDense32;
-void (*xf86WriteMmioNB8) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB8) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB8;
-void (*xf86WriteMmioNB16) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB16) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB16;
-void (*xf86WriteMmioNB32) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB32) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB32;
-int (*xf86ReadMmio8) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio8) (void *Base, unsigned long Offset)
     = readDense8;
-int (*xf86ReadMmio16) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio16) (void *Base, unsigned long Offset)
     = readDense16;
-int (*xf86ReadMmio32) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio32) (void *Base, unsigned long Offset)
     = readDense32;
diff --git a/hw/xfree86/os-support/bsd/arm_video.c b/hw/xfree86/os-support/bsd/arm_video.c
index 71064af..6a977c2 100644
--- a/hw/xfree86/os-support/bsd/arm_video.c
+++ b/hw/xfree86/os-support/bsd/arm_video.c
@@ -71,12 +71,12 @@
 struct memAccess {
     int ioctl;
     struct map_info memInfo;
-    pointer regionVirtBase;
+    void *regionVirtBase;
     Bool Checked;
     Bool OK;
 };
 
-static pointer xf86MapInfoMap();
+static void *xf86MapInfoMap();
 static void xf86MapInfoUnmap();
 static struct memAccess *checkMapInfo();
 extern int vgaPhysLinearBase;
@@ -111,8 +111,8 @@ struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL,
 static Bool useDevMem = FALSE;
 static int devMemFd = -1;
 
-static pointer mapVidMem(int, unsigned long, unsigned long, int);
-static void unmapVidMem(int, pointer, unsigned long);
+static void *mapVidMem(int, unsigned long, unsigned long, int);
+static void unmapVidMem(int, void *, unsigned long);
 
 /*
  * Check if /dev/mem can be mmap'd.  If it can't print a warning when
@@ -123,7 +123,7 @@ checkDevMem(Bool warn)
 {
     static Bool devMemChecked = FALSE;
     int fd;
-    pointer base;
+    void *base;
 
     if (devMemChecked)
         return;
@@ -170,10 +170,10 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
     pVidMem->initialised = TRUE;
 }
 
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
-    pointer base;
+    void *base;
 
     checkDevMem(FALSE);
 
@@ -210,7 +210,7 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 }
 
 static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     munmap((caddr_t) Base, Size);
 }
@@ -310,8 +310,8 @@ checkMapInfo(Bool warn, int Region)
     }
 }
 
-static pointer
-xf86MapInfoMap(struct memAccess *memInfoP, pointer Base, unsigned long Size)
+static void *
+xf86MapInfoMap(struct memAccess *memInfoP, void *Base, unsigned long Size)
 {
     struct map_info *mapInfoP = &(memInfoP->memInfo);
 
@@ -335,7 +335,7 @@ xf86MapInfoMap(struct memAccess *memInfoP, pointer Base, unsigned long Size)
                       MAP_SHARED,
                       xf86Info.consoleFd,
                       (unsigned long) mapInfoP->u.map_info_mmap.map_offset))
-                == (pointer) -1) {
+                == (void *) -1) {
                 FatalError
                     ("xf86MapInfoMap: Failed to map memory at 0x%x\n\t%s\n",
                      mapInfoP->u.map_info_mmap.map_offset, strerror(errno));
@@ -351,7 +351,7 @@ xf86MapInfoMap(struct memAccess *memInfoP, pointer Base, unsigned long Size)
         break;
     }
 
-    return (pointer) ((int) memInfoP->regionVirtBase + (int) Base);
+    return (void *) ((int) memInfoP->regionVirtBase + (int) Base);
 }
 
 static void
@@ -374,7 +374,7 @@ xf86MapInfoUnmap(struct memAccess *memInfoP, unsigned long Size)
     }
 }
 
-static pointer
+static void *
 armMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
     struct memAccess *memInfoP;
@@ -404,7 +404,7 @@ armMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 }
 
 static void
-armUnmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+armUnmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     struct memAccess *memInfoP;
 
@@ -450,17 +450,17 @@ Bool
 xf86EnableIO()
 {
     int fd;
-    pointer base;
+    void *base;
 
     if (ExtendedEnabled)
         return TRUE;
 
     if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
         /* Try to map a page at the pccons I/O space */
-        base = (pointer) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
-                              MAP_FLAGS, fd, (off_t) 0x0000);
+        base = (void *) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
+                             MAP_FLAGS, fd, (off_t) 0x0000);
 
-        if (base != (pointer) -1) {
+        if (base != (void *) -1) {
             IOPortBase = base;
         }
         else {
@@ -509,7 +509,7 @@ int ScreenNum;
 {
     int i;
     int fd;
-    pointer base;
+    void *base;
 
 #ifdef __arm32__
     struct memAccess *memInfoP;
@@ -524,10 +524,10 @@ int ScreenNum;
 #ifdef USE_ARC_MMAP
     if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
         /* Try to map a page at the pccons I/O space */
-        base = (pointer) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
-                              MAP_FLAGS, fd, (off_t) 0x0000);
+        base = (void *) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
+                             MAP_FLAGS, fd, (off_t) 0x0000);
 
-        if (base != (pointer) -1) {
+        if (base != (void *) -1) {
             IOPortBase = base;
         }
         else {
@@ -563,10 +563,10 @@ int ScreenNum;
     checkDevMem(TRUE);
 
     if (devMemFd >= 0 && useDevMem) {
-        base = (pointer) mmap((caddr_t) 0, 0x400, PROT_READ | PROT_WRITE,
+        base = (void *) mmap((caddr_t) 0, 0x400, PROT_READ | PROT_WRITE,
                               MAP_FLAGS, devMemFd, (off_t) DEV_MEM_IOBASE);
 
-        if (base != (pointer) -1)
+        if (base != (void *) -1)
             IOPortBase = (unsigned int) base;
     }
 
diff --git a/hw/xfree86/os-support/bsd/bsd_apm.c b/hw/xfree86/os-support/bsd/bsd_apm.c
index b1938cf..1b92962 100644
--- a/hw/xfree86/os-support/bsd/bsd_apm.c
+++ b/hw/xfree86/os-support/bsd/bsd_apm.c
@@ -14,7 +14,7 @@
 
 #define APM_DEVICE "/dev/apm"
 
-static pointer APMihPtr = NULL;
+static void *APMihPtr = NULL;
 static void bsdCloseAPM(void);
 
 static struct {
diff --git a/hw/xfree86/os-support/bsd/bsd_ev56.c b/hw/xfree86/os-support/bsd/bsd_ev56.c
index 645377e..320bb23 100644
--- a/hw/xfree86/os-support/bsd/bsd_ev56.c
+++ b/hw/xfree86/os-support/bsd/bsd_ev56.c
@@ -22,77 +22,77 @@
  */
 __asm(".arch ev56");
 
-int readDense8(pointer Base, register unsigned long Offset);
-int readDense16(pointer Base, register unsigned long Offset);
-int readDense32(pointer Base, register unsigned long Offset);
+int readDense8(void *Base, register unsigned long Offset);
+int readDense16(void *Base, register unsigned long Offset);
+int readDense32(void *Base, register unsigned long Offset);
 void
- writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB8(int Value, void *Base, register unsigned long Offset);
 void
- writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB16(int Value, void *Base, register unsigned long Offset);
 void
- writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB32(int Value, void *Base, register unsigned long Offset);
 void
- writeDense8(int Value, pointer Base, register unsigned long Offset);
+ writeDense8(int Value, void *Base, register unsigned long Offset);
 void
- writeDense16(int Value, pointer Base, register unsigned long Offset);
+ writeDense16(int Value, void *Base, register unsigned long Offset);
 void
- writeDense32(int Value, pointer Base, register unsigned long Offset);
+ writeDense32(int Value, void *Base, register unsigned long Offset);
 
 int
-readDense8(pointer Base, register unsigned long Offset)
+readDense8(void *Base, register unsigned long Offset)
 {
     mem_barrier();
-    return (alpha_ldbu((pointer) ((unsigned long) Base + (Offset))));
+    return (alpha_ldbu((void *) ((unsigned long) Base + (Offset))));
 }
 
 int
-readDense16(pointer Base, register unsigned long Offset)
+readDense16(void *Base, register unsigned long Offset)
 {
     mem_barrier();
-    return (alpha_ldwu((pointer) ((unsigned long) Base + (Offset))));
+    return (alpha_ldwu((void *) ((unsigned long) Base + (Offset))));
 }
 
 int
-readDense32(pointer Base, register unsigned long Offset)
+readDense32(void *Base, register unsigned long Offset)
 {
     mem_barrier();
     return *(volatile CARD32 *) ((unsigned long) Base + (Offset));
 }
 
 void
-writeDenseNB8(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB8(int Value, void *Base, register unsigned long Offset)
 {
-    alpha_stb((pointer) ((unsigned long) Base + (Offset)), Value);
+    alpha_stb((void *) ((unsigned long) Base + (Offset)), Value);
 }
 
 void
-writeDenseNB16(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB16(int Value, void *Base, register unsigned long Offset)
 {
-    alpha_stw((pointer) ((unsigned long) Base + (Offset)), Value);
+    alpha_stw((void *) ((unsigned long) Base + (Offset)), Value);
 }
 
 void
-writeDenseNB32(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB32(int Value, void *Base, register unsigned long Offset)
 {
     *(volatile CARD32 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDense8(int Value, pointer Base, register unsigned long Offset)
+writeDense8(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
-    alpha_stb((pointer) ((unsigned long) Base + (Offset)), Value);
+    alpha_stb((void *) ((unsigned long) Base + (Offset)), Value);
 }
 
 void
-writeDense16(int Value, pointer Base, register unsigned long Offset)
+writeDense16(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
-    alpha_stw((pointer) ((unsigned long) Base + (Offset)), Value);
+    alpha_stw((void *) ((unsigned long) Base + (Offset)), Value);
 }
 
 void
-writeDense32(int Value, pointer Base, register unsigned long Offset)
+writeDense32(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
     *(volatile CARD32 *) ((unsigned long) Base + (Offset)) = Value;
diff --git a/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c b/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c
index 2294385..32ea489 100644
--- a/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c
+++ b/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c
@@ -45,7 +45,7 @@
 #define _PATH_APM_DEV		"/dev/apm"
 #define _PATH_APM_CTLDEV	"/dev/apmctl"
 
-static pointer APMihPtr = NULL;
+static void *APMihPtr = NULL;
 static int devFd = -1;
 static int ctlFd = -1;
 static void bsdCloseAPM(void);
diff --git a/hw/xfree86/os-support/bsd/i386_video.c b/hw/xfree86/os-support/bsd/i386_video.c
index 569a4ec..7453190 100644
--- a/hw/xfree86/os-support/bsd/i386_video.c
+++ b/hw/xfree86/os-support/bsd/i386_video.c
@@ -85,18 +85,18 @@ static int devMemFd = -1;
 #define DEV_APERTURE "/dev/xf86"
 #endif
 
-static pointer mapVidMem(int, unsigned long, unsigned long, int);
-static void unmapVidMem(int, pointer, unsigned long);
+static void *mapVidMem(int, unsigned long, unsigned long, int);
+static void unmapVidMem(int, void *, unsigned long);
 
 #ifdef HAS_MTRR_SUPPORT
-static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
-static void undoWC(int, pointer);
+static void *setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, void *);
 static Bool cleanMTRR(void);
 #endif
 #if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
-static pointer NetBSDsetWC(int, unsigned long, unsigned long, Bool,
+static void *NetBSDsetWC(int, unsigned long, unsigned long, Bool,
                            MessageType);
-static void NetBSDundoWC(int, pointer);
+static void NetBSDundoWC(int, void *);
 #endif
 
 /*
@@ -108,7 +108,7 @@ checkDevMem(Bool warn)
 {
     static Bool devMemChecked = FALSE;
     int fd;
-    pointer base;
+    void *base;
 
     if (devMemChecked)
         return;
@@ -210,10 +210,10 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
     pVidMem->initialised = TRUE;
 }
 
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
-    pointer base;
+    void *base;
 
     checkDevMem(FALSE);
 
@@ -250,7 +250,7 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 }
 
 static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     munmap((caddr_t) Base, Size);
 }
@@ -690,7 +690,7 @@ fullCoverage(unsigned long base, unsigned long size, RangePtr overlap)
     return FALSE;
 }
 
-static pointer
+static void *
 addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
 {
     RangePtr uc = NULL, wc = NULL, retlist = NULL;
@@ -731,7 +731,7 @@ addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
     }
 }
 
-static pointer
+static void *
 delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
 {
     RangePtr uc = NULL, wc = NULL, retlist = NULL;
@@ -776,7 +776,7 @@ delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
     }
 }
 
-static pointer
+static void *
 setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
       MessageType from)
 {
@@ -787,7 +787,7 @@ setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
 }
 
 static void
-undoWC(int screenNum, pointer list)
+undoWC(int screenNum, void *list)
 {
     RangePtr rp;
     struct mem_range_op mro;
@@ -835,7 +835,7 @@ undoWC(int screenNum, pointer list)
 #endif                          /* HAS_MTRR_SUPPORT */
 
 #if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
-static pointer
+static void *
 NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
             MessageType from)
 {
@@ -871,7 +871,7 @@ NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
 }
 
 static void
-NetBSDundoWC(int screenNum, pointer list)
+NetBSDundoWC(int screenNum, void *list)
 {
     struct mtrr *mtrrp = (struct mtrr *) list;
     int n;
diff --git a/hw/xfree86/os-support/bsd/ppc_video.c b/hw/xfree86/os-support/bsd/ppc_video.c
index 417adbf..947a686 100644
--- a/hw/xfree86/os-support/bsd/ppc_video.c
+++ b/hw/xfree86/os-support/bsd/ppc_video.c
@@ -44,8 +44,8 @@
 #define DEV_MEM "/dev/xf86"
 #endif
 
-static pointer ppcMapVidMem(int, unsigned long, unsigned long, int flags);
-static void ppcUnmapVidMem(int, pointer, unsigned long);
+static void *ppcMapVidMem(int, unsigned long, unsigned long, int flags);
+static void ppcUnmapVidMem(int, void *, unsigned long);
 
 Bool xf86EnableIO(void);
 void xf86DisableIO(void);
@@ -62,11 +62,11 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
 
 volatile unsigned char *ioBase = MAP_FAILED;
 
-static pointer
+static void *
 ppcMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
     int fd = xf86Info.consoleFd;
-    pointer base;
+    void *base;
 
 #ifdef DEBUG
     xf86MsgVerb(X_INFO, 3, "mapVidMem %lx, %lx, fd = %d", Base, Size, fd);
@@ -83,7 +83,7 @@ ppcMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 }
 
 static void
-ppcUnmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+ppcUnmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     munmap(Base, Size);
 }
diff --git a/hw/xfree86/os-support/bsd/sparc64_video.c b/hw/xfree86/os-support/bsd/sparc64_video.c
index 21c1661..02951d6 100644
--- a/hw/xfree86/os-support/bsd/sparc64_video.c
+++ b/hw/xfree86/os-support/bsd/sparc64_video.c
@@ -38,8 +38,8 @@
 /* Video Memory Mapping section                                            */
 /***************************************************************************/
 
-static pointer sparc64MapVidMem(int, unsigned long, unsigned long, int);
-static void sparc64UnmapVidMem(int, pointer, unsigned long);
+static void *sparc64MapVidMem(int, unsigned long, unsigned long, int);
+static void sparc64UnmapVidMem(int, void *, unsigned long);
 
 void
 xf86OSInitVidMem(VidMemInfoPtr pVidMem)
@@ -50,12 +50,12 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
     pVidMem->initialised = TRUE;
 }
 
-static pointer
+static void *
 sparc64MapVidMem(int ScreenNum, unsigned long Base, unsigned long Size,
                  int flags)
 {
     int fd = xf86Info.consoleFd;
-    pointer base;
+    void *base;
 
 #ifdef DEBUG
     xf86MsgVerb(X_INFO, 3, "mapVidMem %lx, %lx, fd = %d", Base, Size, fd);
@@ -71,7 +71,7 @@ sparc64MapVidMem(int ScreenNum, unsigned long Base, unsigned long Size,
 }
 
 static void
-sparc64UnmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+sparc64UnmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     munmap(Base, Size);
 }
diff --git a/hw/xfree86/os-support/bus/Sbus.c b/hw/xfree86/os-support/bus/Sbus.c
index 14e6d4b..16ce5b5 100644
--- a/hw/xfree86/os-support/bus/Sbus.c
+++ b/hw/xfree86/os-support/bus/Sbus.c
@@ -641,10 +641,10 @@ sparcPromPathname2Node(const char *pathName)
     return i;
 }
 
-pointer
+void *
 xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
 {
-    pointer ret;
+    void *ret;
     unsigned long pagemask = getpagesize() - 1;
     unsigned long off = offset & ~pagemask;
     unsigned long len = ((offset + size + pagemask) & ~pagemask) - off;
@@ -657,26 +657,26 @@ xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
     else if (psdp->fd < 0)
         return NULL;
 
-    ret = (pointer) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+    ret = (void *) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
                          psdp->fd, off);
-    if (ret == (pointer) -1) {
-        ret = (pointer) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
+    if (ret == (void *) -1) {
+        ret = (void *) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
                              psdp->fd, off);
     }
-    if (ret == (pointer) -1)
+    if (ret == (void *) -1)
         return NULL;
 
     return (char *) ret + (offset - off);
 }
 
 void
-xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size)
+xf86UnmapSbusMem(sbusDevicePtr psdp, void *addr, unsigned long size)
 {
     unsigned long mask = getpagesize() - 1;
     unsigned long base = (unsigned long) addr & ~mask;
     unsigned long len = (((unsigned long) addr + size + mask) & ~mask) - base;
 
-    munmap((pointer) base, len);
+    munmap((void *) base, len);
 }
 
 /* Tell OS that we are driving the HW cursor ourselves. */
diff --git a/hw/xfree86/os-support/hurd/hurd_video.c b/hw/xfree86/os-support/hurd/hurd_video.c
index b3b94c9..dc1a8e6 100644
--- a/hw/xfree86/os-support/hurd/hurd_video.c
+++ b/hw/xfree86/os-support/hurd/hurd_video.c
@@ -42,7 +42,7 @@
 /**************************************************************************
  * Video Memory Mapping section                                            
  ***************************************************************************/
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags)
 {
     mach_port_t device, mem_dev;
@@ -89,11 +89,11 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags)
             ("xf86MapVidMem() can't mach_port_deallocate.(mem_dev) (%s)\n",
              strerror(errno));
     }
-    return (pointer) addr;
+    return (void *) addr;
 }
 
 static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     kern_return_t err = vm_deallocate(mach_task_self(), (int) Base, Size);
 
diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c
index 8bca375..6181eb9 100644
--- a/hw/xfree86/os-support/linux/int10/linux.c
+++ b/hw/xfree86/os-support/linux/int10/linux.c
@@ -18,7 +18,7 @@
 #define DEV_MEM "/dev/mem"
 #endif
 #define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
-#define SHMERRORPTR (pointer)(-1)
+#define SHMERRORPTR (void *)(-1)
 
 #include <fcntl.h>
 #include <errno.h>
@@ -153,9 +153,9 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
         goto error0;
     pInt->mem = &linuxMem;
     pagesize = getpagesize();
-    pInt->private = (pointer) xnfcalloc(1, sizeof(linuxInt10Priv));
+    pInt->private = (void *) xnfcalloc(1, sizeof(linuxInt10Priv));
     ((linuxInt10Priv *) pInt->private)->alloc =
-        (pointer) xnfcalloc(1, ALLOC_ENTRIES(pagesize));
+        (void *) xnfcalloc(1, ALLOC_ENTRIES(pagesize));
 
     if (!xf86IsEntityPrimary(entityIndex)) {
         DebugF("Mapping high memory area\n");
@@ -233,10 +233,10 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
      * 64K bytes at a time.
      */
     if (!videoBiosMapped) {
-        memset((pointer) V_BIOS, 0, SYS_BIOS - V_BIOS);
+        memset((void *) V_BIOS, 0, SYS_BIOS - V_BIOS);
         DebugF("Reading BIOS\n");
         for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
-            if (xf86ReadBIOS(cs, 0, (pointer) cs, V_BIOS_SIZE) < V_BIOS_SIZE)
+            if (xf86ReadBIOS(cs, 0, (void *) cs, V_BIOS_SIZE) < V_BIOS_SIZE)
                 xf86DrvMsg(screen, X_WARNING,
                            "Unable to retrieve all of segment 0x%06lX.\n",
                            (long) cs);
@@ -319,7 +319,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 Bool
 MapCurrentInt10(xf86Int10InfoPtr pInt)
 {
-    pointer addr;
+    void *addr;
     int fd = -1;
 
     if (Int10Current) {
@@ -327,7 +327,7 @@ MapCurrentInt10(xf86Int10InfoPtr pInt)
         if (((linuxInt10Priv *) Int10Current->private)->highMem >= 0)
             shmdt((char *) HIGH_MEM);
         else
-            munmap((pointer) V_BIOS, (SYS_BIOS - V_BIOS));
+            munmap((void *) V_BIOS, (SYS_BIOS - V_BIOS));
     }
     addr =
         shmat(((linuxInt10Priv *) pInt->private)->lowMem, (char *) 1, SHM_RND);
@@ -392,7 +392,7 @@ xf86FreeInt10(xf86Int10InfoPtr pInt)
         if (((linuxInt10Priv *) pInt->private)->highMem >= 0)
             shmdt((char *) HIGH_MEM);
         else
-            munmap((pointer) V_BIOS, (SYS_BIOS - V_BIOS));
+            munmap((void *) V_BIOS, (SYS_BIOS - V_BIOS));
         Int10Current = NULL;
     }
 
@@ -486,22 +486,22 @@ write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
     *((CARD32 *) (memType) addr) = val;
 }
 
-pointer
+void *
 xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
 {
     if (addr < V_RAM)
         return ((linuxInt10Priv *) pInt->private)->base + addr;
     else if (addr < V_BIOS)
-        return (pointer) (memType) addr;
+        return (void *) (memType) addr;
     else if (addr < SYS_BIOS) {
         if (((linuxInt10Priv *) pInt->private)->base_high)
-            return (pointer) (((linuxInt10Priv *) pInt->private)->base_high
+            return (void *) (((linuxInt10Priv *) pInt->private)->base_high
                               - V_BIOS + addr);
         else
-            return (pointer) (memType) addr;
+            return (void *) (memType) addr;
     }
     else
-        return (pointer) (memType) addr;
+        return (void *) (memType) addr;
 }
 
 #if defined DoSubModules
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index 4e5f7f9..dbd5afe 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -33,14 +33,14 @@
 #define ACPI_VIDEO_HEAD_END		(~0u)
 
 static void lnxCloseACPI(void);
-static pointer ACPIihPtr = NULL;
+static void *ACPIihPtr = NULL;
 PMClose lnxACPIOpen(void);
 
 /* in milliseconds */
 #define ACPI_REOPEN_DELAY 1000
 
 static CARD32
-lnxACPIReopen(OsTimerPtr timer, CARD32 time, pointer arg)
+lnxACPIReopen(OsTimerPtr timer, CARD32 time, void *arg)
 {
     if (lnxACPIOpen()) {
         TimerFree(timer);
diff --git a/hw/xfree86/os-support/linux/lnx_apm.c b/hw/xfree86/os-support/linux/lnx_apm.c
index 3879340..6216919 100644
--- a/hw/xfree86/os-support/linux/lnx_apm.c
+++ b/hw/xfree86/os-support/linux/lnx_apm.c
@@ -36,7 +36,7 @@ extern PMClose lnxACPIOpen(void);
 
 static PMClose lnxAPMOpen(void);
 static void lnxCloseAPM(void);
-static pointer APMihPtr = NULL;
+static void *APMihPtr = NULL;
 
 static struct {
     apm_event_t apmLinux;
diff --git a/hw/xfree86/os-support/linux/lnx_ev56.c b/hw/xfree86/os-support/linux/lnx_ev56.c
index 4995070..b695000 100644
--- a/hw/xfree86/os-support/linux/lnx_ev56.c
+++ b/hw/xfree86/os-support/linux/lnx_ev56.c
@@ -6,77 +6,77 @@
 #include "xf86.h"
 #include "compiler.h"
 
-int readDense8(pointer Base, register unsigned long Offset);
-int readDense16(pointer Base, register unsigned long Offset);
-int readDense32(pointer Base, register unsigned long Offset);
+int readDense8(void *Base, register unsigned long Offset);
+int readDense16(void *Base, register unsigned long Offset);
+int readDense32(void *Base, register unsigned long Offset);
 void
- writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB8(int Value, void *Base, register unsigned long Offset);
 void
- writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB16(int Value, void *Base, register unsigned long Offset);
 void
- writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB32(int Value, void *Base, register unsigned long Offset);
 void
- writeDense8(int Value, pointer Base, register unsigned long Offset);
+ writeDense8(int Value, void *Base, register unsigned long Offset);
 void
- writeDense16(int Value, pointer Base, register unsigned long Offset);
+ writeDense16(int Value, void *Base, register unsigned long Offset);
 void
- writeDense32(int Value, pointer Base, register unsigned long Offset);
+ writeDense32(int Value, void *Base, register unsigned long Offset);
 
 int
-readDense8(pointer Base, register unsigned long Offset)
+readDense8(void *Base, register unsigned long Offset)
 {
     mem_barrier();
     return *(volatile CARD8 *) ((unsigned long) Base + (Offset));
 }
 
 int
-readDense16(pointer Base, register unsigned long Offset)
+readDense16(void *Base, register unsigned long Offset)
 {
     mem_barrier();
     return *(volatile CARD16 *) ((unsigned long) Base + (Offset));
 }
 
 int
-readDense32(pointer Base, register unsigned long Offset)
+readDense32(void *Base, register unsigned long Offset)
 {
     mem_barrier();
     return *(volatile CARD32 *) ((unsigned long) Base + (Offset));
 }
 
 void
-writeDenseNB8(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB8(int Value, void *Base, register unsigned long Offset)
 {
     *(volatile CARD8 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDenseNB16(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB16(int Value, void *Base, register unsigned long Offset)
 {
     *(volatile CARD16 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDenseNB32(int Value, pointer Base, register unsigned long Offset)
+writeDenseNB32(int Value, void *Base, register unsigned long Offset)
 {
     *(volatile CARD32 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDense8(int Value, pointer Base, register unsigned long Offset)
+writeDense8(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
     *(volatile CARD8 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDense16(int Value, pointer Base, register unsigned long Offset)
+writeDense16(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
     *(volatile CARD16 *) ((unsigned long) Base + (Offset)) = Value;
 }
 
 void
-writeDense32(int Value, pointer Base, register unsigned long Offset)
+writeDense32(int Value, void *Base, register unsigned long Offset)
 {
     write_mem_barrier();
     *(volatile CARD32 *) ((unsigned long) Base + (Offset)) = Value;
diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
index 43d0a36..824003d 100644
--- a/hw/xfree86/os-support/linux/lnx_video.c
+++ b/hw/xfree86/os-support/linux/lnx_video.c
@@ -80,17 +80,17 @@ extern int iopl(int __level);
 /* Video Memory Mapping section                                            */
 /***************************************************************************/
 
-static pointer mapVidMem(int, unsigned long, unsigned long, int);
-static void unmapVidMem(int, pointer, unsigned long);
+static void *mapVidMem(int, unsigned long, unsigned long, int);
+static void unmapVidMem(int, void *, unsigned long);
 
 #if defined (__alpha__)
 extern void sethae(unsigned long hae);
 extern unsigned long _bus_base __P((void)) __attribute__ ((const));
 extern unsigned long _bus_base_sparse __P((void)) __attribute__ ((const));
 
-static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
+static void *mapVidMemSparse(int, unsigned long, unsigned long, int);
 extern axpDevice lnxGetAXP(void);
-static void unmapVidMemSparse(int, pointer, unsigned long);
+static void unmapVidMemSparse(int, void *, unsigned long);
 static axpDevice axpSystem = -1;
 static Bool needSparse;
 static unsigned long hae_thresh;
@@ -102,8 +102,8 @@ static unsigned long bus_base;
 
 #define SPLIT_WC_REGIONS 1
 
-static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
-static void undoWC(int, pointer);
+static void *setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, void *);
 
 /* The file desc for /proc/mtrr. Once opened, left opened, and the mtrr
    driver will clean up when we exit. */
@@ -339,7 +339,7 @@ mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr)
     }
 }
 
-static pointer
+static void *
 setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
       MessageType from)
 {
@@ -350,7 +350,7 @@ setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
 }
 
 static void
-undoWC(int screenNum, pointer regioninfo)
+undoWC(int screenNum, void *regioninfo)
 {
     mtrr_undo_wc_region(screenNum, regioninfo);
 }
@@ -396,16 +396,16 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem)
 /* Basically, you simply cannot do this on Sparc.  You have to do something portable
  * like use /dev/fb* or mmap() on /proc/bus/pci/X/Y nodes. -DaveM
  */
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
     return NULL;
 }
 #else
-static pointer
+static void *
 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 {
-    pointer base;
+    void *base;
     int fd;
     int mapflags = MAP_SHARED;
     int prot;
@@ -460,7 +460,7 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 #endif                          /* !(__sparc__) */
 
 static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     uintptr_t alignOff = (uintptr_t) Base
         - ((uintptr_t) Base & ~(getpagesize() - 1));
@@ -565,44 +565,44 @@ xf86DisableIO(void)
 
 #define vuip    volatile unsigned int *
 
-extern int readDense8(pointer Base, register unsigned long Offset);
-extern int readDense16(pointer Base, register unsigned long Offset);
-extern int readDense32(pointer Base, register unsigned long Offset);
+extern int readDense8(void *Base, register unsigned long Offset);
+extern int readDense16(void *Base, register unsigned long Offset);
+extern int readDense32(void *Base, register unsigned long Offset);
 extern void
- writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB8(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB16(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeDenseNB32(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense8(int Value, pointer Base, register unsigned long Offset);
+ writeDense8(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense16(int Value, pointer Base, register unsigned long Offset);
+ writeDense16(int Value, void *Base, register unsigned long Offset);
 extern void
- writeDense32(int Value, pointer Base, register unsigned long Offset);
+ writeDense32(int Value, void *Base, register unsigned long Offset);
 
-static int readSparse8(pointer Base, register unsigned long Offset);
-static int readSparse16(pointer Base, register unsigned long Offset);
-static int readSparse32(pointer Base, register unsigned long Offset);
+static int readSparse8(void *Base, register unsigned long Offset);
+static int readSparse16(void *Base, register unsigned long Offset);
+static int readSparse32(void *Base, register unsigned long Offset);
 static void
- writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB8(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB16(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
+ writeSparseNB32(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse8(int Value, pointer Base, register unsigned long Offset);
+ writeSparse8(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse16(int Value, pointer Base, register unsigned long Offset);
+ writeSparse16(int Value, void *Base, register unsigned long Offset);
 static void
- writeSparse32(int Value, pointer Base, register unsigned long Offset);
+ writeSparse32(int Value, void *Base, register unsigned long Offset);
 
 #define DENSE_BASE	0x2ff00000000UL
 #define SPARSE_BASE	0x30000000000UL
 
 static unsigned long msb_set = 0;
 
-static pointer
+static void *
 mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size,
                 int flags)
 {
@@ -689,11 +689,11 @@ mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size,
                 " to DENSE only at 0x%lx\n", Base, Size, ret);
 
 #endif
-    return (pointer) ret;
+    return (void *) ret;
 }
 
 static void
-unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
+unmapVidMemSparse(int ScreenNum, void *Base, unsigned long Size)
 {
     unsigned long Offset = (unsigned long) Base - DENSE_BASE;
 
@@ -709,7 +709,7 @@ unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
 }
 
 static int
-readSparse8(pointer Base, register unsigned long Offset)
+readSparse8(void *Base, register unsigned long Offset)
 {
     register unsigned long result, shift;
     register unsigned long msb;
@@ -733,7 +733,7 @@ readSparse8(pointer Base, register unsigned long Offset)
 }
 
 static int
-readSparse16(pointer Base, register unsigned long Offset)
+readSparse16(void *Base, register unsigned long Offset)
 {
     register unsigned long result, shift;
     register unsigned long msb;
@@ -757,7 +757,7 @@ readSparse16(pointer Base, register unsigned long Offset)
 }
 
 static int
-readSparse32(pointer Base, register unsigned long Offset)
+readSparse32(void *Base, register unsigned long Offset)
 {
     /* NOTE: this is really using DENSE. */
     mem_barrier();
@@ -765,7 +765,7 @@ readSparse32(pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparse8(int Value, pointer Base, register unsigned long Offset)
+writeSparse8(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int b = Value & 0xffU;
@@ -786,7 +786,7 @@ writeSparse8(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparse16(int Value, pointer Base, register unsigned long Offset)
+writeSparse16(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int w = Value & 0xffffU;
@@ -807,7 +807,7 @@ writeSparse16(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparse32(int Value, pointer Base, register unsigned long Offset)
+writeSparse32(int Value, void *Base, register unsigned long Offset)
 {
     /* NOTE: this is really using DENSE. */
     write_mem_barrier();
@@ -816,7 +816,7 @@ writeSparse32(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB8(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int b = Value & 0xffU;
@@ -834,7 +834,7 @@ writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB16(int Value, void *Base, register unsigned long Offset)
 {
     register unsigned long msb;
     register unsigned int w = Value & 0xffffU;
@@ -852,30 +852,30 @@ writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
 }
 
 static void
-writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
+writeSparseNB32(int Value, void *Base, register unsigned long Offset)
 {
     /* NOTE: this is really using DENSE. */
     *(vuip) ((unsigned long) Base + (Offset)) = Value;
     return;
 }
 
-void (*xf86WriteMmio8) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset)
     = writeDense8;
-void (*xf86WriteMmio16) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset)
     = writeDense16;
-void (*xf86WriteMmio32) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset)
     = writeDense32;
-void (*xf86WriteMmioNB8) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB8) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB8;
-void (*xf86WriteMmioNB16) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB16) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB16;
-void (*xf86WriteMmioNB32) (int Value, pointer Base, unsigned long Offset)
+void (*xf86WriteMmioNB32) (int Value, void *Base, unsigned long Offset)
     = writeDenseNB32;
-int (*xf86ReadMmio8) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio8) (void *Base, unsigned long Offset)
     = readDense8;
-int (*xf86ReadMmio16) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio16) (void *Base, unsigned long Offset)
     = readDense16;
-int (*xf86ReadMmio32) (pointer Base, unsigned long Offset)
+int (*xf86ReadMmio32) (void *Base, unsigned long Offset)
     = readDense32;
 
 #endif                          /* __alpha__ */
diff --git a/hw/xfree86/os-support/shared/vidmem.c b/hw/xfree86/os-support/shared/vidmem.c
index 68ed30e..f473293 100644
--- a/hw/xfree86/os-support/shared/vidmem.c
+++ b/hw/xfree86/os-support/shared/vidmem.c
@@ -51,8 +51,8 @@
 
 typedef struct {
     unsigned long size;
-    pointer virtBase;
-    pointer mtrrInfo;
+    void *virtBase;
+    void *mtrrInfo;
 } MappingRec, *MappingPtr;
 
 typedef struct {
@@ -104,7 +104,7 @@ newMapping(VidMapPtr vp)
 }
 
 static MappingPtr
-findMapping(VidMapPtr vp, pointer vbase, unsigned long size)
+findMapping(VidMapPtr vp, void *vbase, unsigned long size)
 {
     int i;
 
@@ -165,10 +165,10 @@ xf86InitVidMem(void)
     }
 }
 
-pointer
+void *
 xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
 {
-    pointer vbase = NULL;
+    void *vbase = NULL;
     VidMapPtr vp;
     MappingPtr mp;
 
@@ -182,7 +182,7 @@ xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
 
     vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags);
 
-    if (!vbase || vbase == (pointer) -1)
+    if (!vbase || vbase == (void *) -1)
         return NULL;
 
     vp = getVidMapRec(ScreenNum);
@@ -208,7 +208,7 @@ xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
 }
 
 void
-xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+xf86UnMapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     VidMapPtr vp;
     MappingPtr mp;
diff --git a/hw/xfree86/os-support/solaris/sun_apm.c b/hw/xfree86/os-support/solaris/sun_apm.c
index b6a1432..38fa5ec 100644
--- a/hw/xfree86/os-support/solaris/sun_apm.c
+++ b/hw/xfree86/os-support/solaris/sun_apm.c
@@ -90,7 +90,7 @@ typedef struct apm_event_info {
 #define APM_DEVICE "/dev/srn"
 #define APM_DEVICE1 "/dev/apm"
 
-static pointer APMihPtr = NULL;
+static void *APMihPtr = NULL;
 static void sunCloseAPM(void);
 
 static struct {
diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 68527a5..16fc1b7 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -316,7 +316,7 @@ xf86CloseConsole(void)
                         " attributes (%s)\n", strerror(errno));
             }
             else {
-                pointer fbdata;
+                void *fbdata;
 
                 fbdata = mmap(NULL, fbattr.fbtype.fb_size,
                               PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
diff --git a/hw/xfree86/os-support/solaris/sun_vid.c b/hw/xfree86/os-support/solaris/sun_vid.c
index 67ef176..fc46487 100644
--- a/hw/xfree86/os-support/solaris/sun_vid.c
+++ b/hw/xfree86/os-support/solaris/sun_vid.c
@@ -107,10 +107,10 @@ solOpenAperture(void)
     return TRUE;
 }
 
-static pointer
+static void *
 solMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags)
 {
-    pointer base;
+    void *base;
     int fd;
     int prot;
 
@@ -144,7 +144,7 @@ solMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags)
 
 /* ARGSUSED */
 static void
-solUnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+solUnMapVidMem(int ScreenNum, void *Base, unsigned long Size)
 {
     if (munmap(Base, Size) != 0) {
         xf86DrvMsgVerb(ScreenNum, X_WARNING, 0,
diff --git a/hw/xfree86/os-support/xf86OSpriv.h b/hw/xfree86/os-support/xf86OSpriv.h
index bd734f5..7f003e8 100644
--- a/hw/xfree86/os-support/xf86OSpriv.h
+++ b/hw/xfree86/os-support/xf86OSpriv.h
@@ -32,12 +32,12 @@
 #ifndef _XF86OSPRIV_H
 #define _XF86OSPRIV_H
 
-typedef pointer (*MapMemProcPtr) (int, unsigned long, unsigned long, int);
-typedef void (*UnmapMemProcPtr) (int, pointer, unsigned long);
-typedef pointer (*SetWCProcPtr) (int, unsigned long, unsigned long, Bool,
+typedef void *(*MapMemProcPtr) (int, unsigned long, unsigned long, int);
+typedef void (*UnmapMemProcPtr) (int, void *, unsigned long);
+typedef void *(*SetWCProcPtr) (int, unsigned long, unsigned long, Bool,
                                  MessageType);
-typedef void (*ProtectMemProcPtr) (int, pointer, unsigned long, Bool);
-typedef void (*UndoWCProcPtr) (int, pointer);
+typedef void (*ProtectMemProcPtr) (int, void *, unsigned long, Bool);
+typedef void (*UndoWCProcPtr) (int, void *);
 
 typedef struct {
     Bool initialised;
diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h
index 106168a..8d27e8b 100644
--- a/hw/xfree86/os-support/xf86_OSproc.h
+++ b/hw/xfree86/os-support/xf86_OSproc.h
@@ -132,9 +132,9 @@ _XFUNCPROTOBEGIN
 /* public functions */
 extern _X_EXPORT Bool xf86LinearVidMem(void);
 extern _X_EXPORT _X_DEPRECATED Bool xf86CheckMTRR(int);
-extern _X_EXPORT _X_DEPRECATED pointer xf86MapVidMem(int, int, unsigned long,
+extern _X_EXPORT _X_DEPRECATED void *xf86MapVidMem(int, int, unsigned long,
                                                      unsigned long);
-extern _X_EXPORT _X_DEPRECATED void xf86UnMapVidMem(int, pointer,
+extern _X_EXPORT _X_DEPRECATED void xf86UnMapVidMem(int, void *,
                                                     unsigned long);
 extern _X_EXPORT int xf86ReadBIOS(unsigned long, unsigned long, unsigned char *,
                                   int);
diff --git a/hw/xfree86/ramdac/xf86CursorPriv.h b/hw/xfree86/ramdac/xf86CursorPriv.h
index 04be141..a5d2aab 100644
--- a/hw/xfree86/ramdac/xf86CursorPriv.h
+++ b/hw/xfree86/ramdac/xf86CursorPriv.h
@@ -34,7 +34,7 @@ typedef struct {
     int ForceHWCursorCount;
     Bool HWCursorForced;
 
-    pointer transparentData;
+    void *transparentData;
 } xf86CursorScreenRec, *xf86CursorScreenPtr;
 
 void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c
index 197abff..3b69698 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -462,9 +462,9 @@ RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
     }
 
     /* 16 bit interleave */
-    DstS = (pointer) mem2;
+    DstS = (void *) mem2;
     DstM = DstS + (size >> 2);
-    pntr = (pointer) mem;
+    pntr = (void *) mem;
     count = (size >> 1);
     while (count) {
         *pntr++ = *DstS++;
@@ -497,9 +497,9 @@ RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
     }
 
     /* 32 bit interleave */
-    DstS = (pointer) mem2;
+    DstS = (void *) mem2;
     DstM = DstS + (size >> 3);
-    pntr = (pointer) mem;
+    pntr = (void *) mem;
     count = (size >> 2);
     while (count) {
         *pntr++ = *DstS++;
@@ -532,9 +532,9 @@ RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
     }
 
     /* 64 bit interleave */
-    DstS = (pointer) mem2;
+    DstS = (void *) mem2;
     DstM = DstS + (size >> 3);
-    pntr = (pointer) mem;
+    pntr = (void *) mem;
     count = (size >> 2);
     while (count) {
         *pntr++ = *DstS++;
diff --git a/hw/xfree86/shadowfb/shadow.c b/hw/xfree86/shadowfb/shadow.c
index 6c66ffe..4352939 100644
--- a/hw/xfree86/shadowfb/shadow.c
+++ b/hw/xfree86/shadowfb/shadow.c
@@ -243,7 +243,7 @@ ShadowCloseScreen(ScreenPtr pScreen)
         ps->Composite = pPriv->Composite;
     }
 
-    free((pointer) pPriv);
+    free((void *) pPriv);
 
     return (*pScreen->CloseScreen) (pScreen);
 }
@@ -342,7 +342,7 @@ static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
 static void ShadowChangeGC(GCPtr, unsigned long);
 static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
 static void ShadowDestroyGC(GCPtr);
-static void ShadowChangeClip(GCPtr, int, pointer, int);
+static void ShadowChangeClip(GCPtr, int, void *, int);
 static void ShadowDestroyClip(GCPtr);
 static void ShadowCopyClip(GCPtr, GCPtr);
 
@@ -409,7 +409,7 @@ ShadowCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
 }
 
 static void
-ShadowChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+ShadowChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     SHADOW_GC_FUNC_PROLOGUE(pGC);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
@@ -1477,7 +1477,7 @@ ShadowImageGlyphBlt(DrawablePtr pDraw,
                     GCPtr pGC,
                     int x, int y,
                     unsigned int nglyphInit,
-                    CharInfoPtr * ppciInit, pointer pglyphBase)
+                    CharInfoPtr * ppciInit, void *pglyphBase)
 {
     BoxRec box;
     Bool boxNotEmpty = FALSE;
@@ -1538,7 +1538,7 @@ ShadowPolyGlyphBlt(DrawablePtr pDraw,
                    GCPtr pGC,
                    int x, int y,
                    unsigned int nglyphInit,
-                   CharInfoPtr * ppciInit, pointer pglyphBase)
+                   CharInfoPtr * ppciInit, void *pglyphBase)
 {
     BoxRec box;
     Bool boxNotEmpty = FALSE;
diff --git a/hw/xfree86/utils/cvt/cvt.c b/hw/xfree86/utils/cvt/cvt.c
index 5e2888e..d5df17f 100644
--- a/hw/xfree86/utils/cvt/cvt.c
+++ b/hw/xfree86/utils/cvt/cvt.c
@@ -39,10 +39,10 @@ FatalError(const char *f, ...)
 }
 
 /* xnfalloc implementation used by the server code we built in */
-pointer
+void *
 XNFalloc(unsigned long n)
 {
-    pointer r;
+    void *r;
 
     r = malloc(n);
     if (!r) {
@@ -53,10 +53,10 @@ XNFalloc(unsigned long n)
 }
 
 /* xnfcalloc implementation used by the server code we built in */
-pointer
+void *
 XNFcalloc(unsigned long n)
 {
-    pointer r;
+    void *r;
 
     r = calloc(1, n);
     if (!r) {
diff --git a/hw/xfree86/vbe/vbe.c b/hw/xfree86/vbe/vbe.c
index 39f0cef..d41e61b 100644
--- a/hw/xfree86/vbe/vbe.c
+++ b/hw/xfree86/vbe/vbe.c
@@ -50,7 +50,7 @@ vbeInfoPtr
 VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
 {
     int RealOff;
-    pointer page = NULL;
+    void *page = NULL;
     ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
     vbeControllerInfoPtr vbe = NULL;
     Bool init_int10 = FALSE;
@@ -259,7 +259,7 @@ static unsigned char *
 vbeReadEDID(vbeInfoPtr pVbe)
 {
     int RealOff = pVbe->real_mode_base;
-    pointer page = pVbe->memory;
+    void *page = pVbe->memory;
     unsigned char *tmp = NULL;
     Bool novbe = FALSE;
     Bool noddc = FALSE;
@@ -319,7 +319,7 @@ vbeReadEDID(vbeInfoPtr pVbe)
 }
 
 xf86MonPtr
-vbeDoEDID(vbeInfoPtr pVbe, pointer unused)
+vbeDoEDID(vbeInfoPtr pVbe, void *unused)
 {
     unsigned char *DDC_data = NULL;
 
@@ -545,7 +545,7 @@ VBEFreeModeInfo(VbeModeInfoBlock * block)
 
 Bool
 VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
-               pointer *memory, int *size, int *real_mode_pages)
+               void **memory, int *size, int *real_mode_pages)
 {
     /*
        Input:
@@ -929,7 +929,7 @@ VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
             memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
         ErrorF("VBESaveRestore\n");
         if ((VBESaveRestore(pVbe, function,
-                            (pointer) &vbe_sr->state,
+                            (void *) &vbe_sr->state,
                             &vbe_sr->stateSize, &vbe_sr->statePage))) {
             if (function == MODE_SAVE) {
                 SaveSucc = TRUE;
@@ -1055,7 +1055,7 @@ struct vbePanelID *
 VBEReadPanelID(vbeInfoPtr pVbe)
 {
     int RealOff = pVbe->real_mode_base;
-    pointer page = pVbe->memory;
+    void *page = pVbe->memory;
     void *tmp = NULL;
     int screen = pVbe->pInt10->pScrn->scrnIndex;
 
diff --git a/hw/xfree86/vbe/vbe.h b/hw/xfree86/vbe/vbe.h
index 3907c53..bc36533 100644
--- a/hw/xfree86/vbe/vbe.h
+++ b/hw/xfree86/vbe/vbe.h
@@ -25,7 +25,7 @@ typedef enum {
 typedef struct {
     xf86Int10InfoPtr pInt10;
     int version;
-    pointer memory;
+    void *memory;
     int real_mode_base;
     int num_pages;
     Bool init_int10;
@@ -40,7 +40,7 @@ extern _X_EXPORT vbeInfoPtr VBEInit(xf86Int10InfoPtr pInt, int entityIndex);
 extern _X_EXPORT vbeInfoPtr VBEExtendedInit(xf86Int10InfoPtr pInt,
                                             int entityIndex, int Flags);
 extern _X_EXPORT void vbeFree(vbeInfoPtr pVbe);
-extern _X_EXPORT xf86MonPtr vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule);
+extern _X_EXPORT xf86MonPtr vbeDoEDID(vbeInfoPtr pVbe, void *pDDCModule);
 
 #pragma pack(1)
 
@@ -227,7 +227,7 @@ typedef enum {
 extern _X_EXPORT Bool
 
 VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction fuction,
-               pointer *memory, int *size, int *real_mode_pages);
+               void **memory, int *size, int *real_mode_pages);
 
 /*
  * INT 5
diff --git a/hw/xfree86/vgahw/vgaCmap.c b/hw/xfree86/vgahw/vgaCmap.c
index e7a0d02..6e028a7 100644
--- a/hw/xfree86/vgahw/vgaCmap.c
+++ b/hw/xfree86/vgahw/vgaCmap.c
@@ -252,7 +252,7 @@ ColormapPtr pmap;
     if (pmap != GetInstalledmiColormap(pmap->pScreen))
         return;
 
-    dixLookupResourceByType((pointer *) &defColormap,
+    dixLookupResourceByType((void **) &defColormap,
                             pmap->pScreen->defColormap, RT_COLORMAP,
                             serverClient, DixInstallAccess);
 
diff --git a/hw/xfree86/vgahw/vgaHW.h b/hw/xfree86/vgahw/vgaHW.h
index 937a8a5..63a10f4 100644
--- a/hw/xfree86/vgahw/vgaHW.h
+++ b/hw/xfree86/vgahw/vgaHW.h
@@ -107,18 +107,18 @@ typedef void (*vgaHWMiscProcPtr) (vgaHWPtr hwp);
  * via the first 17 attribute registers and not the main 8-bit palette.
  */
 typedef struct _vgaHWRec {
-    pointer Base;               /* Address of "VGA" memory */
+    void *Base;               /* Address of "VGA" memory */
     int MapSize;                /* Size of "VGA" memory */
     unsigned long MapPhys;      /* phys location of VGA mem */
     int IOBase;                 /* I/O Base address */
     CARD8 *MMIOBase;            /* Pointer to MMIO start */
     int MMIOOffset;             /* base + offset + vgareg
                                    = mmioreg */
-    pointer FontInfo1;          /* save area for fonts in
+    void *FontInfo1;          /* save area for fonts in
                                    plane 2 */
-    pointer FontInfo2;          /* save area for fonts in       
+    void *FontInfo2;          /* save area for fonts in       
                                    plane 3 */
-    pointer TextInfo;           /* save area for text */
+    void *TextInfo;           /* save area for text */
     vgaRegRec SavedReg;         /* saved registers */
     vgaRegRec ModeReg;          /* register settings for
                                    current mode */
@@ -148,7 +148,7 @@ typedef struct _vgaHWRec {
     vgaHWWriteProcPtr writeDacReadAddr;
     vgaHWWriteProcPtr writeDacData;
     vgaHWReadProcPtr readDacData;
-    pointer ddc;
+    void *ddc;
     struct pci_io_handle *io;
     vgaHWReadProcPtr readEnable;
     vgaHWWriteProcPtr writeEnable;
diff --git a/hw/xnest/Color.c b/hw/xnest/Color.c
index 7ef137d..95c3343 100644
--- a/hw/xnest/Color.c
+++ b/hw/xnest/Color.c
@@ -137,7 +137,7 @@ xnestDestroyColormap(ColormapPtr pCmap)
   (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
 
 static int
-xnestCountInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
 {
     xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *) ptr;
     int i;
@@ -152,7 +152,7 @@ xnestCountInstalledColormapWindows(WindowPtr pWin, pointer ptr)
 }
 
 static int
-xnestGetInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+xnestGetInstalledColormapWindows(WindowPtr pWin, void *ptr)
 {
     xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *) ptr;
     int i;
@@ -198,12 +198,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
                                        sizeof(Colormap));
     icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
     icws.numWindows = 0;
-    WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer) &icws);
+    WalkTree(pScreen, xnestCountInstalledColormapWindows, (void *) &icws);
     if (icws.numWindows) {
         icws.windows =
             (Window *) malloc((icws.numWindows + 1) * sizeof(Window));
         icws.index = 0;
-        WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer) &icws);
+        WalkTree(pScreen, xnestGetInstalledColormapWindows, (void *) &icws);
         icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
         numWindows = icws.numWindows + 1;
     }
@@ -252,11 +252,11 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
             visual = xnestVisualFromID(pScreen, wVisual(pWin));
 
             if (visual == xnestDefaultVisual(pScreen))
-                dixLookupResourceByType((pointer *) &pCmap, wColormap(pWin),
+                dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
                                         RT_COLORMAP, serverClient,
                                         DixUseAccess);
             else
-                dixLookupResourceByType((pointer *) &pCmap,
+                dixLookupResourceByType((void **) &pCmap,
                                         pScreen->defColormap, RT_COLORMAP,
                                         serverClient, DixUseAccess);
 
@@ -309,7 +309,7 @@ xnestDirectInstallColormaps(ScreenPtr pScreen)
     for (i = 0; i < n; i++) {
         ColormapPtr pCmap;
 
-        dixLookupResourceByType((pointer *) &pCmap, pCmapIDs[i], RT_COLORMAP,
+        dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], RT_COLORMAP,
                                 serverClient, DixInstallAccess);
         if (pCmap)
             XInstallColormap(xnestDisplay, xnestColormap(pCmap));
@@ -330,7 +330,7 @@ xnestDirectUninstallColormaps(ScreenPtr pScreen)
     for (i = 0; i < n; i++) {
         ColormapPtr pCmap;
 
-        dixLookupResourceByType((pointer *) &pCmap, pCmapIDs[i], RT_COLORMAP,
+        dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], RT_COLORMAP,
                                 serverClient, DixUninstallAccess);
         if (pCmap)
             XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
@@ -347,10 +347,10 @@ xnestInstallColormap(ColormapPtr pCmap)
 
         /* Uninstall pInstalledMap. Notify all interested parties. */
         if (pOldCmap != (ColormapPtr) None)
-            WalkTree(pCmap->pScreen, TellLostMap, (pointer) &pOldCmap->mid);
+            WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
 
         SetInstalledColormap(pCmap->pScreen, pCmap);
-        WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &pCmap->mid);
+        WalkTree(pCmap->pScreen, TellGainedMap, (void *) &pCmap->mid);
 
         xnestSetInstalledColormapWindows(pCmap->pScreen);
         xnestDirectInstallColormaps(pCmap->pScreen);
@@ -364,7 +364,7 @@ xnestUninstallColormap(ColormapPtr pCmap)
 
     if (pCmap == pCurCmap) {
         if (pCmap->mid != pCmap->pScreen->defColormap) {
-            dixLookupResourceByType((pointer *) &pCurCmap,
+            dixLookupResourceByType((void **) &pCurCmap,
                                     pCmap->pScreen->defColormap,
                                     RT_COLORMAP,
                                     serverClient, DixInstallAccess);
diff --git a/hw/xnest/Font.c b/hw/xnest/Font.c
index 1e95588..ffdfd24 100644
--- a/hw/xnest/Font.c
+++ b/hw/xnest/Font.c
@@ -35,7 +35,7 @@ int xnestFontPrivateIndex;
 Bool
 xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
 {
-    pointer priv;
+    void *priv;
     Atom name_atom, value_atom;
     int nprops;
     FontPropPtr props;
@@ -64,7 +64,7 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
     if (!name)
         return False;
 
-    priv = (pointer) malloc(sizeof(xnestPrivFont));
+    priv = (void *) malloc(sizeof(xnestPrivFont));
     FontSetPrivate(pFont, xnestFontPrivateIndex, priv);
 
     xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
diff --git a/hw/xnest/GC.c b/hw/xnest/GC.c
index cfaf714..0ec60fc 100644
--- a/hw/xnest/GC.c
+++ b/hw/xnest/GC.c
@@ -188,7 +188,7 @@ xnestDestroyGC(GCPtr pGC)
 }
 
 void
-xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
+xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
 {
     int i, size;
     BoxPtr pBox;
@@ -225,7 +225,7 @@ xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
          * current pixmap contents.
          */
         pGC->clientClip =
-            (pointer) (*pGC->pScreen->BitmapToRegion) ((PixmapPtr) pValue);
+            (void *) (*pGC->pScreen->BitmapToRegion) ((PixmapPtr) pValue);
         (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) pValue);
         pValue = pGC->clientClip;
         type = CT_REGION;
@@ -269,7 +269,7 @@ xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
          * other parts of server can only deal with CT_NONE,
          * CT_PIXMAP and CT_REGION client clips.
          */
-        pGC->clientClip = (pointer) RegionFromRects(nRects,
+        pGC->clientClip = (void *) RegionFromRects(nRects,
                                                     (xRectangle *) pValue,
                                                     type);
         free(pValue);
diff --git a/hw/xnest/GCOps.c b/hw/xnest/GCOps.c
index d00511d..fa60231 100644
--- a/hw/xnest/GCOps.c
+++ b/hw/xnest/GCOps.c
@@ -308,7 +308,7 @@ xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
 void
 xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
                    unsigned int nGlyphs, CharInfoPtr * pCharInfo,
-                   pointer pGlyphBase)
+                   void *pGlyphBase)
 {
     ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
 }
@@ -316,7 +316,7 @@ xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
 void
 xnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
                   unsigned int nGlyphs, CharInfoPtr * pCharInfo,
-                  pointer pGlyphBase)
+                  void *pGlyphBase)
 {
     ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
 }
diff --git a/hw/xnest/GCOps.h b/hw/xnest/GCOps.h
index b1cad11..fd1f6bf 100644
--- a/hw/xnest/GCOps.h
+++ b/hw/xnest/GCOps.h
@@ -58,10 +58,10 @@ void xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
                       unsigned short *string);
 void xnestImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
                         unsigned int nGlyphs, CharInfoPtr * pCharInfo,
-                        pointer pGlyphBase);
+                        void *pGlyphBase);
 void xnestPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
                        unsigned int nGlyphs, CharInfoPtr * pCharInfo,
-                       pointer pGlyphBase);
+                       void *pGlyphBase);
 void xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
                      int width, int height, int x, int y);
 
diff --git a/hw/xnest/Handlers.c b/hw/xnest/Handlers.c
index 4605b90..05d559d 100644
--- a/hw/xnest/Handlers.c
+++ b/hw/xnest/Handlers.c
@@ -32,14 +32,14 @@ is" without express or implied warranty.
 #include "Handlers.h"
 
 void
-xnestBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadMask)
+xnestBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadMask)
 {
     xnestCollectExposures();
     XFlush(xnestDisplay);
 }
 
 void
-xnestWakeupHandler(pointer blockData, int result, pointer pReadMask)
+xnestWakeupHandler(void *blockData, int result, void *pReadMask)
 {
     xnestCollectEvents();
 }
diff --git a/hw/xnest/Handlers.h b/hw/xnest/Handlers.h
index 7160bdd..d4ad6d2 100644
--- a/hw/xnest/Handlers.h
+++ b/hw/xnest/Handlers.h
@@ -15,8 +15,8 @@ is" without express or implied warranty.
 #ifndef XNESTHANDLERS_H
 #define XNESTHANDLERS_H
 
-void xnestBlockHandler(pointer blockData, OSTimePtr pTimeout,
-                       pointer pReadMask);
-void xnestWakeupHandler(pointer blockData, int result, pointer pReadMask);
+void xnestBlockHandler(void *blockData, OSTimePtr pTimeout,
+                       void *pReadMask);
+void xnestWakeupHandler(void *blockData, int result, void *pReadMask);
 
 #endif                          /* XNESTHANDLERS_H */
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index d013dc9..2cf1624 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -59,7 +59,7 @@ extern Status XkbGetControls(Display * /* dpy */ ,
 DeviceIntPtr xnestKeyboardDevice = NULL;
 
 void
-xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
+xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
 {
     XBell(xnestDisplay, volume);
 }
diff --git a/hw/xnest/Keyboard.h b/hw/xnest/Keyboard.h
index 45d56bc..dc5eaa2 100644
--- a/hw/xnest/Keyboard.h
+++ b/hw/xnest/Keyboard.h
@@ -20,7 +20,7 @@ is" without express or implied warranty.
 
 extern DeviceIntPtr xnestKeyboardDevice;
 
-void xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls);
+void xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls);
 void xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl);
 int xnestKeyboardProc(DeviceIntPtr pDev, int onoff);
 void xnestUpdateModifierState(unsigned int state);
diff --git a/hw/xnest/Pixmap.c b/hw/xnest/Pixmap.c
index 2902acd..6514f3b 100644
--- a/hw/xnest/Pixmap.c
+++ b/hw/xnest/Pixmap.c
@@ -80,7 +80,7 @@ xnestDestroyPixmap(PixmapPtr pPixmap)
 
 Bool
 xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
-                        int bitsPerPixel, int devKind, pointer pPixData)
+                        int bitsPerPixel, int devKind, void *pPixData)
 {
   if(!xnestPixmapPriv(pPixmap)->pixmap && width > 0 && height > 0) {
     xnestPixmapPriv(pPixmap)->pixmap =
diff --git a/hw/xnest/Window.c b/hw/xnest/Window.c
index e2b21b5..c33cbaa 100644
--- a/hw/xnest/Window.c
+++ b/hw/xnest/Window.c
@@ -42,7 +42,7 @@ is" without express or implied warranty.
 DevPrivateKeyRec xnestWindowPrivateKeyRec;
 
 static int
-xnestFindWindowMatch(WindowPtr pWin, pointer ptr)
+xnestFindWindowMatch(WindowPtr pWin, void *ptr)
 {
     xnestWindowMatch *wm = (xnestWindowMatch *) ptr;
 
@@ -64,7 +64,7 @@ xnestWindowPtr(Window window)
     wm.window = window;
 
     for (i = 0; i < xnestNumScreens; i++) {
-        WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (pointer) &wm);
+        WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (void *) &wm);
         if (wm.pWin)
             break;
     }
@@ -96,7 +96,7 @@ xnestCreateWindow(WindowPtr pWin)
                     xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
                 mask |= CWColormap;
                 if (pWin->optional->colormap) {
-                    dixLookupResourceByType((pointer *) &pCmap, wColormap(pWin),
+                    dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
                                             RT_COLORMAP, serverClient,
                                             DixUseAccess);
                     attributes.colormap = xnestColormap(pCmap);
@@ -109,7 +109,7 @@ xnestCreateWindow(WindowPtr pWin)
         }
         else {                  /* root windows have their own colormaps at creation time */
             visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
-            dixLookupResourceByType((pointer *) &pCmap, wColormap(pWin),
+            dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
                                     RT_COLORMAP, serverClient, DixUseAccess);
             mask |= CWColormap;
             attributes.colormap = xnestColormap(pCmap);
@@ -331,7 +331,7 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     if (mask & CWColormap) {
         ColormapPtr pCmap;
 
-        dixLookupResourceByType((pointer *) &pCmap, wColormap(pWin),
+        dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
                                 RT_COLORMAP, serverClient, DixUseAccess);
 
         attributes.colormap = xnestColormap(pCmap);
diff --git a/hw/xnest/XNGC.h b/hw/xnest/XNGC.h
index c7c25e4..e2f10fb 100644
--- a/hw/xnest/XNGC.h
+++ b/hw/xnest/XNGC.h
@@ -35,7 +35,7 @@ void xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
 void xnestChangeGC(GCPtr pGC, unsigned long mask);
 void xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
 void xnestDestroyGC(GCPtr pGC);
-void xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects);
+void xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects);
 void xnestDestroyClip(GCPtr pGC);
 void xnestDestroyClipHelper(GCPtr pGC);
 void xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
diff --git a/hw/xnest/XNPixmap.h b/hw/xnest/XNPixmap.h
index 5b2e796..b7b10e9 100644
--- a/hw/xnest/XNPixmap.h
+++ b/hw/xnest/XNPixmap.h
@@ -34,7 +34,7 @@ PixmapPtr xnestCreatePixmap(ScreenPtr pScreen, int width, int height,
                             int depth, unsigned usage_hint);
 Bool xnestDestroyPixmap(PixmapPtr pPixmap);
 Bool xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
-                             int bitsPerPixel, int devKind, pointer pPixData);
+                             int bitsPerPixel, int devKind, void *pPixData);
 RegionPtr xnestPixmapToRegion(PixmapPtr pPixmap);
 
 #endif                          /* XNESTPIXMAP_H */
diff --git a/hw/xquartz/applewm.c b/hw/xquartz/applewm.c
index aea0a45..4409d4b 100644
--- a/hw/xquartz/applewm.c
+++ b/hw/xquartz/applewm.c
@@ -83,9 +83,9 @@ static XID eventResource;
 static unsigned int eventMask = 0;
 
 static int
-WMFreeClient(pointer data, XID id);
+WMFreeClient(void *data, XID id);
 static int
-WMFreeEvents(pointer data, XID id);
+WMFreeEvents(void *data, XID id);
 static void
 SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
 
@@ -175,7 +175,7 @@ updateEventMask(WMEventPtr *pHead)
 
 /*ARGSUSED*/
 static int
-WMFreeClient(pointer data, XID id)
+WMFreeClient(void *data, XID id)
 {
     WMEventPtr pEvent;
     WMEventPtr   *pHead, pCur, pPrev;
@@ -183,7 +183,7 @@ WMFreeClient(pointer data, XID id)
 
     pEvent = (WMEventPtr)data;
     i = dixLookupResourceByType(
-        (pointer *)&pHead, eventResource, EventType, serverClient,
+        (void **)&pHead, eventResource, EventType, serverClient,
         DixReadAccess |
         DixWriteAccess | DixDestroyAccess);
     if (i == Success && pHead) {
@@ -198,13 +198,13 @@ WMFreeClient(pointer data, XID id)
         }
         updateEventMask(pHead);
     }
-    free((pointer)pEvent);
+    free((void *)pEvent);
     return 1;
 }
 
 /*ARGSUSED*/
 static int
-WMFreeEvents(pointer data, XID id)
+WMFreeEvents(void *data, XID id)
 {
     WMEventPtr   *pHead, pCur, pNext;
 
@@ -212,9 +212,9 @@ WMFreeEvents(pointer data, XID id)
     for (pCur = *pHead; pCur; pCur = pNext) {
         pNext = pCur->next;
         FreeResource(pCur->clientResource, ClientType);
-        free((pointer)pCur);
+        free((void *)pCur);
     }
-    free((pointer)pHead);
+    free((void *)pHead);
     eventMask = 0;
     return 1;
 }
@@ -229,7 +229,7 @@ ProcAppleWMSelectInput(register ClientPtr client)
 
     REQUEST_SIZE_MATCH(xAppleWMSelectInputReq);
     i =
-        dixLookupResourceByType((pointer *)&pHead, eventResource, EventType,
+        dixLookupResourceByType((void **)&pHead, eventResource, EventType,
                                 client,
                                 DixWriteAccess);
     if (stuff->mask != 0) {
@@ -257,7 +257,7 @@ ProcAppleWMSelectInput(register ClientPtr client)
          */
         clientResource = FakeClientID(client->index);
         pNewEvent->clientResource = clientResource;
-        if (!AddResource(clientResource, ClientType, (pointer)pNewEvent))
+        if (!AddResource(clientResource, ClientType, (void *)pNewEvent))
             return BadAlloc;
         /*
          * create a resource to contain a pointer to the list
@@ -268,7 +268,7 @@ ProcAppleWMSelectInput(register ClientPtr client)
         if (i != Success || !pHead) {
             pHead = (WMEventPtr *)malloc(sizeof(WMEventPtr));
             if (!pHead ||
-                !AddResource(eventResource, EventType, (pointer)pHead)) {
+                !AddResource(eventResource, EventType, (void *)pHead)) {
                 FreeResource(clientResource, RT_NONE);
                 return BadAlloc;
             }
@@ -317,7 +317,7 @@ AppleWMSendEvent(int type, unsigned int mask, int which, int arg)
     int i;
 
     i =
-        dixLookupResourceByType((pointer *)&pHead, eventResource, EventType,
+        dixLookupResourceByType((void **)&pHead, eventResource, EventType,
                                 serverClient,
                                 DixReadAccess);
     if (i != Success || !pHead)
diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index 813bc77..308a3f1 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -47,8 +47,8 @@ extern int aquaMenuBarHeight;
 extern const char      *quartzOpenGLBundle;
 
 void
-QuartzBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask);
+QuartzBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadmask);
 void
-QuartzWakeupHandler(pointer blockData, int result, pointer pReadmask);
+QuartzWakeupHandler(void *blockData, int result, void *pReadmask);
 
 #endif  /* _QUARTZCOMMON_H */
diff --git a/hw/xquartz/xpr/dri.c b/hw/xquartz/xpr/dri.c
index adba69c..014709b 100644
--- a/hw/xquartz/xpr/dri.c
+++ b/hw/xquartz/xpr/dri.c
@@ -455,7 +455,7 @@ DRICreateSurface(ScreenPtr pScreen, Drawable id,
                                 pDRIDrawablePriv->sid), pDRIDrawablePriv);
 
         /* track this in case this window is destroyed */
-        AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+        AddResource(id, DRIDrawablePrivResType, (void *)pDrawable);
 
         /* Initialize shape */
         DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
@@ -529,7 +529,7 @@ DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
  * drops to <= 0, or the window/pixmap is destroyed.
  */
 Bool
-DRIDrawablePrivDelete(pointer pResource, XID id)
+DRIDrawablePrivDelete(void *pResource, XID id)
 {
     DrawablePtr pDrawable = (DrawablePtr)pResource;
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
@@ -829,7 +829,7 @@ DRICreatePixmap(ScreenPtr pScreen, Drawable id,
 
     dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared);
 
-    AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+    AddResource(id, DRIDrawablePrivResType, (void *)pDrawable);
 
     return TRUE;
 }
@@ -884,7 +884,7 @@ DRIFreePixmapImp(DrawablePtr pDrawable)
     shm_unlink(shared->shmPath);
     free(shared);
 
-    dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL);
+    dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (void *)NULL);
 
     return TRUE;
 }
diff --git a/hw/xquartz/xpr/dri.h b/hw/xquartz/xpr/dri.h
index 8717a51..70cb8b6 100644
--- a/hw/xquartz/xpr/dri.h
+++ b/hw/xquartz/xpr/dri.h
@@ -99,7 +99,7 @@ DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
                                  void *data), void *notify_data);
 
 extern Bool
-DRIDrawablePrivDelete(pointer pResource, XID id);
+DRIDrawablePrivDelete(void *pResource, XID id);
 
 extern DRIWrappedFuncsRec *
 DRIGetWrappedFuncs(ScreenPtr pScreen);
diff --git a/hw/xquartz/xpr/driWrap.c b/hw/xquartz/xpr/driWrap.c
index 5f9f3ab..42282d5 100644
--- a/hw/xquartz/xpr/driWrap.c
+++ b/hw/xquartz/xpr/driWrap.c
@@ -447,7 +447,7 @@ DRIImageText16(DrawablePtr dst, GCPtr pGC,
 static void
 DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
                  int x, int y, unsigned int nglyphInit,
-                 CharInfoPtr *ppciInit, pointer unused)
+                 CharInfoPtr *ppciInit, void *unused)
 {
     DRISavedDrawableState saved;
 
@@ -465,7 +465,7 @@ DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
 static void
 DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
                 int x, int y, unsigned int nglyph,
-                CharInfoPtr *ppci, pointer pglyphBase)
+                CharInfoPtr *ppci, void *pglyphBase)
 {
     DRISavedDrawableState saved;
 
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 3d01bed..f130651 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -832,7 +832,7 @@ glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 
     GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow);
 
-    dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id,
+    dixLookupResourceByType((void *) &pGlxDraw, pWindow->drawable.id,
                             __glXDrawableRes, NullClient, DixUnknownAccess);
 
     /*
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index ce89348..0adb227 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -609,7 +609,7 @@ typedef struct {
 #endif
 
 typedef struct {
-    pointer value;
+    void *value;
     XID id;
 } WindowIDPairRec, *WindowIDPairPtr;
 
@@ -773,7 +773,7 @@ void winSetAuthorization(void);
 void
 
 winBlockHandler(ScreenPtr pScreen,
-                pointer pTimeout, pointer pReadMask);
+                void *pTimeout, void *pReadMask);
 
 #ifdef XWIN_NATIVEGDI
 /*
@@ -1035,7 +1035,7 @@ winModifyPixmapHeaderNativeGDI(PixmapPtr pPixmap,
                                int iWidth, int iHeight,
                                int iDepth,
                                int iBitsPerPixel,
-                               int devKind, pointer pPixData);
+                               int devKind, void *pPixData);
 #endif
 
 #ifdef XWIN_NATIVEGDI
@@ -1106,7 +1106,7 @@ Bool
 void
 
 winWakeupHandler(ScreenPtr pScreen,
-                 unsigned long ulResult, pointer pReadmask);
+                 unsigned long ulResult, void *pReadmask);
 
 /*
  * winwindow.c
diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c
index c3ef4be..07e9078 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -37,7 +37,7 @@
 /* See Porting Layer Definition - p. 6 */
 void
 winBlockHandler(ScreenPtr pScreen,
-                pointer pTimeout, pointer pReadMask)
+                void *pTimeout, void *pReadMask)
 {
 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
     winScreenPriv(pScreen);
diff --git a/hw/xwin/wincmap.c b/hw/xwin/wincmap.c
index 610437a..5dcc8bc 100644
--- a/hw/xwin/wincmap.c
+++ b/hw/xwin/wincmap.c
@@ -177,7 +177,7 @@ winUninstallColormap(ColormapPtr pmap)
 
     /* Install the default cmap in place of the cmap to be uninstalled */
     if (pmap->mid != pmap->pScreen->defColormap) {
-        dixLookupResourceByType((pointer) &curpmap, pmap->pScreen->defColormap,
+        dixLookupResourceByType((void *) &curpmap, pmap->pScreen->defColormap,
                                 RT_COLORMAP, NullClient, DixUnknownAccess);
         (*pmap->pScreen->InstallColormap) (curpmap);
     }
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index 9e38113..a6d3c0a 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -106,7 +106,7 @@ winInfoRec g_winInfo = {
 #ifdef XWIN_XF86CONFIG
 serverLayoutRec g_winConfigLayout;
 
-static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p);
+static Bool ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p);
 static Bool configLayout(serverLayoutPtr, XF86ConfLayoutPtr, char *);
 static Bool configImpliedLayout(serverLayoutPtr, XF86ConfScreenPtr);
 static Bool GetBoolValue(OptionInfoPtr p, const char *s);
@@ -188,7 +188,7 @@ winReadConfigfile()
         /* Check if layout is given in the config file */
         if (g_xf86configptr->conf_flags != NULL) {
             char *dfltlayout = NULL;
-            pointer optlist = g_xf86configptr->conf_flags->flg_option_lst;
+            void *optlist = g_xf86configptr->conf_flags->flg_option_lst;
 
             if (optlist && winFindOption(optlist, "defaultserverlayout"))
                 dfltlayout =
@@ -588,7 +588,7 @@ winConfigScreens(void)
 
 #ifdef XWIN_XF86CONFIG
 char *
-winSetStrOption(pointer optlist, const char *name, char *deflt)
+winSetStrOption(void *optlist, const char *name, char *deflt)
 {
     OptionInfoRec o;
 
@@ -603,7 +603,7 @@ winSetStrOption(pointer optlist, const char *name, char *deflt)
 }
 
 int
-winSetBoolOption(pointer optlist, const char *name, int deflt)
+winSetBoolOption(void *optlist, const char *name, int deflt)
 {
     OptionInfoRec o;
 
@@ -615,7 +615,7 @@ winSetBoolOption(pointer optlist, const char *name, int deflt)
 }
 
 int
-winSetIntOption(pointer optlist, const char *name, int deflt)
+winSetIntOption(void *optlist, const char *name, int deflt)
 {
     OptionInfoRec o;
 
@@ -627,7 +627,7 @@ winSetIntOption(pointer optlist, const char *name, int deflt)
 }
 
 double
-winSetRealOption(pointer optlist, const char *name, double deflt)
+winSetRealOption(void *optlist, const char *name, double deflt)
 {
     OptionInfoRec o;
 
@@ -639,7 +639,7 @@ winSetRealOption(pointer optlist, const char *name, double deflt)
 }
 
 double
-winSetPercentOption(pointer optlist, const char *name, double deflt)
+winSetPercentOption(void *optlist, const char *name, double deflt)
 {
     OptionInfoRec o;
 
@@ -734,7 +734,7 @@ winFindOptionValue(XF86OptionPtr list, const char *name)
  */
 
 static Bool
-ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p)
+ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p)
 {
     char *s, *end;
 
diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h
index 94571ff..798c779 100644
--- a/hw/xwin/winconfig.h
+++ b/hw/xwin/winconfig.h
@@ -58,15 +58,15 @@ typedef struct {
     Bool inUse;
     int videoRam;
     int textClockFreq;
-    pointer options;
+    void *options;
     int screen;                 /* For multi-CRTC cards */
 } GDevRec, *GDevPtr;
 
 typedef struct {
     char *identifier;
     char *driver;
-    pointer commonOptions;
-    pointer extraOptions;
+    void *commonOptions;
+    void *extraOptions;
 } IDevRec, *IDevPtr;
 
 typedef struct {
@@ -81,19 +81,19 @@ typedef struct {
     rgb whiteColour;
     int defaultVisual;
     char **modes;
-    pointer options;
+    void *options;
 } DispRec, *DispPtr;
 
 typedef struct _confxvportrec {
     char *identifier;
-    pointer options;
+    void *options;
 } confXvPortRec, *confXvPortPtr;
 
 typedef struct _confxvadaptrec {
     char *identifier;
     int numports;
     confXvPortPtr ports;
-    pointer options;
+    void *options;
 } confXvAdaptorRec, *confXvAdaptorPtr;
 
 typedef struct _confscreenrec {
@@ -107,7 +107,7 @@ typedef struct _confscreenrec {
     DispPtr displays;
     int numxvadaptors;
     confXvAdaptorPtr xvadaptors;
-    pointer options;
+    void *options;
 } confScreenRec, *confScreenPtr;
 
 typedef enum {
@@ -142,7 +142,7 @@ typedef struct _serverlayoutrec {
     screenLayoutPtr screens;
     GDevPtr inactives;
     IDevPtr inputs;
-    pointer options;
+    void *options;
 } serverLayoutRec, *serverLayoutPtr;
 
 /*
@@ -233,11 +233,11 @@ typedef struct {
  * Function prototypes
  */
 
-char *winSetStrOption(pointer optlist, const char *name, char *deflt);
-int winSetBoolOption(pointer optlist, const char *name, int deflt);
-int winSetIntOption(pointer optlist, const char *name, int deflt);
-double winSetRealOption(pointer optlist, const char *name, double deflt);
-double winSetPercentOption(pointer optlist, const char *name, double deflt);
+char *winSetStrOption(void *optlist, const char *name, char *deflt);
+int winSetBoolOption(void *optlist, const char *name, int deflt);
+int winSetIntOption(void *optlist, const char *name, int deflt);
+double winSetRealOption(void *optlist, const char *name, double deflt);
+double winSetPercentOption(void *optlist, const char *name, double deflt);
 
 #ifdef XWIN_XF86CONFIG
 XF86OptionPtr winFindOption(XF86OptionPtr list, const char *name);
diff --git a/hw/xwin/wingc.c b/hw/xwin/wingc.c
index 814d531..5986e0a 100644
--- a/hw/xwin/wingc.c
+++ b/hw/xwin/wingc.c
@@ -56,7 +56,7 @@ static void
 
 #if 0
 static void
- winChangeClipNativeGDI(GCPtr pGC, int nType, pointer pValue, int nRects);
+ winChangeClipNativeGDI(GCPtr pGC, int nType, void *pValue, int nRects);
 
 static void
  winDestroyClipNativeGDI(GCPtr pGC);
@@ -214,7 +214,7 @@ winDestroyGCNativeGDI(GCPtr pGC)
 #if 0
 /* See Porting Layer Definition - p. 46 */
 static void
-winChangeClipNativeGDI(GCPtr pGC, int nType, pointer pValue, int nRects)
+winChangeClipNativeGDI(GCPtr pGC, int nType, void *pValue, int nRects)
 {
 
 }
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 9c5d4e9..b6b2086 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -51,7 +51,7 @@ static Bool g_winKeyState[NUM_KEYCODES];
  */
 
 static void
- winKeybdBell(int iPercent, DeviceIntPtr pDeviceInt, pointer pCtrl, int iClass);
+ winKeybdBell(int iPercent, DeviceIntPtr pDeviceInt, void *pCtrl, int iClass);
 
 static void
  winKeybdCtrl(DeviceIntPtr pDevice, KeybdCtrl * pCtrl);
@@ -120,7 +120,7 @@ winTranslateKey(WPARAM wParam, LPARAM lParam)
 
 /* Ring the keyboard bell (system speaker on PCs) */
 static void
-winKeybdBell(int iPercent, DeviceIntPtr pDeviceInt, pointer pCtrl, int iClass)
+winKeybdBell(int iPercent, DeviceIntPtr pDeviceInt, void *pCtrl, int iClass)
 {
     /*
      * We can't use Beep () here because it uses the PC speaker
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 44ad193..f2e7907 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -53,7 +53,7 @@ static void
  winUpdateWindowsWindow(WindowPtr pWin);
 
 static void
- winFindWindow(pointer value, XID id, pointer cdata);
+ winFindWindow(void *value, XID id, void *cdata);
 
 static
     void
@@ -724,7 +724,7 @@ winGetWindowID(WindowPtr pWin)
  */
 
 static void
-winFindWindow(pointer value, XID id, pointer cdata)
+winFindWindow(void *value, XID id, void *cdata)
 {
     WindowIDPairPtr wi = (WindowIDPairPtr) cdata;
 
@@ -813,7 +813,7 @@ winMinimizeWindow(Window id)
     ErrorF("winMinimizeWindow\n");
 #endif
 
-    dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient,
+    dixLookupResourceByType((void *) &pWin, id, RT_WINDOW, NullClient,
                             DixUnknownAccess);
     if (!pWin) {
         ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c
index f870007..0106161 100644
--- a/hw/xwin/winpfbdd.c
+++ b/hw/xwin/winpfbdd.c
@@ -306,7 +306,7 @@ winCloseScreenPrimaryDD(ScreenPtr pScreen)
     pScreenInfo->pScreen = NULL;
 
     /* Free the screen privates for this screen */
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
 
     return fReturn;
 }
diff --git a/hw/xwin/winpixmap.c b/hw/xwin/winpixmap.c
index d8a12d5..ef158c8 100644
--- a/hw/xwin/winpixmap.c
+++ b/hw/xwin/winpixmap.c
@@ -178,7 +178,7 @@ Bool
 winModifyPixmapHeaderNativeGDI(PixmapPtr pPixmap,
                                int iWidth, int iHeight,
                                int iDepth,
-                               int iBitsPerPixel, int devKind, pointer pPixData)
+                               int iBitsPerPixel, int devKind, void *pPixData)
 {
     FatalError("winModifyPixmapHeaderNativeGDI ()\n");
     return TRUE;
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index 2e70608..5f3b658 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -676,7 +676,7 @@ winCloseScreenShadowDD(ScreenPtr pScreen)
     pScreenInfo->pScreen = NULL;
 
     /* Free the screen privates for this screen */
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
 
     return fReturn;
 }
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index 01097f2..55af5c3 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -703,7 +703,7 @@ winCloseScreenShadowDDNL(ScreenPtr pScreen)
     pScreenInfo->pScreen = NULL;
 
     /* Free the screen privates for this screen */
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
 
     return fReturn;
 }
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index ebc2339..2e3c64c 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -629,7 +629,7 @@ winCloseScreenShadowGDI(ScreenPtr pScreen)
     pScreenInfo->pScreen = NULL;
 
     /* Free the screen privates for this screen */
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
 
     return fReturn;
 }
diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c
index 795221a..ebcb0fa 100644
--- a/hw/xwin/winwakeup.c
+++ b/hw/xwin/winwakeup.c
@@ -39,7 +39,7 @@
 /* See Porting Layer Definition - p. 7 */
 void
 winWakeupHandler(ScreenPtr pScreen,
-                 unsigned long ulResult, pointer pReadmask)
+                 unsigned long ulResult, void *pReadmask)
 {
     MSG msg;
 
diff --git a/hw/xwin/winwindow.c b/hw/xwin/winwindow.c
index 029bd85..759aa5e 100644
--- a/hw/xwin/winwindow.c
+++ b/hw/xwin/winwindow.c
@@ -39,7 +39,7 @@
  */
 
 static int
- winAddRgn(WindowPtr pWindow, pointer data);
+ winAddRgn(WindowPtr pWindow, void *data);
 
 static
     void
@@ -456,7 +456,7 @@ winSetShapeRootless(WindowPtr pWin, int kind)
 
 static
     int
-winAddRgn(WindowPtr pWin, pointer data)
+winAddRgn(WindowPtr pWin, void *data)
 {
     int iX, iY, iWidth, iHeight, iBorder;
     HRGN hRgn = *(HRGN *) data;
diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c
index be43265..c3503db 100644
--- a/hw/xwin/winwindowswm.c
+++ b/hw/xwin/winwindowswm.c
@@ -53,8 +53,8 @@ static XID eventResource;
 /* Currently selected events */
 static unsigned int eventMask = 0;
 
-static int WMFreeClient(pointer data, XID id);
-static int WMFreeEvents(pointer data, XID id);
+static int WMFreeClient(void *data, XID id);
+static int WMFreeEvents(void *data, XID id);
 static void SNotifyEvent(xWindowsWMNotifyEvent * from,
                          xWindowsWMNotifyEvent * to);
 
@@ -99,13 +99,13 @@ updateEventMask(WMEventPtr * pHead)
 }
 
  /*ARGSUSED*/ static int
-WMFreeClient(pointer data, XID id)
+WMFreeClient(void *data, XID id)
 {
     WMEventPtr pEvent;
     WMEventPtr *pHead, pCur, pPrev;
 
     pEvent = (WMEventPtr) data;
-    dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
+    dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
                             NullClient, DixUnknownAccess);
     if (pHead) {
         pPrev = 0;
@@ -119,12 +119,12 @@ WMFreeClient(pointer data, XID id)
         }
         updateEventMask(pHead);
     }
-    free((pointer) pEvent);
+    free((void *) pEvent);
     return 1;
 }
 
  /*ARGSUSED*/ static int
-WMFreeEvents(pointer data, XID id)
+WMFreeEvents(void *data, XID id)
 {
     WMEventPtr *pHead, pCur, pNext;
 
@@ -132,9 +132,9 @@ WMFreeEvents(pointer data, XID id)
     for (pCur = *pHead; pCur; pCur = pNext) {
         pNext = pCur->next;
         FreeResource(pCur->clientResource, ClientType);
-        free((pointer) pCur);
+        free((void *) pCur);
     }
-    free((pointer) pHead);
+    free((void *) pHead);
     eventMask = 0;
     return 1;
 }
@@ -147,7 +147,7 @@ ProcWindowsWMSelectInput(ClientPtr client)
     XID clientResource;
 
     REQUEST_SIZE_MATCH(xWindowsWMSelectInputReq);
-    dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
+    dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
                             client, DixWriteAccess);
     if (stuff->mask != 0) {
         if (pHead) {
@@ -174,7 +174,7 @@ ProcWindowsWMSelectInput(ClientPtr client)
          */
         clientResource = FakeClientID(client->index);
         pNewEvent->clientResource = clientResource;
-        if (!AddResource(clientResource, ClientType, (pointer) pNewEvent))
+        if (!AddResource(clientResource, ClientType, (void *) pNewEvent))
             return BadAlloc;
         /*
          * create a resource to contain a pointer to the list
@@ -185,7 +185,7 @@ ProcWindowsWMSelectInput(ClientPtr client)
         if (!pHead) {
             pHead = (WMEventPtr *) malloc(sizeof(WMEventPtr));
             if (!pHead ||
-                !AddResource(eventResource, eventResourceType, (pointer) pHead))
+                !AddResource(eventResource, eventResourceType, (void *) pHead))
             {
                 FreeResource(clientResource, RT_NONE);
                 return BadAlloc;
@@ -239,7 +239,7 @@ winWindowsWMSendEvent(int type, unsigned int mask, int which, int arg,
     ErrorF("winWindowsWMSendEvent %d %d %d %d,  %d %d - %d %d\n",
            type, mask, which, arg, x, y, w, h);
 #endif
-    dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
+    dixLookupResourceByType((void *) &pHead, eventResource, eventResourceType,
                             NullClient, DixUnknownAccess);
     if (!pHead)
         return;
diff --git a/include/callback.h b/include/callback.h
index b427089..df638c0 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -62,21 +62,21 @@ typedef struct _CallbackList *CallbackListPtr;  /* also in misc.h */
 #define _XTYPEDEF_CALLBACKLISTPTR
 #endif
 
-typedef void (*CallbackProcPtr) (CallbackListPtr *, pointer, pointer);
+typedef void (*CallbackProcPtr) (CallbackListPtr *, void *, void *);
 
 extern _X_EXPORT Bool AddCallback(CallbackListPtr * /*pcbl */ ,
                                   CallbackProcPtr /*callback */ ,
-                                  pointer /*data */ );
+                                  void */*data */ );
 
 extern _X_EXPORT Bool DeleteCallback(CallbackListPtr * /*pcbl */ ,
                                      CallbackProcPtr /*callback */ ,
-                                     pointer /*data */ );
+                                     void */*data */ );
 
 extern _X_EXPORT void _CallCallbacks(CallbackListPtr * /*pcbl */ ,
-                                     pointer /*call_data */ );
+                                     void */*call_data */ );
 
 static inline void
-CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
+CallCallbacks(CallbackListPtr *pcbl, void *call_data)
 {
     if (!pcbl || !*pcbl)
         return;
diff --git a/include/closestr.h b/include/closestr.h
index d762891..60e6f09 100644
--- a/include/closestr.h
+++ b/include/closestr.h
@@ -64,7 +64,7 @@ typedef struct _LFWIstate {
     int current_fpe;
     int max_names;
     Bool list_started;
-    pointer private;
+    void *private;
 } LFWIstateRec, *LFWIstatePtr;
 
 typedef struct _LFWIclosure {
diff --git a/include/colormap.h b/include/colormap.h
index 8996cfe..22229ca 100644
--- a/include/colormap.h
+++ b/include/colormap.h
@@ -82,14 +82,14 @@ extern _X_EXPORT int CreateColormap(Colormap /*mid */ ,
                                     int /*alloc */ ,
                                     int /*client */ );
 
-extern _X_EXPORT int FreeColormap(pointer /*pmap */ ,
+extern _X_EXPORT int FreeColormap(void */*pmap */ ,
                                   XID /*mid */ );
 
 extern _X_EXPORT int TellLostMap(WindowPtr /*pwin */ ,
-                                 pointer /* Colormap *pmid */ );
+                                 void */* Colormap *pmid */ );
 
 extern _X_EXPORT int TellGainedMap(WindowPtr /*pwin */ ,
-                                   pointer /* Colormap *pmid */ );
+                                   void */* Colormap *pmid */ );
 
 extern _X_EXPORT int CopyColormapAndFree(Colormap /*mid */ ,
                                          ColormapPtr /*pSrc */ ,
@@ -126,7 +126,7 @@ extern _X_EXPORT int QueryColors(ColormapPtr /*pmap */ ,
                                  xrgb * /*prgbList */ ,
                                  ClientPtr client);
 
-extern _X_EXPORT int FreeClientPixels(pointer /*pcr */ ,
+extern _X_EXPORT int FreeClientPixels(void */*pcr */ ,
                                       XID /*fakeid */ );
 
 extern _X_EXPORT int AllocColorCells(int /*client */ ,
diff --git a/include/cursor.h b/include/cursor.h
index 89a650f..9da08af 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -68,7 +68,7 @@ extern _X_EXPORT DevScreenPrivateKeyRec cursorScreenDevPriv;
 
 extern _X_EXPORT CursorPtr rootCursor;
 
-extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
+extern _X_EXPORT int FreeCursor(void */*pCurs */ ,
                                 XID /*cid */ );
 
 extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 3066100..957257b 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -469,4 +469,7 @@
 /* Directory for shared memory temp files */
 #undef SHMDIR
 
+/* Don't let Xdefs.h define 'pointer' */
+#define _XTYPEDEF_POINTER       1
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/dix.h b/include/dix.h
index 7362e07..8371df0 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -147,14 +147,14 @@ extern _X_EXPORT void UpdateCurrentTime(void);
 
 extern _X_EXPORT void UpdateCurrentTimeIf(void);
 
-extern _X_EXPORT int dixDestroyPixmap(pointer /*value */ ,
+extern _X_EXPORT int dixDestroyPixmap(void */*value */ ,
                                       XID /*pid */ );
 
 extern _X_EXPORT void InitClient(ClientPtr /*client */ ,
                                  int /*i */ ,
-                                 pointer /*ospriv */ );
+                                 void */*ospriv */ );
 
-extern _X_EXPORT ClientPtr NextAvailableClient(pointer /*ospriv */ );
+extern _X_EXPORT ClientPtr NextAvailableClient(void */*ospriv */ );
 
 extern _X_EXPORT void SendErrorToClient(ClientPtr /*client */ ,
                                         unsigned int /*majorCode */ ,
@@ -203,11 +203,11 @@ extern _X_EXPORT int AlterSaveSetForClient(ClientPtr /*client */ ,
 
 extern _X_EXPORT void DeleteWindowFromAnySaveSet(WindowPtr /*pWin */ );
 
-extern _X_EXPORT void BlockHandler(pointer /*pTimeout */ ,
-                                   pointer /*pReadmask */ );
+extern _X_EXPORT void BlockHandler(void */*pTimeout */ ,
+                                   void */*pReadmask */ );
 
 extern _X_EXPORT void WakeupHandler(int /*result */ ,
-                                    pointer /*pReadmask */ );
+                                    void */*pReadmask */ );
 
 void
  EnableLimitedSchedulingLatency(void);
@@ -215,21 +215,21 @@ void
 void
  DisableLimitedSchedulingLatency(void);
 
-typedef void (*WakeupHandlerProcPtr) (pointer /* blockData */ ,
+typedef void (*WakeupHandlerProcPtr) (void */* blockData */ ,
                                       int /* result */ ,
-                                      pointer /* pReadmask */ );
+                                      void */* pReadmask */ );
 
 extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr
                                                      /*blockHandler */ ,
                                                      WakeupHandlerProcPtr
                                                      /*wakeupHandler */ ,
-                                                     pointer /*blockData */ );
+                                                     void */*blockData */ );
 
 extern _X_EXPORT void RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr
                                                    /*blockHandler */ ,
                                                    WakeupHandlerProcPtr
                                                    /*wakeupHandler */ ,
-                                                   pointer /*blockData */ );
+                                                   void */*blockData */ );
 
 extern _X_EXPORT void InitBlockAndWakeupHandlers(void);
 
@@ -241,18 +241,18 @@ extern _X_EXPORT Bool QueueWorkProc(Bool (* /*function */ )(
                                                                ClientPtr
                                                                /*clientUnused */
                                                                ,
-                                                               pointer
+                                                               void *
                                                                /*closure */ ),
                                     ClientPtr /*client */ ,
-                                    pointer     /*closure */
+                                    void */*closure */
     );
 
 typedef Bool (*ClientSleepProcPtr) (ClientPtr /*client */ ,
-                                    pointer /*closure */ );
+                                    void */*closure */ );
 
 extern _X_EXPORT Bool ClientSleep(ClientPtr /*client */ ,
                                   ClientSleepProcPtr /* function */ ,
-                                  pointer /*closure */ );
+                                  void */*closure */ );
 
 #ifndef ___CLIENTSIGNAL_DEFINED___
 #define ___CLIENTSIGNAL_DEFINED___
@@ -444,7 +444,7 @@ extern void
 RecalculateDeliverableEvents(WindowPtr /* pWin */ );
 
 extern _X_EXPORT int
-OtherClientGone(pointer /* value */ ,
+OtherClientGone(void */* value */ ,
                 XID /* id */ );
 
 extern void
diff --git a/include/dixfont.h b/include/dixfont.h
index 0598311..40d80c1 100644
--- a/include/dixfont.h
+++ b/include/dixfont.h
@@ -40,9 +40,9 @@ extern _X_EXPORT void QueueFontWakeup(FontPathElementPtr /*fpe */ );
 
 extern _X_EXPORT void RemoveFontWakeup(FontPathElementPtr /*fpe */ );
 
-extern _X_EXPORT void FontWakeup(pointer /*data */ ,
+extern _X_EXPORT void FontWakeup(void */*data */ ,
                                  int /*count */ ,
-                                 pointer /*LastSelectMask */ );
+                                 void */*LastSelectMask */ );
 
 extern _X_EXPORT int OpenFont(ClientPtr /*client */ ,
                               XID /*fid */ ,
@@ -50,7 +50,7 @@ extern _X_EXPORT int OpenFont(ClientPtr /*client */ ,
                               unsigned /*lenfname */ ,
                               const char * /*pfontname */ );
 
-extern _X_EXPORT int CloseFont(pointer /*pfont */ ,
+extern _X_EXPORT int CloseFont(void */*pfont */ ,
                                XID /*fid */ );
 
 typedef struct _xQueryFontReply *xQueryFontReplyPtr;
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index ca3c95b..d78d812 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -47,7 +47,7 @@ extern GrabPtr CreateGrab(int /* client */ ,
                           WindowPtr /* confineTo */ ,
                           CursorPtr /* cursor */ );
 
-extern _X_EXPORT int DeletePassiveGrab(pointer /* value */ ,
+extern _X_EXPORT int DeletePassiveGrab(void */* value */ ,
                                        XID /* id */ );
 
 extern _X_EXPORT Bool GrabMatchesSecond(GrabPtr /* pFirstGrab */ ,
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 6f5667f..a11729b 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -74,8 +74,8 @@ typedef struct _saveSet {
 #define SaveSetAssignMap(ss,m)      ((ss).map = (m))
 
 typedef struct _Client {
-    pointer requestBuffer;
-    pointer osPrivate;          /* for OS layer, including scheduler */
+    void *requestBuffer;
+    void *osPrivate;             /* for OS layer, including scheduler */
     Mask clientAsMask;
     short index;
     unsigned char majorOp, minorOp;
@@ -149,10 +149,10 @@ SmartScheduleInit(void);
 typedef struct _WorkQueue {
     struct _WorkQueue *next;
     Bool (*function) (ClientPtr /* pClient */ ,
-                      pointer   /* closure */
+                      void *    /* closure */
         );
     ClientPtr client;
-    pointer closure;
+    void *closure;
 } WorkQueueRec;
 
 extern _X_EXPORT TimeStamp currentTime;
@@ -166,7 +166,7 @@ ClientTimeToServerTime(CARD32 /*c */ );
 
 typedef struct _CallbackRec {
     CallbackProcPtr proc;
-    pointer data;
+    void *data;
     Bool deleted;
     struct _CallbackRec *next;
 } CallbackRec, *CallbackPtr;
diff --git a/include/extnsionst.h b/include/extnsionst.h
index 126807d..fbdb73c 100644
--- a/include/extnsionst.h
+++ b/include/extnsionst.h
@@ -66,7 +66,7 @@ typedef struct _ExtensionEntry {
     int errorLast;
     int num_aliases;
     const char **aliases;
-    pointer extPrivate;
+    void *extPrivate;
     unsigned short (*MinorOpcode) (     /* called for errors */
                                       ClientPtr /* client */ );
     PrivateRec *devPrivates;
diff --git a/include/gc.h b/include/gc.h
index 6e5b92d..ecaa257 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -88,7 +88,7 @@ extern _X_EXPORT void ValidateGC(DrawablePtr /*pDraw */ ,
 
 typedef union {
     CARD32 val;
-    pointer ptr;
+    void *ptr;
 } ChangeGCVal, *ChangeGCValPtr;
 
 extern int ChangeGCXIDs(ClientPtr /*client */ ,
@@ -112,7 +112,7 @@ extern _X_EXPORT int CopyGC(GCPtr /*pgcSrc */ ,
                             GCPtr /*pgcDst */ ,
                             BITS32 /*mask */ );
 
-extern _X_EXPORT int FreeGC(pointer /*pGC */ ,
+extern _X_EXPORT int FreeGC(void */*pGC */ ,
                             XID /*gid */ );
 
 extern _X_EXPORT void FreeGCperDepth(int /*screenNum */ );
diff --git a/include/gcstruct.h b/include/gcstruct.h
index 253593f..c830ccd 100644
--- a/include/gcstruct.h
+++ b/include/gcstruct.h
@@ -78,7 +78,7 @@ typedef struct _GCFuncs {
 
     void (*ChangeClip) (GCPtr /*pGC */ ,
                         int /*type */ ,
-                        pointer /*pvalue */ ,
+                        void */*pvalue */ ,
                         int /*nrects */ );
 
     void (*DestroyClip) (GCPtr /*pGC */ );
@@ -216,7 +216,7 @@ typedef struct _GCOps {
                            int /*y */ ,
                            unsigned int /*nglyph */ ,
                            CharInfoPtr * /*ppci */ ,
-                           pointer /*pglyphBase */ );
+                           void */*pglyphBase */ );
 
     void (*PolyGlyphBlt) (DrawablePtr /*pDrawable */ ,
                           GCPtr /*pGC */ ,
@@ -224,7 +224,7 @@ typedef struct _GCOps {
                           int /*y */ ,
                           unsigned int /*nglyph */ ,
                           CharInfoPtr * /*ppci */ ,
-                          pointer /*pglyphBase */ );
+                          void */*pglyphBase */ );
 
     void (*PushPixels) (GCPtr /*pGC */ ,
                         PixmapPtr /*pBitMap */ ,
@@ -273,7 +273,7 @@ typedef struct _GC {
     DDXPointRec patOrg;         /* origin for (tile, stipple) */
     struct _Font *font;
     DDXPointRec clipOrg;
-    pointer clientClip;
+    void *clientClip;
     unsigned long stateChanges; /* masked with GC_<kind> */
     unsigned long serialNumber;
     const GCFuncs *funcs;
diff --git a/include/input.h b/include/input.h
index 042128f..455963f 100644
--- a/include/input.h
+++ b/include/input.h
@@ -163,7 +163,7 @@ typedef Bool (*PointerAccelSchemeInitProc) (DeviceIntPtr /*dev */ ,
                                             /*protoScheme */ );
 
 typedef struct _DeviceRec {
-    pointer devicePrivate;
+    void *devicePrivate;
     ProcessInputProc processInputProc;  /* current */
     ProcessInputProc realInputProc;     /* deliver */
     ProcessInputProc enqueueInputProc;  /* enqueue */
@@ -316,7 +316,7 @@ extern _X_EXPORT Bool InitTouchClassDeviceStruct(DeviceIntPtr /*device */ ,
 
 typedef void (*BellProcPtr) (int /*percent */ ,
                              DeviceIntPtr /*device */ ,
-                             pointer /*ctrl */ ,
+                             void */*ctrl */ ,
                              int);
 
 typedef void (*KbdCtrlProcPtr) (DeviceIntPtr /*device */ ,
diff --git a/include/inputstr.h b/include/inputstr.h
index d369c9f..dfcf7c3 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -447,7 +447,7 @@ typedef struct _XIPropertyValue {
     Atom type;                  /* ignored by server */
     short format;               /* format of data for swapping - 8,16,32 */
     long size;                  /* size of data in (format/8) bytes */
-    pointer data;               /* private to client */
+    void *data;                 /* private to client */
 } XIPropertyValueRec;
 
 typedef struct _XIProperty {
diff --git a/include/miscstruct.h b/include/miscstruct.h
index 0820e1e..dbab10f 100644
--- a/include/miscstruct.h
+++ b/include/miscstruct.h
@@ -56,10 +56,10 @@ typedef xPoint DDXPointRec;
 typedef struct pixman_box16 BoxRec;
 
 typedef union _DevUnion {
-    pointer ptr;
+    void *ptr;
     long val;
     unsigned long uval;
-    pointer (*fptr) (void);
+    void *(*fptr) (void);
 } DevUnion;
 
 #endif                          /* MISCSTRUCT_H */
diff --git a/include/os.h b/include/os.h
index 4dacc1e..e5f86d6 100644
--- a/include/os.h
+++ b/include/os.h
@@ -70,12 +70,12 @@ typedef struct _NewClientRec *NewClientPtr;
 #ifndef xalloc
 #define xnfalloc(size) XNFalloc((unsigned long)(size))
 #define xnfcalloc(_num, _size) XNFcalloc((unsigned long)(_num)*(unsigned long)(_size))
-#define xnfrealloc(ptr, size) XNFrealloc((pointer)(ptr), (unsigned long)(size))
+#define xnfrealloc(ptr, size) XNFrealloc((void *)(ptr), (unsigned long)(size))
 
 #define xalloc(size) Xalloc((unsigned long)(size))
 #define xcalloc(_num, _size) Xcalloc((unsigned long)(_num)*(unsigned long)(_size))
-#define xrealloc(ptr, size) Xrealloc((pointer)(ptr), (unsigned long)(size))
-#define xfree(ptr) Xfree((pointer)(ptr))
+#define xrealloc(ptr, size) Xrealloc((void *)(ptr), (unsigned long)(size))
+#define xfree(ptr) Xfree((void *)(ptr))
 #define xstrdup(s) Xstrdup(s)
 #define xnfstrdup(s) XNFstrdup(s)
 #endif
@@ -140,7 +140,7 @@ extern _X_EXPORT const char *ClientAuthorized(ClientPtr /*client */ ,
                                               char * /*auth_string */ );
 
 extern _X_EXPORT Bool EstablishNewConnections(ClientPtr /*clientUnused */ ,
-                                              pointer /*closure */ );
+                                              void */*closure */ );
 
 extern _X_EXPORT void CheckConnections(void);
 
@@ -173,14 +173,14 @@ extern void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
 extern _X_EXPORT CARD32 GetTimeInMillis(void);
 extern _X_EXPORT CARD64 GetTimeInMicros(void);
 
-extern _X_EXPORT void AdjustWaitForDelay(pointer /*waitTime */ ,
+extern _X_EXPORT void AdjustWaitForDelay(void */*waitTime */ ,
                                          unsigned long /*newdelay */ );
 
 typedef struct _OsTimerRec *OsTimerPtr;
 
 typedef CARD32 (*OsTimerCallback) (OsTimerPtr /* timer */ ,
                                    CARD32 /* time */ ,
-                                   pointer /* arg */ );
+                                   void */* arg */ );
 
 extern _X_EXPORT void TimerInit(void);
 
@@ -193,7 +193,7 @@ extern _X_EXPORT OsTimerPtr TimerSet(OsTimerPtr /* timer */ ,
                                      int /* flags */ ,
                                      CARD32 /* millis */ ,
                                      OsTimerCallback /* func */ ,
-                                     pointer /* arg */ );
+                                     void */* arg */ );
 
 extern _X_EXPORT void TimerCheck(void);
 extern _X_EXPORT void TimerCancel(OsTimerPtr /* pTimer */ );
@@ -212,7 +212,7 @@ extern _X_EXPORT void ProcessCommandLine(int /*argc */ , char * /*argv */ []);
 
 extern _X_EXPORT int set_font_authorizations(char ** /* authorizations */ ,
                                              int * /*authlen */ ,
-                                             pointer /* client */ );
+                                             void */* client */ );
 
 #ifndef _HAVE_XALLOC_DECLS
 #define _HAVE_XALLOC_DECLS
@@ -359,14 +359,14 @@ OsAbort(void)
 #if !defined(WIN32)
 extern _X_EXPORT int
 System(const char *);
-extern _X_EXPORT pointer
+extern _X_EXPORT void *
 Popen(const char *, const char *);
 extern _X_EXPORT int
-Pclose(pointer);
-extern _X_EXPORT pointer
+Pclose(void *);
+extern _X_EXPORT void *
 Fopen(const char *, const char *);
 extern _X_EXPORT int
-Fclose(pointer);
+Fclose(void *);
 #else
 
 extern const char *
@@ -395,17 +395,17 @@ ForEachHostInFamily(int /*family */ ,
                     Bool (* /*func */ )(
                                            unsigned char * /* addr */ ,
                                            short /* len */ ,
-                                           pointer /* closure */ ),
-                    pointer /*closure */ );
+                                           void */* closure */ ),
+                    void */*closure */ );
 
 extern _X_EXPORT int
 RemoveHost(ClientPtr /*client */ ,
            int /*family */ ,
            unsigned /*length */ ,
-           pointer /*pAddr */ );
+           void */*pAddr */ );
 
 extern _X_EXPORT int
-GetHosts(pointer * /*data */ ,
+GetHosts(void ** /*data */ ,
          int * /*pnHosts */ ,
          int * /*pLen */ ,
          BOOL * /*pEnabled */ );
@@ -464,7 +464,7 @@ DefineSelf(int /*fd */ );
 
 #if XDMCP
 extern _X_EXPORT void
-AugmentSelf(pointer /*from */ , int /*len */ );
+AugmentSelf(void */*from */ , int /*len */ );
 
 extern _X_EXPORT void
 RegisterAuthorizations(void);
diff --git a/include/pixmap.h b/include/pixmap.h
index 921a94d..46ec3f5 100644
--- a/include/pixmap.h
+++ b/include/pixmap.h
@@ -99,7 +99,7 @@ extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(ScreenPtr /*pScreen */ ,
                                                   int /*depth */ ,
                                                   int /*bitsPerPixel */ ,
                                                   int /*devKind */ ,
-                                                  pointer /*pPixData */ );
+                                                  void */*pPixData */ );
 
 extern _X_EXPORT void FreeScratchPixmapHeader(PixmapPtr /*pPixmap */ );
 
diff --git a/include/privates.h b/include/privates.h
index 0abdce7..7d1461c 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -142,10 +142,10 @@ dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key)
  * dixLookupPrivate(privates, key) will return 'val'.
  */
 static inline void
-dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val)
+dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, void *val)
 {
     assert(key->size == 0);
-    *(pointer *) dixGetPrivateAddr(privates, key) = val;
+    *(void **) dixGetPrivateAddr(privates, key) = val;
 }
 
 #include "dix.h"
@@ -158,7 +158,7 @@ dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val)
  * storage. For privates without defined storage, return the pointer
  * contents
  */
-static inline pointer
+static inline void *
 dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key)
 {
     if (key->size)
@@ -173,11 +173,11 @@ dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key)
  * This returns the place where the private pointer is stored,
  * which is only valid for privates without predefined storage.
  */
-static inline pointer *
+static inline void **
 dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
 {
     assert(key->size == 0);
-    return (pointer *) dixGetPrivateAddr(privates, key);
+    return (void **) dixGetPrivateAddr(privates, key);
 }
 
 extern _X_EXPORT Bool
@@ -204,19 +204,19 @@ dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
 
 static inline void
 dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
-                    ScreenPtr pScreen, pointer val)
+                    ScreenPtr pScreen, void *val)
 {
     dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val);
 }
 
-static inline pointer
+static inline void *
 dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
                        ScreenPtr pScreen)
 {
     return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
 }
 
-static inline pointer *
+static inline void **
 dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key,
                            ScreenPtr pScreen)
 {
diff --git a/include/property.h b/include/property.h
index 4219fc4..3b8ea8b 100644
--- a/include/property.h
+++ b/include/property.h
@@ -64,7 +64,7 @@ extern _X_EXPORT int dixChangeWindowProperty(ClientPtr /*pClient */ ,
                                              int /*format */ ,
                                              int /*mode */ ,
                                              unsigned long /*len */ ,
-                                             pointer /*value */ ,
+                                             void */*value */ ,
                                              Bool /*sendevent */ );
 
 extern _X_EXPORT int ChangeWindowProperty(WindowPtr /*pWin */ ,
@@ -73,7 +73,7 @@ extern _X_EXPORT int ChangeWindowProperty(WindowPtr /*pWin */ ,
                                           int /*format */ ,
                                           int /*mode */ ,
                                           unsigned long /*len */ ,
-                                          pointer /*value */ ,
+                                          void */*value */ ,
                                           Bool /*sendevent */ );
 
 extern _X_EXPORT int DeleteProperty(ClientPtr /*client */ ,
diff --git a/include/propertyst.h b/include/propertyst.h
index c12c71a..da99576 100644
--- a/include/propertyst.h
+++ b/include/propertyst.h
@@ -59,7 +59,7 @@ typedef struct _Property {
     ATOM type;                  /* ignored by server */
     uint32_t format;            /* format of data for swapping - 8,16,32 */
     uint32_t size;              /* size of data in (format/8) bytes */
-    pointer data;               /* private to client */
+    void *data;                 /* private to client */
     PrivateRec *devPrivates;
 } PropertyRec;
 
diff --git a/include/resource.h b/include/resource.h
index 4a8dc31..db44aef 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -133,24 +133,24 @@ typedef struct {
     ResourceState state;
     XID id;
     RESTYPE type;
-    pointer value;
+    void *value;
 } ResourceStateInfoRec;
 
-typedef int (*DeleteType) (pointer /*value */ ,
+typedef int (*DeleteType) (void */*value */ ,
                            XID /*id */ );
 
-typedef void (*FindResType) (pointer /*value */ ,
+typedef void (*FindResType) (void */*value */ ,
                              XID /*id */ ,
-                             pointer /*cdata */ );
+                             void */*cdata */ );
 
-typedef void (*FindAllRes) (pointer /*value */ ,
+typedef void (*FindAllRes) (void */*value */ ,
                             XID /*id */ ,
                             RESTYPE /*type */ ,
-                            pointer /*cdata */ );
+                            void */*cdata */ );
 
-typedef Bool (*FindComplexResType) (pointer /*value */ ,
+typedef Bool (*FindComplexResType) (void */*value */ ,
                                     XID /*id */ ,
-                                    pointer /*cdata */ );
+                                    void */*cdata */ );
 
 /* Structure for estimating resource memory usage. Memory usage
  * consists of space allocated for the resource itself and of
@@ -166,16 +166,16 @@ typedef struct {
     unsigned long refCnt;
 } ResourceSizeRec, *ResourceSizePtr;
 
-typedef void (*SizeType)(pointer /*value*/,
+typedef void (*SizeType)(void */*value*/,
                          XID /*id*/,
                          ResourceSizePtr /*size*/);
 
 extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ ,
                                                const char * /*name */ );
 
-typedef void (*FindTypeSubResources)(pointer /* value */,
+typedef void (*FindTypeSubResources)(void */* value */,
                                      FindAllRes /* func */,
-                                     pointer /* cdata */);
+                                     void */* cdata */);
 
 extern _X_EXPORT SizeType GetResourceTypeSizeFunc(
     RESTYPE /*type*/);
@@ -202,7 +202,7 @@ extern _X_EXPORT XID FakeClientID(int /*client */ );
 #endif
 extern _X_EXPORT Bool AddResource(XID /*id */ ,
                                   RESTYPE /*type */ ,
-                                  pointer /*value */ );
+                                  void */*value */ );
 
 extern _X_EXPORT void FreeResource(XID /*id */ ,
                                    RESTYPE /*skipDeleteFuncType */ );
@@ -213,25 +213,25 @@ extern _X_EXPORT void FreeResourceByType(XID /*id */ ,
 
 extern _X_EXPORT Bool ChangeResourceValue(XID /*id */ ,
                                           RESTYPE /*rtype */ ,
-                                          pointer /*value */ );
+                                          void */*value */ );
 
 extern _X_EXPORT void FindClientResourcesByType(ClientPtr /*client */ ,
                                                 RESTYPE /*type */ ,
                                                 FindResType /*func */ ,
-                                                pointer /*cdata */ );
+                                                void */*cdata */ );
 
 extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ ,
                                              FindAllRes /*func */ ,
-                                             pointer /*cdata */ );
+                                             void */*cdata */ );
 
 /** @brief Iterate through all subresources of a resource.
 
     @note The XID argument provided to the FindAllRes function
           may be 0 for subresources that don't have an XID */
-extern _X_EXPORT void FindSubResources(pointer /*resource*/,
+extern _X_EXPORT void FindSubResources(void */*resource*/,
                                        RESTYPE /*type*/,
                                        FindAllRes /*func*/,
-                                       pointer /*cdata*/);
+                                       void */*cdata*/);
 
 extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ );
 
@@ -242,18 +242,18 @@ extern _X_EXPORT void FreeAllResources(void);
 extern _X_EXPORT Bool LegalNewID(XID /*id */ ,
                                  ClientPtr /*client */ );
 
-extern _X_EXPORT pointer LookupClientResourceComplex(ClientPtr client,
+extern _X_EXPORT void *LookupClientResourceComplex(ClientPtr client,
                                                      RESTYPE type,
                                                      FindComplexResType func,
-                                                     pointer cdata);
+                                                     void *cdata);
 
-extern _X_EXPORT int dixLookupResourceByType(pointer *result,
+extern _X_EXPORT int dixLookupResourceByType(void **result,
                                              XID id,
                                              RESTYPE rtype,
                                              ClientPtr client,
                                              Mask access_mode);
 
-extern _X_EXPORT int dixLookupResourceByClass(pointer *result,
+extern _X_EXPORT int dixLookupResourceByClass(void **result,
                                               XID id,
                                               RESTYPE rclass,
                                               ClientPtr client,
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index df74073..86da789 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -260,12 +260,12 @@ typedef void (*SendGraphicsExposeProcPtr) (ClientPtr /*client */ ,
                                            int /*minor */ );
 
 typedef void (*ScreenBlockHandlerProcPtr) (ScreenPtr /*pScreen*/ ,
-                                           pointer /*pTimeout */ ,
-                                           pointer /*pReadmask */ );
+                                           void */*pTimeout */ ,
+                                           void */*pReadmask */ );
 
 typedef void (*ScreenWakeupHandlerProcPtr) (ScreenPtr /*pScreen*/ ,
                                             unsigned long /*result */ ,
-                                            pointer /*pReadMask */ );
+                                            void */*pReadMask */ );
 
 typedef Bool (*CreateScreenResourcesProcPtr) (ScreenPtr /*pScreen */ );
 
@@ -275,7 +275,7 @@ typedef Bool (*ModifyPixmapHeaderProcPtr) (PixmapPtr /*pPixmap */ ,
                                            int /*depth */ ,
                                            int /*bitsPerPixel */ ,
                                            int /*devKind */ ,
-                                           pointer /*pPixData */ );
+                                           void */*pPixData */ );
 
 typedef PixmapPtr (*GetWindowPixmapProcPtr) (WindowPtr /*pWin */ );
 
@@ -375,7 +375,7 @@ typedef struct _Screen {
        a standard one.
      */
     PixmapPtr PixmapPerDepth[1];
-    pointer devPrivate;
+    void *devPrivate;
     short numVisuals;
     VisualPtr visuals;
     WindowPtr root;
diff --git a/include/window.h b/include/window.h
index b6d61c3..b5a937e 100644
--- a/include/window.h
+++ b/include/window.h
@@ -73,15 +73,15 @@ typedef struct _BackingStore *BackingStorePtr;
 typedef struct _Window *WindowPtr;
 
 typedef int (*VisitWindowProcPtr) (WindowPtr /*pWin */ ,
-                                   pointer /*data */ );
+                                   void */*data */ );
 
 extern _X_EXPORT int TraverseTree(WindowPtr /*pWin */ ,
                                   VisitWindowProcPtr /*func */ ,
-                                  pointer /*data */ );
+                                  void */*data */ );
 
 extern _X_EXPORT int WalkTree(ScreenPtr /*pScreen */ ,
                               VisitWindowProcPtr /*func */ ,
-                              pointer /*data */ );
+                              void */*data */ );
 
 extern _X_EXPORT Bool CreateRootWindow(ScreenPtr /*pScreen */ );
 
@@ -108,7 +108,7 @@ extern _X_EXPORT WindowPtr CreateWindow(Window /*wid */ ,
                                         VisualID /*visual */ ,
                                         int * /*error */ );
 
-extern _X_EXPORT int DeleteWindow(pointer /*pWin */ ,
+extern _X_EXPORT int DeleteWindow(void */*pWin */ ,
                                   XID /*wid */ );
 
 extern _X_EXPORT int DestroySubwindows(WindowPtr /*pWin */ ,
diff --git a/include/windowstr.h b/include/windowstr.h
index a1e608f..6b79bbd 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -144,7 +144,7 @@ typedef struct _Window {
     Mask eventMask;             /* mask from the creating client */
     PixUnion background;
     PixUnion border;
-    pointer backStorage;        /* null when BS disabled */
+    void *backStorage;          /* null when BS disabled */
     WindowOptPtr optional;
     unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */
     unsigned borderIsPixel:1;
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index fbfe403..0b9ca06 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -281,7 +281,7 @@ extern _X_EXPORT DevPrivateKeyRec xkbDevicePrivateKeyRec;
 
 #define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr)dixLookupPrivate(&(dev)->devPrivates, xkbDevicePrivateKey))
 
-extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, pointer);
+extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, void *);
 
 /***====================================================================***/
 
@@ -600,7 +600,7 @@ extern _X_EXPORT void XkbHandleBell(BOOL /* force */ ,
                                     BOOL /* eventOnly */ ,
                                     DeviceIntPtr /* kbd */ ,
                                     CARD8 /* percent */ ,
-                                    pointer /* ctrl */ ,
+                                    void */* ctrl */ ,
                                     CARD8 /* class */ ,
                                     Atom /* name */ ,
                                     WindowPtr /* pWin */ ,
diff --git a/mi/mi.h b/mi/mi.h
index 638fc6b..950ee38 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -271,7 +271,7 @@ extern _X_EXPORT void miPolyGlyphBlt(DrawablePtr /*pDrawable */ ,
                                      int /*y */ ,
                                      unsigned int /*nglyph */ ,
                                      CharInfoPtr * /*ppci */ ,
-                                     pointer    /*pglyphBase */
+                                     void */*pglyphBase */
     );
 
 extern _X_EXPORT void miImageGlyphBlt(DrawablePtr /*pDrawable */ ,
@@ -280,7 +280,7 @@ extern _X_EXPORT void miImageGlyphBlt(DrawablePtr /*pDrawable */ ,
                                       int /*y */ ,
                                       unsigned int /*nglyph */ ,
                                       CharInfoPtr * /*ppci */ ,
-                                      pointer   /*pglyphBase */
+                                      void */*pglyphBase */
     );
 
 /* mipoly.c */
@@ -387,7 +387,7 @@ extern _X_EXPORT Bool miModifyPixmapHeader(PixmapPtr /*pPixmap */ ,
                                            int /*depth */ ,
                                            int /*bitsPerPixel */ ,
                                            int /*devKind */ ,
-                                           pointer      /*pPixData */
+                                           void */*pPixData */
     );
 
 extern _X_EXPORT Bool miCreateScreenResources(ScreenPtr /*pScreen */
@@ -395,11 +395,11 @@ extern _X_EXPORT Bool miCreateScreenResources(ScreenPtr /*pScreen */
 
 extern _X_EXPORT Bool miScreenDevPrivateInit(ScreenPtr /*pScreen */ ,
                                              int /*width */ ,
-                                             pointer    /*pbits */
+                                             void */*pbits */
     );
 
 extern _X_EXPORT Bool miScreenInit(ScreenPtr /*pScreen */ ,
-                                   pointer /*pbits */ ,
+                                   void */*pbits */ ,
                                    int /*xsize */ ,
                                    int /*ysize */ ,
                                    int /*dpix */ ,
diff --git a/mi/miarc.c b/mi/miarc.c
index 0f6448b..0f56c7d 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -1489,7 +1489,7 @@ miGetArcPts(SppArcPtr parc,     /* points to an arc */
     count++;
 
     cdt = 2 * miDcos(dt);
-    if (!(poly = (SppPointPtr) realloc((pointer) *ppPts,
+    if (!(poly = (SppPointPtr) realloc((void *) *ppPts,
                                        (cpt + count) * sizeof(SppPointRec))))
         return 0;
     *ppPts = poly;
diff --git a/mi/micmap.c b/mi/micmap.c
index 3ef0c8c..4648b9a 100644
--- a/mi/micmap.c
+++ b/mi/micmap.c
@@ -75,7 +75,7 @@ miUninstallColormap(ColormapPtr pmap)
 
     if (pmap == curpmap) {
         if (pmap->mid != pmap->pScreen->defColormap) {
-            dixLookupResourceByType((pointer *) &curpmap,
+            dixLookupResourceByType((void **) &curpmap,
                                     pmap->pScreen->defColormap,
                                     RT_COLORMAP, serverClient, DixUseAccess);
             (*pmap->pScreen->InstallColormap) (curpmap);
diff --git a/mi/midispcur.c b/mi/midispcur.c
index edca969..8cca5fe 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -79,7 +79,7 @@ typedef struct {
   (miDCBufferPtr)dixLookupScreenPrivate(&GetMaster(dev, MASTER_POINTER)->devPrivates, miDCDeviceKey, screen))
 
 /* 
- * The core pointer buffer will point to the index of the virtual core pointer
+ * The core pointer buffer will point to the index of the virtual pointer
  * in the pCursorBuffers array. 
  */
 typedef struct {
@@ -114,7 +114,7 @@ miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
     dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, pScreenPriv);
 
     if (!miSpriteInitialize(pScreen, screenFuncs)) {
-        free((pointer) pScreenPriv);
+        free((void *) pScreenPriv);
         return FALSE;
     }
     return TRUE;
@@ -152,7 +152,7 @@ miDCCloseScreen(ScreenPtr pScreen)
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
 
     miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
     return (*pScreen->CloseScreen) (pScreen);
 }
 
diff --git a/mi/miexpose.c b/mi/miexpose.c
index 8b7c93f..198c433 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -610,7 +610,7 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
         gcmask |= GCPlaneMask;
 #endif
         gcval[c++].val = FillTiled;
-        gcval[c++].ptr = (pointer) fill.pixmap;
+        gcval[c++].ptr = (void *) fill.pixmap;
         gcval[c++].val = tile_x_off;
         gcval[c++].val = tile_y_off;
         gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
diff --git a/mi/migc.c b/mi/migc.c
index c9cdd12..9bbe884 100644
--- a/mi/migc.c
+++ b/mi/migc.c
@@ -72,12 +72,12 @@ miDestroyClip(GCPtr pGC)
 }
 
 void
-miChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+miChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     (*pGC->funcs->DestroyClip) (pGC);
     if (type == CT_PIXMAP) {
         /* convert the pixmap to a region */
-        pGC->clientClip = (pointer) BitmapToRegion(pGC->pScreen,
+        pGC->clientClip = (void *) BitmapToRegion(pGC->pScreen,
                                                    (PixmapPtr) pvalue);
         (*pGC->pScreen->DestroyPixmap) (pvalue);
     }
@@ -86,7 +86,7 @@ miChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
         pGC->clientClip = pvalue;
     }
     else if (type != CT_NONE) {
-        pGC->clientClip = (pointer) RegionFromRects(nrects,
+        pGC->clientClip = (void *) RegionFromRects(nrects,
                                                     (xRectangle *) pvalue,
                                                     type);
         free(pvalue);
@@ -112,7 +112,7 @@ miCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
     case CT_REGION:
         prgnNew = RegionCreate(NULL, 1);
         RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip));
-        (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
+        (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (void *) prgnNew, 0);
         break;
     }
 }
diff --git a/mi/migc.h b/mi/migc.h
index 8c13b2e..fb9f35c 100644
--- a/mi/migc.h
+++ b/mi/migc.h
@@ -38,7 +38,7 @@ extern _X_EXPORT void miDestroyClip(GCPtr       /*pGC */
 
 extern _X_EXPORT void miChangeClip(GCPtr /*pGC */ ,
                                    int /*type */ ,
-                                   pointer /*pvalue */ ,
+                                   void */*pvalue */ ,
                                    int  /*nrects */
     );
 
diff --git a/mi/miglblt.c b/mi/miglblt.c
index 1a70911..b53ab9c 100644
--- a/mi/miglblt.c
+++ b/mi/miglblt.c
@@ -81,7 +81,7 @@ with the sample server.
 
 void
 miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci,  /* array of character info */
-               pointer pglyphBase       /* start of array of glyphs */
+               void *pglyphBase       /* start of array of glyphs */
     )
 {
     int width, height;
@@ -182,7 +182,7 @@ miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyp
 
 void
 miImageGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */
-                pointer pglyphBase      /* start of array of glyphs */
+                void *pglyphBase      /* start of array of glyphs */
     )
 {
     ExtentInfoRec info;         /* used by QueryGlyphExtents() */
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 2bfd5e4..7f502fa 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -1050,7 +1050,7 @@ typedef struct {
 } miOverlayTwoRegions;
 
 static int
-miOverlayRecomputeExposures(WindowPtr pWin, pointer value)
+miOverlayRecomputeExposures(WindowPtr pWin, void *value)
 {
     miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value;
     miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
@@ -1404,7 +1404,7 @@ miOverlayResizeWindow(WindowPtr pWin,
                 TwoRegions.under = gravitate2[g];
 
                 TraverseTree(pChild, miOverlayRecomputeExposures,
-                             (pointer) (&TwoRegions));
+                             (void *) (&TwoRegions));
             }
 
             /*
diff --git a/mi/mipointer.c b/mi/mipointer.c
index df027a7..6fa416d 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -152,7 +152,7 @@ miPointerCloseScreen(ScreenPtr pScreen)
     SetupScreen(pScreen);
 
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
-    free((pointer) pScreenPriv);
+    free((void *) pScreenPriv);
     FreeEventList(mipointermove_events, GetMaximumEventsNum());
     mipointermove_events = NULL;
     return (*pScreen->CloseScreen) (pScreen);
diff --git a/mi/mipolyrect.c b/mi/mipolyrect.c
index a0e88d2..e316ae0 100644
--- a/mi/mipolyrect.c
+++ b/mi/mipolyrect.c
@@ -148,7 +148,7 @@ miPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects, xRectangle *pRects)
             }
         }
         (*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp);
-        free((pointer) tmp);
+        free((void *) tmp);
     }
     else {
 
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index 4698b53..6aed52f 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -53,14 +53,14 @@ from The Open Group.
  */
 
 typedef struct {
-    pointer pbits;              /* pointer to framebuffer */
+    void *pbits;                /* pointer to framebuffer */
     int width;                  /* delta to add to a framebuffer addr to move one row down */
 } miScreenInitParmsRec, *miScreenInitParmsPtr;
 
 /* this plugs into pScreen->ModifyPixmapHeader */
 Bool
 miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
-                     int bitsPerPixel, int devKind, pointer pPixData)
+                     int bitsPerPixel, int devKind, void *pPixData)
 {
     if (!pPixmap)
         return FALSE;
@@ -135,7 +135,7 @@ Bool
 miCreateScreenResources(ScreenPtr pScreen)
 {
     miScreenInitParmsPtr pScrInitParms;
-    pointer value;
+    void *value;
 
     pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
 
@@ -161,7 +161,7 @@ miCreateScreenResources(ScreenPtr pScreen)
                                                            pScreen->rootDepth),
                                              pScrInitParms->pbits))
             return FALSE;
-        value = (pointer) pPixmap;
+        value = (void *) pPixmap;
     }
     else {
         value = pScrInitParms->pbits;
@@ -172,7 +172,7 @@ miCreateScreenResources(ScreenPtr pScreen)
 }
 
 Bool
-miScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits)
+miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
 {
     miScreenInitParmsPtr pScrInitParms;
 
@@ -185,7 +185,7 @@ miScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits)
         return FALSE;
     pScrInitParms->pbits = pbits;
     pScrInitParms->width = width;
-    pScreen->devPrivate = (pointer) pScrInitParms;
+    pScreen->devPrivate = (void *) pScrInitParms;
     return TRUE;
 }
 
@@ -199,11 +199,11 @@ static void
 miSetScreenPixmap(PixmapPtr pPix)
 {
     if (pPix)
-        pPix->drawable.pScreen->devPrivate = (pointer) pPix;
+        pPix->drawable.pScreen->devPrivate = (void *) pPix;
 }
 
 Bool
-miScreenInit(ScreenPtr pScreen, pointer pbits,  /* pointer to screen bits */
+miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
              int xsize, int ysize,      /* in pixels */
              int dpix, int dpiy,        /* dots per inch */
              int width,         /* pixel width of frame buffer */
diff --git a/mi/misprite.c b/mi/misprite.c
index 85ca022..eea731a 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -199,7 +199,7 @@ static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
 static void miSpriteCopyWindow(WindowPtr pWindow,
                                DDXPointRec ptOldOrg, RegionPtr prgnSrc);
 static void miSpriteBlockHandler(ScreenPtr pScreen,
-                                 pointer pTimeout, pointer pReadMask);
+                                 void *pTimeout, void *pReadMask);
 static void miSpriteInstallColormap(ColormapPtr pMap);
 static void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef);
 
@@ -512,8 +512,8 @@ miSpriteCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 }
 
 static void
-miSpriteBlockHandler(ScreenPtr pScreen, pointer pTimeout,
-                     pointer pReadmask)
+miSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout,
+                     void *pReadmask)
 {
     miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen);
     DeviceIntPtr pDev;
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 8dd99db..697ffbc 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -305,7 +305,7 @@ miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
  */
 
 static int
-miRecomputeExposures(WindowPtr pWin, pointer value)
+miRecomputeExposures(WindowPtr pWin, void *value)
 {                               /* must conform to VisitWindowProcPtr */
     RegionPtr pValid = (RegionPtr) value;
 
@@ -584,7 +584,7 @@ miSlideAndSizeWindow(WindowPtr pWin,
                 if (pChild->winGravity != g)
                     continue;
                 RegionIntersect(pRegion, &pChild->borderClip, gravitate[g]);
-                TraverseTree(pChild, miRecomputeExposures, (pointer) pRegion);
+                TraverseTree(pChild, miRecomputeExposures, (void *) pRegion);
             }
 
             /*
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 55d8c41..9bd9c84 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -326,7 +326,7 @@ static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
 static void damageChangeGC(GCPtr, unsigned long);
 static void damageCopyGC(GCPtr, unsigned long, GCPtr);
 static void damageDestroyGC(GCPtr);
-static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageChangeClip(GCPtr, int, void *, int);
 static void damageDestroyClip(GCPtr);
 static void damageCopyClip(GCPtr, GCPtr);
 
@@ -410,7 +410,7 @@ damageCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
 }
 
 static void
-damageChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+damageChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     DAMAGE_GC_FUNC_PROLOGUE(pGC);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
@@ -1366,7 +1366,7 @@ damageImageGlyphBlt(DrawablePtr pDrawable,
                     GCPtr pGC,
                     int x,
                     int y,
-                    unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase)
+                    unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase)
 {
     DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
     damageDamageChars(pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
@@ -1381,7 +1381,7 @@ damagePolyGlyphBlt(DrawablePtr pDrawable,
                    GCPtr pGC,
                    int x,
                    int y,
-                   unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase)
+                   unsigned int nglyph, CharInfoPtr * ppci, void *pglyphBase)
 {
     DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
     damageDamageChars(pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
diff --git a/miext/rootless/rootlessCommon.c b/miext/rootless/rootlessCommon.c
index d8f43bd..5043627 100644
--- a/miext/rootless/rootlessCommon.c
+++ b/miext/rootless/rootlessCommon.c
@@ -202,7 +202,7 @@ RootlessStartDrawing(WindowPtr pWindow)
  *  damaged regions are flushed to the screen.
  */
 static int
-RestorePreDrawingPixmapVisitor(WindowPtr pWindow, pointer data)
+RestorePreDrawingPixmapVisitor(WindowPtr pWindow, void *data)
 {
     RootlessWindowRec *winRec = (RootlessWindowRec *) data;
     ScreenPtr pScreen = pWindow->drawable.pScreen;
@@ -249,7 +249,7 @@ RootlessStopDrawing(WindowPtr pWindow, Bool flush)
         SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
 
         FreeScratchPixmapHeader(winRec->pixmap);
-        TraverseTree(top, RestorePreDrawingPixmapVisitor, (pointer) winRec);
+        TraverseTree(top, RestorePreDrawingPixmapVisitor, (void *) winRec);
         winRec->pixmap = NULL;
 
         winRec->is_drawing = FALSE;
diff --git a/miext/rootless/rootlessGC.c b/miext/rootless/rootlessGC.c
index 9328995..23ff393 100644
--- a/miext/rootless/rootlessGC.c
+++ b/miext/rootless/rootlessGC.c
@@ -55,7 +55,7 @@ static void RootlessValidateGC(GCPtr pGC, unsigned long changes,
 static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
 static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
 static void RootlessDestroyGC(GCPtr pGC);
-static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void RootlessChangeClip(GCPtr pGC, int type, void *pvalue, int nrects);
 static void RootlessDestroyClip(GCPtr pGC);
 static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
 
@@ -113,10 +113,10 @@ static void RootlessImageText16(DrawablePtr dst, GCPtr pGC, int x, int y,
                                 int count, unsigned short *chars);
 static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC, int x, int y,
                                   unsigned int nglyphInit,
-                                  CharInfoPtr * ppciInit, pointer unused);
+                                  CharInfoPtr * ppciInit, void *unused);
 static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, int x, int y,
                                  unsigned int nglyph, CharInfoPtr * ppci,
-                                 pointer pglyphBase);
+                                 void *pglyphBase);
 static void RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
                                int dx, int dy, int xOrg, int yOrg);
 
@@ -368,7 +368,7 @@ RootlessDestroyGC(GCPtr pGC)
 }
 
 static void
-RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+RootlessChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
 {
     GCFUNC_UNWRAP(pGC);
     pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
@@ -1356,7 +1356,7 @@ RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
 static void
 RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
                       int x, int y, unsigned int nglyphInit,
-                      CharInfoPtr * ppciInit, pointer unused)
+                      CharInfoPtr * ppciInit, void *unused)
 {
     GC_SAVE(pGC);
     GCOP_UNWRAP(pGC);
@@ -1419,7 +1419,7 @@ RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
 static void
 RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
                      int x, int y, unsigned int nglyph,
-                     CharInfoPtr * ppci, pointer pglyphBase)
+                     CharInfoPtr * ppci, void *pglyphBase)
 {
     GCOP_UNWRAP(pGC);
     RL_DEBUG_MSG("polyglyph start ");
diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c
index a1af3e7..6226ee8 100644
--- a/miext/rootless/rootlessScreen.c
+++ b/miext/rootless/rootlessScreen.c
@@ -603,7 +603,7 @@ RootlessQueueRedisplay(ScreenPtr pScreen)
  *  on select().
  */
 static void
-RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
+RootlessBlockHandler(void *pbdata, OSTimePtr pTimeout, void *pReadmask)
 {
     ScreenPtr pScreen = pbdata;
     RootlessScreenRec *screenRec = SCREENREC(pScreen);
@@ -616,7 +616,7 @@ RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
 }
 
 static void
-RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
+RootlessWakeupHandler(void *data, int i, void *LastSelectMask)
 {
     // nothing here
 }
@@ -728,7 +728,7 @@ RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
 
     if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
                                         RootlessWakeupHandler,
-                                        (pointer) pScreen)) {
+                                        (void *) pScreen)) {
         return FALSE;
     }
 
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index 7e3c281..3dbd588 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -625,7 +625,7 @@ RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
  */
 
 // Globals needed during window resize and move.
-static pointer gResizeDeathBits = NULL;
+static void *gResizeDeathBits = NULL;
 static int gResizeDeathCount = 0;
 static PixmapPtr gResizeDeathPix[2] = { NULL, NULL };
 
diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c
index 1a9088c..522e21b 100644
--- a/miext/shadow/shadow.c
+++ b/miext/shadow/shadow.c
@@ -65,7 +65,7 @@ shadowRedisplay(ScreenPtr pScreen)
 }
 
 static void
-shadowBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+shadowBlockHandler(void *data, OSTimePtr pTimeout, void *pRead)
 {
     ScreenPtr pScreen = (ScreenPtr) data;
 
@@ -73,7 +73,7 @@ shadowBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
 }
 
 static void
-shadowWakeupHandler(pointer data, int i, pointer LastSelectMask)
+shadowWakeupHandler(void *data, int i, void *LastSelectMask)
 {
 }
 
@@ -183,7 +183,7 @@ shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update,
     shadowBuf(pScreen);
 
     if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler,
-                                        (pointer) pScreen))
+                                        (void *) pScreen))
         return FALSE;
 
     /*
@@ -228,7 +228,7 @@ shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap)
     }
 
     RemoveBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler,
-                                 (pointer) pScreen);
+                                 (void *) pScreen);
 }
 
 Bool
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 39fedd9..3eb15b9 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -118,7 +118,7 @@ struct _OsTimerRec {
     CARD32 expires;
     CARD32 delta;
     OsTimerCallback callback;
-    pointer arg;
+    void *arg;
 };
 
 static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
@@ -212,7 +212,7 @@ WaitForSomething(int *pClientsReady)
             XFD_COPYSET(&AllSockets, &LastSelectMask);
         }
 
-        BlockHandler((pointer) &wt, (pointer) &LastSelectMask);
+        BlockHandler((void *) &wt, (void *) &LastSelectMask);
         if (NewOutputPending)
             FlushAllOutput();
         /* keep this check close to select() call to minimize race */
@@ -226,7 +226,7 @@ WaitForSomething(int *pClientsReady)
             i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
         }
         selecterr = GetErrno();
-        WakeupHandler(i, (pointer) &LastSelectMask);
+        WakeupHandler(i, (void *) &LastSelectMask);
         if (i <= 0) {           /* An error or timeout occurred */
             if (dispatchException)
                 return 0;
@@ -303,7 +303,7 @@ WaitForSomething(int *pClientsReady)
             XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
             if (XFD_ANYSET(&tmp_set))
                 QueueWorkProc(EstablishNewConnections, NULL,
-                              (pointer) &LastSelectMask);
+                              (void *) &LastSelectMask);
 
             if (XFD_ANYSET(&devicesReadable) || XFD_ANYSET(&clientsReadable))
                 break;
@@ -416,7 +416,7 @@ DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
 
 OsTimerPtr
 TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
-         OsTimerCallback func, pointer arg)
+         OsTimerCallback func, void *arg)
 {
     register OsTimerPtr *prev;
     CARD32 now = GetTimeInMillis();
@@ -564,7 +564,7 @@ NextDPMSTimeout(INT32 timeout)
 #endif                          /* DPMSExtension */
 
 static CARD32
-ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     INT32 timeout = now - LastEventTime(XIAllDevices).milliseconds;
     CARD32 nextTimeout = 0;
diff --git a/os/access.c b/os/access.c
index c55b0ef..e8c0781 100644
--- a/os/access.c
+++ b/os/access.c
@@ -186,7 +186,7 @@ Bool defeatAccessControl = FALSE;
 
 static int ConvertAddr(struct sockaddr * /*saddr */ ,
                        int * /*len */ ,
-                       pointer * /*addr */ );
+                       void ** /*addr */ );
 
 static int CheckAddr(int /*family */ ,
                      const void * /*pAddr */ ,
@@ -226,7 +226,7 @@ static int LocalHostRequested = FALSE;
 static int UsingXdmcp = FALSE;
 
 /* FamilyServerInterpreted implementation */
-static Bool siAddrMatch(int family, pointer addr, int len, HOST * host,
+static Bool siAddrMatch(int family, void *addr, int len, HOST * host,
                         ClientPtr client);
 static int siCheckAddr(const char *addrString, int length);
 static void siTypesInitialize(void);
@@ -258,7 +258,7 @@ DisableLocalHost(void)
     for (self = selfhosts; self; self = self->next) {
         if (!self->requested)   /* Fix for XFree86 bug #156 */
             (void) RemoveHost((ClientPtr) NULL, self->family, self->len,
-                              (pointer) self->addr);
+                              (void *) self->addr);
     }
 }
 
@@ -382,7 +382,7 @@ DefineSelf(int fd)
         default:
             goto DefineLocalHost;
         }
-        family = ConvertAddr(&(saddr.sa), &len, (pointer *) &addr);
+        family = ConvertAddr(&(saddr.sa), &len, (void **) &addr);
         if (family != -1 && family != FamilyLocal) {
             for (host = selfhosts;
                  host && !addrEqual(family, addr, len, host);
@@ -545,7 +545,7 @@ DefineSelf(int fd)
 #define IFR_IFR_NAME ifr->ifr_name
 #endif
 
-    if (ifioctl(fd, IFC_IOCTL_REQ, (pointer) &ifc) < 0)
+    if (ifioctl(fd, IFC_IOCTL_REQ, (void *) &ifc) < 0)
         ErrorF("Getting interface configuration (4): %s\n", strerror(errno));
 
     cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
@@ -554,7 +554,7 @@ DefineSelf(int fd)
         ifr = (ifr_type *) cp;
         len = ifraddr_size(IFR_IFR_ADDR);
         family = ConvertAddr((struct sockaddr *) &IFR_IFR_ADDR,
-                             &len, (pointer *) &addr);
+                             &len, (void **) &addr);
         if (family == -1 || family == FamilyLocal)
             continue;
 #if defined(IPv6) && defined(AF_INET6)
@@ -649,12 +649,12 @@ DefineSelf(int fd)
                 struct ifreq broad_req;
 
                 broad_req = *ifr;
-                if (ifioctl(fd, SIOCGIFFLAGS, (pointer) &broad_req) != -1 &&
+                if (ifioctl(fd, SIOCGIFFLAGS, (void *) &broad_req) != -1 &&
                     (broad_req.ifr_flags & IFF_BROADCAST) &&
                     (broad_req.ifr_flags & IFF_UP)
                     ) {
                     broad_req = *ifr;
-                    if (ifioctl(fd, SIOCGIFBRDADDR, (pointer) &broad_req) != -1)
+                    if (ifioctl(fd, SIOCGIFBRDADDR, (void *) &broad_req) != -1)
                         broad_addr = broad_req.ifr_addr;
                     else
                         continue;
@@ -679,7 +679,7 @@ DefineSelf(int fd)
             continue;
         len = sizeof(*(ifr->ifa_addr));
         family = ConvertAddr((struct sockaddr *) ifr->ifa_addr, &len,
-                             (pointer *) &addr);
+                             (void **) &addr);
         if (family == -1 || family == FamilyLocal)
             continue;
 #if defined(IPv6) && defined(AF_INET6)
@@ -775,13 +775,13 @@ DefineSelf(int fd)
 
 #ifdef XDMCP
 void
-AugmentSelf(pointer from, int len)
+AugmentSelf(void *from, int len)
 {
     int family;
-    pointer addr;
+    void *addr;
     register HOST *host;
 
-    family = ConvertAddr(from, &len, (pointer *) &addr);
+    family = ConvertAddr(from, &len, (void **) &addr);
     if (family == -1 || family == FamilyLocal)
         return;
     for (host = selfhosts; host; host = host->next) {
@@ -835,7 +835,7 @@ ResetHosts(const char *display)
     } saddr;
 #endif
     int family = 0;
-    pointer addr;
+    void *addr;
     int len;
 
     siTypesInitialize();
@@ -927,7 +927,7 @@ ResetHosts(const char *display)
                         for (a = addresses; a != NULL; a = a->ai_next) {
                             len = a->ai_addrlen;
                             f = ConvertAddr(a->ai_addr, &len,
-                                            (pointer *) &addr);
+                                            (void **) &addr);
                             if ((family == f) ||
                                 ((family == FamilyWild) && (f != -1))) {
                                 NewHost(f, addr, len, FALSE);
@@ -950,15 +950,15 @@ ResetHosts(const char *display)
                     len = sizeof(saddr.sa);
                     if ((family =
                          ConvertAddr(&saddr.sa, &len,
-                                     (pointer *) &addr)) != -1) {
+                                     (void **) &addr)) != -1) {
 #ifdef h_addr                   /* new 4.3bsd version of gethostent */
                         char **list;
 
                         /* iterate over the addresses */
                         for (list = hp->h_addr_list; *list; list++)
-                            (void) NewHost(family, (pointer) *list, len, FALSE);
+                            (void) NewHost(family, (void *) *list, len, FALSE);
 #else
-                        (void) NewHost(family, (pointer) hp->h_addr, len,
+                        (void) NewHost(family, (void *) hp->h_addr, len,
                                        FALSE);
 #endif
                     }
@@ -978,7 +978,7 @@ ComputeLocalClient(ClientPtr client)
 {
     int alen, family, notused;
     Xtransaddr *from = NULL;
-    pointer addr;
+    void *addr;
     register HOST *host;
     OsCommPtr oc = (OsCommPtr) client->osPrivate;
 
@@ -987,7 +987,7 @@ ComputeLocalClient(ClientPtr client)
 
     if (!_XSERVTransGetPeerAddr(oc->trans_conn, &notused, &alen, &from)) {
         family = ConvertAddr((struct sockaddr *) from,
-                             &alen, (pointer *) &addr);
+                             &alen, (void **) &addr);
         if (family == -1) {
             free(from);
             return FALSE;
@@ -1219,8 +1219,8 @@ AddHost(ClientPtr client, int family, unsigned length,  /* of bytes in pAddr */
 Bool
 ForEachHostInFamily(int family, Bool (*func) (unsigned char * /* addr */ ,
                                               short /* len */ ,
-                                              pointer /* closure */ ),
-                    pointer closure)
+                                              void */* closure */ ),
+                    void *closure)
 {
     HOST *host;
 
@@ -1264,7 +1264,7 @@ NewHost(int family, const void *addr, int len, int addingLocalHosts)
 
 int
 RemoveHost(ClientPtr client, int family, unsigned length,       /* of bytes in pAddr */
-           pointer pAddr)
+           void *pAddr)
 {
     int rc, len;
     register HOST *host, **prev;
@@ -1311,7 +1311,7 @@ RemoveHost(ClientPtr client, int family, unsigned length,       /* of bytes in p
 
 /* Get all hosts in the access control list */
 int
-GetHosts(pointer *data, int *pnHosts, int *pLen, BOOL * pEnabled)
+GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled)
 {
     int len;
     register int n = 0;
@@ -1386,12 +1386,12 @@ int
 InvalidHost(register struct sockaddr *saddr, int len, ClientPtr client)
 {
     int family;
-    pointer addr;
+    void *addr;
     register HOST *selfhost, *host;
 
     if (!AccessEnabled)         /* just let them in */
         return 0;
-    family = ConvertAddr(saddr, &len, (pointer *) &addr);
+    family = ConvertAddr(saddr, &len, (void **) &addr);
     if (family == -1)
         return 1;
     if (family == FamilyLocal) {
@@ -1427,7 +1427,7 @@ InvalidHost(register struct sockaddr *saddr, int len, ClientPtr client)
 }
 
 static int
-ConvertAddr(register struct sockaddr *saddr, int *len, pointer *addr)
+ConvertAddr(register struct sockaddr *saddr, int *len, void **addr)
 {
     if (*len == 0)
         return FamilyLocal;
@@ -1444,7 +1444,7 @@ ConvertAddr(register struct sockaddr *saddr, int *len, pointer *addr)
             return FamilyLocal;
 #endif
         *len = sizeof(struct in_addr);
-        *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
+        *addr = (void *) &(((struct sockaddr_in *) saddr)->sin_addr);
         return FamilyInternet;
 #if defined(IPv6) && defined(AF_INET6)
     case AF_INET6:
@@ -1453,12 +1453,12 @@ ConvertAddr(register struct sockaddr *saddr, int *len, pointer *addr)
 
         if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
             *len = sizeof(struct in_addr);
-            *addr = (pointer) &(saddr6->sin6_addr.s6_addr[12]);
+            *addr = (void *) &(saddr6->sin6_addr.s6_addr[12]);
             return FamilyInternet;
         }
         else {
             *len = sizeof(struct in6_addr);
-            *addr = (pointer) &(saddr6->sin6_addr);
+            *addr = (void *) &(saddr6->sin6_addr);
             return FamilyInternet6;
         }
     }
@@ -1505,7 +1505,7 @@ GetAccessControl(void)
  * future to enable loading additional host types, but that was not done for
  * the initial implementation.
  */
-typedef Bool (*siAddrMatchFunc) (int family, pointer addr, int len,
+typedef Bool (*siAddrMatchFunc) (int family, void *addr, int len,
                                  const char *siAddr, int siAddrlen,
                                  ClientPtr client, void *siTypePriv);
 typedef int (*siCheckAddrFunc) (const char *addrString, int length,
@@ -1558,7 +1558,7 @@ siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
 
 /* Checks to see if a host matches a server-interpreted host entry */
 static Bool
-siAddrMatch(int family, pointer addr, int len, HOST * host, ClientPtr client)
+siAddrMatch(int family, void *addr, int len, HOST * host, ClientPtr client)
 {
     Bool matches = FALSE;
     struct siType *s;
@@ -1659,7 +1659,7 @@ siCheckAddr(const char *addrString, int length)
 #endif
 
 static Bool
-siHostnameAddrMatch(int family, pointer addr, int len,
+siHostnameAddrMatch(int family, void *addr, int len,
                     const char *siAddr, int siAddrLen, ClientPtr client,
                     void *typePriv)
 {
@@ -1675,7 +1675,7 @@ siHostnameAddrMatch(int family, pointer addr, int len,
         struct addrinfo *addresses;
         struct addrinfo *a;
         int f, hostaddrlen;
-        pointer hostaddr;
+        void *hostaddr;
 
         if (siAddrLen >= sizeof(hostname))
             return FALSE;
@@ -1704,7 +1704,7 @@ siHostnameAddrMatch(int family, pointer addr, int len,
 #endif
         char hostname[SI_HOSTNAME_MAXLEN];
         int f, hostaddrlen;
-        pointer hostaddr;
+        void *hostaddr;
         const char **addrlist;
 
         if (siAddrLen >= sizeof(hostname))
@@ -1808,7 +1808,7 @@ siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
 #define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
 
 static Bool
-siIPv6AddrMatch(int family, pointer addr, int len,
+siIPv6AddrMatch(int family, void *addr, int len,
                 const char *siAddr, int siAddrlen, ClientPtr client,
                 void *typePriv)
 {
@@ -1934,7 +1934,7 @@ siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
 }
 
 static Bool
-siLocalCredAddrMatch(int family, pointer addr, int len,
+siLocalCredAddrMatch(int family, void *addr, int len,
                      const char *siAddr, int siAddrlen, ClientPtr client,
                      void *typePriv)
 {
diff --git a/os/connection.c b/os/connection.c
index 162e1d9..ddf4f0a 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -760,7 +760,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
     oc->output = (ConnectionOutputPtr) NULL;
     oc->auth_id = None;
     oc->conn_time = conn_time;
-    if (!(client = NextAvailableClient((pointer) oc))) {
+    if (!(client = NextAvailableClient((void *) oc))) {
         free(oc);
         return NullClient;
     }
@@ -798,7 +798,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
  *****************/
 
  /*ARGSUSED*/ Bool
-EstablishNewConnections(ClientPtr clientUnused, pointer closure)
+EstablishNewConnections(ClientPtr clientUnused, void *closure)
 {
     fd_set readyconnections;    /* set of listeners that are ready */
     int curconn;                /* fd of listener that's ready */
@@ -1046,7 +1046,7 @@ CloseDownConnection(ClientPtr client)
     CloseDownFileDescriptor(oc);
     FreeOsBuffers(oc);
     free(client->osPrivate);
-    client->osPrivate = (pointer) NULL;
+    client->osPrivate = (void *) NULL;
     if (auditTrailLevel > 1)
         AuditF("client %d disconnected\n", client->index);
 }
diff --git a/os/io.c b/os/io.c
index 922a8eb..cf5e8f9 100644
--- a/os/io.c
+++ b/os/io.c
@@ -481,7 +481,7 @@ ReadRequestFromClient(ClientPtr client)
         oci->lenLastReq -= (sizeof(xBigReq) - sizeof(xReq));
         client->req_len -= bytes_to_int32(sizeof(xBigReq) - sizeof(xReq));
     }
-    client->requestBuffer = (pointer) oci->bufptr;
+    client->requestBuffer = (void *) oci->bufptr;
 #ifdef DEBUG_COMMUNICATION
     {
         xReq *req = client->requestBuffer;
@@ -809,7 +809,7 @@ WriteToClient(ClientPtr who, int count, const void *__buf)
             who->replyBytesRemaining -= count + padBytes;
             replyinfo.startOfReply = FALSE;
             replyinfo.bytesRemaining = who->replyBytesRemaining;
-            CallCallbacks((&ReplyCallback), (pointer) &replyinfo);
+            CallCallbacks((&ReplyCallback), (void *) &replyinfo);
         }
         else if (who->clientState == ClientStateRunning && buf[0] == X_Reply) { /* start of new reply */
             CARD32 replylen;
@@ -821,7 +821,7 @@ WriteToClient(ClientPtr who, int count, const void *__buf)
             bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes;
             replyinfo.startOfReply = TRUE;
             replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft;
-            CallCallbacks((&ReplyCallback), (pointer) &replyinfo);
+            CallCallbacks((&ReplyCallback), (void *) &replyinfo);
         }
     }
 #ifdef DEBUG_COMMUNICATION
diff --git a/os/log.c b/os/log.c
index 53b3586..792b79e 100644
--- a/os/log.c
+++ b/os/log.c
@@ -826,7 +826,7 @@ AuditF(const char *f, ...)
 }
 
 static CARD32
-AuditFlush(OsTimerPtr timer, CARD32 now, pointer arg)
+AuditFlush(OsTimerPtr timer, CARD32 now, void *arg)
 {
     char *prefix;
 
diff --git a/os/rpcauth.c b/os/rpcauth.c
index bd219ac..d60ea35 100644
--- a/os/rpcauth.c
+++ b/os/rpcauth.c
@@ -113,7 +113,7 @@ authdes_ezdecode(const char *inmsg, int len)
 static XID rpc_id = (XID) ~0L;
 
 static Bool
-CheckNetName(unsigned char *addr, short len, pointer closure)
+CheckNetName(unsigned char *addr, short len, void *closure)
 {
     return (len == strlen((char *) closure) &&
             strncmp((char *) addr, (char *) closure, len) == 0);
@@ -159,7 +159,7 @@ _X_HIDDEN int
 SecureRPCAdd(unsigned short data_length, const char *data, XID id)
 {
     if (data_length)
-        AddHost((pointer) 0, FamilyNetname, data_length, data);
+        AddHost((void *) 0, FamilyNetname, data_length, data);
     rpc_id = id;
     return 1;
 }
diff --git a/os/utils.c b/os/utils.c
index e81dc5f..6f83a08 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -490,7 +490,7 @@ GetTimeInMicros(void)
 #endif
 
 void
-AdjustWaitForDelay(pointer waitTime, unsigned long newdelay)
+AdjustWaitForDelay(void *waitTime, unsigned long newdelay)
 {
     static struct timeval delay_val;
     struct timeval **wt = (struct timeval **) waitTime;
@@ -986,7 +986,7 @@ ProcessCommandLine(int argc, char *argv[])
 /* Implement a simple-minded font authorization scheme.  The authorization
    name is "hp-hostname-1", the contents are simply the host name. */
 int
-set_font_authorizations(char **authorizations, int *authlen, pointer client)
+set_font_authorizations(char **authorizations, int *authlen, void *client)
 {
 #define AUTHORIZATION_NAME "hp-hostname-1"
 #if defined(TCPCONN) || defined(STREAMSCONN)
@@ -1385,7 +1385,7 @@ static struct pid {
 
 OsSigHandlerPtr old_alarm = NULL;       /* XXX horrible awful hack */
 
-pointer
+void *
 Popen(const char *command, const char *type)
 {
     struct pid *cur;
@@ -1473,7 +1473,7 @@ Popen(const char *command, const char *type)
 }
 
 /* fopen that drops privileges */
-pointer
+void *
 Fopen(const char *file, const char *type)
 {
     FILE *iop;
@@ -1568,7 +1568,7 @@ Fopen(const char *file, const char *type)
 }
 
 int
-Pclose(pointer iop)
+Pclose(void *iop)
 {
     struct pid *cur, *last;
     int pstat;
@@ -1605,7 +1605,7 @@ Pclose(pointer iop)
 }
 
 int
-Fclose(pointer iop)
+Fclose(void *iop)
 {
 #ifdef HAS_SAVED_IDS_AND_SETEUID
     return fclose(iop);
diff --git a/os/xdmcp.c b/os/xdmcp.c
index 11f1133..da509e4 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -189,13 +189,13 @@ static void timeout(void);
 
 static void restart(void);
 
-static void XdmcpBlockHandler(pointer /*data */ ,
+static void XdmcpBlockHandler(void */*data */ ,
                               struct timeval ** /*wt */ ,
-                              pointer /*LastSelectMask */ );
+                              void */*LastSelectMask */ );
 
-static void XdmcpWakeupHandler(pointer /*data */ ,
+static void XdmcpWakeupHandler(void */*data */ ,
                                int /*i */ ,
-                               pointer /*LastSelectMask */ );
+                               void */*LastSelectMask */ );
 
 /*
  * Register the Manufacturer display ID
@@ -578,7 +578,7 @@ XdmcpInit(void)
                                   strlen(defaultDisplayClass));
         AccessUsingXdmcp();
         RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (pointer) 0);
+                                       (void *) 0);
         timeOutRtx = 0;
         DisplayNumber = (CARD16) atoi(display);
         get_xdmcp_sock();
@@ -592,7 +592,7 @@ XdmcpReset(void)
     state = XDM_INIT_STATE;
     if (state != XDM_OFF) {
         RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (pointer) 0);
+                                       (void *) 0);
         timeOutRtx = 0;
         send_packet();
     }
@@ -635,8 +635,8 @@ XdmcpCloseDisplay(int sock)
  */
 
  /*ARGSUSED*/ static void
-XdmcpBlockHandler(pointer data, /* unused */
-                  struct timeval **wt, pointer pReadmask)
+XdmcpBlockHandler(void *data, /* unused */
+                  struct timeval **wt, void *pReadmask)
 {
     fd_set *LastSelectMask = (fd_set *) pReadmask;
     CARD32 millisToGo;
@@ -663,8 +663,8 @@ XdmcpBlockHandler(pointer data, /* unused */
  */
 
  /*ARGSUSED*/ static void
-XdmcpWakeupHandler(pointer data,        /* unused */
-                   int i, pointer pReadmask)
+XdmcpWakeupHandler(void *data,        /* unused */
+                   int i, void *pReadmask)
 {
     fd_set *LastSelectMask = (fd_set *) pReadmask;
     fd_set devicesReadable;
diff --git a/present/present.c b/present/present.c
index 30cd3b9..73d5f69 100644
--- a/present/present.c
+++ b/present/present.c
@@ -318,7 +318,7 @@ struct pixmap_visit {
 };
 
 static int
-present_set_tree_pixmap_visit(WindowPtr window, pointer data)
+present_set_tree_pixmap_visit(WindowPtr window, void *data)
 {
     struct pixmap_visit *visit = data;
     ScreenPtr           screen = window->drawable.pScreen;
diff --git a/present/present_event.c b/present/present_event.c
index f0d509e..ff57eba 100644
--- a/present/present_event.c
+++ b/present/present_event.c
@@ -29,7 +29,7 @@
 RESTYPE present_event_type;
 
 static int
-present_free_event(pointer data, XID id)
+present_free_event(void *data, XID id)
 {
     present_event_ptr present_event = (present_event_ptr) data;
     present_window_priv_ptr window_priv = present_window_priv(present_event->window);
@@ -41,7 +41,7 @@ present_free_event(pointer data, XID id)
             break;
         }
     }
-    free((pointer) present_event);
+    free((void *) present_event);
     return 1;
 
 }
@@ -229,7 +229,7 @@ present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
     event->next = window_priv->events;
     window_priv->events = event;
 
-    if (!AddResource(event->id, present_event_type, (pointer) event))
+    if (!AddResource(event->id, present_event_type, (void *) event))
         return BadAlloc;
 
     return Success;
diff --git a/present/present_fake.c b/present/present_fake.c
index e550e98..4985c81 100644
--- a/present/present_fake.c
+++ b/present/present_fake.c
@@ -58,7 +58,7 @@ present_fake_notify(ScreenPtr screen, uint64_t event_id)
 static CARD32
 present_fake_do_timer(OsTimerPtr timer,
                       CARD32 time,
-                      pointer arg)
+                      void *arg)
 {
     present_fake_vblank_ptr     fake_vblank = arg;
 
diff --git a/present/present_request.c b/present/present_request.c
index 1064dcb..835890d 100644
--- a/present/present_request.c
+++ b/present/present_request.c
@@ -89,7 +89,7 @@ proc_present_pixmap(ClientPtr client)
     ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
     if (ret != Success)
         return ret;
-    ret = dixLookupResourceByType((pointer *) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
+    ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
     if (ret != Success)
         return ret;
 
diff --git a/randr/randr.c b/randr/randr.c
index 3c51427..3c97714 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -60,7 +60,7 @@ DevPrivateKeyRec RRClientPrivateKeyRec;
 DevPrivateKeyRec rrPrivKeyRec;
 
 static void
-RRClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+RRClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
@@ -338,7 +338,7 @@ RRScreenInit(ScreenPtr pScreen)
 }
 
  /*ARGSUSED*/ static int
-RRFreeClient(pointer data, XID id)
+RRFreeClient(void *data, XID id)
 {
     RREventPtr pRREvent;
     WindowPtr pWin;
@@ -346,7 +346,7 @@ RRFreeClient(pointer data, XID id)
 
     pRREvent = (RREventPtr) data;
     pWin = pRREvent->window;
-    dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                             RREventType, serverClient, DixDestroyAccess);
     if (pHead) {
         pPrev = 0;
@@ -359,12 +359,12 @@ RRFreeClient(pointer data, XID id)
                 *pHead = pRREvent->next;
         }
     }
-    free((pointer) pRREvent);
+    free((void *) pRREvent);
     return 1;
 }
 
  /*ARGSUSED*/ static int
-RRFreeEvents(pointer data, XID id)
+RRFreeEvents(void *data, XID id)
 {
     RREventPtr *pHead, pCur, pNext;
 
@@ -372,9 +372,9 @@ RRFreeEvents(pointer data, XID id)
     for (pCur = *pHead; pCur; pCur = pNext) {
         pNext = pCur->next;
         FreeResource(pCur->clientResource, RRClientType);
-        free((pointer) pCur);
+        free((void *) pCur);
     }
-    free((pointer) pHead);
+    free((void *) pHead);
     return 1;
 }
 
@@ -447,7 +447,7 @@ RRDeliverResourceEvent(ClientPtr client, WindowPtr pWin)
 }
 
 static int
-TellChanged(WindowPtr pWin, pointer value)
+TellChanged(WindowPtr pWin, void *value)
 {
     RREventPtr *pHead, pRREvent;
     ClientPtr client;
@@ -458,7 +458,7 @@ TellChanged(WindowPtr pWin, pointer value)
     rrScrPriv(pScreen);
     int i;
 
-    dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                             RREventType, serverClient, DixReadAccess);
     if (!pHead)
         return WT_WALKCHILDREN;
@@ -589,7 +589,7 @@ RRTellChanged(ScreenPtr pScreen)
         pScrPriv->changed = FALSE;
         mastersp->changed = FALSE;
 
-        WalkTree(master, TellChanged, (pointer) master);
+        WalkTree(master, TellChanged, (void *) master);
 
         mastersp->resourcesChanged = FALSE;
 
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 15299fd..e142232 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -92,7 +92,7 @@ struct _rrPropertyValue {
     Atom type;                  /* ignored by server */
     short format;               /* format of data for swapping - 8,16,32 */
     long size;                  /* size of data in (format/8) bytes */
-    pointer data;               /* private to client */
+    void *data;                 /* private to client */
 };
 
 struct _rrProperty {
@@ -385,7 +385,7 @@ extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
 
 #define VERIFY_RR_OUTPUT(id, ptr, a)\
     {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	int rc = dixLookupResourceByType((void **)&(ptr), id,\
 	                                 RROutputType, client, a);\
 	if (rc != Success) {\
 	    client->errorValue = id;\
@@ -395,7 +395,7 @@ extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
 
 #define VERIFY_RR_CRTC(id, ptr, a)\
     {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	int rc = dixLookupResourceByType((void **)&(ptr), id,\
 	                                 RRCrtcType, client, a);\
 	if (rc != Success) {\
 	    client->errorValue = id;\
@@ -405,7 +405,7 @@ extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
 
 #define VERIFY_RR_MODE(id, ptr, a)\
     {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	int rc = dixLookupResourceByType((void **)&(ptr), id,\
 	                                 RRModeType, client, a);\
 	if (rc != Success) {\
 	    client->errorValue = id;\
@@ -415,7 +415,7 @@ extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
 
 #define VERIFY_RR_PROVIDER(id, ptr, a)\
     {\
-        int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+        int rc = dixLookupResourceByType((void **)&(ptr), id,\
                                          RRProviderType, client, a);\
         if (rc != Success) {\
             client->errorValue = id;\
@@ -871,7 +871,7 @@ extern _X_EXPORT int
 
 RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       pointer value, Bool sendevent, Bool pending);
+                       void *value, Bool sendevent, Bool pending);
 
 extern _X_EXPORT int
 
@@ -948,7 +948,7 @@ extern _X_EXPORT void
 extern _X_EXPORT int
 RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       pointer value, Bool sendevent, Bool pending);
+                       void *value, Bool sendevent, Bool pending);
 
 extern _X_EXPORT int
  RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 99b3dca..df1e3f1 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -95,7 +95,7 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
     pixman_f_transform_init_identity(&crtc->f_transform);
     pixman_f_transform_init_identity(&crtc->f_inverse);
 
-    if (!AddResource(crtc->id, RRCrtcType, (pointer) crtc))
+    if (!AddResource(crtc->id, RRCrtcType, (void *) crtc))
         return NULL;
 
     /* attach the screen and crtc together */
@@ -654,7 +654,7 @@ RRCrtcDestroy(RRCrtcPtr crtc)
 }
 
 static int
-RRCrtcDestroyResource(pointer value, XID pid)
+RRCrtcDestroyResource(void *value, XID pid)
 {
     RRCrtcPtr crtc = (RRCrtcPtr) value;
     ScreenPtr pScreen = crtc->pScreen;
@@ -1026,7 +1026,7 @@ ProcRRSetCrtcConfig(ClientPtr client)
 
     outputIds = (RROutput *) (stuff + 1);
     for (i = 0; i < numOutputs; i++) {
-        ret = dixLookupResourceByType((pointer *) (outputs + i), outputIds[i],
+        ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i],
                                      RROutputType, client, DixSetAttrAccess);
         if (ret != Success) {
             free(outputs);
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 7fbc9f0..b9346d3 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -83,7 +83,7 @@ ProcRRSelectInput(ClientPtr client)
     rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
     if (rc != Success)
         return rc;
-    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                                  RREventType, client, DixWriteAccess);
     if (rc != Success && rc != BadValue)
         return rc;
@@ -120,7 +120,7 @@ ProcRRSelectInput(ClientPtr client)
              */
             clientResource = FakeClientID(client->index);
             pRREvent->clientResource = clientResource;
-            if (!AddResource(clientResource, RRClientType, (pointer) pRREvent))
+            if (!AddResource(clientResource, RRClientType, (void *) pRREvent))
                 return BadAlloc;
             /*
              * create a resource to contain a pointer to the list
@@ -132,7 +132,7 @@ ProcRRSelectInput(ClientPtr client)
                 pHead = (RREventPtr *) malloc(sizeof(RREventPtr));
                 if (!pHead ||
                     !AddResource(pWin->drawable.id, RREventType,
-                                 (pointer) pHead)) {
+                                 (void *) pHead)) {
                     FreeResource(clientResource, RT_NONE);
                     return BadAlloc;
                 }
diff --git a/randr/rrmode.c b/randr/rrmode.c
index f5d3f9e..befac47 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -89,7 +89,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
     }
 
     mode->mode.id = FakeClientID(0);
-    if (!AddResource(mode->mode.id, RRModeType, (pointer) mode)) {
+    if (!AddResource(mode->mode.id, RRModeType, (void *) mode)) {
         free(newModes);
         return NULL;
     }
@@ -250,7 +250,7 @@ RRModeDestroy(RRModePtr mode)
 }
 
 static int
-RRModeDestroyResource(pointer value, XID pid)
+RRModeDestroyResource(void *value, XID pid)
 {
     RRModeDestroy((RRModePtr) value);
     return 1;
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 2b0b82f..f824f50 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -97,7 +97,7 @@ RROutputCreate(ScreenPtr pScreen,
     output->changed = FALSE;
     output->devPrivate = devPrivate;
 
-    if (!AddResource(output->id, RROutputType, (pointer) output))
+    if (!AddResource(output->id, RROutputType, (void *) output))
         return NULL;
 
     pScrPriv->outputs[pScrPriv->numOutputs++] = output;
@@ -337,7 +337,7 @@ RROutputDestroy(RROutputPtr output)
 }
 
 static int
-RROutputDestroyResource(pointer value, XID pid)
+RROutputDestroyResource(void *value, XID pid)
 {
     RROutputPtr output = (RROutputPtr) value;
     ScreenPtr pScreen = output->pScreen;
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index 67b5467..e385e15 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -30,7 +30,7 @@ DeliverPropertyEvent(WindowPtr pWin, void *value)
     xRROutputPropertyNotifyEvent *event = value;
     RREventPtr *pHead, pRREvent;
 
-    dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                             RREventType, serverClient, DixReadAccess);
     if (!pHead)
         return WT_WALKCHILDREN;
@@ -135,7 +135,7 @@ RRDeleteOutputProperty(RROutputPtr output, Atom property)
 int
 RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       pointer value, Bool sendevent, Bool pending)
+                       void *value, Bool sendevent, Bool pending)
 {
     RRPropertyPtr prop;
     rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
@@ -178,10 +178,10 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
         total_len = prop_value->size + len;
 
     if (mode == PropModeReplace || len > 0) {
-        pointer new_data = NULL, old_data = NULL;
+        void *new_data = NULL, *old_data = NULL;
 
         total_size = total_len * size_in_bytes;
-        new_value.data = (pointer) malloc(total_size);
+        new_value.data = (void *) malloc(total_size);
         if (!new_value.data && total_size) {
             if (add)
                 RRDestroyOutputProperty(prop);
@@ -197,13 +197,13 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
             old_data = NULL;
             break;
         case PropModeAppend:
-            new_data = (pointer) (((char *) new_value.data) +
+            new_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             old_data = new_value.data;
             break;
         case PropModePrepend:
             new_data = new_value.data;
-            old_data = (pointer) (((char *) new_value.data) +
+            old_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             break;
         }
@@ -538,7 +538,7 @@ ProcRRChangeOutputProperty(ClientPtr client)
 
     err = RRChangeOutputProperty(output, stuff->property,
                                  stuff->type, (int) format,
-                                 (int) mode, len, (pointer) &stuff[1], TRUE,
+                                 (int) mode, len, (void *) &stuff[1], TRUE,
                                  TRUE);
     if (err != Success)
         return err;
diff --git a/randr/rrprovider.c b/randr/rrprovider.c
index 2334ad2..3ce7d75 100644
--- a/randr/rrprovider.c
+++ b/randr/rrprovider.c
@@ -365,7 +365,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name,
     provider->name[nameLength] = '\0';
     provider->changed = FALSE;
 
-    if (!AddResource (provider->id, RRProviderType, (pointer) provider))
+    if (!AddResource (provider->id, RRProviderType, (void *) provider))
         return NULL;
     pScrPriv->provider = provider;
     return provider;
@@ -387,7 +387,7 @@ RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities)
 }
 
 static int
-RRProviderDestroyResource (pointer value, XID pid)
+RRProviderDestroyResource (void *value, XID pid)
 {
     RRProviderPtr provider = (RRProviderPtr)value;
     ScreenPtr pScreen = provider->pScreen;
diff --git a/randr/rrproviderproperty.c b/randr/rrproviderproperty.c
index ab601da..ff2c614 100644
--- a/randr/rrproviderproperty.c
+++ b/randr/rrproviderproperty.c
@@ -30,7 +30,7 @@ DeliverPropertyEvent(WindowPtr pWin, void *value)
     xRRProviderPropertyNotifyEvent *event = value;
     RREventPtr *pHead, pRREvent;
 
-    dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
+    dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
                             RREventType, serverClient, DixReadAccess);
     if (!pHead)
         return WT_WALKCHILDREN;
@@ -135,7 +135,7 @@ RRDeleteProviderProperty(RRProviderPtr provider, Atom property)
 int
 RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
                        int format, int mode, unsigned long len,
-                       pointer value, Bool sendevent, Bool pending)
+                       void *value, Bool sendevent, Bool pending)
 {
     RRPropertyPtr prop;
     rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen);
@@ -178,10 +178,10 @@ RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
         total_len = prop_value->size + len;
 
     if (mode == PropModeReplace || len > 0) {
-        pointer new_data = NULL, old_data = NULL;
+        void *new_data = NULL, *old_data = NULL;
 
         total_size = total_len * size_in_bytes;
-        new_value.data = (pointer) malloc(total_size);
+        new_value.data = (void *) malloc(total_size);
         if (!new_value.data && total_size) {
             if (add)
                 RRDestroyProviderProperty(prop);
@@ -197,13 +197,13 @@ RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
             old_data = NULL;
             break;
         case PropModeAppend:
-            new_data = (pointer) (((char *) new_value.data) +
+            new_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             old_data = new_value.data;
             break;
         case PropModePrepend:
             new_data = new_value.data;
-            old_data = (pointer) (((char *) new_value.data) +
+            old_data = (void *) (((char *) new_value.data) +
                                   (prop_value->size * size_in_bytes));
             break;
         }
@@ -534,7 +534,7 @@ ProcRRChangeProviderProperty(ClientPtr client)
 
     err = RRChangeProviderProperty(provider, stuff->property,
                                  stuff->type, (int) format,
-                                 (int) mode, len, (pointer) &stuff[1], TRUE,
+                                 (int) mode, len, (void *) &stuff[1], TRUE,
                                  TRUE);
     if (err != Success)
         return err;
diff --git a/record/record.c b/record/record.c
index 2c70460..8217a44 100644
--- a/record/record.c
+++ b/record/record.c
@@ -130,13 +130,13 @@ static int numEnabledRCAPs;
  *  returns an error.
  */
 #define VERIFY_CONTEXT(_pContext, _contextid, _client) { \
-    int rc = dixLookupResourceByType((pointer *)&(_pContext), _contextid, \
+    int rc = dixLookupResourceByType((void **)&(_pContext), _contextid, \
                                      RTContext, _client, DixUseAccess); \
     if (rc != Success) \
 	return rc; \
 }
 
-static int RecordDeleteContext(pointer /*value */ ,
+static int RecordDeleteContext(void */*value */ ,
                                XID      /*id */
     );
 
@@ -232,7 +232,7 @@ RecordFindContextOnAllContexts(RecordContextPtr pContext)
  */
 static void
 RecordFlushReplyBuffer(RecordContextPtr pContext,
-                       pointer data1, int len1, pointer data2, int len2)
+                       void *data1, int len1, void *data2, int len2)
 {
     if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone ||
         pContext->inFlush)
@@ -279,7 +279,7 @@ RecordFlushReplyBuffer(RecordContextPtr pContext,
  */
 static void
 RecordAProtocolElement(RecordContextPtr pContext, ClientPtr pClient,
-                       int category, pointer data, int datalen, int padlen,
+                       int category, void *data, int datalen, int padlen,
                        int futurelen)
 {
     CARD32 elemHeaderData[2];
@@ -390,8 +390,8 @@ RecordAProtocolElement(RecordContextPtr pContext, ClientPtr pClient,
         }
     }
     else {
-        RecordFlushReplyBuffer(pContext, (pointer) elemHeaderData,
-                               numElemHeaders, (pointer) data,
+        RecordFlushReplyBuffer(pContext, (void *) elemHeaderData,
+                               numElemHeaders, (void *) data,
                                datalen - padlen);
     }
 }                               /* RecordAProtocolElement */
@@ -463,20 +463,20 @@ RecordABigRequest(RecordContextPtr pContext, ClientPtr client, xReq * stuff)
     /* record the request header */
     bytesLeft = client->req_len << 2;
     RecordAProtocolElement(pContext, client, XRecordFromClient,
-                           (pointer) stuff, SIZEOF(xReq), 0, bytesLeft);
+                           (void *) stuff, SIZEOF(xReq), 0, bytesLeft);
 
     /* reinsert the extended length field that was squished out */
     bigLength = client->req_len + bytes_to_int32(sizeof(bigLength));
     if (client->swapped)
         swapl(&bigLength);
     RecordAProtocolElement(pContext, client, XRecordFromClient,
-                           (pointer) &bigLength, sizeof(bigLength), 0,
+                           (void *) &bigLength, sizeof(bigLength), 0,
                            /* continuation */ -1);
     bytesLeft -= sizeof(bigLength);
 
     /* record the rest of the request after the length */
     RecordAProtocolElement(pContext, client, XRecordFromClient,
-                           (pointer) (stuff + 1), bytesLeft, 0,
+                           (void *) (stuff + 1), bytesLeft, 0,
                            /* continuation */ -1);
 }                               /* RecordABigRequest */
 
@@ -520,7 +520,7 @@ RecordARequest(ClientPtr client)
                     RecordABigRequest(pContext, client, stuff);
                 else
                     RecordAProtocolElement(pContext, client, XRecordFromClient,
-                                           (pointer) stuff,
+                                           (void *) stuff,
                                            client->req_len << 2, 0, 0);
             }
             else {              /* extension, check minor opcode */
@@ -543,7 +543,7 @@ RecordARequest(ClientPtr client)
                         else
                             RecordAProtocolElement(pContext, client,
                                                    XRecordFromClient,
-                                                   (pointer) stuff,
+                                                   (void *) stuff,
                                                    client->req_len << 2, 0, 0);
                         break;
                     }
@@ -576,7 +576,7 @@ RecordARequest(ClientPtr client)
  *	chunk of data belonging to this reply, it is set to 0.
  */
 static void
-RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+RecordAReply(CallbackListPtr *pcbl, void *nulldata, void *calldata)
 {
     RecordContextPtr pContext;
     RecordClientsAndProtocolPtr pRCAP;
@@ -592,7 +592,7 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
 
             if (pContext->continuedReply) {
                 RecordAProtocolElement(pContext, client, XRecordFromServer,
-                                       (pointer) pri->replyData,
+                                       (void *) pri->replyData,
                                        pri->dataLenBytes, pri->padBytes,
                                        /* continuation */ -1);
                 if (!pri->bytesRemaining)
@@ -602,7 +602,7 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
                      RecordIsMemberOfSet(pRCAP->pReplyMajorOpSet, majorop)) {
                 if (majorop <= 127) {   /* core reply */
                     RecordAProtocolElement(pContext, client, XRecordFromServer,
-                                           (pointer) pri->replyData,
+                                           (void *) pri->replyData,
                                            pri->dataLenBytes, 0,
                                            pri->bytesRemaining);
                     if (pri->bytesRemaining)
@@ -625,7 +625,7 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
                                                 minorop)) {
                             RecordAProtocolElement(pContext, client,
                                                    XRecordFromServer,
-                                                   (pointer) pri->replyData,
+                                                   (void *) pri->replyData,
                                                    pri->dataLenBytes, 0,
                                                    pri->bytesRemaining);
                             if (pri->bytesRemaining)
@@ -655,8 +655,8 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
  *	it for this client.
  */
 static void
-RecordADeliveredEventOrError(CallbackListPtr *pcbl, pointer nulldata,
-                             pointer calldata)
+RecordADeliveredEventOrError(CallbackListPtr *pcbl, void *nulldata,
+                             void *calldata)
 {
     EventInfoRec *pei = (EventInfoRec *) calldata;
     RecordContextPtr pContext;
@@ -766,7 +766,7 @@ RecordSendProtocolEvents(RecordClientsAndProtocolPtr pRCAP,
  *	it for this client.
  */
 static void
-RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+RecordADeviceEvent(CallbackListPtr *pcbl, void *nulldata, void *calldata)
 {
     DeviceEventInfoRec *pei = (DeviceEventInfoRec *) calldata;
     RecordContextPtr pContext;
@@ -812,7 +812,7 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
  */
 static void
 RecordFlushAllContexts(CallbackListPtr *pcbl,
-                       pointer nulldata, pointer calldata)
+                       void *nulldata, void *calldata)
 {
     int eci;                    /* enabled context index */
     RecordContextPtr pContext;
@@ -1143,7 +1143,7 @@ RecordSanityCheckClientSpecifiers(ClientPtr client, XID *clientspecs,
     int i;
     int clientIndex;
     int rc;
-    pointer value;
+    void *value;
 
     for (i = 0; i < nspecs; i++) {
         if (clientspecs[i] == XRecordCurrentClients ||
@@ -1880,7 +1880,7 @@ ProcRecordCreateContext(ClientPtr client)
         return Success;
     }
     else {
-        RecordDeleteContext((pointer) pContext, pContext->id);
+        RecordDeleteContext((void *) pContext, pContext->id);
         return BadAlloc;
     }
  bailout:
@@ -2416,7 +2416,7 @@ ProcRecordDisableContext(ClientPtr client)
  *	it from the ppAllContexts array.
  */
 static int
-RecordDeleteContext(pointer value, XID id)
+RecordDeleteContext(void *value, XID id)
 {
     int i;
     RecordContextPtr pContext = (RecordContextPtr) value;
@@ -2535,7 +2535,7 @@ SProcRecordCreateContext(ClientPtr client)
 
     swaps(&stuff->length);
     REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
-    if ((status = SwapCreateRegister((pointer) stuff)) != Success)
+    if ((status = SwapCreateRegister((void *) stuff)) != Success)
         return status;
     return ProcRecordCreateContext(client);
 }                               /* SProcRecordCreateContext */
@@ -2548,7 +2548,7 @@ SProcRecordRegisterClients(ClientPtr client)
 
     swaps(&stuff->length);
     REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
-    if ((status = SwapCreateRegister((pointer) stuff)) != Success)
+    if ((status = SwapCreateRegister((void *) stuff)) != Success)
         return status;
     return ProcRecordRegisterClients(client);
 }                               /* SProcRecordRegisterClients */
@@ -2664,7 +2664,7 @@ RecordConnectionSetupInfo(RecordContextPtr pContext, NewClientInfoRec * pci)
         SwapConnSetupInfo((char *) pci->setup,
                           (char *) (pConnSetup + prefixsize));
         RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-                               (pointer) pConnSetup, prefixsize + restsize, 0,
+                               (void *) pConnSetup, prefixsize + restsize, 0,
                                0);
         free(pConnSetup);
     }
@@ -2673,9 +2673,9 @@ RecordConnectionSetupInfo(RecordContextPtr pContext, NewClientInfoRec * pci)
          * data in two pieces
          */
         RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-                               (pointer) pci->prefix, prefixsize, 0, restsize);
+                               (void *) pci->prefix, prefixsize, 0, restsize);
         RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-                               (pointer) pci->setup, restsize, 0,
+                               (void *) pci->setup, restsize, 0,
                                /* continuation */ -1);
     }
 }                               /* RecordConnectionSetupInfo */
@@ -2704,8 +2704,8 @@ RecordConnectionSetupInfo(RecordContextPtr pContext, NewClientInfoRec * pci)
  */
 
 static void
-RecordAClientStateChange(CallbackListPtr *pcbl, pointer nulldata,
-                         pointer calldata)
+RecordAClientStateChange(CallbackListPtr *pcbl, void *nulldata,
+                         void *calldata)
 {
     NewClientInfoRec *pci = (NewClientInfoRec *) calldata;
     int i;
diff --git a/render/animcur.c b/render/animcur.c
index 038c5b9..69f9f88 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -136,7 +136,7 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
 
 static void
 AnimCurScreenBlockHandler(ScreenPtr pScreen,
-                          pointer pTimeout, pointer pReadmask)
+                          void *pTimeout, void *pReadmask)
 {
     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
     DeviceIntPtr dev;
diff --git a/render/glyph.c b/render/glyph.c
index e1dc662..ae38121 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -97,7 +97,7 @@ GlyphUninit(ScreenPtr pScreen)
             glyph = globalGlyphs[fdepth].table[i].glyph;
             if (glyph && glyph != DeletedGlyph) {
                 if (GetGlyphPicture(glyph, pScreen)) {
-                    FreePicture((pointer) GetGlyphPicture(glyph, pScreen), 0);
+                    FreePicture((void *) GetGlyphPicture(glyph, pScreen), 0);
                     SetGlyphPicture(glyph, pScreen, NULL);
                 }
                 (*ps->UnrealizeGlyph) (pScreen, glyph);
@@ -237,7 +237,7 @@ FreeGlyphPicture(GlyphPtr glyph)
         ScreenPtr pScreen = screenInfo.screens[i];
 
         if (GetGlyphPicture(glyph, pScreen))
-            FreePicture((pointer) GetGlyphPicture(glyph, pScreen), 0);
+            FreePicture((void *) GetGlyphPicture(glyph, pScreen), 0);
 
         ps = GetPictureScreenIfSet(pScreen);
         if (ps)
@@ -467,7 +467,7 @@ AllocateGlyphSet(int fdepth, PictFormatPtr format)
 }
 
 int
-FreeGlyphSet(pointer value, XID gid)
+FreeGlyphSet(void *value, XID gid)
 {
     GlyphSetPtr glyphSet = (GlyphSetPtr) value;
 
@@ -678,7 +678,7 @@ miGlyphs(CARD8 op,
                          pDst,
                          xSrc + x - xDst,
                          ySrc + y - yDst, 0, 0, x, y, width, height);
-        FreePicture((pointer) pMask, (XID) 0);
+        FreePicture((void *) pMask, (XID) 0);
         (*pScreen->DestroyPixmap) (pMaskPixmap);
     }
 }
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 7d178be..835c1a7 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -131,7 +131,7 @@ extern _X_EXPORT Bool
 extern _X_EXPORT GlyphSetPtr AllocateGlyphSet(int fdepth, PictFormatPtr format);
 
 extern _X_EXPORT int
- FreeGlyphSet(pointer value, XID gid);
+ FreeGlyphSet(void *value, XID gid);
 
 #define GLYPH_HAS_GLYPH_PICTURE_ACCESSOR 1 /* used for api compat */
 extern _X_EXPORT PicturePtr
diff --git a/render/mipict.c b/render/mipict.c
index 2e64b20..3959fc4 100644
--- a/render/mipict.c
+++ b/render/mipict.c
@@ -69,17 +69,17 @@ miDestroyPictureClip(PicturePtr pPicture)
 }
 
 int
-miChangePictureClip(PicturePtr pPicture, int type, pointer value, int n)
+miChangePictureClip(PicturePtr pPicture, int type, void *value, int n)
 {
     ScreenPtr pScreen = pPicture->pDrawable->pScreen;
     PictureScreenPtr ps = GetPictureScreen(pScreen);
-    pointer clientClip;
+    void *clientClip;
     int clientClipType;
 
     switch (type) {
     case CT_PIXMAP:
         /* convert the pixmap to a region */
-        clientClip = (pointer) BitmapToRegion(pScreen, (PixmapPtr) value);
+        clientClip = (void *) BitmapToRegion(pScreen, (PixmapPtr) value);
         if (!clientClip)
             return BadAlloc;
         clientClipType = CT_REGION;
@@ -94,7 +94,7 @@ miChangePictureClip(PicturePtr pPicture, int type, pointer value, int n)
         clientClipType = CT_NONE;
         break;
     default:
-        clientClip = (pointer) RegionFromRects(n, (xRectangle *) value, type);
+        clientClip = (void *) RegionFromRects(n, (xRectangle *) value, type);
         if (!clientClip)
             return BadAlloc;
         clientClipType = CT_REGION;
diff --git a/render/mipict.h b/render/mipict.h
index 9436228..a16dd31 100644
--- a/render/mipict.h
+++ b/render/mipict.h
@@ -57,7 +57,7 @@ extern _X_EXPORT void
  miDestroyPictureClip(PicturePtr pPicture);
 
 extern _X_EXPORT int
- miChangePictureClip(PicturePtr pPicture, int type, pointer value, int n);
+ miChangePictureClip(PicturePtr pPicture, int type, void *value, int n);
 
 extern _X_EXPORT void
  miChangePicture(PicturePtr pPicture, Mask mask);
diff --git a/render/mirect.c b/render/mirect.c
index 357d528..4e76972 100644
--- a/render/mirect.c
+++ b/render/mirect.c
@@ -156,7 +156,7 @@ miCompositeRects(CARD8 op,
             rects++;
         }
 
-        FreePicture((pointer) pSrc, 0);
+        FreePicture((void *) pSrc, 0);
  bail4:
         FreeScratchGC(pGC);
  bail3:
diff --git a/render/picture.c b/render/picture.c
index 2908b76..7da9310 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -70,7 +70,7 @@ PictureDestroyWindow(WindowPtr pWindow)
         SetPictureWindow(pWindow, pPicture->pNext);
         if (pPicture->id)
             FreeResource(pPicture->id, PictureType);
-        FreePicture((pointer) pPicture, pPicture->id);
+        FreePicture((void *) pPicture, pPicture->id);
     }
     pScreen->DestroyWindow = ps->DestroyWindow;
     ret = (*pScreen->DestroyWindow) (pWindow);
@@ -445,7 +445,7 @@ PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format)
         return TRUE;
 
     if (format->index.vid == pScreen->rootVisual) {
-        dixLookupResourceByType((pointer *) &format->index.pColormap,
+        dixLookupResourceByType((void **) &format->index.pColormap,
                                 pScreen->defColormap, RT_COLORMAP,
                                 serverClient, DixGetAttrAccess);
     }
@@ -601,7 +601,7 @@ PictureParseCmapPolicy(const char *name)
 
 /** @see GetDefaultBytes */
 static void
-GetPictureBytes(pointer value, XID id, ResourceSizePtr size)
+GetPictureBytes(void *value, XID id, ResourceSizePtr size)
 {
     PicturePtr picture = value;
 
@@ -655,7 +655,7 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
     }
     for (n = 0; n < nformats; n++) {
         if (!AddResource
-            (formats[n].id, PictFormatType, (pointer) (formats + n))) {
+            (formats[n].id, PictFormatType, (void *) (formats + n))) {
             free(formats);
             return FALSE;
         }
@@ -1054,7 +1054,7 @@ ChangePicture(PicturePtr pPicture,
                 if (pid == None)
                     pAlpha = 0;
                 else {
-                    error = dixLookupResourceByType((pointer *) &pAlpha, pid,
+                    error = dixLookupResourceByType((void **) &pAlpha, pid,
                                                     PictureType, client,
                                                     DixReadAccess);
                     if (error != Success) {
@@ -1075,7 +1075,7 @@ ChangePicture(PicturePtr pPicture,
                 if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
                     pAlpha->refcnt++;
                 if (pPicture->alphaMap)
-                    FreePicture((pointer) pPicture->alphaMap, (XID) 0);
+                    FreePicture((void *) pPicture->alphaMap, (XID) 0);
                 pPicture->alphaMap = pAlpha;
             }
         }
@@ -1113,7 +1113,7 @@ ChangePicture(PicturePtr pPicture,
                 }
                 else {
                     clipType = CT_PIXMAP;
-                    error = dixLookupResourceByType((pointer *) &pPixmap, pid,
+                    error = dixLookupResourceByType((void **) &pPixmap, pid,
                                                     RT_PIXMAP, client,
                                                     DixReadAccess);
                     if (error != Success) {
@@ -1143,7 +1143,7 @@ ChangePicture(PicturePtr pPicture,
                 }
             }
             error = (*ps->ChangePictureClip) (pPicture, clipType,
-                                              (pointer) pPixmap, 0);
+                                              (void *) pPixmap, 0);
             break;
         }
         case CPGraphicsExposure:
@@ -1240,7 +1240,7 @@ SetPictureClipRects(PicturePtr pPicture,
     if (!clientClip)
         return BadAlloc;
     result = (*ps->ChangePictureClip) (pPicture, CT_REGION,
-                                       (pointer) clientClip, 0);
+                                       (void *) clientClip, 0);
     if (result == Success) {
         pPicture->clipOrigin.x = xOrigin;
         pPicture->clipOrigin.y = yOrigin;
@@ -1276,7 +1276,7 @@ SetPictureClipRegion(PicturePtr pPicture,
         clientClip = 0;
     }
 
-    result = (*ps->ChangePictureClip) (pPicture, type, (pointer) clientClip, 0);
+    result = (*ps->ChangePictureClip) (pPicture, type, (void *) clientClip, 0);
     if (result == Success) {
         pPicture->clipOrigin.x = xOrigin;
         pPicture->clipOrigin.y = yOrigin;
@@ -1354,7 +1354,7 @@ CopyPicture(PicturePtr pSrc, Mask mask, PicturePtr pDst)
                 pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
                 pSrc->alphaMap->refcnt++;
             if (pDst->alphaMap)
-                FreePicture((pointer) pDst->alphaMap, (XID) 0);
+                FreePicture((void *) pDst->alphaMap, (XID) 0);
             pDst->alphaMap = pSrc->alphaMap;
             break;
         case CPAlphaXOrigin:
@@ -1435,7 +1435,7 @@ ValidatePicture(PicturePtr pPicture)
 }
 
 int
-FreePicture(pointer value, XID pid)
+FreePicture(void *value, XID pid)
 {
     PicturePtr pPicture = (PicturePtr) value;
 
@@ -1454,7 +1454,7 @@ FreePicture(pointer value, XID pid)
             PictureScreenPtr ps = GetPictureScreen(pScreen);
 
             if (pPicture->alphaMap)
-                FreePicture((pointer) pPicture->alphaMap, (XID) 0);
+                FreePicture((void *) pPicture->alphaMap, (XID) 0);
             (*ps->DestroyPicture) (pPicture);
             (*ps->DestroyPictureClip) (pPicture);
             if (pPicture->pDrawable->type == DRAWABLE_WINDOW) {
@@ -1480,7 +1480,7 @@ FreePicture(pointer value, XID pid)
 }
 
 int
-FreePictFormat(pointer pPictFormat, XID pid)
+FreePictFormat(void *pPictFormat, XID pid)
 {
     return Success;
 }
diff --git a/render/picturestr.h b/render/picturestr.h
index 5644f28..8c8100d 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -145,7 +145,7 @@ typedef struct _Picture {
     DDXPointRec alphaOrigin;
 
     DDXPointRec clipOrigin;
-    pointer clientClip;
+    void *clientClip;
 
     unsigned long serialNumber;
 
@@ -189,7 +189,7 @@ typedef struct {
 typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
 typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
 typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
-                                         int clipType, pointer value, int n);
+                                         int clipType, void *value, int n);
 typedef void (*DestroyPictureClipProcPtr) (PicturePtr pPicture);
 
 typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
@@ -363,7 +363,7 @@ extern _X_EXPORT RESTYPE GlyphSetType;
 #define SetPictureWindow(w,p) dixSetPrivate(&(w)->devPrivates, PictureWindowPrivateKey, p)
 
 #define VERIFY_PICTURE(pPicture, pid, client, mode) {\
-    int tmprc = dixLookupResourceByType((pointer)&(pPicture), pid,\
+    int tmprc = dixLookupResourceByType((void *)&(pPicture), pid,\
 	                                PictureType, client, mode);\
     if (tmprc != Success)\
 	return tmprc;\
@@ -482,10 +482,10 @@ extern _X_EXPORT void
  ValidatePicture(PicturePtr pPicture);
 
 extern _X_EXPORT int
- FreePicture(pointer pPicture, XID pid);
+ FreePicture(void *pPicture, XID pid);
 
 extern _X_EXPORT int
- FreePictFormat(pointer pPictFormat, XID pid);
+ FreePictFormat(void *pPictFormat, XID pid);
 
 extern _X_EXPORT void
 
diff --git a/render/render.c b/render/render.c
index 51f75ae..3b7151a 100644
--- a/render/render.c
+++ b/render/render.c
@@ -220,7 +220,7 @@ typedef struct _RenderClient {
 #define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey))
 
 static void
-RenderClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+RenderClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
@@ -520,7 +520,7 @@ ProcRenderQueryPictIndexValues(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
 
-    rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
+    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
                                  PictFormatType, client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -587,7 +587,7 @@ ProcRenderCreatePicture(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    rc = dixLookupResourceByType((pointer *) &pFormat, stuff->format,
+    rc = dixLookupResourceByType((void **) &pFormat, stuff->format,
                                  PictFormatType, client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -604,7 +604,7 @@ ProcRenderCreatePicture(ClientPtr client)
                              stuff->mask, (XID *) (stuff + 1), client, &error);
     if (!pPicture)
         return error;
-    if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
+    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
         return BadAlloc;
     return Success;
 }
@@ -744,7 +744,7 @@ ProcRenderTrapezoids(ClientPtr client)
     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
         return BadMatch;
     if (stuff->maskFormat) {
-        rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
+        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
                                      PictFormatType, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -783,7 +783,7 @@ ProcRenderTriangles(ClientPtr client)
     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
         return BadMatch;
     if (stuff->maskFormat) {
-        rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
+        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
                                      PictFormatType, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -822,7 +822,7 @@ ProcRenderTriStrip(ClientPtr client)
     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
         return BadMatch;
     if (stuff->maskFormat) {
-        rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
+        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
                                      PictFormatType, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -861,7 +861,7 @@ ProcRenderTriFan(ClientPtr client)
     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
         return BadMatch;
     if (stuff->maskFormat) {
-        rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
+        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
                                      PictFormatType, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -909,7 +909,7 @@ ProcRenderCreateGlyphSet(ClientPtr client)
     REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
 
     LEGAL_NEW_RESOURCE(stuff->gsid, client);
-    rc = dixLookupResourceByType((pointer *) &format, stuff->format,
+    rc = dixLookupResourceByType((void **) &format, stuff->format,
                                  PictFormatType, client, DixReadAccess);
     if (rc != Success)
         return rc;
@@ -943,7 +943,7 @@ ProcRenderCreateGlyphSet(ClientPtr client)
                   glyphSet, RT_NONE, NULL, DixCreateAccess);
     if (rc != Success)
         return rc;
-    if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
+    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
         return BadAlloc;
     return Success;
 }
@@ -960,14 +960,14 @@ ProcRenderReferenceGlyphSet(ClientPtr client)
 
     LEGAL_NEW_RESOURCE(stuff->gsid, client);
 
-    rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->existing,
+    rc = dixLookupResourceByType((void **) &glyphSet, stuff->existing,
                                  GlyphSetType, client, DixGetAttrAccess);
     if (rc != Success) {
         client->errorValue = stuff->existing;
         return rc;
     }
     glyphSet->refcnt++;
-    if (!AddResource(stuff->gsid, GlyphSetType, (pointer) glyphSet))
+    if (!AddResource(stuff->gsid, GlyphSetType, (void *) glyphSet))
         return BadAlloc;
     return Success;
 }
@@ -984,7 +984,7 @@ ProcRenderFreeGlyphSet(ClientPtr client)
     REQUEST(xRenderFreeGlyphSetReq);
 
     REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
-    rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
+    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
                                  GlyphSetType, client, DixDestroyAccess);
     if (rc != Success) {
         client->errorValue = stuff->glyphset;
@@ -1024,7 +1024,7 @@ ProcRenderAddGlyphs(ClientPtr client)
 
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     err =
-        dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
+        dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
                                 GlyphSetType, client, DixAddAccess);
     if (err != Success) {
         client->errorValue = stuff->glyphset;
@@ -1157,7 +1157,7 @@ ProcRenderAddGlyphs(ClientPtr client)
                                  pSrc,
                                  None, pDst, 0, 0, 0, 0, 0, 0, width, height);
 
-                FreePicture((pointer) pSrc, 0);
+                FreePicture((void *) pSrc, 0);
                 pSrc = NULL;
                 FreeScratchPixmapHeader(pSrcPix);
                 pSrcPix = NULL;
@@ -1189,7 +1189,7 @@ ProcRenderAddGlyphs(ClientPtr client)
     return Success;
  bail:
     if (pSrc)
-        FreePicture((pointer) pSrc, 0);
+        FreePicture((void *) pSrc, 0);
     if (pSrcPix)
         FreeScratchPixmapHeader(pSrcPix);
     for (i = 0; i < nglyphs; i++)
@@ -1216,7 +1216,7 @@ ProcRenderFreeGlyphs(ClientPtr client)
     CARD32 glyph;
 
     REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
-    rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
+    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
                                  GlyphSetType, client, DixRemoveAccess);
     if (rc != Success) {
         client->errorValue = stuff->glyphset;
@@ -1282,7 +1282,7 @@ ProcRenderCompositeGlyphs(ClientPtr client)
     if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
         return BadMatch;
     if (stuff->maskFormat) {
-        rc = dixLookupResourceByType((pointer *) &pFormat, stuff->maskFormat,
+        rc = dixLookupResourceByType((void **) &pFormat, stuff->maskFormat,
                                      PictFormatType, client, DixReadAccess);
         if (rc != Success)
             return rc;
@@ -1290,7 +1290,7 @@ ProcRenderCompositeGlyphs(ClientPtr client)
     else
         pFormat = 0;
 
-    rc = dixLookupResourceByType((pointer *) &glyphSet, stuff->glyphset,
+    rc = dixLookupResourceByType((void **) &glyphSet, stuff->glyphset,
                                  GlyphSetType, client, DixUseAccess);
     if (rc != Success)
         return rc;
@@ -1341,7 +1341,7 @@ ProcRenderCompositeGlyphs(ClientPtr client)
         if (elt->len == 0xff) {
             if (buffer + sizeof(GlyphSet) < end) {
                 memcpy(&gs, buffer, sizeof(GlyphSet));
-                rc = dixLookupResourceByType((pointer *) &glyphSet, gs,
+                rc = dixLookupResourceByType((void **) &glyphSet, gs,
                                              GlyphSetType, client,
                                              DixUseAccess);
                 if (rc != Success)
@@ -1508,7 +1508,7 @@ ProcRenderCreateCursor(ClientPtr client)
     if (pSrc->format == PICT_a8r8g8b8) {
         (*pScreen->GetImage) (pSrc->pDrawable,
                               0, 0, width, height, ZPixmap,
-                              0xffffffff, (pointer) argbbits);
+                              0xffffffff, (void *) argbbits);
     }
     else {
         PixmapPtr pPixmap;
@@ -1544,7 +1544,7 @@ ProcRenderCreateCursor(ClientPtr client)
                          pSrc, 0, pPicture, 0, 0, 0, 0, 0, 0, width, height);
         (*pScreen->GetImage) (pPicture->pDrawable,
                               0, 0, width, height, ZPixmap,
-                              0xffffffff, (pointer) argbbits);
+                              0xffffffff, (void *) argbbits);
         FreePicture(pPicture, 0);
     }
     /*
@@ -1633,7 +1633,7 @@ ProcRenderCreateCursor(ClientPtr client)
                          &pCursor, client, stuff->cid);
     if (rc != Success)
         goto bail;
-    if (!AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor)) {
+    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
         rc = BadAlloc;
         goto bail;
     }
@@ -1799,7 +1799,7 @@ ProcRenderCreateAnimCursor(ClientPtr client)
     deltas = (CARD32 *) (cursors + ncursor);
     elt = (xAnimCursorElt *) (stuff + 1);
     for (i = 0; i < ncursor; i++) {
-        ret = dixLookupResourceByType((pointer *) (cursors + i), elt->cursor,
+        ret = dixLookupResourceByType((void **) (cursors + i), elt->cursor,
                                       RT_CURSOR, client, DixReadAccess);
         if (ret != Success) {
             free(cursors);
@@ -1814,7 +1814,7 @@ ProcRenderCreateAnimCursor(ClientPtr client)
     if (ret != Success)
         return ret;
 
-    if (AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor))
+    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
         return Success;
     return BadAlloc;
 }
@@ -1861,7 +1861,7 @@ ProcRenderCreateSolidFill(ClientPtr client)
                      pPicture, RT_NONE, NULL, DixCreateAccess);
     if (error != Success)
         return error;
-    if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
+    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
         return BadAlloc;
     return Success;
 }
@@ -1900,7 +1900,7 @@ ProcRenderCreateLinearGradient(ClientPtr client)
                      pPicture, RT_NONE, NULL, DixCreateAccess);
     if (error != Success)
         return error;
-    if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
+    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
         return BadAlloc;
     return Success;
 }
@@ -1938,7 +1938,7 @@ ProcRenderCreateRadialGradient(ClientPtr client)
                      pPicture, RT_NONE, NULL, DixCreateAccess);
     if (error != Success)
         return error;
-    if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
+    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
         return BadAlloc;
     return Success;
 }
@@ -1975,7 +1975,7 @@ ProcRenderCreateConicalGradient(ClientPtr client)
                      pPicture, RT_NONE, NULL, DixCreateAccess);
     if (error != Success)
         return error;
-    if (!AddResource(stuff->pid, PictureType, (pointer) pPicture))
+    if (!AddResource(stuff->pid, PictureType, (void *) pPicture))
         return BadAlloc;
     return Success;
 }
@@ -2566,7 +2566,7 @@ SProcRenderDispatch(ClientPtr client)
 
 #ifdef PANORAMIX
 #define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\
-    int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\
+    int rc = dixLookupResourceByType((void **)&(pPicture), pid,\
                                      XRT_PICTURE, client, mode);\
     if (rc != Success)\
 	return rc;\
@@ -2590,7 +2590,7 @@ PanoramiXRenderCreatePicture(ClientPtr client)
     int result, j;
 
     REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
-    result = dixLookupResourceByClass((pointer *) &refDraw, stuff->drawable,
+    result = dixLookupResourceByClass((void **) &refDraw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
         return (result == BadValue) ? BadDrawable : result;
diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c
index 0947898..e171115 100644
--- a/test/xi2/protocol-common.c
+++ b/test/xi2/protocol-common.c
@@ -251,7 +251,7 @@ init_simple(void)
     init_window(&window, &root, CLIENT_WINDOW_ID);
 
     serverClient = &server_client;
-    InitClient(serverClient, 0, (pointer) NULL);
+    InitClient(serverClient, 0, (void *) NULL);
     if (!InitClientResources(serverClient)) /* for root resources */
         FatalError("couldn't init server resources");
     SyncExtensionInit();
diff --git a/test/xi2/protocol-common.h b/test/xi2/protocol-common.h
index f27f248..d303068 100644
--- a/test/xi2/protocol-common.h
+++ b/test/xi2/protocol-common.h
@@ -148,7 +148,7 @@ int __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client,
                            Mask access);
 int __real_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client,
                            Mask access);
-Bool __wrap_AddResource(XID id, RESTYPE type, pointer value);
+Bool __wrap_AddResource(XID id, RESTYPE type, void *value);
 int __wrap_dixLookupClient(ClientPtr *c, XID id, ClientPtr client, Mask access);
 int __real_dixLookupClient(ClientPtr *c, XID id, ClientPtr client, Mask access);
 
diff --git a/test/xi2/protocol-xigetselectedevents.c b/test/xi2/protocol-xigetselectedevents.c
index fc33aa5..bedc217 100644
--- a/test/xi2/protocol-xigetselectedevents.c
+++ b/test/xi2/protocol-xigetselectedevents.c
@@ -82,7 +82,7 @@ __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access)
 
 /* AddResource is called from XISetSEventMask, we don't need this */
 Bool
-__wrap_AddResource(XID id, RESTYPE type, pointer value)
+__wrap_AddResource(XID id, RESTYPE type, void *value)
 {
     return TRUE;
 }
diff --git a/test/xtest.c b/test/xtest.c
index e5e5241..e9fabfb 100644
--- a/test/xtest.c
+++ b/test/xtest.c
@@ -71,7 +71,7 @@ xtest_init_devices(void)
     screen.DeviceCursorCleanup = device_cursor_cleanup;
     dixResetPrivates();
     serverClient = &server_client;
-    InitClient(serverClient, 0, (pointer) NULL);
+    InitClient(serverClient, 0, (void *) NULL);
     if (!InitClientResources(serverClient)) /* for root resources */
         FatalError("couldn't init server resources");
     InitAtoms();
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 753d5f7..2c4b57c 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -72,7 +72,7 @@ static void deleteCursorHideCountsForScreen(ScreenPtr pScreen);
 #define VERIFY_CURSOR(pCursor, cursor, client, access)			\
     do {								\
 	int err;							\
-	err = dixLookupResourceByType((pointer *) &pCursor, cursor,	\
+	err = dixLookupResourceByType((void **) &pCursor, cursor,	\
 				      RT_CURSOR, client, access);	\
 	if (err != Success) {						\
 	    client->errorValue = cursor;				\
@@ -195,7 +195,7 @@ static int
 XFixesSelectCursorInput(ClientPtr pClient, WindowPtr pWindow, CARD32 eventMask)
 {
     CursorEventPtr *prev, e;
-    pointer val;
+    void *val;
     int rc;
 
     for (prev = &cursorEvents; (e = *prev); prev = &e->next) {
@@ -228,12 +228,12 @@ XFixesSelectCursorInput(ClientPtr pClient, WindowPtr pWindow, CARD32 eventMask)
                                      DixGetAttrAccess);
         if (rc != Success)
             if (!AddResource(pWindow->drawable.id, CursorWindowType,
-                             (pointer) pWindow)) {
+                             (void *) pWindow)) {
                 free(e);
                 return BadAlloc;
             }
 
-        if (!AddResource(e->clientResource, CursorClientType, (pointer) e))
+        if (!AddResource(e->clientResource, CursorClientType, (void *) e))
             return BadAlloc;
 
         *prev = e;
@@ -568,13 +568,13 @@ SProcXFixesGetCursorImageAndName(ClientPtr client)
  * whether it should be replaced with a reference to pCursor.
  */
 
-typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure);
+typedef Bool (*TestCursorFunc) (CursorPtr pOld, void *closure);
 
 typedef struct {
     RESTYPE type;
     TestCursorFunc testCursor;
     CursorPtr pNew;
-    pointer closure;
+    void *closure;
 } ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
 
 static const RESTYPE CursorRestypes[] = {
@@ -584,7 +584,7 @@ static const RESTYPE CursorRestypes[] = {
 #define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
 
 static Bool
-ReplaceCursorLookup(pointer value, XID id, pointer closure)
+ReplaceCursorLookup(void *value, XID id, void *closure)
 {
     ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure;
     WindowPtr pWin;
@@ -626,7 +626,7 @@ ReplaceCursorLookup(pointer value, XID id, pointer closure)
 }
 
 static void
-ReplaceCursor(CursorPtr pCursor, TestCursorFunc testCursor, pointer closure)
+ReplaceCursor(CursorPtr pCursor, TestCursorFunc testCursor, void *closure)
 {
     int clientIndex;
     int resIndex;
@@ -652,7 +652,7 @@ ReplaceCursor(CursorPtr pCursor, TestCursorFunc testCursor, pointer closure)
              */
             LookupClientResourceComplex(clients[clientIndex],
                                         rcl.type,
-                                        ReplaceCursorLookup, (pointer) &rcl);
+                                        ReplaceCursorLookup, (void *) &rcl);
         }
     }
     /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
@@ -660,7 +660,7 @@ ReplaceCursor(CursorPtr pCursor, TestCursorFunc testCursor, pointer closure)
 }
 
 static Bool
-TestForCursor(CursorPtr pCursor, pointer closure)
+TestForCursor(CursorPtr pCursor, void *closure)
 {
     return (pCursor == (CursorPtr) closure);
 }
@@ -678,7 +678,7 @@ ProcXFixesChangeCursor(ClientPtr client)
     VERIFY_CURSOR(pDestination, stuff->destination, client,
                   DixWriteAccess | DixSetAttrAccess);
 
-    ReplaceCursor(pSource, TestForCursor, (pointer) pDestination);
+    ReplaceCursor(pSource, TestForCursor, (void *) pDestination);
     return Success;
 }
 
@@ -695,7 +695,7 @@ SProcXFixesChangeCursor(ClientPtr client)
 }
 
 static Bool
-TestForCursorName(CursorPtr pCursor, pointer closure)
+TestForCursorName(CursorPtr pCursor, void *closure)
 {
     Atom *pName = closure;
 
@@ -776,7 +776,7 @@ createCursorHideCount(ClientPtr pClient, ScreenPtr pScreen)
      * Create a resource for this element so it can be deleted
      * when the client goes away.
      */
-    if (!AddResource(pChc->resource, CursorHideCountType, (pointer) pChc)) {
+    if (!AddResource(pChc->resource, CursorHideCountType, (void *) pChc)) {
         free(pChc);
         return BadAlloc;
     }
@@ -841,7 +841,7 @@ ProcXFixesHideCursor(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXFixesHideCursorReq);
 
-    ret = dixLookupResourceByType((pointer *) &pWin, stuff->window, RT_WINDOW,
+    ret = dixLookupResourceByType((void **) &pWin, stuff->window, RT_WINDOW,
                                   client, DixGetAttrAccess);
     if (ret != Success) {
         client->errorValue = stuff->window;
@@ -905,7 +905,7 @@ ProcXFixesShowCursor(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXFixesShowCursorReq);
 
-    rc = dixLookupResourceByType((pointer *) &pWin, stuff->window, RT_WINDOW,
+    rc = dixLookupResourceByType((void **) &pWin, stuff->window, RT_WINDOW,
                                  client, DixGetAttrAccess);
     if (rc != Success) {
         client->errorValue = stuff->window;
@@ -946,7 +946,7 @@ SProcXFixesShowCursor(ClientPtr client)
 }
 
 static int
-CursorFreeClient(pointer data, XID id)
+CursorFreeClient(void *data, XID id)
 {
     CursorEventPtr old = (CursorEventPtr) data;
     CursorEventPtr *prev, e;
@@ -962,7 +962,7 @@ CursorFreeClient(pointer data, XID id)
 }
 
 static int
-CursorFreeHideCount(pointer data, XID id)
+CursorFreeHideCount(void *data, XID id)
 {
     CursorHideCountPtr pChc = (CursorHideCountPtr) data;
     ScreenPtr pScreen = pChc->pScreen;
@@ -978,7 +978,7 @@ CursorFreeHideCount(pointer data, XID id)
 }
 
 static int
-CursorFreeWindow(pointer data, XID id)
+CursorFreeWindow(void *data, XID id)
 {
     WindowPtr pWindow = (WindowPtr) data;
     CursorEventPtr e, next;
diff --git a/xfixes/region.c b/xfixes/region.c
index 14a02ba..cc8f1a5 100644
--- a/xfixes/region.c
+++ b/xfixes/region.c
@@ -35,7 +35,7 @@
 RESTYPE RegionResType;
 
 static int
-RegionResFree(pointer data, XID id)
+RegionResFree(void *data, XID id)
 {
     RegionPtr pRegion = (RegionPtr) data;
 
@@ -85,7 +85,7 @@ ProcXFixesCreateRegion(ClientPtr client)
     pRegion = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
     if (!pRegion)
         return BadAlloc;
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -115,7 +115,7 @@ ProcXFixesCreateRegionFromBitmap(ClientPtr client)
     REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq);
     LEGAL_NEW_RESOURCE(stuff->region, client);
 
-    rc = dixLookupResourceByType((pointer *) &pPixmap, stuff->bitmap, RT_PIXMAP,
+    rc = dixLookupResourceByType((void **) &pPixmap, stuff->bitmap, RT_PIXMAP,
                                  client, DixReadAccess);
     if (rc != Success) {
         client->errorValue = stuff->bitmap;
@@ -129,7 +129,7 @@ ProcXFixesCreateRegionFromBitmap(ClientPtr client)
     if (!pRegion)
         return BadAlloc;
 
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -159,7 +159,7 @@ ProcXFixesCreateRegionFromWindow(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq);
     LEGAL_NEW_RESOURCE(stuff->region, client);
-    rc = dixLookupResourceByType((pointer *) &pWin, stuff->window, RT_WINDOW,
+    rc = dixLookupResourceByType((void **) &pWin, stuff->window, RT_WINDOW,
                                  client, DixGetAttrAccess);
     if (rc != Success) {
         client->errorValue = stuff->window;
@@ -188,7 +188,7 @@ ProcXFixesCreateRegionFromWindow(ClientPtr client)
         pRegion = XFixesRegionCopy(pRegion);
     if (!pRegion)
         return BadAlloc;
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -238,7 +238,7 @@ ProcXFixesCreateRegionFromGC(ClientPtr client)
         return BadImplementation;       /* assume sane server bits */
     }
 
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -285,7 +285,7 @@ ProcXFixesCreateRegionFromPicture(ClientPtr client)
         return BadImplementation;       /* assume sane server bits */
     }
 
-    if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
+    if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
         return BadAlloc;
 
     return Success;
@@ -629,7 +629,7 @@ ProcXFixesSetGCClipRegion(ClientPtr client)
     vals[1].val = stuff->yOrigin;
     ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals);
     (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE,
-                               (pointer) pRegion, 0);
+                               (void *) pRegion, 0);
 
     return Success;
 }
@@ -661,7 +661,7 @@ ProcXFixesSetWindowShapeRegion(ClientPtr client)
     REQUEST(xXFixesSetWindowShapeRegionReq);
 
     REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
-    rc = dixLookupResourceByType((pointer *) &pWin, stuff->dest, RT_WINDOW,
+    rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW,
                                  client, DixSetAttrAccess);
     if (rc != Success) {
         client->errorValue = stuff->dest;
diff --git a/xfixes/select.c b/xfixes/select.c
index ee8ed6f..c088ed3 100644
--- a/xfixes/select.c
+++ b/xfixes/select.c
@@ -51,7 +51,7 @@ typedef struct _SelectionEvent {
 static SelectionEventPtr selectionEvents;
 
 static void
-XFixesSelectionCallback(CallbackListPtr *callbacks, pointer data, pointer args)
+XFixesSelectionCallback(CallbackListPtr *callbacks, void *data, void *args)
 {
     SelectionEventPtr e;
     SelectionInfoRec *info = (SelectionInfoRec *) args;
@@ -119,7 +119,7 @@ static int
 XFixesSelectSelectionInput(ClientPtr pClient,
                            Atom selection, WindowPtr pWindow, CARD32 eventMask)
 {
-    pointer val;
+    void *val;
     int rc;
     SelectionEventPtr *prev, e;
 
@@ -159,12 +159,12 @@ XFixesSelectSelectionInput(ClientPtr pClient,
                                      DixGetAttrAccess);
         if (rc != Success)
             if (!AddResource(pWindow->drawable.id, SelectionWindowType,
-                             (pointer) pWindow)) {
+                             (void *) pWindow)) {
                 free(e);
                 return BadAlloc;
             }
 
-        if (!AddResource(e->clientResource, SelectionClientType, (pointer) e))
+        if (!AddResource(e->clientResource, SelectionClientType, (void *) e))
             return BadAlloc;
 
         *prev = e;
@@ -222,7 +222,7 @@ SXFixesSelectionNotifyEvent(xXFixesSelectionNotifyEvent * from,
 }
 
 static int
-SelectionFreeClient(pointer data, XID id)
+SelectionFreeClient(void *data, XID id)
 {
     SelectionEventPtr old = (SelectionEventPtr) data;
     SelectionEventPtr *prev, e;
@@ -239,7 +239,7 @@ SelectionFreeClient(pointer data, XID id)
 }
 
 static int
-SelectionFreeWindow(pointer data, XID id)
+SelectionFreeWindow(void *data, XID id)
 {
     WindowPtr pWindow = (WindowPtr) data;
     SelectionEventPtr e, next;
diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c
index 48af9ea..3307f87 100644
--- a/xfixes/xfixes.c
+++ b/xfixes/xfixes.c
@@ -213,7 +213,7 @@ SProcXFixesDispatch(ClientPtr client)
 }
 
 static void
-XFixesClientCallback(CallbackListPtr *list, pointer closure, pointer data)
+XFixesClientCallback(CallbackListPtr *list, void *closure, void *data)
 {
     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
     ClientPtr pClient = clientinfo->client;
diff --git a/xfixes/xfixes.h b/xfixes/xfixes.h
index 9882871..fdcf44f 100644
--- a/xfixes/xfixes.h
+++ b/xfixes/xfixes.h
@@ -35,7 +35,7 @@ extern _X_EXPORT int XFixesErrorBase;
 #define VERIFY_REGION(pRegion, rid, client, mode)			\
     do {								\
 	int err;							\
-	err = dixLookupResourceByType((pointer *) &pRegion, rid,	\
+	err = dixLookupResourceByType((void **) &pRegion, rid,	\
 				      RegionResType, client, mode);	\
 	if (err != Success) {						\
 	    client->errorValue = rid;					\
diff --git a/xkb/ddxBeep.c b/xkb/ddxBeep.c
index f95d0ee..caf78c9 100644
--- a/xkb/ddxBeep.c
+++ b/xkb/ddxBeep.c
@@ -113,7 +113,7 @@ _XkbDDXBeepInitAtoms(void)
 }
 
 static CARD32
-_XkbDDXBeepExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+_XkbDDXBeepExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     DeviceIntPtr dev = (DeviceIntPtr) arg;
     KbdFeedbackPtr feed;
@@ -300,11 +300,11 @@ _XkbDDXBeepExpire(OsTimerPtr timer, CARD32 now, pointer arg)
         ctrl->bell_duration = duration;
         ctrl->bell_pitch = pitch;
         if (xkbInfo->beepCount == 0) {
-            XkbHandleBell(0, 0, dev, ctrl->bell, (pointer) ctrl,
+            XkbHandleBell(0, 0, dev, ctrl->bell, (void *) ctrl,
                           KbdFeedbackClass, name, None, NULL);
         }
         else if (xkbInfo->desc->ctrls->enabled_ctrls & XkbAudibleBellMask) {
-            (*dev->kbdfeed->BellProc) (ctrl->bell, dev, (pointer) ctrl,
+            (*dev->kbdfeed->BellProc) (ctrl->bell, dev, (void *) ctrl,
                                        KbdFeedbackClass);
         }
         ctrl->bell_duration = oldDuration;
@@ -340,11 +340,11 @@ XkbDDXAccessXBeep(DeviceIntPtr dev, unsigned what, unsigned which)
 
     xkbInfo->beepType = what;
     xkbInfo->beepCount = 0;
-    next = _XkbDDXBeepExpire(NULL, 0, (pointer) dev);
+    next = _XkbDDXBeepExpire(NULL, 0, (void *) dev);
     if (next > 0) {
         xkbInfo->beepTimer = TimerSet(xkbInfo->beepTimer,
                                       0, next,
-                                      _XkbDDXBeepExpire, (pointer) dev);
+                                      _XkbDDXBeepExpire, (void *) dev);
     }
     return 1;
 }
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 27e761c..31bb8d3 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -370,7 +370,7 @@ _XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
          int percent, int forceSound, int eventOnly, Atom name)
 {
     int base;
-    pointer ctrl;
+    void *ctrl;
     int oldPitch, oldDuration;
     int newPercent;
 
@@ -390,7 +390,7 @@ _XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
             return BadValue;
         }
         base = k->ctrl.bell;
-        ctrl = (pointer) &(k->ctrl);
+        ctrl = (void *) &(k->ctrl);
         oldPitch = k->ctrl.bell_pitch;
         oldDuration = k->ctrl.bell_duration;
         if (pitch != 0) {
@@ -422,7 +422,7 @@ _XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
             return BadValue;
         }
         base = b->ctrl.percent;
-        ctrl = (pointer) &(b->ctrl);
+        ctrl = (void *) &(b->ctrl);
         oldPitch = b->ctrl.pitch;
         oldDuration = b->ctrl.duration;
         if (pitch != 0) {
@@ -6820,7 +6820,7 @@ ProcXkbDispatch(ClientPtr client)
 }
 
 static int
-XkbClientGone(pointer data, XID id)
+XkbClientGone(void *data, XID id)
 {
     DevicePtr pXDev = (DevicePtr) data;
 
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 13051e0..cb4bca0 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -279,7 +279,7 @@ AccessXStickyKeysTurnOff(DeviceIntPtr dev, xkbControlsNotify * pCN)
 }                               /* AccessXStickyKeysTurnOff */
 
 static CARD32
-AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+AccessXKRGExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     xkbControlsNotify cn;
     DeviceIntPtr dev = arg;
@@ -309,7 +309,7 @@ AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 }
 
 static CARD32
-AccessXRepeatKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+AccessXRepeatKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     DeviceIntPtr dev = (DeviceIntPtr) arg;
     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
@@ -331,7 +331,7 @@ AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi, KeyCode key)
 }
 
 static CARD32
-AccessXSlowKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+AccessXSlowKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     DeviceIntPtr keybd;
     XkbSrvInfoPtr xkbi;
@@ -370,7 +370,7 @@ AccessXSlowKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
                 xkbi->repeatKeyTimer = TimerSet(xkbi->repeatKeyTimer,
                                                 0, ctrls->repeat_delay,
                                                 AccessXRepeatKeyExpire,
-                                                (pointer) keybd);
+                                                (void *) keybd);
             }
         }
     }
@@ -378,7 +378,7 @@ AccessXSlowKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 }
 
 static CARD32
-AccessXBounceKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+AccessXBounceKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     XkbSrvInfoPtr xkbi = ((DeviceIntPtr) arg)->key->xkbInfo;
 
@@ -387,7 +387,7 @@ AccessXBounceKeyExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 }
 
 static CARD32
-AccessXTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+AccessXTimeoutExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     DeviceIntPtr dev = (DeviceIntPtr) arg;
     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
@@ -467,12 +467,12 @@ AccessXFilterPressEvent(DeviceEvent *event, DeviceIntPtr keybd)
             if (XkbAX_NeedFeedback(ctrls, XkbAX_SlowWarnFBMask)) {
                 xkbi->krgTimerActive = _KRG_WARN_TIMER;
                 xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 4000,
-                                          AccessXKRGExpire, (pointer) keybd);
+                                          AccessXKRGExpire, (void *) keybd);
             }
             else {
                 xkbi->krgTimerActive = _KRG_TIMER;
                 xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 8000,
-                                          AccessXKRGExpire, (pointer) keybd);
+                                          AccessXKRGExpire, (void *) keybd);
             }
             if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) {
                 CARD32 now = GetTimeInMillis();
@@ -514,7 +514,7 @@ AccessXFilterPressEvent(DeviceEvent *event, DeviceIntPtr keybd)
         xkbi->slowKey = key;
         xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer,
                                        0, ctrls->slow_keys_delay,
-                                       AccessXSlowKeyExpire, (pointer) keybd);
+                                       AccessXSlowKeyExpire, (void *) keybd);
         ignoreKeyEvent = TRUE;
     }
 
@@ -546,7 +546,7 @@ AccessXFilterPressEvent(DeviceEvent *event, DeviceIntPtr keybd)
                     xkbi->repeatKeyTimer = TimerSet(xkbi->repeatKeyTimer,
                                                     0, ctrls->repeat_delay,
                                                     AccessXRepeatKeyExpire,
-                                                    (pointer) keybd);
+                                                    (void *) keybd);
                 }
             }
         }
@@ -608,7 +608,7 @@ AccessXFilterReleaseEvent(DeviceEvent *event, DeviceIntPtr keybd)
         xkbi->bounceKeysTimer = TimerSet(xkbi->bounceKeysTimer, 0,
                                          ctrls->debounce_delay,
                                          AccessXBounceKeyExpire,
-                                         (pointer) keybd);
+                                         (void *) keybd);
     }
 
     /* Don't transmit the KeyRelease if SlowKeys is turned on and
@@ -651,7 +651,7 @@ AccessXFilterReleaseEvent(DeviceEvent *event, DeviceIntPtr keybd)
         xkbi->lastPtrEventTime = 0;
         xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0,
                                   ctrls->ax_timeout * 1000,
-                                  AccessXTimeoutExpire, (pointer) keybd);
+                                  AccessXTimeoutExpire, (void *) keybd);
         xkbi->krgTimerActive = _ALL_TIMEOUT_TIMER;
     }
     else if (xkbi->krgTimerActive != _OFF_TIMER) {
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index e32005c..1443498 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -51,7 +51,7 @@ static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
                                  int y);
 
 void
-xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, pointer data)
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
 {
     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
     ProcessInputProc backupproc;
@@ -470,7 +470,7 @@ _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
 }
 
 static CARD32
-_XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, pointer arg)
+_XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
 {
     XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
     XkbControlsPtr ctrls = xkbi->desc->ctrls;
@@ -540,7 +540,7 @@ _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
         xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
         xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
                                        xkbi->desc->ctrls->mk_delay,
-                                       _XkbPtrAccelExpire, (pointer) xkbi);
+                                       _XkbPtrAccelExpire, (void *) xkbi);
     }
     else if (filter->keycode == keycode) {
         filter->active = 0;
diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index 87a4485..210d8eb 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -482,7 +482,7 @@ XkbHandleBell(BOOL force,
               BOOL eventOnly,
               DeviceIntPtr kbd,
               CARD8 percent,
-              pointer pCtrl,
+              void *pCtrl,
               CARD8 class, Atom name, WindowPtr pWin, ClientPtr pClient)
 {
     xkbBellNotify bn;
@@ -502,7 +502,7 @@ XkbHandleBell(BOOL force,
     if ((force || (xkbi->desc->ctrls->enabled_ctrls & XkbAudibleBellMask)) &&
         (!eventOnly)) {
         if (kbd->kbdfeed->BellProc)
-            (*kbd->kbdfeed->BellProc) (percent, kbd, (pointer) pCtrl, class);
+            (*kbd->kbdfeed->BellProc) (percent, kbd, (void *) pCtrl, class);
     }
     interest = kbd->xkb_interest;
     if ((!interest) || (force))
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index ca3831c..22b971f 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -142,7 +142,7 @@ XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
 }
 
 static Bool
-XkbWriteRulesProp(ClientPtr client, pointer closure)
+XkbWriteRulesProp(ClientPtr client, void *closure)
 {
     int len, out;
     Atom name;
commit 93fa64e17d7bd600ebf18ecab85f5b2d17fe30ce
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 12:18:49 2013 -0800

    Don't build dmx by default
    
    It's clearly un-loved, having piles and piles of warnings. If someone
    wants to fix it up to compile without warnings, we can re-enable it.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/configure.ac b/configure.ac
index c9f0192..234cf21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -632,7 +632,7 @@ AC_ARG_ENABLE(linux_apm, AC_HELP_STRING([--disable-linux-apm], [Disable building
 
 dnl DDXes.
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
-AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto])
+AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=no])
 AC_ARG_ENABLE(xvfb,    	      AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
 AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
 AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
commit 319dff750f99a28a1544bcb81d52172c641ad1ca
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 12:18:16 2013 -0800

    hw/xfree86: nobus.c shouldn't define a static function
    
    Having this function be static generates a compiler warning.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/os-support/bus/nobus.c b/hw/xfree86/os-support/bus/nobus.c
index dc36ecd..4872c5b 100644
--- a/hw/xfree86/os-support/bus/nobus.c
+++ b/hw/xfree86/os-support/bus/nobus.c
@@ -1,4 +1,7 @@
-static void
+void
+__noop_to_appease_ar__(void);
+
+void
 __noop_to_appease_ar__(void)
 {
     return;
commit 7915791bac3ff609e94f355fbb637d7c570a5b32
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 12:17:45 2013 -0800

    kdrive/ephyr; Don't redeclare monitorResolution
    
    It's already declared in globals.h
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 3e01a47..44ad8e2 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -85,8 +85,6 @@ static int HostXWantDamageDebug = 0;
 
 extern EphyrKeySyms ephyrKeySyms;
 
-extern int monitorResolution;
-
 extern Bool EphyrWantResize;
 
 char *ephyrResName = NULL;
commit aa47a4409660634d80c3423ad49b70ca929a8756
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 12:16:51 2013 -0800

    kdrive/ephyr: ddxUseMsg is supposed to return
    
    I'm not sure why ephyr thinks that ddxUseMsg shouldn't return, but
    it's not declared to exit.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index cf8bc90..3230e70 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -149,8 +149,6 @@ ddxUseMsg(void)
     ErrorF
         ("-title [title]       set the window title in the WM_NAME property\n");
     ErrorF("\n");
-
-    exit(1);
 }
 
 void
commit 86d68825c2b75ea9e10954fec00b44b33b38d8b2
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 11:55:01 2013 -0800

    vfb: Remove unused pXWDCmap variable
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 97eccfd..ec3c47a 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -404,7 +404,6 @@ vfbInstallColormap(ColormapPtr pmap)
     if (pmap != oldpmap) {
         int entries;
         XWDFileHeader *pXWDHeader;
-        XWDColor *pXWDCmap;
         VisualPtr pVisual;
         Pixel *ppix;
         xrgb *prgb;
@@ -419,7 +418,6 @@ vfbInstallColormap(ColormapPtr pmap)
 
         entries = pmap->pVisual->ColormapEntries;
         pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
-        pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
         pVisual = pmap->pVisual;
 
         swapcopy32(pXWDHeader->visual_class, pVisual->class);
commit 7353ec7cb6fc235b03e59e35425201429c83ee72
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 11:32:19 2013 -0800

    xfree86: Switch int10 code to stdint types
    
    CARD32 is not type compatible with uint32_t and ends up generating a
    pile of warnings. Fix this by replacing all of the CARD* types with
    stdint types.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/int10/generic.c b/hw/xfree86/int10/generic.c
index d7594de..41e348c 100644
--- a/hw/xfree86/int10/generic.c
+++ b/hw/xfree86/int10/generic.c
@@ -20,12 +20,12 @@
 
 #define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
 
-static CARD8 read_b(xf86Int10InfoPtr pInt, int addr);
-static CARD16 read_w(xf86Int10InfoPtr pInt, int addr);
-static CARD32 read_l(xf86Int10InfoPtr pInt, int addr);
-static void write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val);
-static void write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val);
-static void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val);
+static uint8_t read_b(xf86Int10InfoPtr pInt, int addr);
+static uint16_t read_w(xf86Int10InfoPtr pInt, int addr);
+static uint32_t read_l(xf86Int10InfoPtr pInt, int addr);
+static void write_b(xf86Int10InfoPtr pInt, int addr, uint8_t val);
+static void write_w(xf86Int10InfoPtr pInt, int addr, uint16_t val);
+static void write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val);
 
 /*
  * the emulator cannot pass a pointer to the current xf86Int10InfoRec
@@ -339,39 +339,39 @@ xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
 
 #define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
 #define V_ADDR_RB(addr) \
-	(VRAM(addr)) ? MMIO_IN8((CARD8*)VRAM_BASE,VRAM_ADDR(addr)) \
-	   : *(CARD8*) V_ADDR(addr)
+	(VRAM(addr)) ? MMIO_IN8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr)) \
+	   : *(uint8_t*) V_ADDR(addr)
 #define V_ADDR_RW(addr) \
-	(VRAM(addr)) ? MMIO_IN16((CARD16*)VRAM_BASE,VRAM_ADDR(addr)) \
+	(VRAM(addr)) ? MMIO_IN16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr)) \
 	   : ldw_u((pointer)V_ADDR(addr))
 #define V_ADDR_RL(addr) \
-	(VRAM(addr)) ? MMIO_IN32((CARD32*)VRAM_BASE,VRAM_ADDR(addr)) \
+	(VRAM(addr)) ? MMIO_IN32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr)) \
 	   : ldl_u((pointer)V_ADDR(addr))
 
 #define V_ADDR_WB(addr,val) \
 	if(VRAM(addr)) \
-	    MMIO_OUT8((CARD8*)VRAM_BASE,VRAM_ADDR(addr),val); \
+	    MMIO_OUT8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
 	else \
-	    *(CARD8*) V_ADDR(addr) = val;
+	    *(uint8_t*) V_ADDR(addr) = val;
 #define V_ADDR_WW(addr,val) \
 	if(VRAM(addr)) \
-	    MMIO_OUT16((CARD16*)VRAM_BASE,VRAM_ADDR(addr),val); \
+	    MMIO_OUT16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
 	else \
 	    stw_u((val),(pointer)(V_ADDR(addr)));
 
 #define V_ADDR_WL(addr,val) \
 	if (VRAM(addr)) \
-	    MMIO_OUT32((CARD32*)VRAM_BASE,VRAM_ADDR(addr),val); \
+	    MMIO_OUT32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
 	else \
 	    stl_u(val,(pointer)(V_ADDR(addr)));
 
-static CARD8
+static uint8_t
 read_b(xf86Int10InfoPtr pInt, int addr)
 {
     return V_ADDR_RB(addr);
 }
 
-static CARD16
+static uint16_t
 read_w(xf86Int10InfoPtr pInt, int addr)
 {
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
@@ -381,7 +381,7 @@ read_w(xf86Int10InfoPtr pInt, int addr)
     return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
 }
 
-static CARD32
+static uint32_t
 read_l(xf86Int10InfoPtr pInt, int addr)
 {
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
@@ -394,7 +394,7 @@ read_l(xf86Int10InfoPtr pInt, int addr)
 }
 
 static void
-write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
+write_b(xf86Int10InfoPtr pInt, int addr, uint8_t val)
 {
     V_ADDR_WB(addr, val);
 }
@@ -412,7 +412,7 @@ write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
 }
 
 static void
-write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
+write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val)
 {
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
     if (OFF(addr + 3) > 2) {
@@ -426,7 +426,7 @@ write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
 }
 
 pointer
-xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
+xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr)
 {
     return V_ADDR(addr);
 }
diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index 925da3c..6a83f42 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -37,12 +37,12 @@
 #endif
 #include <pciaccess.h>
 
-static int pciCfg1in(CARD16 addr, CARD32 *val);
-static int pciCfg1out(CARD16 addr, CARD32 val);
-static int pciCfg1inw(CARD16 addr, CARD16 *val);
-static int pciCfg1outw(CARD16 addr, CARD16 val);
-static int pciCfg1inb(CARD16 addr, CARD8 *val);
-static int pciCfg1outb(CARD16 addr, CARD8 val);
+static int pciCfg1in(uint16_t addr, uint32_t *val);
+static int pciCfg1out(uint16_t addr, uint32_t val);
+static int pciCfg1inw(uint16_t addr, uint16_t *val);
+static int pciCfg1outw(uint16_t addr, uint16_t val);
+static int pciCfg1inb(uint16_t addr, uint8_t *val);
+static int pciCfg1outb(uint16_t addr, uint8_t val);
 
 #if defined (_PC)
 static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
@@ -58,13 +58,13 @@ setup_int(xf86Int10InfoPtr pInt)
             return -1;
         Int10Current = pInt;
     }
-    X86_EAX = (CARD32) pInt->ax;
-    X86_EBX = (CARD32) pInt->bx;
-    X86_ECX = (CARD32) pInt->cx;
-    X86_EDX = (CARD32) pInt->dx;
-    X86_ESI = (CARD32) pInt->si;
-    X86_EDI = (CARD32) pInt->di;
-    X86_EBP = (CARD32) pInt->bp;
+    X86_EAX = (uint32_t) pInt->ax;
+    X86_EBX = (uint32_t) pInt->bx;
+    X86_ECX = (uint32_t) pInt->cx;
+    X86_EDX = (uint32_t) pInt->dx;
+    X86_ESI = (uint32_t) pInt->si;
+    X86_EDI = (uint32_t) pInt->di;
+    X86_EBP = (uint32_t) pInt->bp;
     X86_ESP = 0x1000;
     X86_SS = pInt->stackseg >> 4;
     X86_EIP = 0x0600;
@@ -86,15 +86,15 @@ void
 finish_int(xf86Int10InfoPtr pInt, int sig)
 {
     OsReleaseSignals();
-    pInt->ax = (CARD32) X86_EAX;
-    pInt->bx = (CARD32) X86_EBX;
-    pInt->cx = (CARD32) X86_ECX;
-    pInt->dx = (CARD32) X86_EDX;
-    pInt->si = (CARD32) X86_ESI;
-    pInt->di = (CARD32) X86_EDI;
-    pInt->es = (CARD16) X86_ES;
-    pInt->bp = (CARD32) X86_EBP;
-    pInt->flags = (CARD32) X86_FLAGS;
+    pInt->ax = (uint32_t) X86_EAX;
+    pInt->bx = (uint32_t) X86_EBX;
+    pInt->cx = (uint32_t) X86_ECX;
+    pInt->dx = (uint32_t) X86_EDX;
+    pInt->si = (uint32_t) X86_ESI;
+    pInt->di = (uint32_t) X86_EDI;
+    pInt->es = (uint16_t) X86_ES;
+    pInt->bp = (uint32_t) X86_EBP;
+    pInt->flags = (uint32_t) X86_FLAGS;
 #if defined (_PC)
     if (pInt->Flags & RESTORE_BIOS_SCRATCH)
         SetResetBIOSVars(pInt, FALSE);
@@ -102,23 +102,23 @@ finish_int(xf86Int10InfoPtr pInt, int sig)
 }
 
 /* general software interrupt handler */
-CARD32
+uint32_t
 getIntVect(xf86Int10InfoPtr pInt, int num)
 {
     return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
 }
 
 void
-pushw(xf86Int10InfoPtr pInt, CARD16 val)
+pushw(xf86Int10InfoPtr pInt, uint16_t val)
 {
     X86_ESP -= 2;
-    MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
+    MEM_WW(pInt, ((uint32_t) X86_SS << 4) + X86_SP, val);
 }
 
 int
 run_bios_int(int num, xf86Int10InfoPtr pInt)
 {
-    CARD32 eflags;
+    uint32_t eflags;
 
 #ifndef _PC
     /* check if bios vector is initialized */
@@ -167,7 +167,7 @@ void
 dump_code(xf86Int10InfoPtr pInt)
 {
     int i;
-    CARD32 lina = SEG_ADR((CARD32), X86_CS, IP);
+    uint32_t lina = SEG_ADR((uint32_t), X86_CS, IP);
 
     xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_INFO, 3, "code at 0x%8.8" PRIx32 ":\n",
                    (unsigned) lina);
@@ -203,8 +203,8 @@ void
 stack_trace(xf86Int10InfoPtr pInt)
 {
     int i = 0;
-    unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
-    unsigned long tail = (CARD32) ((X86_SS << 4) + 0x1000);
+    unsigned long stack = SEG_ADR((uint32_t), X86_SS, SP);
+    unsigned long tail = (uint32_t) ((X86_SS << 4) + 0x1000);
 
     if (stack >= tail)
         return;
@@ -222,10 +222,10 @@ stack_trace(xf86Int10InfoPtr pInt)
 
 int
 port_rep_inb(xf86Int10InfoPtr pInt,
-             CARD16 port, CARD32 base, int d_f, CARD32 count)
+             uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -1 : 1;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insb(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -239,10 +239,10 @@ port_rep_inb(xf86Int10InfoPtr pInt,
 
 int
 port_rep_inw(xf86Int10InfoPtr pInt,
-             CARD16 port, CARD32 base, int d_f, CARD32 count)
+             uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -2 : 2;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insw(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -256,10 +256,10 @@ port_rep_inw(xf86Int10InfoPtr pInt,
 
 int
 port_rep_inl(xf86Int10InfoPtr pInt,
-             CARD16 port, CARD32 base, int d_f, CARD32 count)
+             uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -4 : 4;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insl(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -273,10 +273,10 @@ port_rep_inl(xf86Int10InfoPtr pInt,
 
 int
 port_rep_outb(xf86Int10InfoPtr pInt,
-              CARD16 port, CARD32 base, int d_f, CARD32 count)
+              uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -1 : 1;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outb(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -290,10 +290,10 @@ port_rep_outb(xf86Int10InfoPtr pInt,
 
 int
 port_rep_outw(xf86Int10InfoPtr pInt,
-              CARD16 port, CARD32 base, int d_f, CARD32 count)
+              uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -2 : 2;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outw(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -307,10 +307,10 @@ port_rep_outw(xf86Int10InfoPtr pInt,
 
 int
 port_rep_outl(xf86Int10InfoPtr pInt,
-              CARD16 port, CARD32 base, int d_f, CARD32 count)
+              uint16_t port, uint32_t base, int d_f, uint32_t count)
 {
     register int inc = d_f ? -4 : 4;
-    CARD32 dst = base;
+    uint32_t dst = base;
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outl(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
@@ -322,14 +322,14 @@ port_rep_outl(xf86Int10InfoPtr pInt,
     return dst - base;
 }
 
-CARD8
-x_inb(CARD16 port)
+uint8_t
+x_inb(uint16_t port)
 {
-    CARD8 val;
+    uint8_t val;
 
     if (port == 0x40) {
         Int10Current->inb40time++;
-        val = (CARD8) (Int10Current->inb40time >>
+        val = (uint8_t) (Int10Current->inb40time >>
                        ((Int10Current->inb40time & 1) << 3));
         if (PRINT_PORT && DEBUG_IO_TRACE())
             ErrorF(" inb(%#x) = %2.2x\n", port, val);
@@ -353,10 +353,10 @@ x_inb(CARD16 port)
     return val;
 }
 
-CARD16
-x_inw(CARD16 port)
+uint16_t
+x_inw(uint16_t port)
 {
-    CARD16 val;
+    uint16_t val;
 
     if (port == 0x5c) {
         struct timeval tv;
@@ -366,7 +366,7 @@ x_inw(CARD16 port)
          * Approximate this by dividing by 3.
          */
         X_GETTIMEOFDAY(&tv);
-        val = (CARD16) (tv.tv_usec / 3);
+        val = (uint16_t) (tv.tv_usec / 3);
     }
     else if (!pciCfg1inw(port, &val)) {
         val = pci_io_read16(Int10Current->io, port);
@@ -377,7 +377,7 @@ x_inw(CARD16 port)
 }
 
 void
-x_outb(CARD16 port, CARD8 val)
+x_outb(uint16_t port, uint8_t val)
 {
     if ((port == 0x43) && (val == 0)) {
         struct timeval tv;
@@ -389,7 +389,7 @@ x_outb(CARD16 port, CARD8 val)
          * the bottom bit as a byte select.  See inb(0x40) above.
          */
         X_GETTIMEOFDAY(&tv);
-        Int10Current->inb40time = (CARD16) (tv.tv_usec | 1);
+        Int10Current->inb40time = (uint16_t) (tv.tv_usec | 1);
         if (PRINT_PORT && DEBUG_IO_TRACE())
             ErrorF(" outb(%#x, %2.2x)\n", port, val);
 #ifdef __NOT_YET__
@@ -411,7 +411,7 @@ x_outb(CARD16 port, CARD8 val)
 }
 
 void
-x_outw(CARD16 port, CARD16 val)
+x_outw(uint16_t port, uint16_t val)
 {
 
     if (!pciCfg1outw(port, val)) {
@@ -421,10 +421,10 @@ x_outw(CARD16 port, CARD16 val)
     }
 }
 
-CARD32
-x_inl(CARD16 port)
+uint32_t
+x_inl(uint16_t port)
 {
-    CARD32 val;
+    uint32_t val;
 
     if (!pciCfg1in(port, &val)) {
         val = pci_io_read32(Int10Current->io, port);
@@ -435,7 +435,7 @@ x_inl(CARD16 port)
 }
 
 void
-x_outl(CARD16 port, CARD32 val)
+x_outl(uint16_t port, uint32_t val)
 {
     if (!pciCfg1out(port, val)) {
         if (PRINT_PORT && DEBUG_IO_TRACE())
@@ -444,43 +444,43 @@ x_outl(CARD16 port, CARD32 val)
     }
 }
 
-CARD8
-Mem_rb(CARD32 addr)
+uint8_t
+Mem_rb(uint32_t addr)
 {
     return (*Int10Current->mem->rb) (Int10Current, addr);
 }
 
-CARD16
-Mem_rw(CARD32 addr)
+uint16_t
+Mem_rw(uint32_t addr)
 {
     return (*Int10Current->mem->rw) (Int10Current, addr);
 }
 
-CARD32
-Mem_rl(CARD32 addr)
+uint32_t
+Mem_rl(uint32_t addr)
 {
     return (*Int10Current->mem->rl) (Int10Current, addr);
 }
 
 void
-Mem_wb(CARD32 addr, CARD8 val)
+Mem_wb(uint32_t addr, uint8_t val)
 {
     (*Int10Current->mem->wb) (Int10Current, addr, val);
 }
 
 void
-Mem_ww(CARD32 addr, CARD16 val)
+Mem_ww(uint32_t addr, uint16_t val)
 {
     (*Int10Current->mem->ww) (Int10Current, addr, val);
 }
 
 void
-Mem_wl(CARD32 addr, CARD32 val)
+Mem_wl(uint32_t addr, uint32_t val)
 {
     (*Int10Current->mem->wl) (Int10Current, addr, val);
 }
 
-static CARD32 PciCfg1Addr = 0;
+static uint32_t PciCfg1Addr = 0;
 
 #define PCI_DOM_FROM_TAG(tag)  (((tag) >> 24) & (PCI_DOM_MASK))
 #define PCI_BUS_FROM_TAG(tag)  (((tag) >> 16) & (PCI_DOMBUS_MASK))
@@ -491,10 +491,10 @@ static CARD32 PciCfg1Addr = 0;
 #define PCI_TAG(x)    ((x) & 0x7fffff00)
 
 static struct pci_device *
-pci_device_for_cfg_address(CARD32 addr)
+pci_device_for_cfg_address(uint32_t addr)
 {
     struct pci_device *dev = NULL;
-    CARD32 tag = PCI_TAG(addr);
+    uint32_t tag = PCI_TAG(addr);
 
     struct pci_slot_match slot_match = {
         .domain = PCI_DOM_FROM_TAG(tag),
@@ -516,7 +516,7 @@ pci_device_for_cfg_address(CARD32 addr)
 }
 
 static int
-pciCfg1in(CARD16 addr, CARD32 *val)
+pciCfg1in(uint16_t addr, uint32_t *val)
 {
     if (addr == 0xCF8) {
         *val = PciCfg1Addr;
@@ -534,7 +534,7 @@ pciCfg1in(CARD16 addr, CARD32 *val)
 }
 
 static int
-pciCfg1out(CARD16 addr, CARD32 val)
+pciCfg1out(uint16_t addr, uint32_t val)
 {
     if (addr == 0xCF8) {
         PciCfg1Addr = val;
@@ -552,7 +552,7 @@ pciCfg1out(CARD16 addr, CARD32 val)
 }
 
 static int
-pciCfg1inw(CARD16 addr, CARD16 *val)
+pciCfg1inw(uint16_t addr, uint16_t *val)
 {
     int shift;
 
@@ -575,14 +575,14 @@ pciCfg1inw(CARD16 addr, CARD16 *val)
 }
 
 static int
-pciCfg1outw(CARD16 addr, CARD16 val)
+pciCfg1outw(uint16_t addr, uint16_t val)
 {
     int shift;
 
     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
         shift = (addr - 0xCF8) * 8;
         PciCfg1Addr &= ~(0xffff << shift);
-        PciCfg1Addr |= ((CARD32) val) << shift;
+        PciCfg1Addr |= ((uint32_t) val) << shift;
         return 1;
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
@@ -599,7 +599,7 @@ pciCfg1outw(CARD16 addr, CARD16 val)
 }
 
 static int
-pciCfg1inb(CARD16 addr, CARD8 *val)
+pciCfg1inb(uint16_t addr, uint8_t *val)
 {
     int shift;
 
@@ -622,14 +622,14 @@ pciCfg1inb(CARD16 addr, CARD8 *val)
 }
 
 static int
-pciCfg1outb(CARD16 addr, CARD8 val)
+pciCfg1outb(uint16_t addr, uint8_t val)
 {
     int shift;
 
     if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
         shift = (addr - 0xCF8) * 8;
         PciCfg1Addr &= ~(0xff << shift);
-        PciCfg1Addr |= ((CARD32) val) << shift;
+        PciCfg1Addr |= ((uint32_t) val) << shift;
         return 1;
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
@@ -645,10 +645,10 @@ pciCfg1outb(CARD16 addr, CARD8 val)
     return 0;
 }
 
-CARD8
-bios_checksum(const CARD8 *start, int size)
+uint8_t
+bios_checksum(const uint8_t *start, int size)
 {
-    CARD8 sum = 0;
+    uint8_t sum = 0;
 
     while (size-- > 0)
         sum += *start++;
@@ -682,12 +682,12 @@ LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
     vga->save_46e8 = pci_io_read8(pInt->io, 0x46E8);
 #endif
     vga->save_pos102 = pci_io_read8(pInt->io, 0x0102);
-    pci_io_write8(pInt->io, 0x03C2, ~(CARD8) 0x03 & vga->save_msr);
-    pci_io_write8(pInt->io, 0x03C3, ~(CARD8) 0x01 & vga->save_vse);
+    pci_io_write8(pInt->io, 0x03C2, ~(uint8_t) 0x03 & vga->save_msr);
+    pci_io_write8(pInt->io, 0x03C3, ~(uint8_t) 0x01 & vga->save_vse);
 #ifndef __ia64__
-    pci_io_write8(pInt->io, 0x46E8, ~(CARD8) 0x08 & vga->save_46e8);
+    pci_io_write8(pInt->io, 0x46E8, ~(uint8_t) 0x08 & vga->save_46e8);
 #endif
-    pci_io_write8(pInt->io, 0x0102, ~(CARD8) 0x01 & vga->save_pos102);
+    pci_io_write8(pInt->io, 0x0102, ~(uint8_t) 0x01 & vga->save_pos102);
 }
 
 void
diff --git a/hw/xfree86/int10/xf86int10.h b/hw/xfree86/int10/xf86int10.h
index 6d564fc..94040c5 100644
--- a/hw/xfree86/int10/xf86int10.h
+++ b/hw/xfree86/int10/xf86int10.h
@@ -21,8 +21,8 @@
 /* int10 info structure */
 typedef struct {
     int entityIndex;
-    CARD16 BIOSseg;
-    CARD16 inb40time;
+    uint16_t BIOSseg;
+    uint16_t inb40time;
     ScrnInfoPtr pScrn;
     pointer cpuRegs;
     char *BIOSScratch;
@@ -45,19 +45,19 @@ typedef struct {
 } xf86Int10InfoRec, *xf86Int10InfoPtr;
 
 typedef struct _int10Mem {
-    CARD8 (*rb) (xf86Int10InfoPtr, int);
-    CARD16 (*rw) (xf86Int10InfoPtr, int);
-    CARD32 (*rl) (xf86Int10InfoPtr, int);
-    void (*wb) (xf86Int10InfoPtr, int, CARD8);
-    void (*ww) (xf86Int10InfoPtr, int, CARD16);
-    void (*wl) (xf86Int10InfoPtr, int, CARD32);
+    uint8_t (*rb) (xf86Int10InfoPtr, int);
+    uint16_t (*rw) (xf86Int10InfoPtr, int);
+    uint32_t (*rl) (xf86Int10InfoPtr, int);
+    void (*wb) (xf86Int10InfoPtr, int, uint8_t);
+    void (*ww) (xf86Int10InfoPtr, int, uint16_t);
+    void (*wl) (xf86Int10InfoPtr, int, uint32_t);
 } int10MemRec, *int10MemPtr;
 
 typedef struct {
-    CARD8 save_msr;
-    CARD8 save_pos102;
-    CARD8 save_vse;
-    CARD8 save_46e8;
+    uint8_t save_msr;
+    uint8_t save_pos102;
+    uint8_t save_vse;
+    uint8_t save_46e8;
 } legacyVGARec, *legacyVGAPtr;
 
 /* OS dependent functions */
@@ -69,7 +69,7 @@ extern _X_EXPORT void *xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num,
                                            int *off);
 extern _X_EXPORT void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase,
                                          int num);
-extern _X_EXPORT pointer xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr);
+extern _X_EXPORT pointer xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr);
 
 /* x86 executor related functions */
 extern _X_EXPORT void xf86ExecX86int10(xf86Int10InfoPtr pInt);
@@ -127,13 +127,13 @@ int int_handler(xf86Int10InfoPtr pInt);
 /* helper_exec.c */
 int setup_int(xf86Int10InfoPtr pInt);
 void finish_int(xf86Int10InfoPtr, int sig);
-CARD32 getIntVect(xf86Int10InfoPtr pInt, int num);
-void pushw(xf86Int10InfoPtr pInt, CARD16 val);
+uint32_t getIntVect(xf86Int10InfoPtr pInt, int num);
+void pushw(xf86Int10InfoPtr pInt, uint16_t val);
 int run_bios_int(int num, xf86Int10InfoPtr pInt);
 void dump_code(xf86Int10InfoPtr pInt);
 void dump_registers(xf86Int10InfoPtr pInt);
 void stack_trace(xf86Int10InfoPtr pInt);
-CARD8 bios_checksum(const CARD8 *start, int size);
+uint8_t bios_checksum(const uint8_t *start, int size);
 void LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga);
 void UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga);
 
@@ -142,31 +142,31 @@ extern _X_EXPORT void xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt,
                                                    Bool save);
 #endif
 int port_rep_inb(xf86Int10InfoPtr pInt,
-                 CARD16 port, CARD32 base, int d_f, CARD32 count);
+                 uint16_t port, uint32_t base, int d_f, uint32_t count);
 int port_rep_inw(xf86Int10InfoPtr pInt,
-                 CARD16 port, CARD32 base, int d_f, CARD32 count);
+                 uint16_t port, uint32_t base, int d_f, uint32_t count);
 int port_rep_inl(xf86Int10InfoPtr pInt,
-                 CARD16 port, CARD32 base, int d_f, CARD32 count);
+                 uint16_t port, uint32_t base, int d_f, uint32_t count);
 int port_rep_outb(xf86Int10InfoPtr pInt,
-                  CARD16 port, CARD32 base, int d_f, CARD32 count);
+                  uint16_t port, uint32_t base, int d_f, uint32_t count);
 int port_rep_outw(xf86Int10InfoPtr pInt,
-                  CARD16 port, CARD32 base, int d_f, CARD32 count);
+                  uint16_t port, uint32_t base, int d_f, uint32_t count);
 int port_rep_outl(xf86Int10InfoPtr pInt,
-                  CARD16 port, CARD32 base, int d_f, CARD32 count);
-
-CARD8 x_inb(CARD16 port);
-CARD16 x_inw(CARD16 port);
-void x_outb(CARD16 port, CARD8 val);
-void x_outw(CARD16 port, CARD16 val);
-CARD32 x_inl(CARD16 port);
-void x_outl(CARD16 port, CARD32 val);
-
-CARD8 Mem_rb(CARD32 addr);
-CARD16 Mem_rw(CARD32 addr);
-CARD32 Mem_rl(CARD32 addr);
-void Mem_wb(CARD32 addr, CARD8 val);
-void Mem_ww(CARD32 addr, CARD16 val);
-void Mem_wl(CARD32 addr, CARD32 val);
+                  uint16_t port, uint32_t base, int d_f, uint32_t count);
+
+uint8_t x_inb(uint16_t port);
+uint16_t x_inw(uint16_t port);
+void x_outb(uint16_t port, uint8_t val);
+void x_outw(uint16_t port, uint16_t val);
+uint32_t x_inl(uint16_t port);
+void x_outl(uint16_t port, uint32_t val);
+
+uint8_t Mem_rb(uint32_t addr);
+uint16_t Mem_rw(uint32_t addr);
+uint32_t Mem_rl(uint32_t addr);
+void Mem_wb(uint32_t addr, uint8_t val);
+void Mem_ww(uint32_t addr, uint16_t val);
+void Mem_wl(uint32_t addr, uint32_t val);
 
 /* helper_mem.c */
 void setup_int_vect(xf86Int10InfoPtr pInt);
diff --git a/hw/xfree86/int10/xf86x86emu.c b/hw/xfree86/int10/xf86x86emu.c
index 0f8737b..b9a4d36 100644
--- a/hw/xfree86/int10/xf86x86emu.c
+++ b/hw/xfree86/int10/xf86x86emu.c
@@ -50,12 +50,12 @@ xf86Int10ExecSetup(xf86Int10InfoPtr pInt)
     X86EMU_intrFuncs intFuncs[256];
 
     X86EMU_pioFuncs pioFuncs = {
-        (&x_inb),
-        (&x_inw),
-        (&x_inl),
-        (&x_outb),
-        (&x_outw),
-        (&x_outl)
+        .inb = x_inb,
+        .inw = x_inw,
+        .inl = x_inl,
+        .outb = x_outb,
+        .outw = x_outw,
+        .outl = x_outl
     };
 
     X86EMU_memFuncs memFuncs = {
commit 93b15b1a47eb414338e8b229f25f11bdca099471
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Dec 11 11:31:46 2013 -0800

    xfree86: Don't complain when the SDK dependency file doesn't exist yet
    
    It won't exist until the build is complete, so don't complain about it
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 15670d0..9672904 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -121,7 +121,7 @@ sdksyms.dep sdksyms.c: sdksyms.sh
 	$(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(AM_CPPFLAGS)
 
 SDKSYMS_DEP = sdksyms.dep
-include $(SDKSYMS_DEP)
+-include $(SDKSYMS_DEP)
 
 i2c/libi2c.la:
 	$(AM_V_at)cd i2c && $(MAKE) libi2c.la
commit eda935627116dd106b99dbcc95d90a723a2de330
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:35:21 2013 -0800

    xkb: Make XkbWriteCountedString take a const char * input parameter
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index c78aceb..27e761c 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -4419,7 +4419,7 @@ ProcXkbSetNames(ClientPtr client)
  * (swapped) 16 bit string length, non-zero terminated.
  */
 static char *
-XkbWriteCountedString(char *wire, char *str, Bool swap)
+XkbWriteCountedString(char *wire, const char *str, Bool swap)
 {
     CARD16 len, *pLen, paddedLen;
 
commit d0339a5c66846c9f14e3b584e34688520a0916ab
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:34:59 2013 -0800

    os: xstrtokenize takes and returns const char * now
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/include/misc.h b/include/misc.h
index 17de710..165d42e 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -246,7 +246,7 @@ padding_for_int32(const int bytes)
 }
 
 
-extern char **xstrtokenize(const char *str, const char *separators);
+extern const char **xstrtokenize(const char *str, const char *separators);
 extern void FormatInt64(int64_t num, char *string);
 extern void FormatUInt64(uint64_t num, char *string);
 extern void FormatUInt64Hex(uint64_t num, char *string);
diff --git a/os/utils.c b/os/utils.c
index 608ee6a..e81dc5f 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1946,10 +1946,10 @@ CheckUserAuthorization(void)
  * Tokenize a string into a NULL terminated array of strings. Always returns
  * an allocated array unless an error occurs.
  */
-char **
+const char **
 xstrtokenize(const char *str, const char *separators)
 {
-    char **list, **nlist;
+    const char **list, **nlist;
     char *tok, *tmp;
     unsigned num = 0, n;
 
@@ -1977,7 +1977,7 @@ xstrtokenize(const char *str, const char *separators)
  error:
     free(tmp);
     for (n = 0; n < num; n++)
-        free(list[n]);
+        free((void *) list[n]);
     free(list);
     return NULL;
 }
commit c608560dbbac18837cb00ef0d774a66ea7706534
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:33:59 2013 -0800

    xfree86/vbe: Make VBEValidateModes take const char **
    
    mode names are now const
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/vbe/vbeModes.c b/hw/xfree86/vbe/vbeModes.c
index 40bd985..50ac50d 100644
--- a/hw/xfree86/vbe/vbeModes.c
+++ b/hw/xfree86/vbe/vbeModes.c
@@ -435,7 +435,7 @@ VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
  */
 int
 VBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
-                 char **modeNames, ClockRangePtr clockRanges,
+                 const char **modeNames, ClockRangePtr clockRanges,
                  int *linePitches, int minPitch, int maxPitch, int pitchInc,
                  int minHeight, int maxHeight, int virtualX, int virtualY,
                  int apertureSize, LookupModeFlags strategy)
diff --git a/hw/xfree86/vbe/vbeModes.h b/hw/xfree86/vbe/vbeModes.h
index affd5b6..ee0257c 100644
--- a/hw/xfree86/vbe/vbeModes.h
+++ b/hw/xfree86/vbe/vbeModes.h
@@ -82,7 +82,7 @@ extern _X_EXPORT void VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
  */
 extern _X_EXPORT int VBEValidateModes(ScrnInfoPtr scrp,
                                       DisplayModePtr availModes,
-                                      char **modeNames,
+                                      const char **modeNames,
                                       ClockRangePtr clockRanges,
                                       int *linePitches, int minPitch,
                                       int maxPitch, int pitchInc, int minHeight,
commit 3835e8b0a1cc7b1e971bcc3f9453422fec014b10
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:33:18 2013 -0800

    xfree86/shadowfb: GCFuncs and GCOps are now const
    
    Change GC private to match and fix resulting warnings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/shadowfb/shadow.c b/hw/xfree86/shadowfb/shadow.c
index 6145017..6c66ffe 100644
--- a/hw/xfree86/shadowfb/shadow.c
+++ b/hw/xfree86/shadowfb/shadow.c
@@ -62,8 +62,8 @@ typedef struct {
 } ShadowScreenRec, *ShadowScreenPtr;
 
 typedef struct {
-    GCOps *ops;
-    GCFuncs *funcs;
+    const GCOps *ops;
+    const GCFuncs *funcs;
 } ShadowGCRec, *ShadowGCPtr;
 
 static DevPrivateKeyRec ShadowScreenKeyRec;
@@ -96,7 +96,7 @@ static DevPrivateKeyRec ShadowGCKeyRec;
 #define SHADOW_GC_OP_PROLOGUE(pGC)\
     ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
     ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
-    GCFuncs *oldFuncs = pGC->funcs;\
+    const GCFuncs *oldFuncs = pGC->funcs;\
     pGC->funcs = pGCPriv->funcs;\
     pGC->ops = pGCPriv->ops
 
commit f71de60355cc76810657f40c7b5461af86b34bf7
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:32:40 2013 -0800

    xfree86/parser: make strings in xf86MatchGroup const
    
    and fix resulting warnings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index de6a816..a7f573e 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -64,7 +64,7 @@ xf86ConfigSymTabRec InputClassTab[] = {
 #define TOKEN_SEP "|"
 
 static void
-add_group_entry(struct xorg_list *head, char **values)
+add_group_entry(struct xorg_list *head, const char **values)
 {
     xf86MatchGroup *group;
 
@@ -257,7 +257,7 @@ void
 xf86printInputClassSection(FILE * cf, XF86ConfInputClassPtr ptr)
 {
     const xf86MatchGroup *group;
-    char *const *cur;
+    const char *const *cur;
 
     while (ptr) {
         fprintf(cf, "Section \"InputClass\"\n");
@@ -363,7 +363,7 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
 
     while (ptr) {
         xf86MatchGroup *group, *next;
-        char **list;
+        const char **list;
 
         TestFree(ptr->identifier);
         TestFree(ptr->driver);
@@ -371,55 +371,55 @@ xf86freeInputClassList(XF86ConfInputClassPtr ptr)
         xorg_list_for_each_entry_safe(group, next, &ptr->match_product, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_vendor, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_device, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_os, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_pnpid, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_usbid, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_tag, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
         xorg_list_for_each_entry_safe(group, next, &ptr->match_layout, entry) {
             xorg_list_del(&group->entry);
             for (list = group->values; *list; list++)
-                free(*list);
+                free((void *) *list);
             free(group);
         }
 
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 0fcf405..83607f2 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -299,7 +299,7 @@ typedef struct {
 
 typedef struct {
     struct xorg_list entry;
-    char **values;
+    const char **values;
 } xf86MatchGroup;
 
 typedef struct {
commit 2a93e75ff81b095bc9cdb80906e23ec705d52df5
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:31:55 2013 -0800

    xfree86/int10: mark printk as _X_ATTRIBUTE_PRINTF
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/x86emu/x86emu/regs.h b/hw/xfree86/x86emu/x86emu/regs.h
index 2ecafa0..3a7456e 100644
--- a/hw/xfree86/x86emu/x86emu/regs.h
+++ b/hw/xfree86/x86emu/x86emu/regs.h
@@ -39,6 +39,8 @@
 #ifndef __X86EMU_REGS_H
 #define __X86EMU_REGS_H
 
+#include <X11/Xfuncproto.h>
+
 /*---------------------- Macros and type definitions ----------------------*/
 
 #ifdef PACK
@@ -337,7 +339,8 @@ extern "C" {                    /* Use "C" linkage when in C++ mode */
 
 /* Function to log information at runtime */
 
-    void printk(const char *fmt, ...);
+    void printk(const char *fmt, ...)
+        _X_ATTRIBUTE_PRINTF(1, 2);
 
 #ifdef  __cplusplus
 }                               /* End of "C" linkage for C++           */
commit 7fe436a7b786ff02ed55cf9ed65edfd2fe07ac22
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:31:06 2013 -0800

    xfree86/fbdevhw: Fix warnings
    
    Unused fPtr variable. Deal with string constants.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index cbb4093..0450822 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -81,15 +81,13 @@ typedef struct {
 Bool
 fbdevHWGetRec(ScrnInfoPtr pScrn)
 {
-    fbdevHWPtr fPtr;
-
     if (fbdevHWPrivateIndex < 0)
         fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
 
     if (FBDEVHWPTR(pScrn) != NULL)
         return TRUE;
 
-    fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
+    FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
     return TRUE;
 }
 
@@ -301,7 +299,7 @@ fbdev_open_pci(struct pci_device *pPci, char **namep)
 }
 
 static int
-fbdev_open(int scrnIndex, char *dev, char **namep)
+fbdev_open(int scrnIndex, const char *dev, char **namep)
 {
     struct fb_fix_screeninfo fix;
     int fd;
@@ -497,7 +495,7 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
 void
 fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
 {
-    char **modename;
+    const char **modename;
     DisplayModePtr mode, this, last = pScrn->modes;
 
     if (NULL == pScrn->display->modes)
commit 6990de00eb23478d9343660ad3981fb1d33f8be4
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:30:29 2013 -0800

    xfree86/exa: xf86GetOptValString returns const char * now
    
    fix exaDDXDriverInit to match.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c
index 4e809ea..76f780a 100644
--- a/hw/xfree86/exa/examodule.c
+++ b/hw/xfree86/exa/examodule.c
@@ -128,7 +128,7 @@ exaDDXDriverInit(ScreenPtr pScreen)
     if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
         if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
             pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
-            char *heuristicName;
+            const char *heuristicName;
 
             heuristicName = xf86GetOptValString(pScreenPriv->options,
                                                 EXAOPT_MIGRATION_HEURISTIC);
commit 017307f0b41476c3c73a9414a7ce9eb42373c3f4
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:29:30 2013 -0800

    xfree86/dri: Mark DRIDrvMsg and dri_drm_debug_print _X_ATTRIBUTE_PRINTF
    
    And fix resulting warnings.
    
    v2: (Adam Jackson) Cast handles through uintptr_t to avoid size change warnings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 6292e87..bfa3e36 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -100,6 +100,11 @@ drmServerInfo DRIDRMServerInfo;
  * easily changed here.
  */
 #define DRI_MSG_VERBOSITY 1
+
+static void
+DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+    _X_ATTRIBUTE_PRINTF(3,4);
+
 static void
 DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
 {
@@ -400,7 +405,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
         }
         DRIDrvMsg(pScreen->myNum, X_INFO,
                   "[drm] added %d byte SAREA at %p\n",
-                  pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
+                  (int) pDRIPriv->pDriverInfo->SAREASize, (void *) (uintptr_t) pDRIPriv->hSAREA);
 
         /* Backwards compat. */
         if (drmMap(pDRIPriv->drmFD,
@@ -414,7 +419,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
             return FALSE;
         }
         DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
-                  pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+                  (void *) (uintptr_t) pDRIPriv->hSAREA, pDRIPriv->pSAREA);
         memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
     }
     else {
@@ -442,7 +447,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
             return FALSE;
         }
         DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
-                  pDRIPriv->pDriverInfo->hFrameBuffer);
+                  (void *) (uintptr_t) pDRIPriv->pDriverInfo->hFrameBuffer);
     }
     else {
         DRIDrvMsg(pScreen->myNum, X_INFO,
@@ -513,7 +518,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
     pDRIPriv->myContextPriv = pDRIContextPriv;
 
     DRIDrvMsg(pScreen->myNum, X_INFO,
-              "X context handle = %p\n", pDRIPriv->myContext);
+              "X context handle = %p\n", (void *) (uintptr_t) pDRIPriv->myContext);
 
     /* Now that we have created the X server's context, we can grab the
      * hardware lock for the X server.
@@ -731,13 +736,13 @@ DRICloseScreen(ScreenPtr pScreen)
         if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
             DRIDrvMsg(pScreen->myNum, X_INFO,
                       "[drm] unmapping %d bytes of SAREA %p at %p\n",
-                      pDRIInfo->SAREASize, pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+                      (int) pDRIInfo->SAREASize, (void *) (uintptr_t) pDRIPriv->hSAREA, pDRIPriv->pSAREA);
             if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
                 DRIDrvMsg(pScreen->myNum, X_ERROR,
                           "[drm] unable to unmap %d bytes"
                           " of SAREA %p at %p\n",
-                          pDRIInfo->SAREASize,
-                          pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+                          (int) pDRIInfo->SAREASize,
+                          (void *) (uintptr_t) pDRIPriv->hSAREA, pDRIPriv->pSAREA);
             }
         }
         else {
@@ -761,6 +766,10 @@ DRICloseScreen(ScreenPtr pScreen)
 
 static int
 dri_drm_debug_print(const char *format, va_list ap)
+    _X_ATTRIBUTE_PRINTF(1,0);
+
+static int
+dri_drm_debug_print(const char *format, va_list ap)
 {
     xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
     return 0;
@@ -2214,9 +2223,9 @@ DRILock(ScreenPtr pScreen, int flags)
     else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
         DRIDrvMsg(pScreen->myNum, X_ERROR,
                   "[DRI] Locking deadlock.\n"
-                  "\tAlready locked with context %d,\n"
-                  "\ttrying to lock with context %d.\n",
-                  pDRIPriv->pLockingContext, pDRIPriv->myContext);
+                  "\tAlready locked with context %p,\n"
+                  "\ttrying to lock with context %p.\n",
+                  pDRIPriv->pLockingContext, (void *) (uintptr_t) pDRIPriv->myContext);
     }
     (*pDRIPriv->pLockRefCount)++;
 }
@@ -2233,8 +2242,8 @@ DRIUnlock(ScreenPtr pScreen)
         if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
             DRIDrvMsg(pScreen->myNum, X_ERROR,
                       "[DRI] Unlocking inconsistency:\n"
-                      "\tContext %d trying to unlock lock held by context %d\n",
-                      pDRIPriv->pLockingContext, pDRIPriv->myContext);
+                      "\tContext %p trying to unlock lock held by context %p\n",
+                      pDRIPriv->pLockingContext, (void *) (uintptr_t) pDRIPriv->myContext);
         }
         (*pDRIPriv->pLockRefCount)--;
     }
commit 22592855e90d23013ba7f9e945d567725cb44bf3
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:28:48 2013 -0800

    xfree86/common: handle string constants in xf86Xinput configuration
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f563052..5b0b6a1 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -539,7 +539,7 @@ MatchAttrToken(const char *attr, struct xorg_list *patterns,
      * match. Each list entry is a separate Match line of the same type.
      */
     xorg_list_for_each_entry(group, patterns, entry) {
-        char *const *cur;
+        const char *const *cur;
         Bool match = FALSE;
 
         for (cur = group->values; *cur; cur++)
@@ -598,7 +598,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
      * See if any of the device's tags match any of the MatchTag tokens.
      */
     if (!xorg_list_is_empty(&iclass->match_tag)) {
-        char *const *tag;
+        const char *const *tag;
         Bool match;
 
         if (!attrs->tags)
commit 3a163d2af48a7cf8fd5c2db6ac68166a5fdbeb8d
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:28:16 2013 -0800

    xfree86/common: Const GC funcs and ops in xf86VAarbiter
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h
index ba6edfc..f91de0c 100644
--- a/hw/xfree86/common/xf86VGAarbiterPriv.h
+++ b/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -137,8 +137,8 @@ typedef struct _VGAarbiterScreen {
 } VGAarbiterScreenRec, *VGAarbiterScreenPtr;
 
 typedef struct _VGAarbiterGC {
-    GCOps *wrapOps;
-    GCFuncs *wrapFuncs;
+    const GCOps *wrapOps;
+    const GCFuncs *wrapFuncs;
 } VGAarbiterGCRec, *VGAarbiterGCPtr;
 
 /* Screen funcs */
commit 8a9aa44a45377d8953d11a0b035c86eb139283ba
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:26:19 2013 -0800

    xfree86/config: Kludge around const strings
    
    defaultFontPath is now a const char * so that it can be initialized
    from a string constant. This patch kludges around that by inserting
    suitable casts to eliminate warnings. Fixing this 'correctly' would
    involve inserting some new variables and conditionals to use them.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 6ea7d01..de50ec0 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -171,7 +171,7 @@ xf86GetPathElem(char **pnt)
 static char *
 xf86ValidateFontPath(char *path)
 {
-    char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
+    char *next, *tmp_path, *out_pnt, *path_elem, *p1, *dir_elem;
     struct stat stat_buf;
     int flag;
     int dirlen;
@@ -589,33 +589,35 @@ configFiles(XF86ConfFilesPtr fileconf)
     /* FontPath */
     must_copy = TRUE;
 
-    temp_path = defaultFontPath ? defaultFontPath : (char *) "";
+    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
     if (xf86fpFlag)
         pathFrom = X_CMDLINE;
     else if (fileconf && fileconf->file_fontpath) {
         pathFrom = X_CONFIG;
         if (xf86Info.useDefaultFontPath) {
-            if (asprintf(&defaultFontPath, "%s%s%s", fileconf->file_fontpath,
+            char *new_font_path;
+            if (asprintf(&new_font_path, "%s%s%s", fileconf->file_fontpath,
                          *temp_path ? "," : "", temp_path) == -1)
-                defaultFontPath = NULL;
+                new_font_path = NULL;
             else
                 must_copy = FALSE;
+            defaultFontPath = new_font_path;
         }
         else
             defaultFontPath = fileconf->file_fontpath;
     }
     else
         pathFrom = X_DEFAULT;
-    temp_path = defaultFontPath ? defaultFontPath : (char *) "";
+    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
 
     /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
-    temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
+    temp_path = must_copy ? xnfstrdup(defaultFontPath) : (char *) defaultFontPath;
     defaultFontPath = xf86ValidateFontPath(temp_path);
     free(temp_path);
 
     /* make fontpath more readable in the logfiles */
     countDirs = 1;
-    temp_path = defaultFontPath;
+    temp_path = (char *) defaultFontPath;
     while ((temp_path = index(temp_path, ',')) != NULL) {
         countDirs++;
         temp_path++;
@@ -623,7 +625,7 @@ configFiles(XF86ConfFilesPtr fileconf)
 
     log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
     temp_path = log_buf;
-    start = defaultFontPath;
+    start = (char *) defaultFontPath;
     while ((end = index(start, ',')) != NULL) {
         size = (end - start) + 1;
         *(temp_path++) = '\t';
commit 86647e7279163b13492d39ecb9c44414b752a61e
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:25:50 2013 -0800

    config/udev: handle const strings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/config/udev.c b/config/udev.c
index b55b78e..23a53f4 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -137,11 +137,13 @@ device_added(struct udev_device *udev_device)
         /* construct USB ID in lowercase hex - "0000:ffff" */
         if (product &&
             sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) {
-            if (asprintf(&attrs.usb_id, "%04x:%04x", usb_vendor, usb_model)
+            char *usb_id;
+            if (asprintf(&usb_id, "%04x:%04x", usb_vendor, usb_model)
                 == -1)
-                attrs.usb_id = NULL;
+                usb_id = NULL;
             else
                 LOG_PROPERTY(ppath, "PRODUCT", product);
+            attrs.usb_id = usb_id;
         }
     }
     if (!name)
@@ -240,16 +242,16 @@ device_added(struct udev_device *udev_device)
     free(config_info);
     input_option_free_list(&input_options);
 
-    free(attrs.usb_id);
-    free(attrs.pnp_id);
-    free(attrs.product);
-    free(attrs.device);
-    free(attrs.vendor);
+    free((void *) attrs.usb_id);
+    free((void *) attrs.pnp_id);
+    free((void *) attrs.product);
+    free((void *) attrs.device);
+    free((void *) attrs.vendor);
     if (attrs.tags) {
-        char **tag = attrs.tags;
+        const char **tag = attrs.tags;
 
         while (*tag) {
-            free(*tag);
+            free((void *) *tag);
             tag++;
         }
         free(attrs.tags);
commit b7633c6ff2c273621df6c0fac9c269f8ab217a46
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:24:03 2013 -0800

    composite: Remove unused pScreen variables
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/composite/compext.c b/composite/compext.c
index e4821c5..e253f3c 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -335,12 +335,10 @@ ProcCompositeReleaseOverlayWindow(ClientPtr client)
 {
     REQUEST(xCompositeReleaseOverlayWindowReq);
     WindowPtr pWin;
-    ScreenPtr pScreen;
     CompOverlayClientPtr pOc;
 
     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
-    pScreen = pWin->drawable.pScreen;
 
     /* 
      * Has client queried a reference to the overlay window
@@ -873,7 +871,6 @@ PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
 {
     REQUEST(xCompositeReleaseOverlayWindowReq);
     WindowPtr pWin;
-    ScreenPtr pScreen;
     CompOverlayClientPtr pOc;
     PanoramiXRes *win;
     int i, rc;
@@ -893,7 +890,6 @@ PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
             client->errorValue = stuff->window;
             return rc;
         }
-        pScreen = pWin->drawable.pScreen;
 
         /*
          * Has client queried a reference to the overlay window
commit 5bc5684d4cb4905cd82fe1c036cc8a48c3c4868f
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 06:02:05 2013 -0800

    test: Warning cleanup
    
    const char in test/xfree86.c. Cast values to (intmax_t) for %ju format
    in test/signal-logging.c.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/test/signal-logging.c b/test/signal-logging.c
index a03c5ac..7bbd910 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -56,7 +56,7 @@ check_signed_number_format_test(long int number)
     FormatInt64(number, string);
     if(strncmp(string, expected, 21) != 0) {
         fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n",
-                number, expected, string);
+                (intmax_t) number, expected, string);
         return FALSE;
     }
 
@@ -93,7 +93,7 @@ check_number_format_test(long unsigned int number)
     FormatUInt64(number, string);
     if(strncmp(string, expected, 21) != 0) {
         fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n",
-                number, expected, string);
+                (intmax_t) number, expected, string);
         return FALSE;
     }
 
@@ -101,7 +101,7 @@ check_number_format_test(long unsigned int number)
     FormatUInt64Hex(number, string);
     if(strncmp(string, expected, 17) != 0) {
         fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
-                number, expected, string);
+                (intmax_t) number, expected, string);
         return FALSE;
     }
 
diff --git a/test/xfree86.c b/test/xfree86.c
index f9892e6..a986711 100644
--- a/test/xfree86.c
+++ b/test/xfree86.c
@@ -73,7 +73,8 @@ xfree86_option_list_duplicate(void)
 static void
 xfree86_add_comment(void)
 {
-    char *current = NULL, *comment;
+    char *current = NULL;
+    const char *comment;
     char compare[1024] = { 0 };
 
     comment = "# foo";
commit fecc7eb1cf66db64728ee2d68cd9443df7e70879
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 06:00:44 2013 -0800

    xi: More warning cleanup for input
    
    Lots more const char stuff.
    
    Remove duplicate defs of CoreKeyboardProc and CorePointerProc from
    test/xi2/protocol-common.c
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index a49a421..c13bc47 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1169,8 +1169,8 @@ IResetProc(ExtensionEntry * unused)
     EventSwapVector[DevicePropertyNotify] = NotImplemented;
     RestoreExtensionEvents();
 
-    free(xi_all_devices.name);
-    free(xi_all_master_devices.name);
+    free((void *) xi_all_devices.name);
+    free((void *) xi_all_master_devices.name);
 
     XIBarrierReset();
 }
diff --git a/Xi/listdev.c b/Xi/listdev.c
index 014c61d..470fb52 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -119,7 +119,7 @@ SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
  */
 
 static void
-CopyDeviceName(char **namebuf, char *name)
+CopyDeviceName(char **namebuf, const char *name)
 {
     char *nameptr = (char *) *namebuf;
 
diff --git a/dix/devices.c b/dix/devices.c
index a680ed8..3aecd1b 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -955,7 +955,7 @@ CloseDevice(DeviceIntPtr dev)
     while (dev->xkb_interest)
         XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource);
 
-    free(dev->name);
+    free((void *) dev->name);
 
     classes = (ClassesPtr) &dev->key;
     FreeAllDeviceClasses(classes);
@@ -2735,6 +2735,7 @@ AllocDevicePair(ClientPtr client, const char *name,
 {
     DeviceIntPtr pointer;
     DeviceIntPtr keyboard;
+    char *dev_name;
 
     *ptr = *keybd = NULL;
 
@@ -2745,12 +2746,12 @@ AllocDevicePair(ClientPtr client, const char *name,
     if (!pointer)
         return BadAlloc;
 
-    if (asprintf(&pointer->name, "%s pointer", name) == -1) {
-        pointer->name = NULL;
+    if (asprintf(&dev_name, "%s pointer", name) == -1) {
         RemoveDevice(pointer, FALSE);
 
         return BadAlloc;
     }
+    pointer->name = dev_name;
 
     pointer->public.processInputProc = ProcessOtherEvent;
     pointer->public.realInputProc = ProcessOtherEvent;
@@ -2771,13 +2772,13 @@ AllocDevicePair(ClientPtr client, const char *name,
         return BadAlloc;
     }
 
-    if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
-        keyboard->name = NULL;
+    if (asprintf(&dev_name, "%s keyboard", name) == -1) {
         RemoveDevice(keyboard, FALSE);
         RemoveDevice(pointer, FALSE);
 
         return BadAlloc;
     }
+    keyboard->name = dev_name;
 
     keyboard->public.processInputProc = ProcessOtherEvent;
     keyboard->public.realInputProc = ProcessOtherEvent;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index a10a7c7..3e1d75f 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -351,7 +351,7 @@ DuplicateInputAttributes(InputAttributes * attrs)
 {
     InputAttributes *new_attr;
     int ntags = 0;
-    char **tags, **new_tags;
+    const char **tags, **new_tags;
 
     if (!attrs)
         return NULL;
@@ -403,20 +403,20 @@ DuplicateInputAttributes(InputAttributes * attrs)
 void
 FreeInputAttributes(InputAttributes * attrs)
 {
-    char **tags;
+    const char **tags;
 
     if (!attrs)
         return;
 
-    free(attrs->product);
-    free(attrs->vendor);
-    free(attrs->device);
-    free(attrs->pnp_id);
-    free(attrs->usb_id);
+    free((void *) attrs->product);
+    free((void *) attrs->vendor);
+    free((void *) attrs->device);
+    free((void *) attrs->pnp_id);
+    free((void *) attrs->usb_id);
 
     if ((tags = attrs->tags))
         while (*tags)
-            free(*tags++);
+            free((void *) *tags++);
 
     free(attrs->tags);
     free(attrs);
diff --git a/include/input.h b/include/input.h
index 2d5e531..042128f 100644
--- a/include/input.h
+++ b/include/input.h
@@ -221,12 +221,12 @@ typedef struct _InputOption InputOption;
 typedef struct _XI2Mask XI2Mask;
 
 typedef struct _InputAttributes {
-    char *product;
-    char *vendor;
-    char *device;
-    char *pnp_id;
-    char *usb_id;
-    char **tags;                /* null-terminated */
+    const char *product;
+    const char *vendor;
+    const char *device;
+    const char *pnp_id;
+    const char *usb_id;
+    const char **tags;                /* null-terminated */
     uint32_t flags;
 } InputAttributes;
 
diff --git a/include/inputstr.h b/include/inputstr.h
index dc36c5d..d369c9f 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -542,7 +542,7 @@ typedef struct _DeviceIntRec {
     GrabInfoRec deviceGrab;     /* grab on the device */
     int type;                   /* MASTER_POINTER, MASTER_KEYBOARD, SLAVE */
     Atom xinput_type;
-    char *name;
+    const char *name;
     int id;
     KeyClassPtr key;
     ValuatorClassPtr valuator;
diff --git a/test/input.c b/test/input.c
index df20f82..aaa7a69 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1101,7 +1101,7 @@ xi_unregister_handlers(void)
 static void
 cmp_attr_fields(InputAttributes * attr1, InputAttributes * attr2)
 {
-    char **tags1, **tags2;
+    const char **tags1, **tags2;
 
     assert(attr1 && attr2);
     assert(attr1 != attr2);
@@ -1182,7 +1182,7 @@ dix_input_attributes(void)
 {
     InputAttributes orig = { 0 };
     InputAttributes *new;
-    char *tags[4] = { "tag1", "tag2", "tag2", NULL };
+    const char *tags[4] = { "tag1", "tag2", "tag2", NULL };
 
     new = DuplicateInputAttributes(NULL);
     assert(!new);
diff --git a/test/xi2/protocol-common.c b/test/xi2/protocol-common.c
index e2b0b8b..0947898 100644
--- a/test/xi2/protocol-common.c
+++ b/test/xi2/protocol-common.c
@@ -43,9 +43,6 @@ static ClientRec server_client;
 
 void *userdata;
 
-extern int CorePointerProc(DeviceIntPtr pDev, int what);
-extern int CoreKeyboardProc(DeviceIntPtr pDev, int what);
-
 static void
 fake_init_sprite(DeviceIntPtr dev)
 {
commit af04cf6968b16cc9efd17905471047e7de62058a
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 05:55:38 2013 -0800

    Xext: Clean up warnings in hashtable code
    
    Make keys const void *
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/hashtable.c b/Xext/hashtable.c
index 9d9ef89..76ebc6d 100644
--- a/Xext/hashtable.c
+++ b/Xext/hashtable.c
@@ -118,7 +118,7 @@ double_size(HashTable ht)
 }
 
 pointer
-ht_add(HashTable ht, pointer key)
+ht_add(HashTable ht, const void *key)
 {
     unsigned index = ht->hash(ht->cdata, key, ht->bucketBits);
     struct xorg_list *bucket = &ht->buckets[index];
@@ -164,7 +164,7 @@ ht_add(HashTable ht, pointer key)
 }
 
 void
-ht_remove(HashTable ht, pointer key)
+ht_remove(HashTable ht, const void *key)
 {
     unsigned index = ht->hash(ht->cdata, key, ht->bucketBits);
     struct xorg_list *bucket = &ht->buckets[index];
@@ -183,7 +183,7 @@ ht_remove(HashTable ht, pointer key)
 }
 
 pointer
-ht_find(HashTable ht, pointer key)
+ht_find(HashTable ht, const void *key)
 {
     unsigned index = ht->hash(ht->cdata, key, ht->bucketBits);
     struct xorg_list *bucket = &ht->buckets[index];
diff --git a/Xext/hashtable.h b/Xext/hashtable.h
index 5d15984..8a65732 100644
--- a/Xext/hashtable.h
+++ b/Xext/hashtable.h
@@ -75,12 +75,12 @@ extern _X_EXPORT void ht_destroy(HashTable ht);
          to avoid returning NULL. Obviously the data pointed cannot be
          modified, as implied by dataSize being 0.
 */
-extern _X_EXPORT pointer ht_add(HashTable ht, pointer key);
+extern _X_EXPORT pointer ht_add(HashTable ht, const void *key);
 
 /** @brief  Removes a key from the hash table along with its
             associated data, which will be free'd.
 */
-extern _X_EXPORT void ht_remove(HashTable ht, pointer key);
+extern _X_EXPORT void ht_remove(HashTable ht, const void *key);
 
 /** @brief  Finds the associated data of a key from the hash table.
 
@@ -93,7 +93,7 @@ extern _X_EXPORT void ht_remove(HashTable ht, pointer key);
           use HtMember instead to determine if a key has been
           inserted.
 */
-extern _X_EXPORT pointer ht_find(HashTable ht, pointer key);
+extern _X_EXPORT pointer ht_find(HashTable ht, const void *key);
 
 /** @brief  A generic hash function */
 extern _X_EXPORT unsigned ht_generic_hash(void *cdata,
commit 00438c9f943b219ba33055969ae7f9ba07214b2a
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 05:41:54 2013 -0800

    exa: Clean up warnings
    
    Declare GC ops/funcs as const.
    Use 'typeof' in the 'swap' macro to capture the right type.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/exa/exa.c b/exa/exa.c
index f8e499c..e961733 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -620,8 +620,8 @@ exaCreateGC(GCPtr pGC)
 
     swap(pExaScr, pScreen, CreateGC);
     if ((ret = (*pScreen->CreateGC) (pGC))) {
-        wrap(pExaGC, pGC, funcs, (GCFuncs *) &exaGCFuncs);
-        wrap(pExaGC, pGC, ops, (GCOps *) &exaOps);
+        wrap(pExaGC, pGC, funcs, &exaGCFuncs);
+        wrap(pExaGC, pGC, ops, &exaOps);
     }
     swap(pExaScr, pScreen, CreateGC);
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 1f56056..aba3934 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -248,11 +248,19 @@ extern DevPrivateKeyRec exaScreenPrivateKeyRec;
     real->mem = priv->Saved##mem; \
 }
 
+#ifdef HAVE_TYPEOF
+#define swap(priv, real, mem) {\
+    typeof(real->mem) tmp = priv->Saved##mem; \
+    priv->Saved##mem = real->mem; \
+    real->mem = tmp; \
+}
+#else
 #define swap(priv, real, mem) {\
     void *tmp = priv->Saved##mem; \
     priv->Saved##mem = real->mem; \
     real->mem = tmp; \
 }
+#endif
 
 #define EXA_PRE_FALLBACK(_screen_) \
     ExaScreenPriv(_screen_); \
@@ -333,8 +341,8 @@ typedef struct {
 
 typedef struct {
     /* GC values from the layer below. */
-    GCOps *Savedops;
-    GCFuncs *Savedfuncs;
+    const GCOps *Savedops;
+    const GCFuncs *Savedfuncs;
 } ExaGCPrivRec, *ExaGCPrivPtr;
 
 typedef struct {
commit 6e51645b4796fc3a02206fefd416b84beb2fcdf7
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 05:28:47 2013 -0800

    xkb: Clean up warnings
    
    Add const to lots of strings.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/include/xkbrules.h b/include/xkbrules.h
index 5b69d0d..956eade 100644
--- a/include/xkbrules.h
+++ b/include/xkbrules.h
@@ -64,7 +64,7 @@ typedef struct _XkbRF_Rule {
 typedef struct _XkbRF_Group {
     int number;
     const char *name;
-    const char *words;
+    char *words;
 } XkbRF_GroupRec, *XkbRF_GroupPtr;
 
 #define	XkbRF_PendingMatch	(1L<<1)
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 346ebcc..fbfe403 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -852,7 +852,7 @@ extern _X_EXPORT unsigned int XkbDDXLoadKeymapByNames(DeviceIntPtr /* keybd */ ,
     );
 
 extern _X_EXPORT Bool XkbDDXNamesFromRules(DeviceIntPtr /* keybd */ ,
-                                           char * /* rules */ ,
+                                           const char * /* rules */ ,
                                            XkbRF_VarDefsPtr /* defs */ ,
                                            XkbComponentNamesPtr /* names */
     );
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index d462957..f458e3b 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -299,7 +299,7 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
 
 Bool
 XkbDDXNamesFromRules(DeviceIntPtr keybd,
-                     char *rules_name,
+                     const char *rules_name,
                      XkbRF_VarDefsPtr defs, XkbComponentNamesPtr names)
 {
     char buf[PATH_MAX];
diff --git a/xkb/maprules.c b/xkb/maprules.c
index 5462763..6f5f8cc 100644
--- a/xkb/maprules.c
+++ b/xkb/maprules.c
@@ -218,10 +218,10 @@ typedef struct _FileSpec {
 } FileSpec;
 
 typedef struct {
-    char *model;
-    char *layout[XkbNumKbdGroups + 1];
-    char *variant[XkbNumKbdGroups + 1];
-    char *options;
+    const char *model;
+    const char *layout[XkbNumKbdGroups + 1];
+    const char *variant[XkbNumKbdGroups + 1];
+    const char *options;
 } XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
 
 #define NDX_BUFF_SIZE	4
@@ -343,9 +343,9 @@ SetUpRemap(InputLine * line, RemapSpec * remap)
 }
 
 static Bool
-MatchOneOf(char *wanted, char *vals_defined)
+MatchOneOf(const char *wanted, const char *vals_defined)
 {
-    char *str, *next;
+    const char *str, *next;
     int want_len = strlen(wanted);
 
     for (str = vals_defined, next = NULL; str != NULL; str = next) {
@@ -469,7 +469,7 @@ CheckLine(InputLine * line,
 }
 
 static char *
-_Concat(char *str1, char *str2)
+_Concat(char *str1, const char *str2)
 {
     int len;
 
@@ -498,12 +498,13 @@ squeeze_spaces(char *p1)
 static Bool
 MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
 {
-
+    char *options;
     memset((char *) mdefs, 0, sizeof(XkbRF_MultiDefsRec));
     mdefs->model = defs->model;
-    mdefs->options = Xstrdup(defs->options);
-    if (mdefs->options)
-        squeeze_spaces(mdefs->options);
+    options = Xstrdup(defs->options);
+    if (options)
+        squeeze_spaces(options);
+    mdefs->options = options;
 
     if (defs->layout) {
         if (!strchr(defs->layout, ',')) {
@@ -511,13 +512,15 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
         }
         else {
             char *p;
+            char *layout;
             int i;
 
-            mdefs->layout[1] = Xstrdup(defs->layout);
-            if (mdefs->layout[1] == NULL)
+            layout = Xstrdup(defs->layout);
+            if (layout == NULL)
                 return FALSE;
-            squeeze_spaces(mdefs->layout[1]);
-            p = mdefs->layout[1];
+            squeeze_spaces(layout);
+            mdefs->layout[1] = layout;
+            p = layout;
             for (i = 2; i <= XkbNumKbdGroups; i++) {
                 if ((p = strchr(p, ','))) {
                     *p++ = '\0';
@@ -538,13 +541,15 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
         }
         else {
             char *p;
+            char *variant;
             int i;
 
-            mdefs->variant[1] = Xstrdup(defs->variant);
-            if (mdefs->variant[1] == NULL)
+            variant = Xstrdup(defs->variant);
+            if (variant == NULL)
                 return FALSE;
-            squeeze_spaces(mdefs->variant[1]);
-            p = mdefs->variant[1];
+            squeeze_spaces(variant);
+            mdefs->variant[1] = variant;
+            p = variant;
             for (i = 2; i <= XkbNumKbdGroups; i++) {
                 if ((p = strchr(p, ','))) {
                     *p++ = '\0';
@@ -564,13 +569,13 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
 static void
 FreeMultiDefs(XkbRF_MultiDefsPtr defs)
 {
-    free(defs->options);
-    free(defs->layout[1]);
-    free(defs->variant[1]);
+    free((void *) defs->options);
+    free((void *) defs->layout[1]);
+    free((void *) defs->variant[1]);
 }
 
 static void
-Apply(char *src, char **dst)
+Apply(const char *src, char **dst)
 {
     if (src) {
         if (*src == '+' || *src == '!') {
@@ -596,7 +601,7 @@ XkbRF_ApplyRule(XkbRF_RulePtr rule, XkbComponentNamesPtr names)
 }
 
 static Bool
-CheckGroup(XkbRF_RulesPtr rules, char *group_name, char *name)
+CheckGroup(XkbRF_RulesPtr rules, const char *group_name, const char *name)
 {
     int i;
     char *p;
@@ -1013,15 +1018,15 @@ XkbRF_Free(XkbRF_RulesPtr rules, Bool freeRules)
         return;
     if (rules->rules) {
         for (i = 0, rule = rules->rules; i < rules->num_rules; i++, rule++) {
-            free(rule->model);
-            free(rule->layout);
-            free(rule->variant);
-            free(rule->option);
-            free(rule->keycodes);
-            free(rule->symbols);
-            free(rule->types);
-            free(rule->compat);
-            free(rule->geometry);
+            free((void *) rule->model);
+            free((void *) rule->layout);
+            free((void *) rule->variant);
+            free((void *) rule->option);
+            free((void *) rule->keycodes);
+            free((void *) rule->symbols);
+            free((void *) rule->types);
+            free((void *) rule->compat);
+            free((void *) rule->geometry);
             memset((char *) rule, 0, sizeof(XkbRF_RuleRec));
         }
         free(rules->rules);
@@ -1031,7 +1036,7 @@ XkbRF_Free(XkbRF_RulesPtr rules, Bool freeRules)
 
     if (rules->groups) {
         for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
-            free(group->name);
+            free((void *) group->name);
             free(group->words);
         }
         free(rules->groups);
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index f72655f..ca3831c 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -129,11 +129,11 @@ XkbFreeRMLVOSet(XkbRMLVOSet * rmlvo, Bool freeRMLVO)
     if (!rmlvo)
         return;
 
-    free(rmlvo->rules);
-    free(rmlvo->model);
-    free(rmlvo->layout);
-    free(rmlvo->variant);
-    free(rmlvo->options);
+    free((void *) rmlvo->rules);
+    free((void *) rmlvo->model);
+    free((void *) rmlvo->layout);
+    free((void *) rmlvo->variant);
+    free((void *) rmlvo->options);
 
     if (freeRMLVO)
         free(rmlvo);
commit abce3206cbc82f632abae5344e0ce46622e00f24
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 05:19:24 2013 -0800

    os: Clean up warnings
    
    Just const char stuff.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/include/os.h b/include/os.h
index 9b67294..4dacc1e 100644
--- a/include/os.h
+++ b/include/os.h
@@ -448,7 +448,7 @@ extern _X_EXPORT void
 AddLocalHosts(void);
 
 extern _X_EXPORT void
-ResetHosts(char *display);
+ResetHosts(const char *display);
 
 extern _X_EXPORT void
 EnableLocalHost(void);
@@ -471,7 +471,7 @@ RegisterAuthorizations(void);
 #endif
 
 extern _X_EXPORT void
-InitAuthorization(char * /*filename */ );
+InitAuthorization(const char * /*filename */ );
 
 /* extern int LoadAuthorization(void); */
 
diff --git a/os/access.c b/os/access.c
index 6d991b3..c55b0ef 100644
--- a/os/access.c
+++ b/os/access.c
@@ -814,7 +814,7 @@ AddLocalHosts(void)
 
 /* Reset access control list to initial hosts */
 void
-ResetHosts(char *display)
+ResetHosts(const char *display)
 {
     register HOST *host;
     char lhostname[120], ohostname[120];
diff --git a/os/auth.c b/os/auth.c
index ac20de4..5fcb538 100644
--- a/os/auth.c
+++ b/os/auth.c
@@ -96,12 +96,12 @@ static struct protocol protocols[] = {
  * specified authorization file
  */
 
-static char *authorization_file = (char *) NULL;
+static const char *authorization_file = NULL;
 
 static Bool ShouldLoadAuth = TRUE;
 
 void
-InitAuthorization(char *file_name)
+InitAuthorization(const char *file_name)
 {
     authorization_file = file_name;
 }
commit a1cb69dc28fdbfbdfaf954e0bec221f759462399
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 22:05:44 2013 +0900

    Xext: Clean up warnings
    
    GC funcs and ops are const.
    Remove unused variables.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index ce0d072..6f8939f 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -118,7 +118,7 @@ static DevPrivateKeyRec PanoramiXScreenKeyRec;
 typedef struct {
     DDXPointRec clipOrg;
     DDXPointRec patOrg;
-    GCFuncs *wrapFuncs;
+    const GCFuncs *wrapFuncs;
 } PanoramiXGCRec, *PanoramiXGCPtr;
 
 typedef struct {
@@ -134,7 +134,7 @@ static void XineramaChangeClip(GCPtr, int, pointer, int);
 static void XineramaDestroyClip(GCPtr);
 static void XineramaCopyClip(GCPtr, GCPtr);
 
-static GCFuncs XineramaGCFuncs = {
+static const GCFuncs XineramaGCFuncs = {
     XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC,
     XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip
 };
diff --git a/Xext/xres.c b/Xext/xres.c
index 445abca..bdd49eb 100644
--- a/Xext/xres.c
+++ b/Xext/xres.c
@@ -193,7 +193,6 @@ DestroyConstructResourceBytesCtx(ConstructResourceBytesCtx *ctx)
 static int
 ProcXResQueryVersion(ClientPtr client)
 {
-    REQUEST(xXResQueryVersionReq);
     xXResQueryVersionReply rep = {
         .type = X_Reply,
         .sequenceNumber = client->sequence,
@@ -1103,7 +1102,6 @@ ProcResDispatch(ClientPtr client)
 static int
 SProcXResQueryVersion(ClientPtr client)
 {
-    REQUEST(xXResQueryVersionReq);
     REQUEST_SIZE_MATCH(xXResQueryVersionReq);
     return ProcXResQueryVersion(client);
 }
commit 2f6e8eb70d527541178433933d6230466421bd15
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 22:02:58 2013 +0900

    damage: Clean up warnings
    
    GC funcs and ops are const now, so all wrappers need to declare them
    as such.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 173fe50..55d8c41 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -359,7 +359,7 @@ damageCreateGC(GCPtr pGC)
 
 #define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
     damageGCPriv(pGC);  \
-    GCFuncs *oldFuncs = pGC->funcs; \
+    const GCFuncs *oldFuncs = pGC->funcs; \
     unwrap(pGCPriv, pGC, funcs);  \
     unwrap(pGCPriv, pGC, ops); \
 
@@ -379,7 +379,6 @@ damageCreateGC(GCPtr pGC)
 static void
 damageValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 {
-    drawableDamage(pDrawable);
     DAMAGE_GC_FUNC_PROLOGUE(pGC);
     (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
     pGCPriv->ops = pGC->ops; /* just so it's not NULL */
diff --git a/miext/damage/damagestr.h b/miext/damage/damagestr.h
index 36753ee..2786156 100644
--- a/miext/damage/damagestr.h
+++ b/miext/damage/damagestr.h
@@ -76,8 +76,8 @@ typedef struct _damageScrPriv {
 } DamageScrPrivRec, *DamageScrPrivPtr;
 
 typedef struct _damageGCPriv {
-    GCOps *ops;
-    GCFuncs *funcs;
+    const GCOps *ops;
+    const GCFuncs *funcs;
 } DamageGCPrivRec, *DamageGCPrivPtr;
 
 /* XXX should move these into damage.c, damageScrPrivateIndex is static */
commit c706fb0db86d6946482700d65ad6803c4daaa6f9
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 22:00:29 2013 +0900

    Clean up warnings in mi.
    
    A coupel of unused variables, and some debug code with mis-matching
    printf format and variable types.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/mi/mieq.c b/mi/mieq.c
index 4c07480..bc7f945 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -585,7 +585,7 @@ mieqProcessInputEvents(void)
     if (n_enqueued >= (miEventQueue.nevents - (2 * QUEUE_RESERVED_SIZE)) &&
         miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) {
         ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n",
-               miEventQueue.nevents << 1);
+               (unsigned long) (miEventQueue.nevents << 1));
         if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) {
             ErrorF("[mi] Increasing the size of EQ failed.\n");
         }
@@ -593,7 +593,7 @@ mieqProcessInputEvents(void)
 
     if (miEventQueue.dropped) {
         ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n",
-               miEventQueue.dropped);
+               (unsigned long) miEventQueue.dropped);
         ErrorF
             ("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n");
         miEventQueue.dropped = 0;
diff --git a/mi/mipointer.c b/mi/mipointer.c
index 5d591a1..df027a7 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -352,7 +352,6 @@ miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     miPointerPtr pPointer;
     BOOL changedScreen = FALSE;
 
-    SetupScreen(pScreen);
     pPointer = MIPOINTER(pDev);
 
     if (pPointer->pScreen != pScreen) {
@@ -465,14 +464,12 @@ miPointerUpdateSprite(DeviceIntPtr pDev)
 void
 miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
 {
-    miPointerScreenPtr pScreenPriv;
     ScreenPtr pScreen;
     miPointerPtr pPointer;
 
     pPointer = MIPOINTER(pDev);
 
     pScreen = screenInfo.screens[screen_no];
-    pScreenPriv = GetScreenPrivate(pScreen);
     mieqSwitchScreen(pDev, pScreen, FALSE);
     NewCurrentScreen(pDev, pScreen, x, y);
 
commit d89b42bda46d36fc0879611cc3b3566957ce36d0
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 21:57:05 2013 +0900

    Clean up warnings in DIX
    
    As usual, mostly const char changes. However, filter_device_events had
    a potentially uninitialized value, 'raw', which I added a bunch of
    checks for. I suspect most of those are 'can't happen', but it's hard
    to see that inside the function.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/xvmc.c b/Xext/xvmc.c
index 5f0123b..2235fd5 100644
--- a/Xext/xvmc.c
+++ b/Xext/xvmc.c
@@ -800,8 +800,8 @@ XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
 }
 
 int
-xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
-                       char *busID, int major, int minor, int patchLevel)
+xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
+                       const char *busID, int major, int minor, int patchLevel)
 {
     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
 
diff --git a/Xext/xvmcext.h b/Xext/xvmcext.h
index 2201d7b..832e443 100644
--- a/Xext/xvmcext.h
+++ b/Xext/xvmcext.h
@@ -91,8 +91,8 @@ extern _X_EXPORT int XvMCScreenInit(ScreenPtr pScreen,
 
 extern _X_EXPORT XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id);
 
-extern _X_EXPORT int xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
-                                            char *busID, int major, int minor,
+extern _X_EXPORT int xf86XvMCRegisterDRInfo(ScreenPtr pScreen, const char *name,
+                                            const char *busID, int major, int minor,
                                             int patchLevel);
 
 #endif                          /* _XVMC_H */
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 8dcd9cb..64f8ef9 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -470,7 +470,7 @@ Dispatch(void)
 }
 
 static int VendorRelease = VENDOR_RELEASE;
-static char *VendorString = VENDOR_NAME;
+static const char *VendorString = VENDOR_NAME;
 
 void
 SetVendorRelease(int release)
@@ -479,7 +479,7 @@ SetVendorRelease(int release)
 }
 
 void
-SetVendorString(char *string)
+SetVendorString(const char *string)
 {
     VendorString = string;
 }
diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 2e34d37..57177ac 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -128,7 +128,7 @@ dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars,
  * adding RT_FONT prevents conflict with default cursor font
  */
 Bool
-SetDefaultFont(char *defaultfontname)
+SetDefaultFont(const char *defaultfontname)
 {
     int err;
     FontPtr pf;
@@ -224,7 +224,7 @@ FreeFPE(FontPathElementPtr fpe)
     fpe->refcount--;
     if (fpe->refcount == 0) {
         (*fpe_functions[fpe->type].free_fpe) (fpe);
-        free(fpe->name);
+        free((void *) fpe->name);
         free(fpe);
     }
 }
@@ -288,7 +288,7 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 
         if (err == FontNameAlias && alias) {
             newlen = strlen(alias);
-            newname = (char *) realloc(c->fontname, newlen);
+            newname = (char *) realloc((char *) c->fontname, newlen);
             if (!newname) {
                 err = AllocError;
                 break;
@@ -368,14 +368,14 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
         FreeFPE(c->fpe_list[i]);
     }
     free(c->fpe_list);
-    free(c->fontname);
+    free((void *) c->fontname);
     free(c);
     return TRUE;
 }
 
 int
 OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
-         char *pfontname)
+         const char *pfontname)
 {
     OFclosurePtr c;
     int i;
@@ -426,7 +426,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
      */
     c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes);
     if (!c->fpe_list) {
-        free(c->fontname);
+        free((void *) c->fontname);
         free(c);
         return BadAlloc;
     }
@@ -1537,7 +1537,7 @@ ImageText(ClientPtr client, DrawablePtr pDraw, GC * pGC, int nChars,
 
 /* does the necessary magic to figure out the fpe type */
 static int
-DetermineFPEType(char *pathname)
+DetermineFPEType(const char *pathname)
 {
     int i;
 
@@ -1633,21 +1633,23 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
             }
             /* if error or can't do it, act like it's a new one */
             if (!fpe) {
+                char *name;
                 fpe = malloc(sizeof(FontPathElementRec));
                 if (!fpe) {
                     err = BadAlloc;
                     goto bail;
                 }
-                fpe->name = malloc(len + 1);
-                if (!fpe->name) {
+                name = malloc(len + 1);
+                if (!name) {
                     free(fpe);
                     err = BadAlloc;
                     goto bail;
                 }
                 fpe->refcount = 1;
 
-                strncpy(fpe->name, (char *) cp, (int) len);
-                fpe->name[len] = '\0';
+                strncpy(name, (char *) cp, (int) len);
+                name[len] = '\0';
+                fpe->name = name;
                 fpe->name_length = len;
                 fpe->type = DetermineFPEType(fpe->name);
                 if (fpe->type == -1)
@@ -1660,7 +1662,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
                             ("[dix] Could not init font path element %s, removing from list!\n",
                              fpe->name);
                     }
-                    free(fpe->name);
+                    free((void *) fpe->name);
                     free(fpe);
                 }
             }
@@ -1712,9 +1714,10 @@ SetFontPath(ClientPtr client, int npaths, unsigned char *paths)
 }
 
 int
-SetDefaultFontPath(char *path)
+SetDefaultFontPath(const char *path)
 {
-    char *temp_path, *start, *end;
+    const char *start, *end;
+    char *temp_path;
     unsigned char *cp, *pp, *nump, *newpath;
     int num = 1, len, err, size = 0, bad;
 
diff --git a/dix/events.c b/dix/events.c
index 4aaa54c..e198112 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2671,6 +2671,9 @@ DeliverOneEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level,
     case CORE:
         rc = EventToCore(event, &xE, &count);
         break;
+    default:
+        rc = BadImplementation;
+        break;
     }
 
     if (rc == Success) {
@@ -3828,6 +3831,8 @@ MatchForType(const GrabPtr grab, GrabPtr tmp, enum InputLevel level,
         match = CORE_MATCH;
         ignore_device = TRUE;
         break;
+    default:
+        return NO_MATCH;
     }
 
     tmp->grabtype = grabtype;
diff --git a/dix/extension.c b/dix/extension.c
index 6380db3..ede4bf5 100644
--- a/dix/extension.c
+++ b/dix/extension.c
@@ -96,7 +96,7 @@ AddExtension(const char *name, int NumEvents, int NumErrors,
     }
     ext->name = strdup(name);
     ext->num_aliases = 0;
-    ext->aliases = (char **) NULL;
+    ext->aliases = (const char **) NULL;
     if (!ext->name) {
         dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
         free(ext);
@@ -106,7 +106,7 @@ AddExtension(const char *name, int NumEvents, int NumErrors,
     newexts = (ExtensionEntry **) realloc(extensions,
                                           (i + 1) * sizeof(ExtensionEntry *));
     if (!newexts) {
-        free(ext->name);
+        free((void *) ext->name);
         dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION);
         free(ext);
         return ((ExtensionEntry *) NULL);
@@ -147,12 +147,12 @@ Bool
 AddExtensionAlias(const char *alias, ExtensionEntry * ext)
 {
     char *name;
-    char **aliases;
+    const char **aliases;
 
     if (!ext)
         return FALSE;
-    aliases = (char **) realloc(ext->aliases,
-                                (ext->num_aliases + 1) * sizeof(char *));
+    aliases = realloc(ext->aliases,
+                      (ext->num_aliases + 1) * sizeof(char *));
     if (!aliases)
         return FALSE;
     ext->aliases = aliases;
@@ -229,9 +229,9 @@ CloseDownExtensions(void)
         if (extensions[i]->CloseDown)
             extensions[i]->CloseDown(extensions[i]);
         NumExtensions = i;
-        free(extensions[i]->name);
+        free((void *) extensions[i]->name);
         for (j = extensions[i]->num_aliases; --j >= 0;)
-            free(extensions[i]->aliases[j]);
+            free((void *) extensions[i]->aliases[j]);
         free(extensions[i]->aliases);
         dixFreePrivates(extensions[i]->devPrivates, PRIVATE_EXTENSION);
         free(extensions[i]);
diff --git a/dix/getevents.c b/dix/getevents.c
index 14b65ca..646c723 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1382,10 +1382,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
 {
     int num_events = 1;
     DeviceEvent *event;
-    RawDeviceEvent *raw;
+    RawDeviceEvent *raw = NULL;
     double screenx = 0.0, screeny = 0.0;        /* desktop coordinate system */
     double devx = 0.0, devy = 0.0;      /* desktop-wide in device coords */
-    int sx, sy;                         /* for POINTER_SCREEN */
+    int sx = 0, sy = 0;                 /* for POINTER_SCREEN */
     ValuatorMask mask;
     ScreenPtr scr;
     int num_barrier_events = 0;
@@ -1437,7 +1437,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
 
         transformAbsolute(pDev, &mask);
         clipAbsolute(pDev, &mask);
-        if ((flags & POINTER_NORAW) == 0)
+        if ((flags & POINTER_NORAW) == 0 && raw)
             set_raw_valuators(raw, &mask, raw->valuators.data);
     }
     else {
@@ -1445,7 +1445,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
 
         if (flags & POINTER_ACCELERATE)
             accelPointer(pDev, &mask, ms);
-        if ((flags & POINTER_NORAW) == 0)
+        if ((flags & POINTER_NORAW) == 0 && raw)
             set_raw_valuators(raw, &mask, raw->valuators.data);
 
         moveRelative(pDev, flags, &mask);
@@ -1512,7 +1512,8 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
 
     if (flags & POINTER_EMULATED) {
-        raw->flags = XIPointerEmulated;
+        if (raw)
+            raw->flags = XIPointerEmulated;
         event->flags = XIPointerEmulated;
     }
 
diff --git a/dix/globals.c b/dix/globals.c
index ad9145b..9738e9c 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -112,9 +112,9 @@ int defaultScreenSaverAllowExposures = DEFAULT_SCREEN_SAVER_EXPOSURES;
 Bool screenSaverSuspended = FALSE;
 #endif
 
-char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
-char *defaultTextFont = COMPILEDDEFAULTFONT;
-char *defaultCursorFont = COMPILEDCURSORFONT;
+const char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
+const char *defaultTextFont = COMPILEDDEFAULTFONT;
+const char *defaultCursorFont = COMPILEDCURSORFONT;
 FontPtr defaultFont;            /* not declared in dix.h to avoid including font.h in
                                    every compilation of dix code */
 CursorPtr rootCursor;
@@ -126,7 +126,7 @@ TimeStamp currentTime;
 int defaultColorVisualClass = -1;
 int monitorResolution = 0;
 
-char *display;
+const char *display;
 int displayfd;
 char *ConnectionInfo;
 
diff --git a/dix/window.c b/dix/window.c
index 0e9109e..fad57fa 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -227,7 +227,7 @@ log_window_info(WindowPtr pWin, int depth)
 
     win_name = get_window_name(pWin);
     ErrorF("win 0x%.8x (%s), [%d, %d] to [%d, %d]",
-           pWin->drawable.id,
+           (unsigned) pWin->drawable.id,
            win_name ? win_name : "no name",
            pWin->drawable.x, pWin->drawable.y,
            pWin->drawable.x + pWin->drawable.width,
@@ -240,7 +240,7 @@ log_window_info(WindowPtr pWin, int depth)
         ErrorF(" (%s compositing: pixmap %x)",
                (pWin->redirectDraw == RedirectDrawAutomatic) ?
                "automatic" : "manual",
-               pScreen->GetWindowPixmap(pWin)->drawable.id);
+               (unsigned) pScreen->GetWindowPixmap(pWin)->drawable.id);
 #endif
 
     switch (pWin->visibility) {
@@ -283,7 +283,7 @@ PrintWindowTree(void)
     for (scrnum = 0; scrnum < screenInfo.numScreens; scrnum++) {
         pScreen = screenInfo.screens[scrnum];
         ErrorF("[dix] Dumping windows for screen %d (pixmap %x):\n", scrnum,
-               pScreen->GetScreenPixmap(pScreen)->drawable.id);
+               (unsigned) pScreen->GetScreenPixmap(pScreen)->drawable.id);
         pWin = pScreen->root;
         depth = 1;
         while (pWin) {
diff --git a/include/closestr.h b/include/closestr.h
index c6aa129..d762891 100644
--- a/include/closestr.h
+++ b/include/closestr.h
@@ -47,7 +47,7 @@ typedef struct _OFclosure {
     Mask flags;
 
 /* XXX -- get these from request buffer instead? */
-    char *origFontName;
+    const char *origFontName;
     int origFontNameLen;
     XID fontid;
     char *fontname;
diff --git a/include/dix.h b/include/dix.h
index fa7ccd4..7362e07 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -289,7 +289,10 @@ extern _X_EXPORT void
 SetVendorRelease(int release);
 
 extern _X_EXPORT void
-SetVendorString(char *string);
+SetVendorString(const char *string);
+
+int
+dix_main(int argc, char *argv[], char *envp[]);
 
 /* events.c */
 
diff --git a/include/dixfont.h b/include/dixfont.h
index 0a5f105..0598311 100644
--- a/include/dixfont.h
+++ b/include/dixfont.h
@@ -34,7 +34,7 @@ SOFTWARE.
 
 typedef struct _DIXFontProp *DIXFontPropPtr;
 
-extern _X_EXPORT Bool SetDefaultFont(char * /*defaultfontname */ );
+extern _X_EXPORT Bool SetDefaultFont(const char * /*defaultfontname */ );
 
 extern _X_EXPORT void QueueFontWakeup(FontPathElementPtr /*fpe */ );
 
@@ -48,7 +48,7 @@ extern _X_EXPORT int OpenFont(ClientPtr /*client */ ,
                               XID /*fid */ ,
                               Mask /*flags */ ,
                               unsigned /*lenfname */ ,
-                              char * /*pfontname */ );
+                              const char * /*pfontname */ );
 
 extern _X_EXPORT int CloseFont(pointer /*pfont */ ,
                                XID /*fid */ );
@@ -99,7 +99,7 @@ extern _X_EXPORT int SetFontPath(ClientPtr /*client */ ,
                                  int /*npaths */ ,
                                  unsigned char * /*paths */ );
 
-extern _X_EXPORT int SetDefaultFontPath(char * /*path */ );
+extern _X_EXPORT int SetDefaultFontPath(const char * /*path */ );
 
 extern _X_EXPORT int GetFontPath(ClientPtr client,
                                  int *count,
diff --git a/include/extnsionst.h b/include/extnsionst.h
index e825236..126807d 100644
--- a/include/extnsionst.h
+++ b/include/extnsionst.h
@@ -58,14 +58,14 @@ typedef struct _ExtensionEntry {
     int index;
     void (*CloseDown) (         /* called at server shutdown */
                           struct _ExtensionEntry * /* extension */ );
-    char *name;                 /* extension name */
+    const char *name;           /* extension name */
     int base;                   /* base request number */
     int eventBase;
     int eventLast;
     int errorBase;
     int errorLast;
     int num_aliases;
-    char **aliases;
+    const char **aliases;
     pointer extPrivate;
     unsigned short (*MinorOpcode) (     /* called for errors */
                                       ClientPtr /* client */ );
diff --git a/include/gcstruct.h b/include/gcstruct.h
index 7621ceb..253593f 100644
--- a/include/gcstruct.h
+++ b/include/gcstruct.h
@@ -276,8 +276,8 @@ typedef struct _GC {
     pointer clientClip;
     unsigned long stateChanges; /* masked with GC_<kind> */
     unsigned long serialNumber;
-    GCFuncs *funcs;
-    GCOps *ops;
+    const GCFuncs *funcs;
+    const GCOps *ops;
     PrivateRec *devPrivates;
     /*
      * The following were moved here from private storage to allow device-
diff --git a/include/globals.h b/include/globals.h
index 7786987..858c9a3 100644
--- a/include/globals.h
+++ b/include/globals.h
@@ -18,7 +18,7 @@ extern _X_EXPORT CARD32 ScreenSaverInterval;
 extern _X_EXPORT Bool screenSaverSuspended;
 #endif
 
-extern _X_EXPORT char *defaultFontPath;
+extern _X_EXPORT const char *defaultFontPath;
 extern _X_EXPORT int monitorResolution;
 extern _X_EXPORT int defaultColorVisualClass;
 
diff --git a/include/opaque.h b/include/opaque.h
index b76ab6e..73d40c3 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -33,8 +33,8 @@ from The Open Group.
 
 #include "globals.h"
 
-extern _X_EXPORT char *defaultTextFont;
-extern _X_EXPORT char *defaultCursorFont;
+extern _X_EXPORT const char *defaultTextFont;
+extern _X_EXPORT const char *defaultCursorFont;
 extern _X_EXPORT int MaxClients;
 extern _X_EXPORT volatile char isItTimeToYield;
 extern _X_EXPORT volatile char dispatchException;
@@ -49,7 +49,7 @@ extern _X_EXPORT int ScreenSaverBlanking;
 extern _X_EXPORT int ScreenSaverAllowExposures;
 extern _X_EXPORT int defaultScreenSaverBlanking;
 extern _X_EXPORT int defaultScreenSaverAllowExposures;
-extern _X_EXPORT char *display;
+extern _X_EXPORT const char *display;
 extern _X_EXPORT int displayfd;
 
 extern _X_EXPORT int defaultBackingStore;
commit d6da9f23cca562fc0c6ae398665ab7fa770a4fa8
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 18:07:54 2013 +0900

    hw/xfree86: More const declarations for strings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 37ac42c..143be1e 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -389,7 +389,7 @@ extern _X_EXPORT ModeStatus
 xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags);
 extern _X_EXPORT int
 xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
-                  char **modeNames, ClockRangePtr clockRanges,
+                  const char **modeNames, ClockRangePtr clockRanges,
                   int *linePitches, int minPitch, int maxPitch,
                   int minHeight, int maxHeight, int pitchInc,
                   int virtualX, int virtualY, int apertureSize,
diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 15214ea..44bc559 100644
--- a/hw/xfree86/common/xf86Mode.c
+++ b/hw/xfree86/common/xf86Mode.c
@@ -1354,7 +1354,7 @@ scanLineWidth(unsigned int xsize,       /* pixels */
 
 int
 xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
-                  char **modeNames, ClockRangePtr clockRanges,
+                  const char **modeNames, ClockRangePtr clockRanges,
                   int *linePitches, int minPitch, int maxPitch, int pitchInc,
                   int minHeight, int maxHeight, int virtualX, int virtualY,
                   int apertureSize, LookupModeFlags strategy)
commit 644725ac5e28a00d8c24372f55ae7e7e2fe0cb2e
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 18:06:37 2013 +0900

    Just remove dpms functsion from xf86.h
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 206a9d7..37ac42c 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -203,10 +203,6 @@ extern _X_EXPORT void xf86ReconfigureLayout(void);
 extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set,
                                    int flags);
 
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
-
 /* xf86DGA.c */
 
 #ifdef XFreeXDGA
commit c85e26d59901fbf8c7a437cf934b51fa64160073
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 17:55:15 2013 +0900

    Bunch of DMX warning fixes
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/dmx/config/Canvas.c b/hw/dmx/config/Canvas.c
index f0586e5..1031033 100644
--- a/hw/dmx/config/Canvas.c
+++ b/hw/dmx/config/Canvas.c
@@ -98,10 +98,10 @@ static XtResource resources[] = {
     {XtNcallback, XtCCallback, XtRCallback,
      sizeof(XtCallbackList), offset(input_callback), XtRCallback, NULL}
     ,
-    {XtNcanvasExposeCallback, XtCcanvasExposeCallback, XtRCallback,
+    {(char *) XtNcanvasExposeCallback, (char *) XtCcanvasExposeCallback, XtRCallback,
      sizeof(XtCallbackList), offset(expose_callback), XtRCallback, NULL}
     ,
-    {XtNcanvasResizeCallback, XtCcanvasResizeCallback, XtRCallback,
+    {(char *) XtNcanvasResizeCallback, (char *) XtCcanvasResizeCallback, XtRCallback,
      sizeof(XtCallbackList), offset(resize_callback), XtRCallback, NULL}
     ,
 };
@@ -109,7 +109,7 @@ static XtResource resources[] = {
 #undef offset
 
 static XtActionsRec actions[] = {
-    {"canvas", CanvasAction},
+    {(char *) "canvas", CanvasAction},
 };
 
 static char translations[] = "<Key>:    canvas()\n\
@@ -123,7 +123,7 @@ CanvasClassRec canvasClassRec = {
     /* core */
     {
      (WidgetClass) Superclass,  /* superclass */
-     "Canvas",                  /* class_name */
+     (char *) "Canvas",         /* class_name */
      sizeof(CanvasRec),         /* widget_size */
      NULL,                      /* class_initialize */
      NULL,                      /* class_part_initialize */
diff --git a/hw/dmx/config/xdmxconfig.c b/hw/dmx/config/xdmxconfig.c
index 2121dd7..2b7b968 100644
--- a/hw/dmx/config/xdmxconfig.c
+++ b/hw/dmx/config/xdmxconfig.c
@@ -974,9 +974,9 @@ main(int argc, char **argv)
     const char *canvastrans =
         "<Btn3Down>: placeMenu() XtMenuPopup(buttonpopup)";
     XtActionsRec actiontable[] = {
-        {"openOk", dmxConfigOkAction},
-        {"placeMenu", dmxConfigPlaceMenu},
-        {"noop", NULL}
+        {(char *) "openOk", dmxConfigOkAction},
+        {(char *) "placeMenu", dmxConfigPlaceMenu},
+        {(char *) "noop", NULL}
     };
 
     dmxConfigFilename = XtNewString((argc >= 2) ? argv[1] : "");
diff --git a/hw/dmx/dmxclient.h b/hw/dmx/dmxclient.h
index 19dfdbe..be8116f 100644
--- a/hw/dmx/dmxclient.h
+++ b/hw/dmx/dmxclient.h
@@ -118,17 +118,6 @@ typedef XID KeySym64;
 #undef KeySym
 #endif
 
-/* These are in exglobals.h, but that conflicts with xkbsrv.h */
-extern int ProximityIn;
-extern int ProximityOut;
-extern int DeviceValuator;
-extern int DeviceMotionNotify;
-extern int DeviceFocusIn;
-extern int DeviceFocusOut;
-extern int DeviceStateNotify;
-extern int DeviceMappingNotify;
-extern int ChangeDeviceNotify;
-
 /* Some protocol gets included last, after undefines. */
 #include <X11/XKBlib.h>
 #include <X11/extensions/XKBproto.h>
diff --git a/hw/dmx/input/dmxcommon.c b/hw/dmx/input/dmxcommon.c
index db558b5..6eb94b2 100644
--- a/hw/dmx/input/dmxcommon.c
+++ b/hw/dmx/input/dmxcommon.c
@@ -339,7 +339,7 @@ dmxCommonOthOn(DevicePtr pDev)
     if (!(priv->xi = XOpenDevice(priv->display, dmxLocal->deviceId))) {
         dmxLog(dmxWarning, "Cannot open %s device (id=%d) on %s\n",
                dmxLocal->deviceName ? dmxLocal->deviceName : "(unknown)",
-               dmxLocal->deviceId, dmxInput->name);
+               (int) dmxLocal->deviceId, dmxInput->name);
         return -1;
     }
     ADD(DeviceKeyPress);
diff --git a/hw/dmx/input/dmxconsole.c b/hw/dmx/input/dmxconsole.c
index 600a705..cb80bd8 100644
--- a/hw/dmx/input/dmxconsole.c
+++ b/hw/dmx/input/dmxconsole.c
@@ -825,8 +825,8 @@ dmxConsoleInit(DevicePtr pDev)
 
     /* Set up properties */
     XStoreName(dpy, win, DMX_CONSOLE_NAME);
-    class_hints.res_name = DMX_RES_NAME;
-    class_hints.res_class = DMX_RES_CLASS;
+    class_hints.res_name = (char *) DMX_RES_NAME;
+    class_hints.res_class = (char *) DMX_RES_CLASS;
     XSetClassHint(dpy, win, &class_hints);
 
     /* Map the window */
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index bcb5c2e..14ac05f 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -701,7 +701,6 @@ dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
            XEvent * e, DMXBlockType block)
 {
     GETDMXINPUTFROMPDEV;
-    xEvent xE;
     DeviceIntPtr p = dmxLocal->pDevice;
     int valuators[3];
     ValuatorMask mask;
@@ -716,7 +715,7 @@ dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
         if (dmxCheckFunctionKeys(dmxLocal, type, keySym))
             return;
         if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
-            xE.u.u.detail = dmxFixup(pDev, detail, keySym);
+            detail = dmxFixup(pDev, detail, keySym);
 
         /*ErrorF("KEY %d  sym %d\n", detail, (int) keySym); */
         QueueKeyboardEvents(p, type, detail, NULL);
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index b22a41f..e06fc87 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -921,7 +921,7 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
                 break;
             }
             dmxLogInput(dmxInput, "  %2d %-10.10s %-16.16s\n",
-                        devices[i].id,
+                        (int) devices[i].id,
                         devices[i].name ? devices[i].name : "", use);
         }
 
@@ -993,7 +993,6 @@ dmxInputLateReInit(DMXInputInfo * dmxInput)
 void
 dmxInputInit(DMXInputInfo * dmxInput)
 {
-    DeviceIntPtr pPointer = NULL, pKeyboard = NULL;
     dmxArg a;
     const char *name;
     int i;
@@ -1108,12 +1107,6 @@ dmxInputInit(DMXInputInfo * dmxInput)
         DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
 
         dmxLocal->pDevice = dmxAddDevice(dmxLocal);
-        if (dmxLocal->isCore) {
-            if (dmxLocal->type == DMX_LOCAL_MOUSE)
-                pPointer = dmxLocal->pDevice;
-            if (dmxLocal->type == DMX_LOCAL_KEYBOARD)
-                pKeyboard = dmxLocal->pDevice;
-        }
     }
 
     dmxInput->processInputEvents = dmxProcessInputEvents;
@@ -1136,7 +1129,7 @@ dmxInputFreeLocal(DMXLocalInputInfoRec * local)
         local->destroy_private(local->private);
     free(local->history);
     free(local->valuators);
-    free(local->deviceName);
+    free((void *) local->deviceName);
     local->private = NULL;
     local->history = NULL;
     local->deviceName = NULL;
@@ -1164,7 +1157,7 @@ dmxInputFree(DMXInputInfo * dmxInput)
     dmxInput->devs = NULL;
     dmxInput->numDevs = 0;
     if (dmxInput->freename)
-        free(dmxInput->name);
+        free((void *) dmxInput->name);
     dmxInput->name = NULL;
 }
 
@@ -1218,7 +1211,7 @@ dmxInputLogDevices(void)
                 dmxLogCont(dmxInfo, "\t[i%d/%*.*s",
                            dmxInput->inputIdx, len, len, dmxInput->name);
                 if (dmxInput->devs[i]->deviceId >= 0)
-                    dmxLogCont(dmxInfo, "/id%d", dmxInput->devs[i]->deviceId);
+                    dmxLogCont(dmxInfo, "/id%d", (int) dmxInput->devs[i]->deviceId);
                 if (dmxInput->devs[i]->deviceName)
                     dmxLogCont(dmxInfo, "=%s", dmxInput->devs[i]->deviceName);
                 dmxLogCont(dmxInfo, "] %s\n",
commit 493d992501b586d95823e045d1dc994bd6c00d27
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 17:43:46 2013 +0900

    More warning fixes in hw/xfree86
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/i2c/bt829.c b/hw/xfree86/i2c/bt829.c
index 070cb20..991c26e 100644
--- a/hw/xfree86/i2c/bt829.c
+++ b/hw/xfree86/i2c/bt829.c
@@ -500,6 +500,7 @@ bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
 {
     BT829Ptr bt;
     I2CByte a;
+    char *devname;
 
     bt = calloc(1, sizeof(BT829Rec));
     if (bt == NULL)
@@ -520,31 +521,31 @@ bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
 
     bt->id = btread(bt, IDCODE);
 
-    free(bt->d.DevName);
-    bt->d.DevName = calloc(200, sizeof(char));
+    free((void *) bt->d.DevName);
+    bt->d.DevName = devname = calloc(200, sizeof(char));
     switch (BTVERSION) {
     case BT815:
-        sprintf(bt->d.DevName, "bt815a video decoder, revision %d",
+        sprintf(devname, "bt815a video decoder, revision %d",
                 bt->id & 0xf);
         break;
     case BT817:
-        sprintf(bt->d.DevName, "bt817a video decoder, revision %d",
+        sprintf(devname, "bt817a video decoder, revision %d",
                 bt->id & 0xf);
         break;
     case BT819:
-        sprintf(bt->d.DevName, "bt819a video decoder, revision %d",
+        sprintf(devname, "bt819a video decoder, revision %d",
                 bt->id & 0xf);
         break;
     case BT827:
-        sprintf(bt->d.DevName, "bt827a/b video decoder, revision %d",
+        sprintf(devname, "bt827a/b video decoder, revision %d",
                 bt->id & 0xf);
         break;
     case BT829:
-        sprintf(bt->d.DevName, "bt829a/b video decoder, revision %d",
+        sprintf(devname, "bt829a/b video decoder, revision %d",
                 bt->id & 0xf);
         break;
     default:
-        sprintf(bt->d.DevName,
+        sprintf(devname,
                 "bt8xx/unknown video decoder version %d, revision %d",
                 bt->id >> 4, bt->id & 0xf);
         break;
diff --git a/hw/xfree86/i2c/msp3430.c b/hw/xfree86/i2c/msp3430.c
index 312a2d1..a501489 100644
--- a/hw/xfree86/i2c/msp3430.c
+++ b/hw/xfree86/i2c/msp3430.c
@@ -163,7 +163,7 @@ DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr)
     m->d.ByteTimeout = b->ByteTimeout;
 
     if (!I2C_WriteRead(&(m->d), NULL, 0, &a, 1)) {
-        free(m->d.DevName);
+        free((void *) m->d.DevName);
         free(m);
         return NULL;
     }
@@ -250,12 +250,12 @@ DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr)
                supported ? "" : " (unsupported)", rom_version, m->chip_id);
 
     if (!supported) {
-        free(m->d.DevName);
+        free((void *) m->d.DevName);
         free(m);
         return NULL;
     }
     if (!I2CDevInit(&(m->d))) {
-        free(m->d.DevName);
+        free((void *) m->d.DevName);
         free(m);
         return NULL;
     }
diff --git a/hw/xfree86/vbe/vbeModes.c b/hw/xfree86/vbe/vbeModes.c
index 415167d..40bd985 100644
--- a/hw/xfree86/vbe/vbeModes.c
+++ b/hw/xfree86/vbe/vbeModes.c
@@ -356,8 +356,10 @@ VBESetModeNames(DisplayModePtr pMode)
                 pMode->name = strdup("BADMODE");
             }
             else {
-                XNFasprintf(&pMode->name, "%dx%d",
+                char *tmp;
+                XNFasprintf(&tmp, "%dx%d",
                             pMode->HDisplay, pMode->VDisplay);
+                pMode->name = tmp;
             }
         }
         pMode = pMode->next;
commit c78be3a4b714deb7ad75cacd54042ca1b51d6261
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 17:36:26 2013 +0900

    xfree86 warning reduction
    
    This gets the easy warnings, mostly constant string problems.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/ddc/ddc.c b/hw/xfree86/ddc/ddc.c
index 44c1d53..04d1a09 100644
--- a/hw/xfree86/ddc/ddc.c
+++ b/hw/xfree86/ddc/ddc.c
@@ -299,7 +299,7 @@ xf86DoEDID_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDC1SetSpeed,
 /* DDC2 */
 
 static I2CDevPtr
-DDC2MakeDevice(I2CBusPtr pBus, int address, char *name)
+DDC2MakeDevice(I2CBusPtr pBus, int address, const char *name)
 {
     I2CDevPtr dev = NULL;
 
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0b047f0..34cc02f 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1563,8 +1563,6 @@ DRI2CloseScreen(ScreenPtr pScreen)
     dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
 }
 
-extern Bool DRI2ModuleSetup(void);
-
 /* Called by InitExtensions() */
 Bool
 DRI2ModuleSetup(void)
diff --git a/hw/xfree86/i2c/xf86i2c.h b/hw/xfree86/i2c/xf86i2c.h
index e296d7d..26303ff 100644
--- a/hw/xfree86/i2c/xf86i2c.h
+++ b/hw/xfree86/i2c/xf86i2c.h
@@ -66,7 +66,7 @@ extern _X_EXPORT int xf86I2CGetScreenBuses(int scrnIndex,
 /* I2C slave devices */
 
 typedef struct _I2CDevRec {
-    char *DevName;
+    const char *DevName;
 
     int BitTimeout;             /* usec */
     int ByteTimeout;            /* usec */
diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index 1c58cf7..925da3c 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -170,7 +170,7 @@ dump_code(xf86Int10InfoPtr pInt)
     CARD32 lina = SEG_ADR((CARD32), X86_CS, IP);
 
     xf86DrvMsgVerb(pInt->pScrn->scrnIndex, X_INFO, 3, "code at 0x%8.8" PRIx32 ":\n",
-                   lina);
+                   (unsigned) lina);
     for (i = 0; i < 0x10; i++)
         xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
     xf86ErrorFVerb(3, "\n");
@@ -229,7 +229,7 @@ port_rep_inb(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insb(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         MEM_WB(pInt, dst, x_inb(port));
         dst += inc;
@@ -246,7 +246,7 @@ port_rep_inw(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insw(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         MEM_WW(pInt, dst, x_inw(port));
         dst += inc;
@@ -263,7 +263,7 @@ port_rep_inl(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_insl(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         MEM_WL(pInt, dst, x_inl(port));
         dst += inc;
@@ -280,7 +280,7 @@ port_rep_outb(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outb(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         x_outb(port, MEM_RB(pInt, dst));
         dst += inc;
@@ -297,7 +297,7 @@ port_rep_outw(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outw(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         x_outw(port, MEM_RW(pInt, dst));
         dst += inc;
@@ -314,7 +314,7 @@ port_rep_outl(xf86Int10InfoPtr pInt,
 
     if (PRINT_PORT && DEBUG_IO_TRACE())
         ErrorF(" rep_outl(%#x) %" PRIu32 " bytes at %8.8" PRIx32 " %s\n",
-               port, count, base, d_f ? "up" : "down");
+               port, (unsigned) count, (unsigned) base, d_f ? "up" : "down");
     while (count--) {
         x_outl(port, MEM_RL(pInt, dst));
         dst += inc;
@@ -429,7 +429,7 @@ x_inl(CARD16 port)
     if (!pciCfg1in(port, &val)) {
         val = pci_io_read32(Int10Current->io, port);
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" inl(%#x) = %8.8" PRIx32 "\n", port, val);
+            ErrorF(" inl(%#x) = %8.8" PRIx32 "\n", port, (unsigned) val);
     }
     return val;
 }
@@ -439,7 +439,7 @@ x_outl(CARD16 port, CARD32 val)
 {
     if (!pciCfg1out(port, val)) {
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" outl(%#x, %8.8" PRIx32 ")\n", port, val);
+            ErrorF(" outl(%#x, %8.8" PRIx32 ")\n", port, (unsigned) val);
         pci_io_write32(Int10Current->io, port, val);
     }
 }
@@ -526,8 +526,8 @@ pciCfg1in(CARD16 addr, CARD32 *val)
         pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
                                 (uint32_t *) val, PCI_OFFSET(PciCfg1Addr));
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_inl(%#" PRIx32 ") = %8.8" PRIx32 "\n", PciCfg1Addr,
-                   *val);
+            ErrorF(" cfg_inl(%#" PRIx32 ") = %8.8" PRIx32 "\n", (unsigned) PciCfg1Addr,
+                   (unsigned) *val);
         return 1;
     }
     return 0;
@@ -542,8 +542,8 @@ pciCfg1out(CARD16 addr, CARD32 val)
     }
     if (addr == 0xCFC) {
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_outl(%#" PRIx32 ", %8.8" PRIx32 ")\n", PciCfg1Addr,
-                   val);
+            ErrorF(" cfg_outl(%#" PRIx32 ", %8.8" PRIx32 ")\n", (unsigned) PciCfg1Addr,
+                   (unsigned) val);
         pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr), val,
                                  PCI_OFFSET(PciCfg1Addr));
         return 1;
@@ -567,8 +567,8 @@ pciCfg1inw(CARD16 addr, CARD16 *val)
         pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
                                 val, PCI_OFFSET(PciCfg1Addr) + offset);
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_inw(%#" PRIx32 ") = %4.4x\n", PciCfg1Addr + offset,
-                   *val);
+            ErrorF(" cfg_inw(%#" PRIx32 ") = %4.4x\n", (unsigned) (PciCfg1Addr + offset),
+                   (unsigned) *val);
         return 1;
     }
     return 0;
@@ -589,8 +589,8 @@ pciCfg1outw(CARD16 addr, CARD16 val)
         const unsigned offset = addr - 0xCFC;
 
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_outw(%#" PRIx32 ", %4.4x)\n", PciCfg1Addr + offset,
-                   val);
+            ErrorF(" cfg_outw(%#" PRIx32 ", %4.4x)\n", (unsigned) (PciCfg1Addr + offset),
+                   (unsigned) val);
         pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr), val,
                                  PCI_OFFSET(PciCfg1Addr) + offset);
         return 1;
@@ -614,8 +614,8 @@ pciCfg1inb(CARD16 addr, CARD8 *val)
         pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
                                val, PCI_OFFSET(PciCfg1Addr) + offset);
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_inb(%#" PRIx32 ") = %2.2x\n", PciCfg1Addr + offset,
-                   *val);
+            ErrorF(" cfg_inb(%#" PRIx32 ") = %2.2x\n", (unsigned) (PciCfg1Addr + offset),
+                   (unsigned) *val);
         return 1;
     }
     return 0;
@@ -636,8 +636,8 @@ pciCfg1outb(CARD16 addr, CARD8 val)
         const unsigned offset = addr - 0xCFC;
 
         if (PRINT_PORT && DEBUG_IO_TRACE())
-            ErrorF(" cfg_outb(%#" PRIx32 ", %2.2x)\n", PciCfg1Addr + offset,
-                   val);
+            ErrorF(" cfg_outb(%#" PRIx32 ", %2.2x)\n", (unsigned) (PciCfg1Addr + offset),
+                   (unsigned) val);
         pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr), val,
                                 PCI_OFFSET(PciCfg1Addr) + offset);
         return 1;
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a441fd1..b2eb72e 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -379,7 +379,7 @@ xf86CrtcSetModeTransform(xf86CrtcPtr crtc, DisplayModePtr mode,
         crtc->transformPresent = saved_transform_present;
     }
 
-    free(adjusted_mode->name);
+    free((void *) adjusted_mode->name);
     free(adjusted_mode);
 
     if (didLock)
@@ -564,8 +564,8 @@ static const char *direction[4] = {
 static Rotation
 xf86OutputInitialRotation(xf86OutputPtr output)
 {
-    char *rotate_name = xf86GetOptValString(output->options,
-                                            OPTION_ROTATE);
+    const char *rotate_name = xf86GetOptValString(output->options,
+                                                  OPTION_ROTATE);
     int i;
 
     if (!rotate_name) {
@@ -926,7 +926,6 @@ xf86PickCrtcs(ScrnInfoPtr scrn,
     xf86OutputPtr output;
     xf86CrtcPtr crtc;
     xf86CrtcPtr *crtcs;
-    xf86CrtcPtr best_crtc;
     int best_score;
     int score;
     int my_score;
@@ -939,7 +938,6 @@ xf86PickCrtcs(ScrnInfoPtr scrn,
      * Compute score with this output disabled
      */
     best_crtcs[n] = NULL;
-    best_crtc = NULL;
     best_score = xf86PickCrtcs(scrn, best_crtcs, modes, n + 1, width, height);
     if (modes[n] == NULL)
         return best_score;
@@ -993,7 +991,6 @@ xf86PickCrtcs(ScrnInfoPtr scrn,
         score =
             my_score + xf86PickCrtcs(scrn, crtcs, modes, n + 1, width, height);
         if (score > best_score) {
-            best_crtc = crtc;
             best_score = score;
             memcpy(best_crtcs, crtcs, config->num_output * sizeof(xf86CrtcPtr));
         }
@@ -1087,8 +1084,8 @@ xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr * modes)
 
     for (o = 0; o < config->num_output; o++) {
         xf86OutputPtr output = config->output[o];
-        char *position;
-        char *relative_name;
+        const char *position;
+        const char *relative_name;
         OutputOpts relation;
         int r;
 
@@ -1145,8 +1142,8 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes)
             };
             xf86OutputPtr output = config->output[o];
             xf86OutputPtr relative;
-            char *relative_name;
-            char *position;
+            const char *relative_name;
+            const char *position;
             OutputOpts relation;
             int r;
 
@@ -1306,7 +1303,7 @@ xf86InitialPanning(ScrnInfoPtr scrn)
 
     for (o = 0; o < config->num_output; o++) {
         xf86OutputPtr output = config->output[o];
-        char *panning = xf86GetOptValString(output->options, OPTION_PANNING);
+        const char *panning = xf86GetOptValString(output->options, OPTION_PANNING);
         int width, height, left, top;
         int track_width, track_height, track_left, track_top;
         int brdr[4];
@@ -1389,7 +1386,7 @@ xf86SortModes(DisplayModePtr input)
     for (o = output; o && (n = o->next); o = n) {
         if (!strcmp(o->name, n->name) && xf86ModesEqual(o, n)) {
             o->next = n->next;
-            free(n->name);
+            free((void *) n->name);
             free(n);
             n = o;
         }
@@ -1403,10 +1400,10 @@ xf86SortModes(DisplayModePtr input)
     return output;
 }
 
-static char *
+static const char *
 preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
-    char *preferred_mode = NULL;
+    const char *preferred_mode = NULL;
 
     /* Check for a configured preference for a particular mode */
     preferred_mode = xf86GetOptValString(output->options,
@@ -1610,7 +1607,7 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
         xf86OutputPtr output = config->output[o];
         DisplayModePtr mode;
         DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
-        char *preferred_mode;
+        const char *preferred_mode;
         xf86MonPtr edid_monitor;
         XF86ConfMonitorPtr conf_monitor;
         MonRec mon_rec;
@@ -1833,10 +1830,6 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
  * Copy one of the output mode lists to the ScrnInfo record
  */
 
-/* XXX where does this function belong? Here? */
-void
- xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-
 static DisplayModePtr
 biggestMode(DisplayModePtr a, DisplayModePtr b)
 {
diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c
index c4a3eb0..43b2233 100644
--- a/hw/xfree86/modes/xf86Modes.c
+++ b/hw/xfree86/modes/xf86Modes.c
@@ -129,11 +129,13 @@ void
 xf86SetModeDefaultName(DisplayModePtr mode)
 {
     Bool interlaced = ! !(mode->Flags & V_INTERLACE);
+    char *tmp;
 
-    free(mode->name);
+    free((void *) mode->name);
 
-    XNFasprintf(&mode->name, "%dx%d%s", mode->HDisplay, mode->VDisplay,
+    XNFasprintf(&tmp, "%dx%d%s", mode->HDisplay, mode->VDisplay,
                 interlaced ? "i" : "");
+    mode->name = tmp;
 }
 
 /*
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 76614de..f7a7d44 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -454,7 +454,6 @@ xf86RandR12GetInfo(ScreenPtr pScreen, Rotation * rotations)
     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
     DisplayModePtr mode;
-    int refresh0 = 60;
     int maxX = 0, maxY = 0;
 
     *rotations = randrp->supported_rotations;
@@ -479,8 +478,6 @@ xf86RandR12GetInfo(ScreenPtr pScreen, Rotation * rotations)
             if (maxY < mode->VDisplay)
                 maxY = mode->VDisplay;
         }
-        if (mode == scrp->modes)
-            refresh0 = refresh;
         pSize = RRRegisterSize(pScreen,
                                mode->HDisplay, mode->VDisplay,
                                randrp->mmWidth, randrp->mmHeight);
@@ -684,7 +681,6 @@ xf86RandR12ScreenSetSize(ScreenPtr pScreen,
     WindowPtr pRoot = pScreen->root;
     PixmapPtr pScrnPix;
     Bool ret = FALSE;
-    Bool panning = FALSE;
     int c;
 
     if (xf86RandR12Key) {
@@ -716,7 +712,6 @@ xf86RandR12ScreenSetSize(ScreenPtr pScreen,
                 crtc->panningTrackingArea.y2 += height - pScreen->height;
             xf86RandR13VerifyPanningArea(crtc, width, height);
             xf86RandR13Pan(crtc, randrp->pointerX, randrp->pointerY);
-	    panning = TRUE;
         }
     }
 
@@ -946,8 +941,6 @@ xf86RandR12SetRotations(ScreenPtr pScreen, Rotation rotations)
 void
 xf86RandR12SetTransformSupport(ScreenPtr pScreen, Bool transforms)
 {
-    XF86RandRInfoPtr randrp;
-
 #if RANDR_13_INTERFACE
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     int c;
@@ -957,7 +950,6 @@ xf86RandR12SetTransformSupport(ScreenPtr pScreen, Bool transforms)
     if (xf86RandR12Key == NULL)
         return;
 
-    randrp = XF86RANDRINFO(pScreen);
 #if RANDR_13_INTERFACE
     for (c = 0; c < config->num_crtc; c++) {
         xf86CrtcPtr crtc = config->crtc[c];
@@ -1455,7 +1447,6 @@ xf86RandR12SetInfo12(ScreenPtr pScreen)
     RRCrtcPtr *crtcs;
     int ncrtc;
     int o, c, l;
-    RRCrtcPtr randr_crtc;
     int nclone;
 
     clones = malloc(config->num_output * sizeof(RROutputPtr));
@@ -1468,11 +1459,6 @@ xf86RandR12SetInfo12(ScreenPtr pScreen)
             if (output->possible_crtcs & (1 << c))
                 crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
 
-        if (output->crtc)
-            randr_crtc = output->crtc->randr_crtc;
-        else
-            randr_crtc = NULL;
-
         if (!RROutputSetCrtcs(output->randr_output, crtcs, ncrtc)) {
             free(crtcs);
             free(clones);
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 495af9b..2c9c31b 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -233,9 +233,8 @@ xf86RotateBlockHandler(ScreenPtr pScreen,
 {
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    Bool rotation_active;
 
-    rotation_active = xf86RotateRedisplay(pScreen);
+    xf86RotateRedisplay(pScreen);
     pScreen->BlockHandler = xf86_config->BlockHandler;
     (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
     /* cannot avoid re-wrapping until all wrapping is audited */
@@ -247,7 +246,6 @@ void
 xf86RotateDestroy(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int c;
 
@@ -267,9 +265,6 @@ xf86RotateDestroy(xf86CrtcPtr crtc)
      * Clean up damage structures when no crtcs are rotated
      */
     if (xf86_config->rotation_damage) {
-        DrawablePtr screenDrawable = NULL;
-        if (pScreen && pScreen->root)
-            screenDrawable = &pScreen->root->drawable;
         /* Free damage structure */
         if (xf86_config->rotation_damage_registered) {
             xf86_config->rotation_damage_registered = FALSE;
diff --git a/hw/xfree86/modes/xf86cvt.c b/hw/xfree86/modes/xf86cvt.c
index de07844..8b7bb8b 100644
--- a/hw/xfree86/modes/xf86cvt.c
+++ b/hw/xfree86/modes/xf86cvt.c
@@ -89,6 +89,7 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
     int HDisplayRnd, HMargin;
     int VDisplayRnd, VMargin, VSync;
     float Interlace;            /* Please rename this */
+    char *tmp;
 
     /* CVT default is 60.0Hz */
     if (!VRefresh)
@@ -177,6 +178,7 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
 
         /* 10. Find number of lines in back porch */
         VBackPorch = VSyncAndBackPorch - VSync;
+        (void) VBackPorch;
 
         /* 11. Find total number of lines in vertical field */
         Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
@@ -282,7 +284,8 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
     if (Interlaced)
         Mode->VTotal *= 2;
 
-    XNFasprintf(&Mode->name, "%dx%d", HDisplay, VDisplay);
+    XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
+    Mode->name = tmp;
 
     if (Reduced)
         Mode->Flags |= V_PHSYNC | V_NVSYNC;
diff --git a/hw/xfree86/modes/xf86gtf.c b/hw/xfree86/modes/xf86gtf.c
index 23707b4..0a80784 100644
--- a/hw/xfree86/modes/xf86gtf.c
+++ b/hw/xfree86/modes/xf86gtf.c
@@ -215,6 +215,7 @@ xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins)
      */
 
     v_back_porch = vsync_plus_bp - V_SYNC_RQD;
+    (void) v_back_porch;
 
     /*  10. Find the total number of lines in Vertical field period:
      *
@@ -253,6 +254,7 @@ xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins)
      */
 
     v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
+    (void) v_frame_rate;
 
     /*  15. Find number of pixels in left margin:
      *
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index dcaa19e..4e5f7f9 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -74,13 +74,12 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 
     /* Check that we have a video event */
     if (!strncmp(ev, "video", 5)) {
-        char *video = NULL;
         char *GFX = NULL;
         char *notify = NULL;
         char *data = NULL;      /* doesn't appear to be used in the kernel */
-        unsigned long int notify_l, data_l;
+        unsigned long int notify_l;
 
-        video = strtok(ev, " ");
+        strtok(ev, " ");
 
         if (!(GFX = strtok(NULL, " ")))
             return 0;
@@ -97,8 +96,8 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 
         if (!(data = strtok(NULL, " ")))
             return 0;
-        data_l = strtoul(data, NULL, 16);
 #if 0
+        data_l = strtoul(data, NULL, 16);
         ErrorF("data: 0x%lx\n", data_l);
 #endif
 
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index bcb039f..e2e8d08 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -83,8 +83,8 @@ xf86OpenConsole(void)
     struct vt_mode VT;
     struct vt_stat vts;
     MessageType from = X_PROBED;
-    char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
-    char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
+    const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+    const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
 
     if (serverGeneration == 1) {
 
diff --git a/hw/xfree86/os-support/linux/lnx_kmod.c b/hw/xfree86/os-support/linux/lnx_kmod.c
index 0a17c2a..f5917ee 100644
--- a/hw/xfree86/os-support/linux/lnx_kmod.c
+++ b/hw/xfree86/os-support/linux/lnx_kmod.c
@@ -37,7 +37,7 @@ int
 xf86LoadKernelModule(const char *modName)
 {
     char mpPath[MAX_PATH] = "";
-    int fd = -1, status, n;
+    int fd = -1, status;
     pid_t pid;
 
     /* get the path to the modprobe program */
@@ -76,7 +76,7 @@ xf86LoadKernelModule(const char *modName)
                     "Setting of real/effective user Id to 0/0 failed");
         }
         setenv("PATH", "/sbin", 1);
-        n = execl(mpPath, "modprobe", modName, NULL);
+        execl(mpPath, "modprobe", modName, NULL);
         xf86Msg(X_WARNING, "LoadKernelModule %s\n", strerror(errno));
         exit(EXIT_FAILURE);     /* if we get here the child's exec failed */
         break;
diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh
index d7f259d..d9a4478 100755
--- a/hw/xfree86/sdksyms.sh
+++ b/hw/xfree86/sdksyms.sh
@@ -261,6 +261,7 @@ cat > sdksyms.c << EOF
 #include "dix.h"
 #include "dixaccess.h"
 #include "dixevents.h"
+#define _FONTPROTO_H
 #include "dixfont.h"
 #include "dixfontstr.h"
 #include "dixfontstubs.h"
diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index 76b8358..8af1df4 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -10189,8 +10189,8 @@ Handles opcode 0xe8
 static void
 x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
 {
-    s16 ip16;
-    s32 ip32;
+    s16 ip16 = 0;
+    s32 ip32 = 0;
 
     START_OF_INSTR();
     DECODE_PRINTF("CALL\t");
commit 1ce15ed5bae60a184c6bd9440e3c017488a5f415
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:44:51 2013 -0800

    Xext: _X_EXPORT DPMSSet and DPMSSupported
    
    These are needed by drivers, and it's better to export them from here
    rather than redefining them in hw/xfree86 and exporting them from there.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/dpmsproc.h b/Xext/dpmsproc.h
index 7494dfd..82dccbd 100644
--- a/Xext/dpmsproc.h
+++ b/Xext/dpmsproc.h
@@ -9,7 +9,7 @@
 
 #include "dixstruct.h"
 
-int DPMSSet(ClientPtr client, int level);
-Bool DPMSSupported(void);
+int _X_EXPORT DPMSSet(ClientPtr client, int level);
+Bool _X_EXPORT DPMSSupported(void);
 
 #endif
commit 1f407763be28745f18d224077d6b07b9431ee16b
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 16 23:43:49 2013 -0800

    include: Make xkbrules structures all const char *
    
    This lets them be initialized with string constants
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/include/xkbrules.h b/include/xkbrules.h
index d217318..5b69d0d 100644
--- a/include/xkbrules.h
+++ b/include/xkbrules.h
@@ -30,41 +30,41 @@
 /***====================================================================***/
 
 typedef struct _XkbRMLVOSet {
-    char *rules;
-    char *model;
-    char *layout;
-    char *variant;
-    char *options;
+    const char *rules;
+    const char *model;
+    const char *layout;
+    const char *variant;
+    const char *options;
 } XkbRMLVOSet;
 
 typedef struct _XkbRF_VarDefs {
-    char *model;
-    char *layout;
-    char *variant;
-    char *options;
+    const char *model;
+    const char *layout;
+    const char *variant;
+    const char *options;
 } XkbRF_VarDefsRec, *XkbRF_VarDefsPtr;
 
 typedef struct _XkbRF_Rule {
     int number;
     int layout_num;
     int variant_num;
-    char *model;
-    char *layout;
-    char *variant;
-    char *option;
+    const char *model;
+    const char *layout;
+    const char *variant;
+    const char *option;
     /* yields */
-    char *keycodes;
-    char *symbols;
-    char *types;
-    char *compat;
-    char *geometry;
+    const char *keycodes;
+    const char *symbols;
+    const char *types;
+    const char *compat;
+    const char *geometry;
     unsigned flags;
 } XkbRF_RuleRec, *XkbRF_RulePtr;
 
 typedef struct _XkbRF_Group {
     int number;
-    char *name;
-    char *words;
+    const char *name;
+    const char *words;
 } XkbRF_GroupRec, *XkbRF_GroupPtr;
 
 #define	XkbRF_PendingMatch	(1L<<1)
commit e1e01d2e33c632e395d7e396f73fba8ae606b15a
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 16:56:15 2013 +0900

    xfree86/common: Warning fixes. Mostly const string handling.
    
    Also removes DPMS functiosn from Xext/dpmsproc.h
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/vidmodeproc.h b/hw/xfree86/common/vidmodeproc.h
index 311d35c..f547efd 100644
--- a/hw/xfree86/common/vidmodeproc.h
+++ b/hw/xfree86/common/vidmodeproc.h
@@ -34,7 +34,7 @@ typedef enum {
 } VidModeSelectMonitor;
 
 typedef union {
-    pointer ptr;
+    const void *ptr;
     int i;
     float f;
 } vidMonitorValue;
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 9fc0c5b..206a9d7 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -204,8 +204,7 @@ extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set,
                                    int flags);
 
 #ifdef DPMSExtension
-extern _X_EXPORT int DPMSSet(ClientPtr client, int level);
-extern _X_EXPORT Bool DPMSSupported(void);
+#include "dpmsproc.h"
 #endif
 
 /* xf86DGA.c */
@@ -339,7 +338,7 @@ xf86LoadDrvSubModule(DriverPtr drv, const char *name);
 extern _X_EXPORT pointer
 xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
 extern _X_EXPORT pointer
-xf86LoadOneModule(char *name, pointer optlist);
+xf86LoadOneModule(const char *name, pointer optlist);
 extern _X_EXPORT void
 xf86UnloadSubModule(pointer mod);
 extern _X_EXPORT Bool
@@ -350,7 +349,7 @@ extern _X_EXPORT void
 xf86SetSilkenMouse(ScreenPtr pScreen);
 extern _X_EXPORT pointer
 xf86FindXvOptions(ScrnInfoPtr pScrn, int adapt_index, const char *port_name,
-                  char **adaptor_name, pointer *adaptor_options);
+                  const char **adaptor_name, pointer *adaptor_options);
 extern _X_EXPORT void
 xf86GetOS(const char **name, int *major, int *minor, int *teeny);
 extern _X_EXPORT ScrnInfoPtr
diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index af2b7f8..4eb86de 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -300,6 +300,7 @@ copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
 {
     confScreenPtr nscreen;
     GDevPtr cptr = NULL;
+    char *identifier;
 
     nscreen = malloc(sizeof(confScreenRec));
     if (!nscreen)
@@ -313,13 +314,14 @@ copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
     }
     memcpy(cptr, odev, sizeof(GDevRec));
 
-    if (asprintf(&cptr->identifier, "Autoconfigured Video Device %s", driver)
+    if (asprintf(&identifier, "Autoconfigured Video Device %s", driver)
         == -1) {
         free(cptr);
         free(nscreen);
         return FALSE;
     }
     cptr->driver = driver;
+    cptr->identifier = identifier;
 
     xf86ConfigLayout.screens[i].screen = nscreen;
 
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index b5efc02..6ea7d01 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -236,11 +236,11 @@ xf86ValidateFontPath(char *path)
  * use the datastructure that the parser provides and pick out the parts
  * that we need at this point
  */
-char **
+const char **
 xf86ModulelistFromConfig(pointer **optlist)
 {
     int count = 0, i = 0;
-    char **modulearray;
+    const char **modulearray;
 
     const char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
         "freetype", "type1",
@@ -374,12 +374,12 @@ xf86ModulelistFromConfig(pointer **optlist)
     return modulearray;
 }
 
-char **
+const char **
 xf86DriverlistFromConfig(void)
 {
     int count = 0;
     int j;
-    char **modulearray;
+    const char **modulearray;
     screenLayoutPtr slp;
 
     /*
@@ -446,11 +446,11 @@ xf86DriverlistFromConfig(void)
     return modulearray;
 }
 
-char **
+const char **
 xf86InputDriverlistFromConfig(void)
 {
     int count = 0;
-    char **modulearray;
+    const char **modulearray;
     InputInfoPtr *idp;
 
     /*
@@ -505,11 +505,11 @@ xf86InputDriverlistFromConfig(void)
 }
 
 static void
-fixup_video_driver_list(char **drivers)
+fixup_video_driver_list(const char **drivers)
 {
     static const char *fallback[4] = { "fbdev", "vesa", "wsfb", NULL };
-    char **end, **drv;
-    char *x;
+    const char **end, **drv;
+    const char *x;
     int i;
 
     /* walk to the end of the list */
@@ -533,10 +533,10 @@ fixup_video_driver_list(char **drivers)
     }
 }
 
-static char **
+static const char **
 GenerateDriverlist(const char *dirname)
 {
-    char **ret;
+    const char **ret;
     const char *subdirs[] = { dirname, NULL };
     static const char *patlist[] = { "(.*)_drv\\.so", NULL };
     ret = LoaderListDirs(subdirs, patlist);
@@ -548,10 +548,10 @@ GenerateDriverlist(const char *dirname)
     return ret;
 }
 
-char **
+const char **
 xf86DriverlistFromCompile(void)
 {
-    static char **driverlist = NULL;
+    static const char **driverlist = NULL;
 
     if (!driverlist)
         driverlist = GenerateDriverlist("drivers");
@@ -589,7 +589,7 @@ configFiles(XF86ConfFilesPtr fileconf)
     /* FontPath */
     must_copy = TRUE;
 
-    temp_path = defaultFontPath ? defaultFontPath : "";
+    temp_path = defaultFontPath ? defaultFontPath : (char *) "";
     if (xf86fpFlag)
         pathFrom = X_CMDLINE;
     else if (fileconf && fileconf->file_fontpath) {
@@ -606,7 +606,7 @@ configFiles(XF86ConfFilesPtr fileconf)
     }
     else
         pathFrom = X_DEFAULT;
-    temp_path = defaultFontPath ? defaultFontPath : "";
+    temp_path = defaultFontPath ? defaultFontPath : (char *) "";
 
     /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
     temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
@@ -2349,7 +2349,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout)
 ConfigStatus
 xf86HandleConfigFile(Bool autoconfig)
 {
-    char *scanptr;
+    const char *scanptr;
     Bool singlecard = 0;
     Bool implicit_layout = FALSE;
 
diff --git a/hw/xfree86/common/xf86Config.h b/hw/xfree86/common/xf86Config.h
index de06677..84013e1 100644
--- a/hw/xfree86/common/xf86Config.h
+++ b/hw/xfree86/common/xf86Config.h
@@ -59,10 +59,10 @@ typedef struct _ModuleDefault {
 /*
  * prototypes
  */
-char **xf86ModulelistFromConfig(pointer **);
-char **xf86DriverlistFromConfig(void);
-char **xf86DriverlistFromCompile(void);
-char **xf86InputDriverlistFromConfig(void);
+const char **xf86ModulelistFromConfig(pointer **);
+const char **xf86DriverlistFromConfig(void);
+const char **xf86DriverlistFromCompile(void);
+const char **xf86InputDriverlistFromConfig(void);
 Bool xf86BuiltinInputDriver(const char *);
 ConfigStatus xf86HandleConfigFile(Bool);
 
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 5bf1f14..1348b27 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -195,11 +195,15 @@ configureScreenSection(int screennum)
 {
     int i;
     int depths[] = { 1, 4, 8, 15, 16, 24 /*, 32 */  };
+    char *tmp;
     parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec)
 
-        XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum);
-    XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum);
-    XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum);
+    XNFasprintf(&tmp, "Screen%d", screennum);
+    ptr->scrn_identifier = tmp;
+    XNFasprintf(&tmp, "Monitor%d", screennum);
+    ptr->scrn_monitor_str = tmp;
+    XNFasprintf(&tmp, "Card%d", screennum);
+    ptr->scrn_device_str = tmp;
 
     for (i = 0; i < sizeof(depths) / sizeof(depths[0]); i++) {
         XF86ConfDisplayPtr display;
@@ -248,12 +252,14 @@ configureDeviceSection(int screennum)
 {
     OptionInfoPtr p;
     int i = 0;
+    char *identifier;
 
     parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec)
 
         /* Move device info to parser structure */
-        if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1)
-        ptr->dev_identifier = NULL;
+   if (asprintf(&identifier, "Card%d", screennum) == -1)
+        identifier = NULL;
+    ptr->dev_identifier = identifier;
     ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
     ptr->dev_busid = DevToConfig[screennum].GDev.busID;
     ptr->dev_driver = DevToConfig[screennum].GDev.driver;
@@ -355,20 +361,24 @@ configureLayoutSection(void)
 
     for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
         XF86ConfAdjacencyPtr aptr;
+        char *tmp;
 
         aptr = malloc(sizeof(XF86ConfAdjacencyRec));
         aptr->list.next = NULL;
         aptr->adj_x = 0;
         aptr->adj_y = 0;
         aptr->adj_scrnum = scrnum;
-        XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum);
+        XNFasprintf(&tmp, "Screen%d", scrnum);
+        aptr->adj_screen_str = tmp;
         if (scrnum == 0) {
             aptr->adj_where = CONF_ADJ_ABSOLUTE;
             aptr->adj_refscreen = NULL;
         }
         else {
+            char *tmp;
             aptr->adj_where = CONF_ADJ_RIGHTOF;
-            XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1);
+            XNFasprintf(&tmp, "Screen%d", scrnum - 1);
+            aptr->adj_refscreen = tmp;
         }
         ptr->lay_adjacency_lst =
             (XF86ConfAdjacencyPtr) xf86addListItem((glp) ptr->lay_adjacency_lst,
@@ -389,7 +399,7 @@ configureFlagsSection(void)
 static XF86ConfModulePtr
 configureModuleSection(void)
 {
-    char **elist, **el;
+    const char **elist, **el;
 
     /* Find the list of extension & font modules. */
     const char *esubdirs[] = {
@@ -432,9 +442,11 @@ configureFilesSection(void)
 static XF86ConfMonitorPtr
 configureMonitorSection(int screennum)
 {
+    char *tmp;
     parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec)
 
-        XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+    XNFasprintf(&tmp, "Monitor%d", screennum);
+    ptr->mon_identifier = tmp;
     ptr->mon_vendor = strdup("Monitor Vendor");
     ptr->mon_modelname = strdup("Monitor Model");
 
@@ -474,10 +486,12 @@ configureDDCMonitorSection(int screennum)
 #define displaySizeMaxLen 80
     char displaySize_string[displaySizeMaxLen];
     int displaySizeLen;
+    char *tmp;
 
     parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec)
 
-        XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+    XNFasprintf(&tmp, "Monitor%d", screennum);
+    ptr->mon_identifier = tmp;
     ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
     XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
 
@@ -530,7 +544,7 @@ DoConfigure(void)
     char filename[PATH_MAX];
     const char *addslash = "";
     XF86ConfigPtr xf86config = NULL;
-    char **vlist, **vl;
+    const char **vlist, **vl;
     int *dev2screen;
 
     vlist = xf86DriverlistFromCompile();
@@ -768,7 +782,7 @@ void
 DoShowOptions(void)
 {
     int i = 0;
-    char **vlist = 0;
+    const char **vlist = NULL;
     char *pSymbol = 0;
     XF86ModuleData *initData = 0;
 
diff --git a/hw/xfree86/common/xf86Extensions.c b/hw/xfree86/common/xf86Extensions.c
index f9e7916..c80de34 100644
--- a/hw/xfree86/common/xf86Extensions.c
+++ b/hw/xfree86/common/xf86Extensions.c
@@ -89,7 +89,6 @@ load_extension_config(void)
 {
     XF86ConfModulePtr mod_con = xf86configptr->conf_modules;
     XF86LoadPtr modp;
-    int i;
 
     /* Only the best. */
     if (!mod_con)
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index f1e6783..a59f4fc 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1068,9 +1068,7 @@ void
 xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable)
 {
     ScreenPtr pScreen = pScrnInfo->pScreen;
-    PixmapPtr pspix;
 
-    pspix = (*pScreen->GetScreenPixmap) (pScreen);
     if (enable) {
         /*
          * Restore all of the clip lists on the screen
@@ -1566,7 +1564,7 @@ xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
  * xf86LoadOneModule loads a single module.
  */
 pointer
-xf86LoadOneModule(char *name, pointer opt)
+xf86LoadOneModule(const char *name, pointer opt)
 {
     int errmaj, errmin;
     char *Name;
@@ -1698,8 +1696,8 @@ xf86SetSilkenMouse(ScreenPtr pScreen)
 /* Wrote this function for the PM2 Xv driver, preliminary. */
 
 pointer
-xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, char *port_name,
-                  char **adaptor_name, pointer *adaptor_options)
+xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
+                  const char **adaptor_name, pointer *adaptor_options)
 {
     confXvAdaptorPtr adaptor;
     int i;
@@ -1817,7 +1815,7 @@ xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
         pNewProp->next = NULL;
     }
     else {
-        free(pNewProp->name);
+        free((void *) pNewProp->name);
         existing = TRUE;
     }
 
diff --git a/hw/xfree86/common/xf86InPriv.h b/hw/xfree86/common/xf86InPriv.h
index 5826ac3..b8229d2 100644
--- a/hw/xfree86/common/xf86InPriv.h
+++ b/hw/xfree86/common/xf86InPriv.h
@@ -37,7 +37,4 @@
 extern InputDriverPtr *xf86InputDriverList;
 extern int xf86NumInputDrivers;
 
-/* xf86Helper.c */
-InputDriverPtr xf86LookupInputDriver(const char *name);
-
 #endif                          /* _xf86InPriv_h */
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 91ec4c8..6feedc8 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -395,7 +395,7 @@ void
 InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
 {
     int i, j, k, scr_index;
-    char **modulelist;
+    const char **modulelist;
     pointer *optionlist;
     Pix24Flags screenpix24, pix24;
     MessageType pix24From = X_DEFAULT;
@@ -623,7 +623,9 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
 
         for (i = 0; i < xf86NumScreens; i++) {
             if (xf86Screens[i]->name == NULL) {
-                XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
+                char *tmp;
+                XNFasprintf(&tmp, "screen%d", i);
+                xf86Screens[i]->name = tmp;
                 xf86MsgVerb(X_WARNING, 0,
                             "Screen driver %d has no name set, using `%s'.\n",
                             i, xf86Screens[i]->name);
@@ -1536,7 +1538,7 @@ ddxUseMsg(void)
  * xf86LoadModules iterates over a list that is being passed in.
  */
 Bool
-xf86LoadModules(char **list, pointer *optlist)
+xf86LoadModules(const char **list, pointer *optlist)
 {
     int errmaj, errmin;
     pointer opt;
diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 706ab64..15214ea 100644
--- a/hw/xfree86/common/xf86Mode.c
+++ b/hw/xfree86/common/xf86Mode.c
@@ -1998,7 +1998,7 @@ xf86DeleteMode(DisplayModePtr * modeList, DisplayModePtr mode)
             mode->next->prev = mode->prev;
     }
 
-    free(mode->name);
+    free((void *) mode->name);
     free(mode);
 }
 
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 265b553..396f63c 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -176,7 +176,7 @@ extern _X_EXPORT pointer LoadSubModule(pointer, const char *, const char **,
 extern _X_EXPORT void UnloadSubModule(pointer);
 extern _X_EXPORT void UnloadModule(pointer);
 extern _X_EXPORT pointer LoaderSymbol(const char *);
-extern _X_EXPORT char **LoaderListDirs(const char **, const char **);
+extern _X_EXPORT const char **LoaderListDirs(const char **, const char **);
 extern _X_EXPORT void LoaderFreeDirList(char **);
 extern _X_EXPORT void LoaderErrorMsg(const char *, const char *, int, int);
 extern _X_EXPORT void LoaderGetOS(const char **name, int *major, int *minor,
diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h
index f99a924..3be2a0f 100644
--- a/hw/xfree86/common/xf86Opt.h
+++ b/hw/xfree86/common/xf86Opt.h
@@ -123,7 +123,7 @@ extern _X_EXPORT OptionInfoPtr xf86TokenToOptinfo(const OptionInfoRec * table,
 extern _X_EXPORT const char *xf86TokenToOptName(const OptionInfoRec * table,
                                                 int token);
 extern _X_EXPORT Bool xf86IsOptionSet(const OptionInfoRec * table, int token);
-extern _X_EXPORT char *xf86GetOptValString(const OptionInfoRec * table,
+extern _X_EXPORT const char *xf86GetOptValString(const OptionInfoRec * table,
                                            int token);
 extern _X_EXPORT Bool xf86GetOptValInteger(const OptionInfoRec * table,
                                            int token, int *value);
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index 607c333..0e8bc1f 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -478,7 +478,8 @@ static Bool
 ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p,
                  Bool markUsed)
 {
-    char *s, *end;
+    const char *s;
+    char *end;
     Bool wasUsed = FALSE;
 
     if ((s = xf86findOptionValue(options, p->name)) != NULL) {
@@ -755,7 +756,7 @@ xf86IsOptionSet(const OptionInfoRec * table, int token)
     return p && p->found;
 }
 
-char *
+const char *
 xf86GetOptValString(const OptionInfoRec * table, int token)
 {
     OptionInfoPtr p;
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 58cfe0a..5239a6b 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -156,7 +156,7 @@ xf86CloseLog(enum ExitCode error);
 
 /* xf86Init.c */
 extern _X_EXPORT Bool
-xf86LoadModules(char **list, pointer *optlist);
+xf86LoadModules(const char **list, pointer *optlist);
 extern _X_EXPORT int
 xf86SetVerbosity(int verb);
 extern _X_EXPORT int
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 26c03c6..f563052 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -107,7 +107,7 @@ static int
  * Eval config and modify DeviceVelocityRec accordingly
  */
 static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char *devname, pointer list,
+ProcessVelocityConfiguration(DeviceIntPtr pDev, const char *devname, pointer list,
                              DeviceVelocityPtr s)
 {
     int tempi;
@@ -661,7 +661,7 @@ MergeInputClasses(const InputInfoPtr idev, const InputAttributes * attrs)
         /* Collect class options and driver settings */
         classopts = xf86optionListDup(cl->option_lst);
         if (cl->driver) {
-            free(idev->driver);
+            free((void *) idev->driver);
             idev->driver = xstrdup(cl->driver);
             if (!idev->driver) {
                 xf86Msg(X_ERROR, "Failed to allocate memory while merging "
@@ -773,8 +773,8 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
         /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
     }
 
-    free(pInp->driver);
-    free(pInp->name);
+    free((void *) pInp->driver);
+    free((void *) pInp->name);
     xf86optionListFree(pInp->options);
     free(pInp);
 }
@@ -1067,7 +1067,7 @@ xf86CheckMotionEvent4DGA(DeviceIntPtr device, int is_absolute,
 
 #if XFreeXDGA
     ScreenPtr scr = NULL;
-    int idx, i;
+    int idx = 0, i;
 
     /* The evdev driver may not always send all axes across. */
     if (valuator_mask_isset(mask, 0) || valuator_mask_isset(mask, 1)) {
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 258988a..2704766 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -575,7 +575,7 @@ xf86PciProbeDev(DriverPtr drvp)
 }
 
 void
-xf86PciIsolateDevice(char *argument)
+xf86PciIsolateDevice(const char *argument)
 {
     int bus, device, func;
 
@@ -1484,6 +1484,7 @@ xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
                        GDevRec * GDev, int *chipset)
 {
     char busnum[8];
+    char *tmp;
 
     pVideo = (struct pci_device *) busData;
 
@@ -1493,8 +1494,9 @@ xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
         snprintf(busnum, sizeof(busnum), "%d@%d",
                  pVideo->bus & 0x00ff, pVideo->bus >> 8);
 
-    XNFasprintf(&GDev->busID, "PCI:%s:%d:%d",
+    XNFasprintf(&tmp, "PCI:%s:%d:%d",
                 busnum, pVideo->dev, pVideo->func);
+    GDev->busID = tmp;
 
     GDev->chipID = pVideo->device_id;
     GDev->chipRev = pVideo->revision;
diff --git a/hw/xfree86/common/xf86pciBus.h b/hw/xfree86/common/xf86pciBus.h
index 4972c36..b497a7f 100644
--- a/hw/xfree86/common/xf86pciBus.h
+++ b/hw/xfree86/common/xf86pciBus.h
@@ -36,7 +36,7 @@
 void xf86PciProbe(void);
 Bool xf86PciAddMatchingDev(DriverPtr drvp);
 Bool xf86PciProbeDev(DriverPtr drvp);
-void xf86PciIsolateDevice(char *argument);
+void xf86PciIsolateDevice(const char *argument);
 int xf86PciMatchDriver(char *matches[], int nmatches);
 Bool xf86PciConfigure(void *busData, struct pci_device *pDev);
 void xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 33b2b7d..5875a91 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -400,7 +400,7 @@ xf86platformAddDevice(int index)
     DriverPtr drvp = NULL;
     int entity;
     screenLayoutPtr layout;
-    static char *hotplug_driver_name = "modesetting";
+    static const char *hotplug_driver_name = "modesetting";
 
     /* force load the driver for now */
     xf86LoadOneModule(hotplug_driver_name, NULL);
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index d90d1ad..fe13816 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -424,7 +424,7 @@ typedef struct {
     rgb blackColour;
     rgb whiteColour;
     int defaultVisual;
-    char **modes;
+    const char **modes;
     pointer options;
 } DispRec, *DispPtr;
 
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index 2347b8e..d70ba28 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -482,7 +482,7 @@ FindModule(const char *module, const char *dirname, const char **subdirlist,
     return name;
 }
 
-char **
+const char **
 LoaderListDirs(const char **subdirlist, const char **patternlist)
 {
     char buf[PATH_MAX + 1];
@@ -490,7 +490,7 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
     char **elem;
     const char **subdirs;
     const char **s;
-    PatternPtr patterns;
+    PatternPtr patterns = NULL;
     PatternPtr p;
     DIR *d;
     struct dirent *dp;
@@ -571,7 +571,7 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
     FreePatterns(patterns);
     FreeSubdirs(subdirs);
     FreePathList(pathlist);
-    return ret;
+    return (const char **) ret;
 }
 
 void
diff --git a/hw/xfree86/parser/Module.c b/hw/xfree86/parser/Module.c
index 87ddfc6..243ba91 100644
--- a/hw/xfree86/parser/Module.c
+++ b/hw/xfree86/parser/Module.c
@@ -218,7 +218,7 @@ xf86printModuleSection(FILE * cf, XF86ConfModulePtr ptr)
 }
 
 XF86LoadPtr
-xf86addNewLoadDirective(XF86LoadPtr head, char *name, int type,
+xf86addNewLoadDirective(XF86LoadPtr head, const char *name, int type,
                         XF86OptionPtr opts)
 {
     XF86LoadPtr new;
diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h
index 4576ee1..60509dc 100644
--- a/hw/xfree86/parser/configProcs.h
+++ b/hw/xfree86/parser/configProcs.h
@@ -67,7 +67,7 @@ int xf86validateLayout(XF86ConfigPtr p);
 XF86ConfModulePtr xf86parseModuleSection(void);
 void xf86printModuleSection(FILE * cf, XF86ConfModulePtr ptr);
 extern _X_EXPORT XF86LoadPtr xf86addNewLoadDirective(XF86LoadPtr head,
-                                                     char *name, int type,
+                                                     const char *name, int type,
                                                      XF86OptionPtr opts);
 void xf86freeModules(XF86ConfModulePtr ptr);
 
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index 1f66329..0fcf405 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -180,7 +180,7 @@ typedef struct {
     GenericListRec list;
     const char *mon_identifier;
     const char *mon_vendor;
-    const char *mon_modelname;
+    char *mon_modelname;
     int mon_width;              /* in mm */
     int mon_height;             /* in mm */
     XF86ConfModeLinePtr mon_modeline_lst;
@@ -304,7 +304,7 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    const char *identifier;
+    char *identifier;
     const char *driver;
     struct xorg_list match_product;
     struct xorg_list match_vendor;
commit 27b44949a3d2e34ac10e801bd8a8fc2c28791e7e
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 16:24:15 2013 +0900

    hw/xfree86: Lots of constant string support
    
    Make lots of string pointers 'const char' so that we can use constant
    strings with them without eliciting warnings.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/dgaproc.h b/hw/xfree86/common/dgaproc.h
index e824d30..87e923f 100644
--- a/hw/xfree86/common/dgaproc.h
+++ b/hw/xfree86/common/dgaproc.h
@@ -24,7 +24,7 @@
 
 typedef struct {
     int num;                    /* A unique identifier for the mode (num > 0) */
-    char *name;                 /* name of mode given in the XF86Config */
+    const char *name;           /* name of mode given in the XF86Config */
     int VSync_num;
     int VSync_den;
     int flags;                  /* DGA_CONCURRENT_ACCESS, etc... */
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index eada01c..9fc0c5b 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -349,7 +349,7 @@ xf86SetBackingStore(ScreenPtr pScreen);
 extern _X_EXPORT void
 xf86SetSilkenMouse(ScreenPtr pScreen);
 extern _X_EXPORT pointer
-xf86FindXvOptions(ScrnInfoPtr pScrn, int adapt_index, char *port_name,
+xf86FindXvOptions(ScrnInfoPtr pScrn, int adapt_index, const char *port_name,
                   char **adaptor_name, pointer *adaptor_options);
 extern _X_EXPORT void
 xf86GetOS(const char **name, int *major, int *minor, int *teeny);
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c
index 91e8df9..5bf1f14 100644
--- a/hw/xfree86/common/xf86Configure.c
+++ b/hw/xfree86/common/xf86Configure.c
@@ -81,6 +81,7 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData,
                             int chipset)
 {
     int ret, i, j;
+    char *lower_driver;
 
     if (!xf86DoConfigure || !xf86DoConfigurePass1)
         return NULL;
@@ -117,8 +118,9 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData,
     DevToConfig[i].iDriver = CurrentDriver;
 
     /* Fill in what we know, converting the driver name to lower case */
-    DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
-    for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
+    lower_driver = xnfalloc(strlen(driver) + 1);
+    for (j = 0; (lower_driver[j] = tolower(driver[j])); j++);
+    DevToConfig[i].GDev.driver = lower_driver;
 
     switch (bus) {
 #ifdef XSERVER_LIBPCIACCESS
diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h
index c3ba2d7..f99a924 100644
--- a/hw/xfree86/common/xf86Opt.h
+++ b/hw/xfree86/common/xf86Opt.h
@@ -39,7 +39,7 @@ typedef struct {
 
 typedef union {
     unsigned long num;
-    char *str;
+    const char *str;
     double realnum;
     Bool bool;
     OptFrequency freq;
diff --git a/hw/xfree86/common/xf86Optionstr.h b/hw/xfree86/common/xf86Optionstr.h
index c38499c..4ef917d 100644
--- a/hw/xfree86/common/xf86Optionstr.h
+++ b/hw/xfree86/common/xf86Optionstr.h
@@ -31,10 +31,10 @@
  */
 typedef struct _XF86OptionRec {
     GenericListRec list;
-    char *opt_name;
-    char *opt_val;
+    const char *opt_name;
+    const char *opt_val;
     int opt_used;
-    char *opt_comment;
+    const char *opt_comment;
 } XF86OptionRec;
 
 typedef struct _InputOption *XF86OptionPtr;
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index e20be03..ddcb3ca 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -136,7 +136,7 @@ typedef struct {
 /* Information for root window properties. */
 typedef struct _RootWinProp {
     struct _RootWinProp *next;
-    char *name;
+    const char *name;
     Atom type;
     short format;
     long size;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 35c38a5..b95fbe5 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -82,8 +82,8 @@ typedef struct _InputDriverRec {
 
 typedef struct _InputInfoRec {
     struct _InputInfoRec *next;
-    char *name;
-    char *driver;
+    const char *name;
+    const char *driver;
 
     int flags;
 
diff --git a/hw/xfree86/common/xf86sbusBus.h b/hw/xfree86/common/xf86sbusBus.h
index a4d9c6c..5ebdf25 100644
--- a/hw/xfree86/common/xf86sbusBus.h
+++ b/hw/xfree86/common/xf86sbusBus.h
@@ -52,16 +52,16 @@ typedef struct sbus_device {
     int fd;
     int width, height;
     sbusPromNode node;
-    char *descr;
-    char *device;
+    const char *descr;
+    const char *device;
 } sbusDevice, *sbusDevicePtr;
 
 struct sbus_devtable {
     int devId;
     int fbType;
-    char *promName;
-    char *driverName;
-    char *descr;
+    const char *promName;
+    const char *driverName;
+    const char *descr;
 };
 
 extern _X_EXPORT void xf86SbusProbe(void);
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 0244fd4..d90d1ad 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -145,7 +145,7 @@ typedef enum {
 typedef struct _DisplayModeRec {
     struct _DisplayModeRec *prev;
     struct _DisplayModeRec *next;
-    char *name;                 /* identifier for the mode */
+    const char *name;           /* identifier for the mode */
     ModeStatus status;
     int type;
 
@@ -212,9 +212,9 @@ typedef struct {
 #define GAMMA_ZERO	(GAMMA_MIN / 100.0)
 
 typedef struct {
-    char *id;
-    char *vendor;
-    char *model;
+    const char *id;
+    const char *vendor;
+    const char *model;
     int nHsync;
     range hsync[MAX_HSYNC];
     int nVrefresh;
@@ -386,19 +386,19 @@ typedef enum {
 } DacSpeedIndex;
 
 typedef struct {
-    char *identifier;
-    char *vendor;
-    char *board;
-    char *chipset;
-    char *ramdac;
-    char *driver;
+    const char *identifier;
+    const char *vendor;
+    const char *board;
+    const char *chipset;
+    const char *ramdac;
+    const char *driver;
     struct _confscreenrec *myScreenSection;
     Bool claimed;
     int dacSpeeds[MAXDACSPEEDS];
     int numclocks;
     int clock[MAXCLOCKS];
-    char *clockchip;
-    char *busID;
+    const char *clockchip;
+    const char *busID;
     Bool active;
     Bool inUse;
     int videoRam;
@@ -429,19 +429,19 @@ typedef struct {
 } DispRec, *DispPtr;
 
 typedef struct _confxvportrec {
-    char *identifier;
+    const char *identifier;
     pointer options;
 } confXvPortRec, *confXvPortPtr;
 
 typedef struct _confxvadaptrec {
-    char *identifier;
+    const char *identifier;
     int numports;
     confXvPortPtr ports;
     pointer options;
 } confXvAdaptorRec, *confXvAdaptorPtr;
 
 typedef struct _confscreenrec {
-    char *id;
+    const char *id;
     int screennum;
     int defaultdepth;
     int defaultbpp;
@@ -467,25 +467,25 @@ typedef enum {
 
 typedef struct _screenlayoutrec {
     confScreenPtr screen;
-    char *topname;
+    const char *topname;
     confScreenPtr top;
-    char *bottomname;
+    const char *bottomname;
     confScreenPtr bottom;
-    char *leftname;
+    const char *leftname;
     confScreenPtr left;
-    char *rightname;
+    const char *rightname;
     confScreenPtr right;
     PositionType where;
     int x;
     int y;
-    char *refname;
+    const char *refname;
     confScreenPtr refscreen;
 } screenLayoutRec, *screenLayoutPtr;
 
 typedef struct _InputInfoRec InputInfoRec;
 
 typedef struct _serverlayoutrec {
-    char *id;
+    const char *id;
     screenLayoutPtr screens;
     GDevPtr inactives;
     InputInfoRec **inputs;      /* NULL terminated */
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index 091efca..f393369 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -137,7 +137,7 @@ typedef enum {
 
 typedef struct {
     int id;
-    char *name;
+    const char *name;
     unsigned short width, height;
     XvRationalRec rate;
 } XF86VideoEncodingRec, *XF86VideoEncodingPtr;
@@ -151,13 +151,13 @@ typedef struct {
     int flags;
     int min_value;
     int max_value;
-    char *name;
+    const char *name;
 } XF86AttributeRec, *XF86AttributePtr;
 
 typedef struct {
     unsigned int type;
     int flags;
-    char *name;
+    const char *name;
     int nEncodings;
     XF86VideoEncodingPtr pEncodings;
     int nFormats;
diff --git a/hw/xfree86/common/xf86xvmc.h b/hw/xfree86/common/xf86xvmc.h
index 2478fe3..aaa4e65 100644
--- a/hw/xfree86/common/xf86xvmc.h
+++ b/hw/xfree86/common/xf86xvmc.h
@@ -109,7 +109,7 @@ typedef void (*xf86XvMCDestroySubpictureProcPtr) (ScrnInfoPtr pScrn,
                                                   XvMCSubpicturePtr subpicture);
 
 typedef struct {
-    char *name;
+    const char *name;
     int num_surfaces;
     XF86MCSurfaceInfoPtr *surfaces;
     int num_subpictures;
diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h
index 81cc1fc..62e5142 100644
--- a/hw/xfree86/parser/Configint.h
+++ b/hw/xfree86/parser/Configint.h
@@ -90,7 +90,7 @@ typedef struct {
 #include "configProcs.h"
 #include <stdlib.h>
 
-#define TestFree(a) if (a) { free (a); a = NULL; }
+#define TestFree(a) if (a) { free ((void *) a); a = NULL; }
 
 #define parsePrologue(typeptr,typerec) typeptr ptr; \
 if( (ptr=calloc(1,sizeof(typerec))) == NULL ) { return NULL; }
diff --git a/hw/xfree86/parser/Files.c b/hw/xfree86/parser/Files.c
index 0d3e47a..a6e18dd 100644
--- a/hw/xfree86/parser/Files.c
+++ b/hw/xfree86/parser/Files.c
@@ -97,8 +97,7 @@ xf86parseFilesSection(void)
             j = FALSE;
             str = val.str;
             if (ptr->file_fontpath == NULL) {
-                ptr->file_fontpath = malloc(1);
-                ptr->file_fontpath[0] = '\0';
+                ptr->file_fontpath = calloc(1, 1);
                 i = strlen(str) + 1;
             }
             else {
diff --git a/hw/xfree86/parser/Flags.c b/hw/xfree86/parser/Flags.c
index 2461476..326c6b7 100644
--- a/hw/xfree86/parser/Flags.c
+++ b/hw/xfree86/parser/Flags.c
@@ -189,7 +189,7 @@ xf86printServerFlagsSection(FILE * f, XF86ConfFlagsPtr flags)
 }
 
 static XF86OptionPtr
-addNewOption2(XF86OptionPtr head, char *name, char *val, int used)
+addNewOption2(XF86OptionPtr head, char *name, char *_val, int used)
 {
     XF86OptionPtr new, old = NULL;
 
@@ -202,7 +202,7 @@ addNewOption2(XF86OptionPtr head, char *name, char *val, int used)
     else
         new = calloc(1, sizeof(*new));
     new->opt_name = name;
-    new->opt_val = val;
+    new->opt_val = _val;
     new->opt_used = used;
 
     if (old)
@@ -211,9 +211,9 @@ addNewOption2(XF86OptionPtr head, char *name, char *val, int used)
 }
 
 XF86OptionPtr
-xf86addNewOption(XF86OptionPtr head, char *name, char *val)
+xf86addNewOption(XF86OptionPtr head, char *name, char *_val)
 {
-    return addNewOption2(head, name, val, 0);
+    return addNewOption2(head, name, _val, 0);
 }
 
 void
@@ -230,11 +230,11 @@ XF86OptionPtr
 xf86optionListDup(XF86OptionPtr opt)
 {
     XF86OptionPtr newopt = NULL;
-    char *val;
+    char *_val;
 
     while (opt) {
-        val = opt->opt_val ? strdup(opt->opt_val) : NULL;
-        newopt = xf86addNewOption(newopt, strdup(opt->opt_name), val);
+        _val = opt->opt_val ? strdup(opt->opt_val) : NULL;
+        newopt = xf86addNewOption(newopt, strdup(opt->opt_name), _val);
         newopt->opt_used = opt->opt_used;
         if (opt->opt_comment)
             newopt->opt_comment = strdup(opt->opt_comment);
diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h
index 1250f39..4576ee1 100644
--- a/hw/xfree86/parser/configProcs.h
+++ b/hw/xfree86/parser/configProcs.h
@@ -141,7 +141,7 @@ xf86freeExtensions(XF86ConfExtensionsPtr ptr);
 #include <xorg-config.h>
 #endif
 
-#ifndef IN_XSERVER
+#ifndef HAVE_XORG_CONFIG_H
 /* Externally provided functions */
 void
 ErrorF(const char *f, ...);
diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c
index f852b83..55a8442 100644
--- a/hw/xfree86/parser/scan.c
+++ b/hw/xfree86/parser/scan.c
@@ -820,7 +820,7 @@ static char *
 OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
               const char *confname)
 {
-    char *dirpath, *pathcopy;
+    char *dirpath = NULL, *pathcopy;
     const char *template;
     Bool found = FALSE;
     int cmdlineUsed = 0;
@@ -1078,9 +1078,10 @@ xf86nameCompare(const char *s1, const char *s2)
 }
 
 char *
-xf86addComment(char *cur, char *add)
+xf86addComment(char *cur, const char *add)
 {
     char *str;
+    const char *cstr;
     int len, curlen, iscomment, hasnewline = 0, insnewline, endnewline;
 
     if (add == NULL || add[0] == '\0')
@@ -1095,14 +1096,14 @@ xf86addComment(char *cur, char *add)
     else
         curlen = 0;
 
-    str = add;
+    cstr = add;
     iscomment = 0;
-    while (*str) {
-        if (*str != ' ' && *str != '\t')
+    while (*cstr) {
+        if (*cstr != ' ' && *cstr != '\t')
             break;
-        ++str;
+        ++cstr;
     }
-    iscomment = (*str == '#');
+    iscomment = (*cstr == '#');
 
     len = strlen(add);
     endnewline = add[len - 1] == '\n';
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
index e7210e8..1f66329 100644
--- a/hw/xfree86/parser/xf86Parser.h
+++ b/hw/xfree86/parser/xf86Parser.h
@@ -85,7 +85,7 @@ typedef struct {
 typedef struct {
     GenericListRec list;
     int load_type;
-    char *load_name;
+    const char *load_name;
     XF86OptionPtr load_opt;
     char *load_comment;
     int ignore;
@@ -116,7 +116,7 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *ml_identifier;
+    const char *ml_identifier;
     int ml_clock;
     int ml_hdisplay;
     int ml_hsyncstart;
@@ -134,21 +134,21 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *vp_identifier;
+    const char *vp_identifier;
     XF86OptionPtr vp_option_lst;
     char *vp_comment;
 } XF86ConfVideoPortRec, *XF86ConfVideoPortPtr;
 
 typedef struct {
     GenericListRec list;
-    char *va_identifier;
-    char *va_vendor;
-    char *va_board;
-    char *va_busid;
-    char *va_driver;
+    const char *va_identifier;
+    const char *va_vendor;
+    const char *va_board;
+    const char *va_busid;
+    const char *va_driver;
     XF86OptionPtr va_option_lst;
     XF86ConfVideoPortPtr va_port_lst;
-    char *va_fwdref;
+    const char *va_fwdref;
     char *va_comment;
 } XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr;
 
@@ -165,22 +165,22 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *modes_identifier;
+    const char *modes_identifier;
     XF86ConfModeLinePtr mon_modeline_lst;
     char *modes_comment;
 } XF86ConfModesRec, *XF86ConfModesPtr;
 
 typedef struct {
     GenericListRec list;
-    char *ml_modes_str;
+    const char *ml_modes_str;
     XF86ConfModesPtr ml_modes;
 } XF86ConfModesLinkRec, *XF86ConfModesLinkPtr;
 
 typedef struct {
     GenericListRec list;
-    char *mon_identifier;
-    char *mon_vendor;
-    char *mon_modelname;
+    const char *mon_identifier;
+    const char *mon_vendor;
+    const char *mon_modelname;
     int mon_width;              /* in mm */
     int mon_height;             /* in mm */
     XF86ConfModeLinePtr mon_modeline_lst;
@@ -201,21 +201,21 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *dev_identifier;
-    char *dev_vendor;
-    char *dev_board;
-    char *dev_chipset;
-    char *dev_busid;
-    char *dev_card;
-    char *dev_driver;
-    char *dev_ramdac;
+    const char *dev_identifier;
+    const char *dev_vendor;
+    const char *dev_board;
+    const char *dev_chipset;
+    const char *dev_busid;
+    const char *dev_card;
+    const char *dev_driver;
+    const char *dev_ramdac;
     int dev_dacSpeeds[CONF_MAXDACSPEEDS];
     int dev_videoram;
     int dev_textclockfreq;
     unsigned long dev_bios_base;
     unsigned long dev_mem_base;
     unsigned long dev_io_base;
-    char *dev_clockchip;
+    const char *dev_clockchip;
     int dev_clocks;
     int dev_clock[CONF_MAXCLOCKS];
     int dev_chipid;
@@ -228,7 +228,7 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *mode_name;
+    const char *mode_name;
 } XF86ModeRec, *XF86ModePtr;
 
 typedef struct {
@@ -239,7 +239,7 @@ typedef struct {
     int disp_virtualY;
     int disp_depth;
     int disp_bpp;
-    char *disp_visual;
+    const char *disp_visual;
     parser_rgb disp_weight;
     parser_rgb disp_black;
     parser_rgb disp_white;
@@ -255,20 +255,20 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *al_adaptor_str;
+    const char *al_adaptor_str;
     XF86ConfVideoAdaptorPtr al_adaptor;
 } XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
 
 typedef struct {
     GenericListRec list;
-    char *scrn_identifier;
-    char *scrn_obso_driver;
+    const char *scrn_identifier;
+    const char *scrn_obso_driver;
     int scrn_defaultdepth;
     int scrn_defaultbpp;
     int scrn_defaultfbbpp;
-    char *scrn_monitor_str;
+    const char *scrn_monitor_str;
     XF86ConfMonitorPtr scrn_monitor;
-    char *scrn_device_str;
+    const char *scrn_device_str;
     XF86ConfDevicePtr scrn_device;
     XF86ConfAdaptorLinkPtr scrn_adaptor_lst;
     XF86ConfDisplayPtr scrn_display_lst;
@@ -279,8 +279,8 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *inp_identifier;
-    char *inp_driver;
+    const char *inp_identifier;
+    const char *inp_driver;
     XF86OptionPtr inp_option_lst;
     char *inp_comment;
 } XF86ConfInputRec, *XF86ConfInputPtr;
@@ -288,7 +288,7 @@ typedef struct {
 typedef struct {
     GenericListRec list;
     XF86ConfInputPtr iref_inputdev;
-    char *iref_inputdev_str;
+    const char *iref_inputdev_str;
     XF86OptionPtr iref_option_lst;
 } XF86ConfInputrefRec, *XF86ConfInputrefPtr;
 
@@ -304,8 +304,8 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *identifier;
-    char *driver;
+    const char *identifier;
+    const char *driver;
     struct xorg_list match_product;
     struct xorg_list match_vendor;
     struct xorg_list match_device;
@@ -338,30 +338,30 @@ typedef struct {
     GenericListRec list;
     int adj_scrnum;
     XF86ConfScreenPtr adj_screen;
-    char *adj_screen_str;
+    const char *adj_screen_str;
     XF86ConfScreenPtr adj_top;
-    char *adj_top_str;
+    const char *adj_top_str;
     XF86ConfScreenPtr adj_bottom;
-    char *adj_bottom_str;
+    const char *adj_bottom_str;
     XF86ConfScreenPtr adj_left;
-    char *adj_left_str;
+    const char *adj_left_str;
     XF86ConfScreenPtr adj_right;
-    char *adj_right_str;
+    const char *adj_right_str;
     int adj_where;
     int adj_x;
     int adj_y;
-    char *adj_refscreen;
+    const char *adj_refscreen;
 } XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr;
 
 typedef struct {
     GenericListRec list;
-    char *inactive_device_str;
+    const char *inactive_device_str;
     XF86ConfDevicePtr inactive_device;
 } XF86ConfInactiveRec, *XF86ConfInactivePtr;
 
 typedef struct {
     GenericListRec list;
-    char *lay_identifier;
+    const char *lay_identifier;
     XF86ConfAdjacencyPtr lay_adjacency_lst;
     XF86ConfInactivePtr lay_inactive_lst;
     XF86ConfInputrefPtr lay_input_lst;
@@ -371,22 +371,22 @@ typedef struct {
 
 typedef struct {
     GenericListRec list;
-    char *vs_name;
-    char *vs_identifier;
+    const char *vs_name;
+    const char *vs_identifier;
     XF86OptionPtr vs_option_lst;
     char *vs_comment;
 } XF86ConfVendSubRec, *XF86ConfVendSubPtr;
 
 typedef struct {
     GenericListRec list;
-    char *vnd_identifier;
+    const char *vnd_identifier;
     XF86OptionPtr vnd_option_lst;
     XF86ConfVendSubPtr vnd_sub_lst;
     char *vnd_comment;
 } XF86ConfVendorRec, *XF86ConfVendorPtr;
 
 typedef struct {
-    char *dri_group_name;
+    const char *dri_group_name;
     int dri_group;
     int dri_mode;
     char *dri_comment;
@@ -462,7 +462,7 @@ extern _X_EXPORT int xf86itemNotSublist(GenericListPtr list_1,
 
 extern _X_EXPORT int xf86pathIsAbsolute(const char *path);
 extern _X_EXPORT int xf86pathIsSafe(const char *path);
-extern _X_EXPORT char *xf86addComment(char *cur, char *add);
+extern _X_EXPORT char *xf86addComment(char *cur, const char *add);
 extern _X_EXPORT Bool xf86getBoolValue(Bool *val, const char *str);
 
 #endif                          /* _xf86Parser_h_ */
commit 6f77e2645ea36e324ccc664aae1d36464418bdea
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Nov 15 13:40:30 2013 +0900

    hw/xfree86: Make strings in DriverRec and ScrnInfoRec const
    
    This avoids compiler warnings when initializing with string constants.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 4c2d147..0244fd4 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -299,7 +299,7 @@ struct _DriverRec;
 
 typedef struct {
     int driverVersion;
-    char *driverName;
+    const char *driverName;
     void (*Identify) (int flags);
     Bool (*Probe) (struct _DriverRec * drv, int flags);
     const OptionInfoRec *(*AvailableOptions) (int chipid, int bustype);
@@ -315,7 +315,7 @@ struct xf86_platform_device;
 
 typedef struct _DriverRec {
     int driverVersion;
-    char *driverName;
+    const char *driverName;
     void (*Identify) (int flags);
     Bool (*Probe) (struct _DriverRec * drv, int flags);
     const OptionInfoRec *(*AvailableOptions) (int chipid, int bustype);
@@ -671,7 +671,7 @@ typedef void xf86ModeSetProc(ScrnInfoPtr);
 
 typedef struct _ScrnInfoRec {
     int driverVersion;
-    char *driverName;           /* canonical name used in */
+    const char *driverName;     /* canonical name used in */
     /* the config file */
     ScreenPtr pScreen;          /* Pointer to the ScreenRec */
     int scrnIndex;              /* Number of this screen */
@@ -730,7 +730,7 @@ typedef struct _ScrnInfoRec {
     int heightmm;
     int xDpi;                   /* width DPI */
     int yDpi;                   /* height DPI */
-    char *name;                 /* Name to prefix messages */
+    const char *name;           /* Name to prefix messages */
     pointer driverPrivate;      /* Driver private area */
     DevUnion *privates;         /* Other privates can hook in
                                  * here */
@@ -741,9 +741,9 @@ typedef struct _ScrnInfoRec {
 
     /* Some of these may be moved out of here into the driver private area */
 
-    char *chipset;              /* chipset name */
-    char *ramdac;               /* ramdac name */
-    char *clockchip;            /* clock name */
+    const char *chipset;        /* chipset name */
+    const char *ramdac;         /* ramdac name */
+    const char *clockchip;      /* clock name */
     Bool progClock;             /* clock is programmable */
     int numClocks;              /* number of clocks */
     int clock[MAXCLOCKS];       /* list of clock frequencies */
commit e81902872176fa9848211fcd7a5eafa4f861a1b7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 9 15:29:23 2014 +1000

    ephyr: don't allow a shift+ctrl keygrab if mod1 was enabled
    
    Xephyr wants ctrl+shift to grab the window, but that conflicts with
    ctrl+alt+shift key combos. Remember the modifier state on key presses and
    releases, if mod1 is pressed, we need ctrl, shift and mod1 released
    before we allow a shift-ctrl grab activation.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index b2a7985..94b9397 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1008,6 +1008,29 @@ ephyrProcessButtonRelease(xcb_generic_event_t *xev)
     KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
 }
 
+/* Xephyr wants ctrl+shift to grab the window, but that conflicts with
+   ctrl+alt+shift key combos. Remember the modifier state on key presses and
+   releases, if mod1 is pressed, we need ctrl, shift and mod1 released
+   before we allow a shift-ctrl grab activation.
+
+   note: a key event contains the mask _before_ the current key takes
+   effect, so mod1_was_down will be reset on the first key press after all
+   three were released, not on the last release. That'd require some more
+   effort.
+ */
+static int
+ephyrUpdateGrabModifierState(int state)
+{
+    static int mod1_was_down = 0;
+
+    if ((state & (XCB_MOD_MASK_CONTROL|XCB_MOD_MASK_SHIFT|XCB_MOD_MASK_1)) == 0)
+        mod1_was_down = 0;
+    else if (state & XCB_MOD_MASK_1)
+        mod1_was_down = 1;
+
+    return mod1_was_down;
+}
+
 static void
 ephyrProcessKeyPress(xcb_generic_event_t *xev)
 {
@@ -1018,6 +1041,7 @@ ephyrProcessKeyPress(xcb_generic_event_t *xev)
         return;
     }
 
+    ephyrUpdateGrabModifierState(key->state);
     ephyrUpdateModifierState(key->state);
     KdEnqueueKeyboardEvent(ephyrKbd, key->detail, FALSE);
 }
@@ -1029,6 +1053,7 @@ ephyrProcessKeyRelease(xcb_generic_event_t *xev)
     xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
     static xcb_key_symbols_t *keysyms;
     static int grabbed_screen = -1;
+    int mod1_down = ephyrUpdateGrabModifierState(key->state);
 
     if (!keysyms)
         keysyms = xcb_key_symbols_alloc(conn);
@@ -1049,7 +1074,7 @@ ephyrProcessKeyRelease(xcb_generic_event_t *xev)
             hostx_set_win_title(screen,
                                 "(ctrl+shift grabs mouse and keyboard)");
         }
-        else {
+        else if (!mod1_down) {
             /* Attempt grab */
             xcb_grab_keyboard_cookie_t kbgrabc =
                 xcb_grab_keyboard(conn,
commit b2d5ee2e3684951b611fd2068d57cc65fd8305a3
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Thu Jan 2 21:33:30 2014 +0100

    Xi: Ensure DeviceChanged is emitted after grabs are deactivated
    
    When a grab on a slave device is deactivated, the master device must
    be checked, just in case there were events from other devices while
    the slave device was stolen away by the passive grab. This may
    introduce misbehaviors on mismatching valuators and device features
    later on UpdateDeviceState().
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index dff0a92..528e105 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1783,8 +1783,25 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
         DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
                             NullGrab, NullWindow, device);
 
-    if (deactivateDeviceGrab == TRUE)
+    if (deactivateDeviceGrab == TRUE) {
         (*device->deviceGrab.DeactivateGrab) (device);
+
+        if (!IsMaster (device) && !IsFloating (device)) {
+            int flags, num_events = 0;
+            InternalEvent dce;
+
+            flags = (IsPointerDevice (device)) ?
+                DEVCHANGE_POINTER_EVENT : DEVCHANGE_KEYBOARD_EVENT;
+            UpdateFromMaster (&dce, device, flags, &num_events);
+            BUG_WARN(num_events > 1);
+
+            if (num_events == 1)
+                ChangeMasterDeviceClasses(GetMaster (device, MASTER_ATTACHED),
+                                          &dce.changed_event);
+        }
+
+    }
+
     event->detail.key = key;
 }
 
commit 863d2ad5c02cccde9a4d1a392a7cae78d001c8a9
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Jan 6 17:10:40 2014 -0800

    CheckPassiveGrabsOnWindow() needs to handle NULL return value from AllocGrab()
    
    CheckPassiveGrabsOnWindow() calls AllocGrab() which can fail and return NULL.
    This return value is not checked, and can cause NULL pointer dereferences.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 2f0605e..acf97cc 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3956,6 +3956,8 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
         return NULL;
 
     tempGrab = AllocGrab(NULL);
+    if (tempGrab == NULL)
+        return NULL;
 
     /* Fill out the grab details, but leave the type for later before
      * comparing */
commit 5493a67ec256d22a8a41597a345d8e1c54d6e335
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Jan 6 17:10:39 2014 -0800

    GrabDevice() needs to handle NULL return value from AllocGrab()
    
    GrabDevice() calls AllocGrab() which can fail and return NULL.
    This return value is not checked, and can cause NULL pointer dereferences.
    
    Reported-by: Ilja Van Sprundel <ivansprundel at ioactive.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 4aaa54c..2f0605e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5051,7 +5051,7 @@ ProcUngrabPointer(ClientPtr client)
  * @param other_mode GrabModeSync or GrabModeAsync
  * @param status Return code to be returned to the caller.
  *
- * @returns Success or BadValue.
+ * @returns Success or BadValue or BadAlloc.
  */
 int
 GrabDevice(ClientPtr client, DeviceIntPtr dev,
@@ -5132,6 +5132,8 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
         GrabPtr tempGrab;
 
         tempGrab = AllocGrab(NULL);
+        if (tempGrab == NULL)
+            return BadAlloc;
 
         tempGrab->next = NULL;
         tempGrab->window = pWin;
commit 3a113815a0cc86d64789494e905da9778174f738
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Jan 6 17:10:38 2014 -0800

    If AllocGrab() fails to set up grab, don't copy to a NULL grab
    
    If either the initial calloc or the xi2mask_new fails, grab is NULL,
    but if a src grab is passed in, it was always being written to by
    CopyGrab (and if that failed, dereferenced again in teardown).
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/grabs.c b/dix/grabs.c
index a03897a..7f4c871 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -199,12 +199,11 @@ AllocGrab(const GrabPtr src)
             free(grab);
             grab = NULL;
         }
-    }
-
-    if (src && !CopyGrab(grab, src)) {
-        free(grab->xi2mask);
-        free(grab);
-        grab = NULL;
+        else if (src && !CopyGrab(grab, src)) {
+            free(grab->xi2mask);
+            free(grab);
+            grab = NULL;
+        }
     }
 
     return grab;
commit a92c6406e7f6c0b74fb1cb9361ad904facc0f722
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Jan 9 11:10:11 2014 +0800

    Bump release to 1.15.99.900
    
    The merge window for 1.16 is open
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 8f82386..c9f0192 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.15.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-12-27"
-RELEASE_NAME="Egg Nog"
+AC_INIT([xorg-server], 1.15.99.900, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2014-01-09"
+RELEASE_NAME="Golden Gaytime"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AC_USE_SYSTEM_EXTENSIONS
commit d6c8d7509727060b8e2358b9ed1c0e17b2ec3401
Author: Damien Lespiau <damien.lespiau at intel.com>
Date:   Wed Jul 31 19:16:45 2013 +0100

    xfree86: Use the TMDS maximum frequency to prune modes
    
    Instead of only relying on the Range section, we can do better on
    HDMI to find out what is the max dot clock the monitor supports. The
    HDMI CEA vendor block adds a TMDS max freq we can use.
    
    This makes X not prune 4k resolutions on HDMI.
    
    v2: Replace X_INFO by X_PROBED in the message that prints the max
        TMDS frequency (Chris Wilson)
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a441fd1..42fdad9 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1676,6 +1676,7 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
         if (edid_monitor) {
             struct det_monrec_parameter p;
             struct disp_features *features = &edid_monitor->features;
+            struct cea_data_block *hdmi_db;
 
             /* if display is not continuous-frequency, don't add default modes */
             if (!GTF_SUPPORTED(features->msc))
@@ -1688,6 +1689,16 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
             p.sync_source = &sync_source;
 
             xf86ForEachDetailedBlock(edid_monitor, handle_detailed_monrec, &p);
+
+            /* Look at the CEA HDMI vendor block for the max TMDS freq */
+            hdmi_db = xf86MonitorFindHDMIBlock(edid_monitor);
+            if (hdmi_db && hdmi_db->len >= 7) {
+                int tmds_freq = hdmi_db->u.vendor.hdmi.max_tmds_clock * 5000;
+                xf86DrvMsg(scrn->scrnIndex, X_PROBED,
+                           "HDMI max TMDS frequency %dKHz\n", tmds_freq);
+                if (tmds_freq > max_clock)
+                    max_clock = tmds_freq;
+            }
         }
 
         if (xf86GetOptValFreq(output->options, OPTION_MIN_CLOCK,
commit 95c2287465138ac251bf792f354cee3626e76b44
Author: Damien Lespiau <damien.lespiau at intel.com>
Date:   Wed Aug 7 15:16:21 2013 +0100

    xfree86: Refactor xf86MonitorIsHDMI() using xf86MonitorFindHDMIBlock()
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index 6c531b4..17a8f81 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -757,49 +757,5 @@ validate_version(int scrnIndex, struct edid_version *r)
 Bool
 xf86MonitorIsHDMI(xf86MonPtr mon)
 {
-    int i = 0, version, offset;
-    char *edid = NULL;
-
-    if (!mon)
-        return FALSE;
-
-    if (!(mon->flags & EDID_COMPLETE_RAWDATA))
-        return FALSE;
-
-    if (!mon->no_sections)
-        return FALSE;
-
-    edid = (char *) mon->rawData;
-    if (!edid)
-        return FALSE;
-
-    /* find the CEA extension block */
-    for (i = 1; i <= mon->no_sections; i++)
-        if (edid[i * 128] == 0x02)
-            break;
-    if (i == mon->no_sections + 1)
-        return FALSE;
-    edid += (i * 128);
-
-    version = edid[1];
-    offset = edid[2];
-    if (version < 3 || offset < 4)
-        return FALSE;
-
-    /* walk the cea data blocks */
-    for (i = 4; i < offset; i += (edid[i] & 0x1f) + 1) {
-        char *x = edid + i;
-
-        /* find a vendor specific block */
-        if ((x[0] & 0xe0) >> 5 == 0x03) {
-            int oui = (x[3] << 16) + (x[2] << 8) + x[1];
-
-            /* find the HDMI vendor OUI */
-            if (oui == 0x000c03)
-                return TRUE;
-        }
-    }
-
-    /* guess it's not HDMI after all */
-    return FALSE;
+    return xf86MonitorFindHDMIBlock(mon) != NULL;
 }
commit a279fb3ff3f3cfc41530aff1d9ff5620279348f6
Author: Damien Lespiau <damien.lespiau at intel.com>
Date:   Wed Jul 31 19:11:45 2013 +0100

    xfree86: Add a xf86MonitorFindHDMIBlock()
    
    The HDMI CEA vendor specific block has some interesting information,
    such as the maximum TMDS dot clock.
    
    v2: Don't parse CEA blocks with invalid offsets, remove spurious
        brackets (Chris Wilson)
    
    v3: Fix the looping through the CEA data blocks, it had a typo using the
        wrong variable coming from the code it was ported from.
        Replace x << 16 + y << 8 + z by x << 16 | y << 8 | z
        (Chris Wilson)
    
    v4: Remove the stray ';' at the end of "if (*end == 0)".
        (Dominik Behr on IRC)
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>

diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
index 882a6b2..6c531b4 100644
--- a/hw/xfree86/ddc/interpret_edid.c
+++ b/hw/xfree86/ddc/interpret_edid.c
@@ -332,6 +332,97 @@ xf86ForEachVideoBlock(xf86MonPtr mon, handle_video_fn fn, void *data)
     }
 }
 
+static Bool
+cea_db_offsets(Uchar *cea, int *start, int *end)
+{
+    /* Data block offset in CEA extension block */
+    *start = CEA_EXT_MIN_DATA_OFFSET;
+    *end = cea[2];
+    if (*end == 0)
+        *end = CEA_EXT_MAX_DATA_OFFSET;
+    if (*end < CEA_EXT_MIN_DATA_OFFSET || *end > CEA_EXT_MAX_DATA_OFFSET)
+        return FALSE;
+    return TRUE;
+}
+
+static int
+cea_db_len(Uchar *db)
+{
+    return db[0] & 0x1f;
+}
+
+static int
+cea_db_tag(Uchar *db)
+{
+    return db[0] >> 5;
+}
+
+typedef void (*handle_cea_db_fn) (Uchar *, void *);
+
+static void
+cea_for_each_db(xf86MonPtr mon, handle_cea_db_fn fn, void *data)
+{
+    int i;
+
+    if (!mon)
+        return;
+
+    if (!(mon->flags & EDID_COMPLETE_RAWDATA))
+        return;
+
+    if (!mon->no_sections)
+        return;
+
+    if (!mon->rawData)
+        return;
+
+    for (i = 0; i < mon->no_sections; i++) {
+        int start, end, offset;
+        Uchar *ext;
+
+        ext = mon->rawData + EDID1_LEN * (i + 1);
+        if (ext[EXT_TAG] != CEA_EXT)
+            continue;
+
+        if (!cea_db_offsets(ext, &start, &end))
+            continue;
+
+        for (offset = start;
+             offset < end && offset + cea_db_len(&ext[offset]) < end;
+             offset += cea_db_len(&ext[offset]) + 1)
+                fn(&ext[offset], data);
+    }
+}
+
+struct find_hdmi_block_data {
+    struct cea_data_block *hdmi;
+};
+
+static void find_hdmi_block(Uchar *db, void *data)
+{
+    struct find_hdmi_block_data *result = data;
+    int oui;
+
+    if (cea_db_tag(db) != CEA_VENDOR_BLK)
+        return;
+
+    if (cea_db_len(db) < 5)
+        return;
+
+    oui = (db[3] << 16) | (db[2] << 8) | db[1];
+    if (oui == IEEE_ID_HDMI)
+        result->hdmi = (struct cea_data_block *)db;
+}
+
+struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon)
+{
+    struct find_hdmi_block_data result = { NULL };
+
+    cea_for_each_db(mon, find_hdmi_block, &result);
+
+    return result.hdmi;
+}
+
 xf86MonPtr
 xf86InterpretEEDID(int scrnIndex, Uchar * block)
 {
diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
index bdc7648..de8e718 100644
--- a/hw/xfree86/ddc/xf86DDC.h
+++ b/hw/xfree86/ddc/xf86DDC.h
@@ -98,4 +98,6 @@ typedef void (*handle_video_fn) (struct cea_video_block *, void *);
 
 void xf86ForEachVideoBlock(xf86MonPtr, handle_video_fn, void *);
 
+struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon);
+
 #endif
commit 295d41fa2aa97b74c1b9ffd7ef4ccf52f3e97dde
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Dec 16 10:52:19 2013 -0800

    glx: unifdef swrast dri_interface.h values from Mesa 7.1.
    
    We can't remove all the ifdefs (__DRI_TEX_BUFFER_VERSION) because
    configure.ac is only checking for that version of Mesa in the absence
    of dri2.
    
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index cbc109a..6fa3288 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -170,8 +170,6 @@ __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc,
                                          src->driContext, mask);
 }
 
-#ifdef __DRI_TEX_BUFFER
-
 static int
 __glXDRIbindTexImage(__GLXcontext * baseContext,
                      int buffer, __GLXdrawable * glxPixmap)
@@ -205,24 +203,6 @@ __glXDRIreleaseTexImage(__GLXcontext * baseContext,
     return Success;
 }
 
-#else
-
-static int
-__glXDRIbindTexImage(__GLXcontext * baseContext,
-                     int buffer, __GLXdrawable * glxPixmap)
-{
-    return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext * baseContext,
-                        int buffer, __GLXdrawable * pixmap)
-{
-    return Success;
-}
-
-#endif
-
 static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
     __glXDRIbindTexImage,
     __glXDRIreleaseTexImage
@@ -407,20 +387,17 @@ initializeExtensions(__GLXDRIscreen * screen)
     extensions = screen->core->getExtensions(screen->driScreen);
 
     for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_COPY_SUB_BUFFER
         if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
             screen->copySubBuffer =
                 (const __DRIcopySubBufferExtension *) extensions[i];
             /* GLX_MESA_copy_sub_buffer is always enabled. */
         }
-#endif
 
-#ifdef __DRI_TEX_BUFFER
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
             screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
             /* GLX_EXT_texture_from_pixmap is always enabled. */
         }
-#endif
+
         /* Ignore unknown extensions */
     }
 }
commit 4ab1a2797ba366179f8a2e621334dd45df2a5a65
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Nov 5 11:41:06 2013 -0800

    glx: unifdef for DRI2 dri_interface.h things in mesa 9.2.
    
    Thanks to configure.ac's check, we know that we have a new enough
    dri_interface.h that we don't need to conditionalize all this code.
    
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index b2f3d6e..8c10586 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -55,14 +55,9 @@ typedef struct __GLXDRIscreen __GLXDRIscreen;
 typedef struct __GLXDRIcontext __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
 
-#ifdef __DRI2_ROBUSTNESS
 #define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG                         \
                            | __DRI_CTX_FLAG_FORWARD_COMPATIBLE          \
                            | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
-#else
-#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG                         \
-                           | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)
-#endif
 
 struct __GLXDRIscreen {
     __GLXscreen base;
@@ -210,15 +205,10 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable)
     __GLXDRIscreen *screen = priv->screen;
     CARD64 unused;
 
-#if __DRI2_FLUSH_VERSION >= 3
     if (screen->flush) {
         (*screen->flush->flush) (priv->driDrawable);
         (*screen->flush->invalidate) (priv->driDrawable);
     }
-#else
-    if (screen->flush)
-        (*screen->flush->flushInvalidate) (priv->driDrawable);
-#endif
 
     if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
                         __glXdriSwapEvent, drawable) != Success)
@@ -294,8 +284,6 @@ __glXDRIcontextWait(__GLXcontext * baseContext,
     return FALSE;
 }
 
-#ifdef __DRI_TEX_BUFFER
-
 static int
 __glXDRIbindTexImage(__GLXcontext * baseContext,
                      int buffer, __GLXdrawable * glxPixmap)
@@ -307,14 +295,12 @@ __glXDRIbindTexImage(__GLXcontext * baseContext,
     if (texBuffer == NULL)
         return Success;
 
-#if __DRI_TEX_BUFFER_VERSION >= 2
     if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
         (*texBuffer->setTexBuffer2) (context->driContext,
                                      glxPixmap->target,
                                      glxPixmap->format, drawable->driDrawable);
     }
     else
-#endif
     {
         texBuffer->setTexBuffer(context->driContext,
                                 glxPixmap->target, drawable->driDrawable);
@@ -331,24 +317,6 @@ __glXDRIreleaseTexImage(__GLXcontext * baseContext,
     return Success;
 }
 
-#else
-
-static int
-__glXDRIbindTexImage(__GLXcontext * baseContext,
-                     int buffer, __GLXdrawable * glxPixmap)
-{
-    return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext * baseContext,
-                        int buffer, __GLXdrawable * pixmap)
-{
-    return Success;
-}
-
-#endif
-
 static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
     __glXDRIbindTexImage,
     __glXDRIreleaseTexImage
@@ -398,11 +366,7 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
 
     *major_ver = 1;
     *minor_ver = 0;
-#ifdef __DRI2_ROBUSTNESS
     *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
-#else
-    (void) reset;
-#endif
 
     for (i = 0; i < num_attribs; i++) {
         switch (attribs[i * 2]) {
@@ -433,7 +397,6 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
                 return False;
             }
             break;
-#ifdef __DRI2_ROBUSTNESS
         case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
             if (screen->dri2->base.version >= 4) {
                 *error = BadValue;
@@ -452,7 +415,6 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
                 return False;
             }
             break;
-#endif
         default:
             /* If an unknown attribute is received, fail.
              */
@@ -493,7 +455,6 @@ create_driver_context(__GLXDRIcontext * context,
 {
     context->driContext = NULL;
 
-#if __DRI_DRI2_VERSION >= 3
     if (screen->dri2->base.version >= 3) {
         uint32_t ctx_attribs[3 * 2];
         unsigned num_ctx_attribs = 0;
@@ -525,13 +486,11 @@ create_driver_context(__GLXDRIcontext * context,
                 ctx_attribs[num_ctx_attribs++] = flags;
             }
 
-#ifdef __DRI2_ROBUSTNESS
             if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) {
                 ctx_attribs[num_ctx_attribs++] =
                     __DRI_CTX_ATTRIB_RESET_STRATEGY;
                 ctx_attribs[num_ctx_attribs++] = reset;
             }
-#endif
         }
 
         context->driContext =
@@ -567,7 +526,6 @@ create_driver_context(__GLXDRIcontext * context,
 
         return;
     }
-#endif
 
     if (num_attribs != 0) {
         *error = BadValue;
@@ -625,13 +583,11 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
 static void
 __glXDRIinvalidateBuffers(DrawablePtr pDraw, void *priv, XID id)
 {
-#if __DRI2_FLUSH_VERSION >= 3
     __GLXDRIdrawable *private = priv;
     __GLXDRIscreen *screen = private->screen;
 
     if (screen->flush)
         (*screen->flush->invalidate) (private->driDrawable);
-#endif
 }
 
 static __GLXdrawable *
@@ -778,18 +734,14 @@ static const __DRIdri2LoaderExtension loaderExtension = {
     dri2GetBuffersWithFormat,
 };
 
-#ifdef __DRI_USE_INVALIDATE
 static const __DRIuseInvalidateExtension dri2UseInvalidate = {
     {__DRI_USE_INVALIDATE, 1}
 };
-#endif
 
 static const __DRIextension *loader_extensions[] = {
     &systemTimeExtension.base,
     &loaderExtension.base,
-#ifdef __DRI_USE_INVALIDATE
     &dri2UseInvalidate.base,
-#endif
     NULL
 };
 
@@ -850,8 +802,6 @@ initializeExtensions(__GLXDRIscreen * screen)
     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
-
-#if __DRI_DRI2_VERSION >= 3
     if (screen->dri2->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
@@ -864,7 +814,6 @@ initializeExtensions(__GLXDRIscreen * screen)
         LogMessage(X_INFO,
                    "AIGLX: enabled GLX_EXT_create_context_es2_profile\n");
     }
-#endif
 
     if (DRI2HasSwapControl(pScreen)) {
         __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
@@ -889,32 +838,25 @@ initializeExtensions(__GLXDRIscreen * screen)
     }
 
     for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_READ_DRAWABLE
         if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
             __glXEnableExtension(screen->glx_enable_bits,
                                  "GLX_SGI_make_current_read");
 
             LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
         }
-#endif
 
-#ifdef __DRI_TEX_BUFFER
         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
             screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
             /* GLX_EXT_texture_from_pixmap is always enabled. */
             LogMessage(X_INFO,
                        "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
         }
-#endif
 
-#ifdef __DRI2_FLUSH
         if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
             extensions[i]->version >= 3) {
             screen->flush = (__DRI2flushExtension *) extensions[i];
         }
-#endif
 
-#ifdef __DRI2_ROBUSTNESS
         if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0 &&
             screen->dri2->base.version >= 3) {
             __glXEnableExtension(screen->glx_enable_bits,
@@ -922,7 +864,6 @@ initializeExtensions(__GLXDRIscreen * screen)
             LogMessage(X_INFO,
                        "AIGLX: enabled GLX_ARB_create_context_robustness\n");
         }
-#endif
 
         /* Ignore unknown extensions */
     }
commit 4dd62d7807b47efbc9065ae8f17f73e1ec6e9d26
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Tue Dec 10 11:13:32 2013 -0500

    libglamoregl: remove -I$(top_srcdir)/src
    
    Automake always provide -I. It is at the beginning of the list of compiler
    options.
    
    Not needed either to find glamor_egl.c source.
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 79ea959..2fd521f 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -59,11 +59,10 @@ module_LTLIBRARIES = $(LIBGLAMOREGL)
 libglamoregl_la_DEPENDENCIES = libglamor.la
 libglamoregl_la_LDFLAGS = -avoid-version -module
 libglamoregl_la_LIBADD = $(EGL_LIBS) $(GLX_SYS_LIBS) $(GBM_LIBS) libglamor.la
-libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
+libglamoregl_la_SOURCES = glamor_eglmodule.c glamor_egl.c
 libglamoregl_la_CFLAGS = \
 	$(AM_CFLAGS) \
 	$(GLX_DEFINES) \
-	-I$(top_srcdir)/src \
 	$(LIBDRM_CFLAGS) \
 	$(EGL_CFLAGS) \
 	$(GBM_CFLAGS)
commit 08c23ff8aefe80f2940ecb90adda27156084f57c
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Tue Dec 10 11:13:31 2013 -0500

    Make: remove cruft copied over from the X server makefiles
    
    In toplevel makefile:
    nostdinc: only xserver, no other X modules
    aclocaldir: no local macros to install
    xkb_path: xserver only
    "Gross hack": xserver only
    
    In src/makefile:
    SOLARIS_ASM_CFLAGS; server only
    XORG_INCS: undefined variable
    DIX_CFLAGS: undefined variable
    
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 50cfe97..79ea959 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -1,19 +1,12 @@
 lib_LTLIBRARIES = libglamor.la
 
-# Override these since glamor doesn't need them and the needed files aren't
-# built (in hw/xfree86/os-support/solaris) until after glamor is built
-SOLARIS_ASM_CFLAGS=""
-
 if GLAMOR_GLES2
 libglamor_la_LIBADD = $(GLESV2_LIBS)
 else
 libglamor_la_LIBADD = $(GL_LIBS)
 endif
 
-AM_CPPFLAGS = \
-	$(XORG_INCS)
-
-AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
+AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(LIBDRM_CFLAGS)
 
 libglamor_la_LDFLAGS = -version-info 0:0:0
 
commit b8055bd1f6c9dea0fe8f7a786d2a1522f5f32129
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Dec 13 11:33:46 2013 +1000

    glamor: fix leak in xv code.
    
    This loop needed to go one higher, not sure if this fixes the leak
    MrCooper was seeing on irc, but it fixes a leak.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 8f12c1f..a89b4cd 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -490,7 +490,7 @@ static int glamor_xv_put_image(ScrnInfoPtr pScrn,
 
 	if (!port_priv->src_pix[0] || (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
 		int i;
-		for (i = 0; i < 2; i++)
+		for (i = 0; i < 3; i++)
 			if (port_priv->src_pix[i])
 				glamor_destroy_pixmap(port_priv->src_pix[i]);
 
commit 752a79562eb13f59fa54b4181d65367c8488c0a5
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sun Dec 8 16:43:08 2013 -0500

    Fix glamor_egl->egl_create_image_khr makes pointer from integer
    
    This is a warning, but a real problem can occur on some system.
    
    Reported-by: Fabio Pedretti <fabio.ped at libero.it>
    Reviewed-by: Axel Davy <davyaxel at free.fr>
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index bf0db3a..ff4c0bd 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -453,7 +453,7 @@ int glamor_egl_dri3_fd_name_from_tex (ScreenPtr screen,
 		image = glamor_egl->egl_create_image_khr(glamor_egl->display,
 							 glamor_egl->context,
 							 EGL_GL_TEXTURE_2D_KHR,
-							 tex, attribs);
+							 (EGLClientBuffer)(uintptr_t)tex, attribs);
 		if (image == EGL_NO_IMAGE_KHR)
 			goto failure;
 
commit 7cfd9cc23270c0246d584e167fe14bf5af4571df
Author: Axel Davy <axel.davy at ens.fr>
Date:   Thu Dec 5 08:49:15 2013 +0100

    Add DRI3 support to glamor
    
    This implements some DRI3 helpers to help the DDXs using
    glamor to support DRI3.
    
    Signed-off-by: Axel Davy <axel.davy at ens.fr>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e8e68be..93d3c5e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -209,7 +209,12 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
-	glamor_destroy_textured_pixmap(pixmap);
+	glamor_screen_private
+	  *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+	if (glamor_priv->dri3_enabled)
+		glamor_egl_destroy_textured_pixmap(pixmap);
+	else
+		glamor_destroy_textured_pixmap(pixmap);
 	return fbDestroyPixmap(pixmap);
 }
 
@@ -552,3 +557,72 @@ glamor_fini(ScreenPtr screen)
 {
 	/* Do nothing currently. */
 }
+
+void glamor_enable_dri3(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_priv->dri3_enabled = TRUE;
+}
+
+Bool glamor_is_dri3_support_enabled(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	return glamor_priv->dri3_enabled;
+}
+
+int
+glamor_dri3_fd_from_pixmap (ScreenPtr screen,
+                            PixmapPtr pixmap,
+                            CARD16 *stride,
+                            CARD32 *size)
+{
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
+		return -1;
+	switch (pixmap_priv->type)
+	{
+		case GLAMOR_TEXTURE_DRM:
+		case GLAMOR_TEXTURE_ONLY:
+			glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+			return glamor_egl_dri3_fd_name_from_tex(screen,
+								pixmap,
+								pixmap_priv->base.fbo->tex,
+								FALSE,
+								stride,
+								size);
+		default: break;
+	}
+	return -1;
+}
+
+int
+glamor_dri3_name_from_pixmap (PixmapPtr pixmap)
+{
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
+		return -1;
+	switch (pixmap_priv->type)
+	{
+		case GLAMOR_TEXTURE_DRM:
+		case GLAMOR_TEXTURE_ONLY:
+			glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+			return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
+								pixmap,
+								pixmap_priv->base.fbo->tex,
+								TRUE,
+								NULL,
+								NULL);
+		default: break;
+	}
+	return -1;
+}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 927892f..1bb48ed 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -164,6 +164,71 @@ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr bac
 
 extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
 
+/* The DDX is not supposed to call these three functions */
+extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
+extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h);
+extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16*, CARD32*);
+
+/* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled.
+ *
+ * @screen: Current screen pointer.
+ *
+ * To have DRI3 support enabled, glamor and glamor_egl need to be initialized,
+ * and glamor_egl_init_textured_pixmap need to be called. glamor also
+ * has to be compiled with gbm support.
+ * The EGL layer need to have the following extensions working:
+ * .EGL_KHR_gl_texture_2D_image
+ * .EGL_EXT_image_dma_buf_import
+ * If DRI3 support is not enabled, the following helpers will return an error.
+ * */
+extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen);
+
+/* @glamor_dri3_fd_from_pixmap: DRI3 helper to get a dma-buf fd from a pixmap.
+ *
+ * @screen: Current screen pointer.
+ * @pixmap: The pixmap from which we want the fd.
+ * @stride, @size: Pointers to fill the stride and size of the
+ * 		   buffer associated to the fd.
+ *
+ * the pixmap and the buffer associated by the fd will share the same
+ * content.
+ * Returns the fd on success, -1 on error.
+ * */
+extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen,
+						 PixmapPtr pixmap,
+						 CARD16 *stride,
+						 CARD32 *size);
+
+/* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap.
+ *
+ * @pixmap: The pixmap from which we want the gem name.
+ *
+ * the pixmap and the buffer associated by the gem name will share the same
+ * content. This function can be used by the DDX to support DRI2, but needs
+ * glamor DRI3 support to be activated.
+ * Returns the name on success, -1 on error.
+ * */
+extern _X_EXPORT int glamor_dri3_name_from_pixmap (PixmapPtr pixmap);
+
+/* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd.
+ *
+ * @screen: Current screen pointer.
+ * @fd: The dma-buf fd to import.
+ * @width: The width of the buffer.
+ * @height: The height of the buffer.
+ * @stride: The stride of the buffer.
+ * @depth: The depth of the buffer.
+ * @bpp: The number of bpp of the buffer.
+ *
+ * Returns a valid pixmap if the import succeeded, else NULL.
+ * */
+extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
+							   int fd,
+							   CARD16 width,
+							   CARD16 height,
+							   CARD16 stride,
+							   CARD8 depth,
+							   CARD8 bpp);
 
 #ifdef GLAMOR_FOR_XORG
 
@@ -243,9 +308,10 @@ extern _X_EXPORT Bool
 	glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
 						      void *bo);
 
-extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
 
+extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
+
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 
 extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 13b7f44..bf0db3a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -45,6 +45,7 @@
 
 #ifdef GLAMOR_HAS_GBM
 #include <gbm.h>
+#include <drm_fourcc.h>
 #endif
 
 #if GLAMOR_GLES2
@@ -95,6 +96,7 @@ struct glamor_egl_screen_private {
 	void *glamor_context;
 	void *current_context;
 	int gl_context_depth;
+	int dri3_capable;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
@@ -218,6 +220,47 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
 	return TRUE;
 }
 
+unsigned int
+glamor_egl_create_argb8888_based_texture(ScreenPtr screen,
+					 int w,
+					 int h)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_egl_screen_private *glamor_egl;
+	EGLImageKHR image;
+	GLuint texture;
+#ifdef GLAMOR_HAS_DRI3_SUPPORT
+	struct gbm_bo *bo;
+	EGLNativePixmapType native_pixmap;
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+	bo = gbm_bo_create (glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
+				      GBM_BO_USE_RENDERING |
+				      GBM_BO_USE_SCANOUT);
+	if (!bo)
+		return 0;
+
+	/* If the following assignment raises an error or a warning
+	 * then that means EGLNativePixmapType is not struct gbm_bo *
+	 * on your platform: This code won't work and you should not
+	 * compile with dri3 support enabled */
+	native_pixmap = bo;
+
+	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+						 EGL_NO_CONTEXT,
+						 EGL_NATIVE_PIXMAP_KHR,
+						 native_pixmap, NULL);
+	gbm_bo_destroy(bo);
+	if (image == EGL_NO_IMAGE_KHR)
+		return 0;
+	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+
+	return texture;
+#else
+	return 0; /* this path should never happen */
+#endif
+}
+
 Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
@@ -349,6 +392,178 @@ done:
 	return ret;
 }
 
+#ifdef GLAMOR_HAS_DRI3_SUPPORT
+int glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd);
+void glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name);
+int
+glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd)
+{
+	union gbm_bo_handle handle;
+	struct drm_prime_handle args;
+
+	handle = gbm_bo_get_handle(bo);
+	args.handle = handle.u32;
+	args.flags = DRM_CLOEXEC;
+	if (ioctl (gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
+		return FALSE;
+	*fd = args.fd;
+	return TRUE;
+}
+
+void
+glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name)
+{
+	union gbm_bo_handle handle;
+
+	handle = gbm_bo_get_handle(bo);
+	if (!glamor_get_flink_name(gbm_fd, handle.u32, name))
+		*name = -1;
+}
+#endif
+
+int glamor_egl_dri3_fd_name_from_tex (ScreenPtr screen,
+				      PixmapPtr pixmap,
+				      unsigned int tex,
+				      Bool want_name,
+				      CARD16 *stride,
+				      CARD32 *size)
+{
+#ifdef GLAMOR_HAS_DRI3_SUPPORT
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_egl_screen_private *glamor_egl;
+	EGLImageKHR image;
+	struct gbm_bo* bo;
+	int fd = -1;
+
+	EGLint attribs[] = {
+		EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+		EGL_GL_TEXTURE_LEVEL_KHR, 0,
+		EGL_NONE
+	};
+
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+
+	glamor_egl_make_current(screen);
+
+	image = dixLookupPrivate(&pixmap->devPrivates,
+				 glamor_egl_pixmap_private_key);
+
+	if (image == EGL_NO_IMAGE_KHR || image == NULL)
+	{
+		image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+							 glamor_egl->context,
+							 EGL_GL_TEXTURE_2D_KHR,
+							 tex, attribs);
+		if (image == EGL_NO_IMAGE_KHR)
+			goto failure;
+
+		dixSetPrivate(&pixmap->devPrivates,
+			      glamor_egl_pixmap_private_key,
+			      image);
+		glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+	}
+
+	bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
+	if (!bo)
+		goto failure;
+
+	pixmap->devKind = gbm_bo_get_stride(bo);
+
+	if (want_name)
+	{
+		if (glamor_egl->has_gem)
+			glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
+	}
+	else
+	{
+		if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd))
+		{
+			*stride = pixmap->devKind;
+			*size = pixmap->devKind * gbm_bo_get_height(bo);
+		}
+	}
+
+	gbm_bo_destroy(bo);
+failure:
+	glamor_egl_restore_context(screen);
+	return fd;
+#else
+	return -1;
+#endif
+}
+
+PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
+					  int fd,
+					  CARD16 width,
+					  CARD16 height,
+					  CARD16 stride,
+					  CARD8 depth,
+					  CARD8 bpp)
+{
+#ifdef GLAMOR_HAS_DRI3_SUPPORT
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_egl_screen_private *glamor_egl;
+	struct gbm_bo* bo;
+	EGLImageKHR image;
+	PixmapPtr pixmap;
+	Bool ret = FALSE;
+	EGLint attribs[] = {
+		EGL_WIDTH, 0,
+		EGL_HEIGHT, 0,
+		EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
+		EGL_DMA_BUF_PLANE0_FD_EXT, 0,
+		EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+		EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
+		EGL_NONE
+	};
+
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+
+	if (!glamor_egl->dri3_capable)
+		return NULL;
+
+	if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
+		return NULL;
+
+	attribs[1] = width;
+	attribs[3] = height;
+	attribs[7] = fd;
+	attribs[11] = stride;
+	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+						 EGL_NO_CONTEXT,
+						 EGL_LINUX_DMA_BUF_EXT,
+						 NULL, attribs);
+
+	if (image == EGL_NO_IMAGE_KHR)
+		return NULL;
+
+	/* EGL_EXT_image_dma_buf_import can impose restrictions on the
+	 * usage of the image. Use gbm_bo to bypass the limitations. */
+
+	bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
+	glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+
+	if (!bo)
+		return NULL;
+
+	pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
+	screen->ModifyPixmapHeader (pixmap, width, height, 0, 0, stride, NULL);
+
+	ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
+	gbm_bo_destroy(bo);
+
+	if (ret)
+		return pixmap;
+	else
+	{
+		screen->DestroyPixmap(pixmap);
+		return NULL;
+	}
+#else
+	return NULL;
+#endif
+}
+
 static void
 _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
@@ -558,6 +773,11 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_opengl);
 #endif
 
+#ifdef GLAMOR_HAS_DRI3_SUPPORT
+	if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
+	    glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import") )
+	    glamor_egl->dri3_capable = TRUE;
+#endif
 	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
 	    eglGetProcAddress("eglCreateImageKHR");
 
@@ -609,6 +829,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 Bool
 glamor_egl_init_textured_pixmap(ScreenPtr screen)
 {
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
 	if (!dixRegisterPrivateKey
 	    (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
 		LogMessage(X_WARNING,
@@ -616,6 +839,8 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen)
 			   screen->myNum);
 		return FALSE;
 	}
+	if (glamor_egl->dri3_capable)
+		glamor_enable_dri3(screen);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 4838a27..d1b087e 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -328,18 +328,30 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
 		   int w, int h, GLenum format)
 {
 	glamor_gl_dispatch *dispatch;
-	unsigned int tex;
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glGenTextures(1, &tex);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
-			       GL_UNSIGNED_BYTE, NULL);
-	glamor_put_dispatch(glamor_priv);
+	unsigned int tex = 0;
+
+	/* With dri3, we want to allocate ARGB8888 pixmaps only.
+	 * Depending on the implementation, GL_RGBA might not
+	 * give us ARGB8888. We ask glamor_egl to use get
+	 * an ARGB8888 based texture for us. */
+	if (glamor_priv->dri3_enabled && format == GL_RGBA)
+	{
+		tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
+								w, h);
+	}
+	if (!tex)
+	{
+		dispatch = glamor_get_dispatch(glamor_priv);
+		dispatch->glGenTextures(1, &tex);
+		dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+				       format, GL_UNSIGNED_BYTE, NULL);
+		glamor_put_dispatch(glamor_priv);
+	}
 	return tex;
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b6a1075..7b8f762 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -305,6 +305,7 @@ typedef struct glamor_screen_private {
 	int state;
 	unsigned int render_idle_cnt;
 	ScreenPtr screen;
+	int dri3_enabled;
 
 	/* xv */
 	GLint xv_prog;
commit 06ba3fdfd6162a64c149ea6fda85f9f56d7f3c31
Author: Zhigang Gong <zhigang.gong at intel.com>
Date:   Tue Nov 19 15:16:57 2013 +0800

    Fixed some compilation warning/error or error checking.
    
    There is one compilation error ,cast int to pointer, when built without
    libgbm, reported by Gaetan Nadon.
    And some error checking after memory allocation, reported by Seth Arnold.
    There are still some similar issues in the largepixmap implementation.
    They are relatively more complicate due to the heavy usage of RegionXXX
    APIs which may allocate implicitly. Will fix them in the future.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
    Tested-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 22065bc..eb1a08d 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -68,11 +68,14 @@ glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
 
 		dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
 		info = malloc(size);
-
-		dispatch->glGetShaderInfoLog(prog, size, NULL, info);
-		ErrorF("Failed to compile %s: %s\n",
-		       type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
-		ErrorF("Program source:\n%s", source);
+		if (info) {
+			dispatch->glGetShaderInfoLog(prog, size, NULL, info);
+			ErrorF("Failed to compile %s: %s\n",
+			       type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
+			ErrorF("Program source:\n%s", source);
+			free(info);
+		} else
+			ErrorF("Failed to get shader compilation info.\n");
 		FatalError("GLSL compile failure\n");
 	}
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 50b764b..13b7f44 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -500,6 +500,8 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 
 	glamor_identify(0);
 	glamor_egl = calloc(sizeof(*glamor_egl), 1);
+	if (glamor_egl == NULL)
+		return FALSE;
 	if (xf86GlamorEGLPrivateIndex == -1)
 		xf86GlamorEGLPrivateIndex =
 		    xf86AllocateScrnInfoPrivateIndex();
@@ -514,7 +516,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	}
 	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
 #else
-	glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)fd);
+	glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)(intptr_t)fd);
 #endif
 
 	glamor_egl->has_gem = glamor_egl_check_has_gem(fd);
commit a5321ea431376feca2dcd55cf04925dc492270fc
Author: Axel Davy <axel.davy at ens.fr>
Date:   Mon Nov 18 22:52:22 2013 +0100

    Allow to create textured pixmaps from gbm_bo without using gem names
    
    This implements glamor_egl_create_textured_pixmap_from_gbm_bo,
    which is similar to glamor_egl_create_textured_pixmap, except
    it takes a gbm_bo as argument.
    
    Signed-off-by: Axel Davy <axel.davy at ens.fr>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index c143c4d..927892f 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -230,6 +230,19 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
 							int handle,
 							int stride);
 
+/*
+ * @glamor_egl_create_textured_pixmap_from_bo: Try to create a textured pixmap
+ * 					       from a gbm_bo.
+ *
+ * @pixmap: The pixmap need to be processed.
+ * @bo: a pointer on a gbm_bo structure attached to this pixmap at DDX layer.
+ *
+ * This function is similar to glamor_egl_create_textured_pixmap.
+ */
+extern _X_EXPORT Bool
+	glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
+						      void *bo);
+
 extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index cd0bdc0..50b764b 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -315,6 +315,40 @@ done:
 	return ret;
 }
 
+Bool
+glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_egl_screen_private *glamor_egl;
+	EGLImageKHR image;
+	GLuint texture;
+	Bool ret = FALSE;
+
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+
+	glamor_egl_make_current(screen);
+
+	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+						 glamor_egl->context,
+						 EGL_NATIVE_PIXMAP_KHR,
+						 bo, NULL);
+	if (image == EGL_NO_IMAGE_KHR) {
+		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+		goto done;
+	}
+	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+	glamor_set_pixmap_texture(pixmap, texture);
+	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
+		      image);
+	ret = TRUE;
+
+done:
+	glamor_egl_restore_context(screen);
+	return ret;
+}
+
 static void
 _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
commit 403004fe799f293bf299fe78da821635b19d9a1a
Author: Fabio Pedretti <fabio.ped at libero.it>
Date:   Mon Nov 4 12:08:42 2013 +0100

    glamor: remove unused variable
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 1d77eaa..8f12c1f 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -90,7 +90,6 @@ glamor_init_xv_shader(ScreenPtr screen)
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
 	GLint fs_prog, vs_prog;
-	GLint sampler_loc;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch =  glamor_get_dispatch(glamor_priv);
commit 842cd7eb4353492bc9c29439f975c3bd33445cbd
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Wed Nov 6 10:25:27 2013 +0100

    fixup picture in SetWindowPixmap
    
    When creating a window with recordmydesktop running, the following may happen:
    
    create picture 0x1cd457e0, with drawable 0x1327d1f0
    (SetWindowPixmap is called)
    destroy picture 0x1cd457e0, with drawable 0x1cd65820
    
    Obtaining format for pixmap 0x1327d1f0 and picture 0x1cd457e0
    ==7989== Invalid read of size 4
    ==7989==    at 0x8CAA0CA: glamor_get_tex_format_type_from_pixmap (glamor_utils.h:1252)
    ==7989==    by 0x8CAD1B7: glamor_download_sub_pixmap_to_cpu (glamor_pixmap.c:1074)
    ==7989==    by 0x8CA8BB7: _glamor_get_image (glamor_getimage.c:66)
    ==7989==    by 0x8CA8D2F: glamor_get_image (glamor_getimage.c:92)
    ==7989==    by 0x29AEF2: miSpriteGetImage (misprite.c:413)
    ==7989==    by 0x1E7674: compGetImage (compinit.c:148)
    ==7989==    by 0x1F5E5B: ProcShmGetImage (shm.c:684)
    ==7989==    by 0x1F686F: ProcShmDispatch (shm.c:1121)
    ==7989==    by 0x15D00D: Dispatch (dispatch.c:432)
    ==7989==    by 0x14C569: main (main.c:298)
    ==7989==  Address 0x1cd457f0 is 16 bytes inside a block of size 120 free'd
    ==7989==    at 0x4C2B60C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==7989==    by 0x228897: FreePicture (picture.c:1477)
    ==7989==    by 0x228B23: PictureDestroyWindow (picture.c:73)
    ==7989==    by 0x234C19: damageDestroyWindow (damage.c:1646)
    ==7989==    by 0x1E92C0: compDestroyWindow (compwindow.c:590)
    ==7989==    by 0x20FF85: DbeDestroyWindow (dbe.c:1389)
    ==7989==    by 0x185D46: FreeWindowResources (window.c:907)
    ==7989==    by 0x1889A7: DeleteWindow (window.c:975)
    ==7989==    by 0x17EBF1: doFreeResource (resource.c:873)
    ==7989==    by 0x17FC1B: FreeClientResources (resource.c:1139)
    ==7989==    by 0x15C4DE: CloseDownClient (dispatch.c:3402)
    ==7989==    by 0x2AB843: CheckConnections (connection.c:1008)
    ==7989==
    (II) fail to get matched format for dfdfdfdf
    
    The fix is to update the picture pointer when the window pixmap is changed,
    so it moves the picture around with the window rather than the pixmap.
    
    This makes FreePicture work correctly.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71088
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7637f3b..e8e68be 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -413,6 +413,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_priv->saved_procs.create_picture = ps->CreatePicture;
 	ps->CreatePicture = glamor_create_picture;
 
+	glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
+	screen->SetWindowPixmap = glamor_set_window_pixmap;
+
 	glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
 	ps->DestroyPicture = glamor_destroy_picture;
 	glamor_init_composite_shaders(screen);
@@ -531,6 +534,7 @@ glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
 	ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
 	ps->Glyphs = glamor_priv->saved_procs.glyphs;
 	ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
+	screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
 #endif
 	screen_pixmap = screen->GetScreenPixmap(screen);
 	glamor_set_pixmap_private(screen_pixmap, NULL);
diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index f1564a2..1a57699 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -215,8 +215,8 @@ glamor_composite_rectangles(CARD8	 op,
 	if (dst->pCompositeClip->data &&
 	    (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
 	     region_is_empty(&region))) {
-		DEBUGF(("%s: zero-intersection between rectangles and clip\n",
-		     __FUNCTION__));
+		DEBUGF("%s: zero-intersection between rectangles and clip\n",
+		     __FUNCTION__);
 		pixman_region_fini(&region);
 		return;
 	}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ffdd7fd..b6a1075 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -221,6 +221,7 @@ struct glamor_saved_procs {
 	CreatePictureProcPtr create_picture;
 	DestroyPictureProcPtr destroy_picture;
 	UnrealizeGlyphProcPtr unrealize_glyph;
+	SetWindowPixmapProcPtr set_window_pixmap;
 };
 
 #ifdef GLAMOR_GLES2
@@ -934,6 +935,8 @@ void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
 
 int glamor_create_picture(PicturePtr picture);
 
+void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
+
 Bool
 glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
index 3da11e4..b67c728 100644
--- a/glamor/glamor_window.c
+++ b/glamor/glamor_window.c
@@ -69,3 +69,35 @@ glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
 	}
 	return TRUE;
 }
+
+void
+glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
+{
+	ScreenPtr screen = win->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+		glamor_get_screen_private(screen);
+	PixmapPtr old = screen->GetWindowPixmap(win);
+
+	if (pPixmap != old) {
+		glamor_pixmap_private *pixmap_priv;
+		PicturePtr pic = NULL;
+
+		pixmap_priv = glamor_get_pixmap_private(old);
+		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) && pixmap_priv->base.picture->pDrawable == (DrawablePtr)win) {
+			pic = pixmap_priv->base.picture;
+			pixmap_priv->base.is_picture = 0;
+			pixmap_priv->base.picture = NULL;
+		}
+
+		pixmap_priv = glamor_get_pixmap_private(pPixmap);
+		if (pixmap_priv) {
+			pixmap_priv->base.is_picture = !!pic;
+			pixmap_priv->base.picture = pic;
+		}
+	}
+
+	screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
+	(screen->SetWindowPixmap)(win, pPixmap);
+	glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
+	screen->SetWindowPixmap = glamor_set_window_pixmap;
+}
commit 2925db6616944c8d1e911caee0637a00e5586576
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Nov 2 00:08:11 2013 +0800

    Fixed an incorrect printf format.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69573
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index a46a740..4838a27 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -212,7 +212,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 			break;
 		}
 
-		FatalError("destination is framebuffer incomplete: %s [%#x]\n",
+		FatalError("destination is framebuffer incomplete: %s [%x]\n",
 			   str, status);
 	}
 	glamor_put_dispatch(fbo->glamor_priv);
commit 644e05562e401f192c93964be06c33fe92099089
Author: Brian Paul <brianp at vmware.com>
Date:   Sat Oct 19 16:10:54 2013 -0600

    Remove useless return statement
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index f446c83..5df576c 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -90,7 +90,6 @@ glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
 		 unsigned int format, unsigned long planeMask, char *d)
 {
 	_glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE);
-	return;
 }
 
 Bool
commit 8c51eb8239247c98057eb9daf06c905a1dc0588c
Author: Brian Paul <brianp at vmware.com>
Date:   Sat Oct 19 16:10:53 2013 -0600

    Remove redundant dispatch->glEnable(GL_TEXTURE_2D)
    
    The same call was already made a few lines earlier.
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 6567f14..99f7ac6 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -181,7 +181,6 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 			       w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
 	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-	dispatch->glEnable(GL_TEXTURE_2D);
 
 	/* Now that we've set up our bitmap texture and the shader, shove
 	 * the destination rectangle through the cliprects and run the
commit 3bf1eb577e2d2b4d55d38b5a0043b0efb9abb385
Author: Brian Paul <brianp at vmware.com>
Date:   Sat Oct 19 16:10:52 2013 -0600

    Fix _glamor_set_spans() bug (re-used 'n' variable)
    
    n was used as a function parameter.  But inside the for (i=1..n) loop,
    n got reassigned as REGION_NUM_RECTS() and then decremented to zero by
    the while loop.  This caused the for loop to only iterate once instead
    of 'n' times.
    
    This patch renames the n parameter to numPoints.
    
    Found by code inspection.  Untested.
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index a71efe9..3d447b6 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -30,7 +30,7 @@
 
 static Bool
 _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		 DDXPointPtr points, int *widths, int n, int sorted,
+		 DDXPointPtr points, int *widths, int numPoints, int sorted,
 		 Bool fallback)
 {
 	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
@@ -53,9 +53,9 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		goto fail;
 
 	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
-	for (i = 0; i < n; i++) {
+	for (i = 0; i < numPoints; i++) {
 
-		n = REGION_NUM_RECTS(clip);
+		int n = REGION_NUM_RECTS(clip);
 		pbox = REGION_RECTS(clip);
 		while (n--) {
 			int x1 = points[i].x;
@@ -85,7 +85,7 @@ fail:
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-		fbSetSpans(drawable, gc, src, points, widths, n, sorted);
+		fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 	ret = TRUE;
commit 2f62bd46cc002af57f8fe3246b9aea9e0c0bbcc9
Author: Grigori Goronzy <greg at chown.ath.cx>
Date:   Wed Oct 2 00:37:57 2013 +0200

    glamor_render: fix PictFilters
    
    Add Fast/Good/Best and appropriately map to Nearest and
    Bilinear. Additionally, add a fallback path for unsupported filters.
    
    Notably, this fixes window shadow rendering with Compiz, which uses
    PictFilterConvolution for some odd reason.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ca8e509..76a571f 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -568,6 +568,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
 
 	switch (picture->filter) {
 	default:
+	case PictFilterFast:
 	case PictFilterNearest:
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
@@ -576,6 +577,8 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
 					  GL_TEXTURE_MAG_FILTER,
 					  GL_NEAREST);
 		break;
+	case PictFilterGood:
+	case PictFilterBest:
 	case PictFilterBilinear:
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
@@ -1771,6 +1774,12 @@ _glamor_composite(CARD8 op,
 		}
 	}
 
+	if ((source && source->filter >= PictFilterConvolution)
+			|| (mask && mask->filter >= PictFilterConvolution)) {
+		glamor_fallback("glamor_composite(): unsupported filter\n");
+		goto fail;
+	}
+
 	if (!miComputeCompositeRegion(&region,
 				      source, mask, dest,
 				      x_source + (source_pixmap ? source->pDrawable->x : 0),
commit 5695708ecd2a26fcb9c05985c6758e719071995a
Author: Grigori Goronzy <greg at chown.ath.cx>
Date:   Wed Oct 2 00:37:56 2013 +0200

    Use GL_STATIC_DRAW for element index buffer
    
    The buffer never changes anyway.
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d2ac381..ca8e509 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -408,7 +408,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
 				       eb_size,
-				       NULL, GL_DYNAMIC_DRAW);
+				       NULL, GL_STATIC_DRAW);
 		eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
 	}
 	else {
@@ -428,7 +428,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	} else {
 		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
 				       eb_size,
-				       eb, GL_DYNAMIC_DRAW);
+				       eb, GL_STATIC_DRAW);
 		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
 		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
commit 8afa008ec4b393666bb3c506a711b4d50cc4e756
Author: Grigori Goronzy <greg at chown.ath.cx>
Date:   Wed Oct 2 00:37:55 2013 +0200

    Use glDrawRangeElements instead of glDrawElements
    
    This lets us explicitly specify the range of vertices that are used,
    which the OpenGL driver can use for optimization. Particularly,
    it results in lower CPU overhead with Mesa-based drivers.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 2f08d72..fbc8739 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -244,10 +244,19 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 		if (box_cnt == 1)
 			dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
 		else
+#ifndef GLAMOR_GLES2
+			dispatch->glDrawRangeElements(GL_TRIANGLES,
+						      0,
+						      box_cnt * 4,
+						      box_cnt * 6,
+						      GL_UNSIGNED_SHORT,
+						      NULL);
+#else
 			dispatch->glDrawElements(GL_TRIANGLES,
 						 box_cnt * 6,
 						 GL_UNSIGNED_SHORT,
 						 NULL);
+#endif
 		nbox -= box_cnt;
 		box += box_cnt;
 	}
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index f996504..da99e26 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -54,6 +54,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
 	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
+	INIT_FUNC(dispatch, glDrawRangeElements, get_proc_address);
 #endif
 	INIT_FUNC(dispatch, glViewport, get_proc_address);
 	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index b3fc3a6..76dadd4 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -12,6 +12,7 @@ typedef struct glamor_gl_dispatch {
 
 	/* Elements Array*/
 	void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices);
+	void (*glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices);
 
 	/* Raster functions */
 	void (*glReadPixels) (GLint x, GLint y,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 27d5dc5..d2ac381 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -841,8 +841,14 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	if (!glamor_priv->render_nr_verts)
 		return;
 
+#ifndef GLAMOR_GLES2
+	dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
+				      (glamor_priv->render_nr_verts * 3) / 2,
+				      GL_UNSIGNED_SHORT, NULL);
+#else
 	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 				 GL_UNSIGNED_SHORT, NULL);
+#endif
 	glamor_put_dispatch(glamor_priv);
 }
 
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 7c934e3..76b3729 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1543,8 +1543,14 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 			        glamor_priv->vb, GL_DYNAMIC_DRAW);
 		}
 
+#ifndef GLAMOR_GLES2
+		dispatch->glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
+			(glamor_priv->render_nr_verts * 3) / 2,
+		        GL_UNSIGNED_SHORT, NULL);
+#else
 		dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 		        GL_UNSIGNED_SHORT, NULL);
+#endif
 	}
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
commit 229601e080aefad21927c1449cd520733317858b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Sep 27 05:25:54 2013 +0800

    Shoud return null subpixmap if we fail to get a valid map address.
    
    The patch is prepared by Raul Fernandes.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86693
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 9bbc989..84694ec 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1377,6 +1377,10 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 
 	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
 						 data, pbo, access);
+	if(data == NULL) {
+		fbDestroyPixmap(sub_pixmap);
+		return NULL;
+	}
 	if (pbo) {
 		assert(sub_pixmap->devPrivate.ptr == NULL);
 		sub_pixmap->devPrivate.ptr = data;
commit e3d1d4e3caaab8076eba89b58d037d24e203e506
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Sep 23 06:42:24 2013 +0100

    glamor: add initial Xv support
    
    This does YV12 and I420 for now, not sure if we can do packed without
    a GL extension.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index c1759c6..50cfe97 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -53,6 +53,7 @@ libglamor_la_SOURCES = \
 	glamor_gl_dispatch.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
+	glamor_xv.c\
 	glamor_utils.h\
 	glamor.h\
 	glapi.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index d51811e..7637f3b 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -428,6 +428,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #ifdef GLAMOR_GRADIENT_SHADER
 	glamor_init_gradient_shader(screen);
 #endif
+#ifdef GLAMOR_XV
+	glamor_init_xv_shader(screen);
+#endif
 	glamor_pixmap_init(screen);
 
 	glamor_priv->flags = flags;
@@ -447,6 +450,9 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_screen_private *glamor_priv;
 
 	glamor_priv = glamor_get_screen_private(screen);
+#ifdef GLAMOR_XV
+	glamor_fini_xv_shader(screen);
+#endif
 #ifdef RENDER
 	glamor_fini_composite_shaders(screen);
 #endif
diff --git a/glamor/glamor.h b/glamor/glamor.h
index bafd543..c143c4d 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -37,7 +37,7 @@
 #include <picturestr.h>
 #include <fb.h>
 #include <fbpict.h>
-
+#include <xf86xv.h>
 /*
  * glamor_pixmap_type : glamor pixmap's type.
  * @MEMORY: pixmap is in memory.
@@ -348,4 +348,6 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int
 extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
 					   DDXPointPtr points);
 
+extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports);
+
 #endif /* GLAMOR_H */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6e80ebd..ffdd7fd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -304,6 +304,9 @@ typedef struct glamor_screen_private {
 	int state;
 	unsigned int render_idle_cnt;
 	ScreenPtr screen;
+
+	/* xv */
+	GLint xv_prog;
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -993,6 +996,30 @@ glamor_composite_rectangles(CARD8	 op,
 			 int		 num_rects,
 			 xRectangle	*rects);
 
+/* glamor_xv */
+typedef struct {
+    uint32_t	 transform_index;
+    uint32_t	 gamma; /* gamma value x 1000 */
+    int brightness;
+    int saturation;
+    int hue;
+    int contrast;
+
+    DrawablePtr pDraw;
+    PixmapPtr pPixmap;
+    uint32_t src_pitch;
+    uint8_t *src_addr;
+    int src_w, src_h, dst_w, dst_h;
+    int src_x, src_y, drw_x, drw_y;
+    int w, h;
+    RegionRec     clip;
+    PixmapPtr src_pix[3]; /* y, u, v for planar */
+    int src_pix_w, src_pix_h;
+} glamor_port_private;
+
+void glamor_init_xv_shader(ScreenPtr screen);
+void glamor_fini_xv_shader(ScreenPtr screen);
+
 #include"glamor_utils.h"
 
 /* Dynamic pixmap upload to texture if needed. 
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
new file mode 100644
index 0000000..1d77eaa
--- /dev/null
+++ b/glamor/glamor_xv.c
@@ -0,0 +1,646 @@
+/*
+ * Copyright © 2013 Red Hat
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *      Dave Airlie <airlied at redhat.com>
+ *
+ * some code is derived from the xf86-video-ati radeon driver, mainly
+ * the calculations.
+ */
+
+/** @file glamor_xv.c
+ *
+ * Xv acceleration implementation
+ */
+
+#include "glamor_priv.h"
+
+#ifdef GLAMOR_XV
+#include "xf86xv.h"
+#include <X11/extensions/Xv.h>
+#include "fourcc.h"
+/* Reference color space transform data */
+typedef struct tagREF_TRANSFORM
+{
+	float   RefLuma;
+	float   RefRCb;
+	float   RefRCr;
+	float   RefGCb;
+	float   RefGCr;
+	float   RefBCb;
+	float   RefBCr;
+} REF_TRANSFORM;
+
+#define RTFSaturation(a)   (1.0 + ((a)*1.0)/1000.0)
+#define RTFBrightness(a)   (((a)*1.0)/2000.0)
+#define RTFIntensity(a)   (((a)*1.0)/2000.0)
+#define RTFContrast(a)   (1.0 + ((a)*1.0)/1000.0)
+#define RTFHue(a)   (((a)*3.1416)/1000.0)
+
+static const char *xv_vs= "attribute vec4 v_position;\n"
+	"attribute vec4 v_texcoord0;\n"
+	"varying vec2 tcs;\n"
+	"void main()\n" "{\n" "     gl_Position = v_position;\n"
+	"tcs = v_texcoord0.xy;\n"
+	"}\n";
+
+static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
+	"uniform sampler2D y_sampler;\n"
+	"uniform sampler2D u_sampler;\n"
+	"uniform sampler2D v_sampler;\n"
+	"uniform vec4 offsetyco;\n"
+	"uniform vec4 ucogamma;\n"
+	"uniform vec4 vco;\n"
+	"varying vec2 tcs;\n"
+	"float sample;\n"
+	"vec4 temp1;\n"
+	"void main()\n" "{\n"
+	"sample = texture2D(y_sampler, tcs).w;\n"
+	"temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
+	"sample = texture2D(u_sampler, tcs).w;\n"
+	"temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
+	"sample = texture2D(v_sampler, tcs).w;\n"
+	"temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
+	"temp1.w = 1.0;\n"
+	"gl_FragColor = temp1;\n"
+	"}\n";
+
+void
+glamor_init_xv_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	GLint fs_prog, vs_prog;
+	GLint sampler_loc;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  glamor_get_dispatch(glamor_priv);
+	glamor_priv->xv_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, xv_vs);
+	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, xv_ps);
+	dispatch->glAttachShader(glamor_priv->xv_prog, vs_prog);
+	dispatch->glAttachShader(glamor_priv->xv_prog, fs_prog);
+
+	dispatch->glBindAttribLocation(glamor_priv->xv_prog,
+				       GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(glamor_priv->xv_prog,
+				       GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+	glamor_link_glsl_prog(dispatch, glamor_priv->xv_prog);
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+void
+glamor_fini_xv_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  glamor_get_dispatch(glamor_priv);
+
+	dispatch->glDeleteProgram(glamor_priv->xv_prog);
+	glamor_put_dispatch(glamor_priv);
+}
+
+#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace, xvGamma;
+
+#define NUM_ATTRIBUTES 5
+static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES+1] =
+{
+    {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
+    {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
+    {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
+    {0, 0, 0, NULL}
+	    };
+
+#define NUM_FORMATS 3
+
+static XF86VideoFormatRec Formats[NUM_FORMATS] =
+{
+    {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+	    };
+
+#define NUM_IMAGES 2
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+XVIMAGE_YV12,
+	XVIMAGE_I420,
+	};
+
+static void
+glamor_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
+{
+glamor_port_private *port_priv = (glamor_port_private *)data;
+int i;
+if (!cleanup)
+	return;
+
+for (i = 0; i < 3; i++) {
+if (port_priv->src_pix[i]) {
+glamor_destroy_pixmap(port_priv->src_pix[i]);
+port_priv->src_pix[i] = NULL;
+}
+}
+}
+
+static int
+glamor_xv_set_port_attribute(ScrnInfoPtr  pScrn,
+				     Atom	    attribute,
+				     INT32	    value,
+				     pointer	    data)
+{
+glamor_port_private *port_priv = (glamor_port_private *)data;
+if (attribute == xvBrightness)
+	port_priv->brightness = ClipValue(value, -1000, 1000);
+else if (attribute == xvHue)
+	port_priv->hue = ClipValue(value, -1000, 1000);
+else if (attribute == xvContrast)
+	port_priv->contrast = ClipValue(value, -1000, 1000);
+else if (attribute == xvSaturation)
+	port_priv->saturation = ClipValue(value, -1000, 1000);
+else if (attribute == xvGamma)
+	port_priv->gamma = ClipValue (value, 100, 10000);
+else if(attribute == xvColorspace)
+	port_priv->transform_index = ClipValue (value, 0, 1);
+else
+	return BadMatch;
+return Success;
+}
+
+static int
+glamor_xv_get_port_attribute(ScrnInfoPtr  pScrn,
+				     Atom	    attribute,
+				     INT32	    *value,
+				     pointer	    data)
+{
+glamor_port_private *port_priv = (glamor_port_private *)data;
+if (attribute == xvBrightness)
+	*value = port_priv->brightness;
+else if (attribute == xvHue)
+	*value = port_priv->hue;
+else if (attribute == xvContrast)
+	*value = port_priv->contrast;
+else if (attribute == xvSaturation)
+	*value = port_priv->saturation;
+else if (attribute == xvGamma)
+	*value = port_priv->gamma;
+else if(attribute == xvColorspace)
+	*value = port_priv->transform_index;
+else
+	return BadMatch;
+
+return Success;
+}
+
+static void
+glamor_xv_query_best_size(ScrnInfoPtr pScrn,
+				  Bool motion,
+				  short vid_w, short vid_h,
+				  short drw_w, short drw_h,
+				  unsigned int *p_w, unsigned int *p_h,
+				  pointer data)
+{
+*p_w = drw_w;
+*p_h = drw_h;
+}
+
+static int
+glamor_xv_query_image_attributes(ScrnInfoPtr pScrn,
+					 int id,
+					 unsigned short *w, unsigned short *h,
+					 int *pitches, int *offsets)
+{
+int size = 0, tmp;
+
+if (offsets) offsets[0] = 0;
+switch (id) {
+case FOURCC_YV12:
+case FOURCC_I420:
+*h = *h;
+*w = *w;
+size = *w;
+if (pitches) pitches[0] = size;
+size *= *h;
+if (offsets) offsets[1] = size;
+tmp = *w >> 1;
+if (pitches) pitches[1] = pitches[2] = tmp;
+tmp *= (*h >> 1);
+size += tmp;
+if (offsets) offsets[2] = size;
+size += tmp;
+break;
+}
+return size;
+}
+/* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces
+   note the difference to the parameters used in overlay are due
+   to 10bit vs. float calcs */
+static REF_TRANSFORM trans[2] =
+{
+    {1.1643, 0.0, 1.5960, -0.3918, -0.8129, 2.0172, 0.0}, /* BT.601 */
+    {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0}  /* BT.709 */
+	    };
+
+static void
+glamor_display_textured_video(glamor_port_private *port_priv)
+{
+ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
+glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(screen);
+glamor_pixmap_private *pixmap_priv =
+	glamor_get_pixmap_private(port_priv->pPixmap);
+glamor_pixmap_private *src_pixmap_priv[3];
+glamor_gl_dispatch *dispatch;
+float vertices[32], texcoords[8];
+BoxPtr box = REGION_RECTS(&port_priv->clip);
+int nBox = REGION_NUM_RECTS(&port_priv->clip);
+int dst_x_off, dst_y_off;
+GLfloat dst_xscale, dst_yscale;
+GLfloat src_xscale[3], src_yscale[3];
+int i;
+const float Loff = -0.0627;
+const float Coff = -0.502;
+float uvcosf, uvsinf;
+float yco;
+float uco[3], vco[3], off[3];
+float bright, cont, gamma;
+int ref = port_priv->transform_index;
+GLint uloc, sampler_loc;
+
+cont = RTFContrast(port_priv->contrast);
+bright = RTFBrightness(port_priv->brightness);
+gamma = (float)port_priv->gamma / 1000.0;
+uvcosf = RTFSaturation(port_priv->saturation) * cos(RTFHue(port_priv->hue));
+uvsinf = RTFSaturation(port_priv->saturation) * sin(RTFHue(port_priv->hue));
+/* overlay video also does pre-gamma contrast/sat adjust, should we? */
+
+yco = trans[ref].RefLuma * cont;
+uco[0] = -trans[ref].RefRCr * uvsinf;
+uco[1] = trans[ref].RefGCb * uvcosf - trans[ref].RefGCr * uvsinf;
+uco[2] = trans[ref].RefBCb * uvcosf;
+vco[0] = trans[ref].RefRCr * uvcosf;
+vco[1] = trans[ref].RefGCb * uvsinf + trans[ref].RefGCr * uvcosf;
+vco[2] = trans[ref].RefBCb * uvsinf;
+off[0] = Loff * yco + Coff * (uco[0] + vco[0]) + bright;
+off[1] = Loff * yco + Coff * (uco[1] + vco[1]) + bright;
+off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
+gamma = 1.0;
+
+pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
+				   &dst_y_off);
+glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+for (i = 0; i < 3; i++) {
+if (port_priv->src_pix[i]) {
+src_pixmap_priv[i] = glamor_get_pixmap_private(port_priv->src_pix[i]);
+pixmap_priv_get_scale(src_pixmap_priv[i], &src_xscale[i], &src_yscale[i]);
+}
+}
+dispatch = glamor_get_dispatch(glamor_priv);
+dispatch->glUseProgram(glamor_priv->xv_prog);
+
+uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
+dispatch->glUniform4f(uloc, off[0], off[1], off[2], yco);
+uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
+dispatch->glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
+uloc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "vco");
+dispatch->glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
+
+dispatch->glActiveTexture(GL_TEXTURE0);
+dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_S,
+				  GL_CLAMP_TO_EDGE);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_T,
+				  GL_CLAMP_TO_EDGE);
+
+dispatch->glActiveTexture(GL_TEXTURE1);
+dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_S,
+				  GL_CLAMP_TO_EDGE);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_T,
+				  GL_CLAMP_TO_EDGE);
+
+dispatch->glActiveTexture(GL_TEXTURE2);
+dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_LINEAR);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_S,
+				  GL_CLAMP_TO_EDGE);
+dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_T,
+				  GL_CLAMP_TO_EDGE);
+
+sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
+dispatch->glUniform1i(sampler_loc, 0);
+sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
+dispatch->glUniform1i(sampler_loc, 1);
+sampler_loc = dispatch->glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
+dispatch->glUniform1i(sampler_loc, 2);
+
+dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+					GL_FLOAT, GL_FALSE,
+					2 * sizeof(float),
+					texcoords);
+dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+
+dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+for (i = 0; i < nBox; i++) {
+float off_x = box[i].x1 - port_priv->drw_x;
+float off_y = box[i].y1 - port_priv->drw_y;
+float diff_x = (float)port_priv->src_w / (float)port_priv->dst_w;
+float diff_y = (float)port_priv->src_h / (float)port_priv->dst_h;
+float srcx, srcy, srcw, srch;
+int dstx, dsty, dstw, dsth;
+
+
+dstx = box[i].x1 + dst_x_off;
+dsty = box[i].y1 + dst_y_off;
+dstw = box[i].x2 - box[i].x1;
+dsth = box[i].y2 - box[i].y1;
+
+srcx = port_priv->src_x + off_x * diff_x;
+srcy = port_priv->src_y + off_y * diff_y;
+srcw = (port_priv->src_w * dstw) / (float)port_priv->dst_w;
+srch = (port_priv->src_h * dsth) / (float)port_priv->dst_h;
+
+glamor_set_normalize_vcoords(pixmap_priv,
+				     dst_xscale, dst_yscale,
+			     dstx,
+			     dsty,
+			     dstx + dstw,
+			     dsty + dsth,
+			     glamor_priv->yInverted,
+			     vertices);
+
+glamor_set_normalize_tcoords(src_pixmap_priv[0],
+			     src_xscale[0],
+			     src_yscale[0],
+			     srcx,
+			     srcy,
+			     srcx + srcw,
+			     srcy + srch,
+			     glamor_priv->yInverted,
+			     texcoords);
+
+dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+dispatch->glUseProgram(0);
+glamor_put_dispatch(glamor_priv);
+DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
+}
+
+static int glamor_xv_put_image(ScrnInfoPtr pScrn,
+			       short src_x, short src_y,
+			       short drw_x, short drw_y,
+			       short src_w, short src_h,
+			       short drw_w, short drw_h,
+			       int id,
+			       unsigned char *buf,
+			       short width,
+			       short height,
+			       Bool sync,
+			       RegionPtr clipBoxes,
+			       pointer data,
+			       DrawablePtr pDrawable)
+{
+	ScreenPtr screen = xf86ScrnToScreen(pScrn);
+	glamor_port_private *port_priv = (glamor_port_private *)data;
+	INT32 x1, x2, y1, y2;
+	int srcPitch, srcPitch2;
+	BoxRec dstBox;
+	int top, nlines;
+	int s2offset, s3offset, tmp;
+
+	s2offset = s3offset = srcPitch2 = 0;
+
+	/* Clip */
+	x1 = src_x;
+	x2 = src_x + src_w;
+	y1 = src_y;
+	y2 = src_y + src_h;
+
+	dstBox.x1 = drw_x;
+	dstBox.x2 = drw_x + drw_w;
+	dstBox.y1 = drw_y;
+	dstBox.y2 = drw_y + drw_h;
+	if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
+		return Success;
+
+	if ((x1 >= x2) || (y1 >= y2))
+		return Success;
+
+	srcPitch = width;
+	srcPitch2 = width >> 1;
+
+	if (!port_priv->src_pix[0] || (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) {
+		int i;
+		for (i = 0; i < 2; i++)
+			if (port_priv->src_pix[i])
+				glamor_destroy_pixmap(port_priv->src_pix[i]);
+
+		port_priv->src_pix[0] = glamor_create_pixmap(screen, width, height, 8, 0);
+		port_priv->src_pix[1] = glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
+		port_priv->src_pix[2] = glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
+		port_priv->src_pix_w = width;
+		port_priv->src_pix_h = height;
+
+		if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || !port_priv->src_pix[2])
+			return BadAlloc;
+	}
+
+	top = (y1 >> 16) & ~1;
+	nlines = ((y2 + 0xffff) >> 16) - top;
+
+	switch (id) {
+	case FOURCC_YV12:
+	case FOURCC_I420:
+		s2offset = srcPitch * height;
+		s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1));
+		s2offset += ((top >> 1) * srcPitch2);
+		s3offset += ((top >> 1) * srcPitch2);
+		if (id == FOURCC_YV12) {
+			tmp = s2offset;
+			s2offset = s3offset;
+			s3offset = tmp;
+		}
+		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
+						    0, 0, srcPitch, nlines,
+						    port_priv->src_pix[0]->devKind,
+						    buf + (top * srcPitch), 0);
+
+		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
+						    0, 0, srcPitch2, (nlines + 1) >> 1,
+						    port_priv->src_pix[1]->devKind,
+						    buf + s2offset, 0);
+
+		glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
+						    0, 0, srcPitch2, (nlines + 1) >> 1,
+						    port_priv->src_pix[2]->devKind,
+						    buf + s3offset, 0);
+		break;
+	default:
+		return BadMatch;
+	}
+
+	if (pDrawable->type == DRAWABLE_WINDOW)
+		port_priv->pPixmap = (*screen->GetWindowPixmap)((WindowPtr)pDrawable);
+	else
+		port_priv->pPixmap = (PixmapPtr)pDrawable;
+
+	if (!RegionEqual(&port_priv->clip, clipBoxes)) {
+		RegionCopy(&port_priv->clip, clipBoxes);
+	}
+
+	port_priv->src_x = src_x;
+	port_priv->src_y = src_y;
+	port_priv->src_w = src_w;
+	port_priv->src_h = src_h;
+	port_priv->dst_w = drw_w;
+	port_priv->dst_h = drw_h;
+	port_priv->drw_x = drw_x;
+	port_priv->drw_y = drw_y;
+	port_priv->w = width;
+	port_priv->h = height;
+	port_priv->pDraw = pDrawable;
+	glamor_display_textured_video(port_priv);
+	return Success;
+}
+
+static XF86VideoEncodingRec DummyEncodingGLAMOR[1] =
+{
+	{
+		0,
+		"XV_IMAGE",
+		8192, 8192,
+		{1, 1}
+	}
+};
+
+XF86VideoAdaptorPtr
+glamor_xv_init(ScreenPtr screen, int num_texture_ports)
+{
+	glamor_port_private *port_priv;
+	XF86VideoAdaptorPtr adapt;
+	int i;
+
+	adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
+		       (sizeof(glamor_port_private) + sizeof(DevUnion)));
+	if (adapt == NULL)
+		return NULL;
+
+	xvBrightness      = MAKE_ATOM("XV_BRIGHTNESS");
+	xvContrast        = MAKE_ATOM("XV_CONTRAST");
+	xvSaturation      = MAKE_ATOM("XV_SATURATION");
+	xvHue             = MAKE_ATOM("XV_HUE");
+	xvGamma           = MAKE_ATOM("XV_GAMMA");
+	xvColorspace      = MAKE_ATOM("XV_COLORSPACE");
+
+	adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+	adapt->flags = 0;
+	adapt->name = "GLAMOR Textured Video";
+	adapt->nEncodings = 1;
+	adapt->pEncodings = DummyEncodingGLAMOR;
+
+	adapt->nFormats = NUM_FORMATS;
+	adapt->pFormats = Formats;
+	adapt->nPorts = num_texture_ports;
+	adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+	adapt->pAttributes = Attributes_glamor;
+	adapt->nAttributes = NUM_ATTRIBUTES;
+
+	port_priv = (glamor_port_private *)(&adapt->pPortPrivates[num_texture_ports]);
+	adapt->pImages = Images;
+	adapt->nImages = NUM_IMAGES;
+	adapt->PutVideo = NULL;
+	adapt->PutStill = NULL;
+	adapt->GetVideo = NULL;
+	adapt->GetStill = NULL;
+	adapt->StopVideo = glamor_xv_stop_video;
+	adapt->SetPortAttribute = glamor_xv_set_port_attribute;
+	adapt->GetPortAttribute = glamor_xv_get_port_attribute;
+	adapt->QueryBestSize = glamor_xv_query_best_size;
+	adapt->PutImage = glamor_xv_put_image;
+	adapt->ReputImage = NULL;
+	adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
+
+	for (i = 0; i < num_texture_ports; i++) {
+		glamor_port_private *pPriv = &port_priv[i];
+
+		pPriv->brightness = 0;
+		pPriv->contrast = 0;
+		pPriv->saturation = 0;
+		pPriv->hue = 0;
+		pPriv->gamma = 1000;
+		pPriv->transform_index = 0;
+
+		REGION_NULL(pScreen, &pPriv->clip);
+
+		adapt->pPortPrivates[i].ptr = (pointer)(pPriv);
+	}
+	return adapt;
+}
+#else
+XF86VideoAdaptorPtr
+glamor_xv_init(ScreenPtr screen, int num_texture_ports)
+{
+	return NULL;
+}
+#endif
commit 39e95cd0f50cf471d8220d5428788d5be6a59d3f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Fri Sep 20 10:41:10 2013 +0200

    Reset traps_count and ptrap when necessary for the next trapezoid cliprect
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64912
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: He Junyan <junyan.he at inbox.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 57a178c..7c934e3 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -934,6 +934,9 @@ NTRAPS_LOOP_AGAIN:
 				traps_not_completed -= traps_count;
 				glamor_flush_composite_triangles(screen);
 				goto NTRAPS_LOOP_AGAIN;
+			} else {
+				ptrap = traps;
+				traps_count = ntrap;
 			}
 
 			pbox++;
commit 61fca4342a65be2dbc7f890f2e67da56a50db978
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Sep 17 13:25:02 2013 +0200

    Fix RegionContainsRect test for PutImage
    
    The return value of RegionContainsRect() is not a boolean but an enum
    indicating that the region contains the rectangle completely, partially
    or not at all. We can only take the PutImage fastpath when the region
    contatins the rectangle completely.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65964
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 34e86a1..6567f14 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -287,7 +287,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	box.x2 = x + w + drawable->x;
 	box.y2 = y + h + drawable->y;
 
-	if ((clip != NULL && !RegionContainsRect(clip, &box))
+	if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
 	     || gc->alu != GXcopy) {
 		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
 		if (temp_pixmap == NULL)
commit 2ea618f2cf906fec9807b321f9e8ef3a4706c708
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Aug 26 14:57:47 2013 +0800

    Use GBM_LIBS and GBM_CFLAGS
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 4beb559..c1759c6 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -64,9 +64,15 @@ LIBGLAMOREGL = libglamoregl.la
 module_LTLIBRARIES = $(LIBGLAMOREGL)
 libglamoregl_la_DEPENDENCIES = libglamor.la
 libglamoregl_la_LDFLAGS = -avoid-version -module
-libglamoregl_la_LIBADD = $(EGL_LIBS) $(GLX_SYS_LIBS) libglamor.la
+libglamoregl_la_LIBADD = $(EGL_LIBS) $(GLX_SYS_LIBS) $(GBM_LIBS) libglamor.la
 libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
-libglamoregl_la_CFLAGS = $(AM_CFLAGS) $(GLX_DEFINES) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
+libglamoregl_la_CFLAGS = \
+	$(AM_CFLAGS) \
+	$(GLX_DEFINES) \
+	-I$(top_srcdir)/src \
+	$(LIBDRM_CFLAGS) \
+	$(EGL_CFLAGS) \
+	$(GBM_CFLAGS)
 endif
 
 
commit 7e818f7d39cfef2701fe9cf95c7854ee8c9f3be6
Author: Armin K <krejzi at email.com>
Date:   Wed Mar 13 18:49:32 2013 +0100

    First attempt to make libglamor.so shared versioned library
    
    As recommended by Michel in this thread reply:
    http://lists.freedesktop.org/archives/glamor/2013-March/000305.html
    
    v2: Correct shared library location in glamor.pc.in
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=62259
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 0879287..4beb559 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -1,4 +1,4 @@
-inst_LTLIBRARIES = libglamor.la
+lib_LTLIBRARIES = libglamor.la
 
 # Override these since glamor doesn't need them and the needed files aren't
 # built (in hw/xfree86/os-support/solaris) until after glamor is built
@@ -10,14 +10,12 @@ else
 libglamor_la_LIBADD = $(GL_LIBS)
 endif
 
-instdir = $(moduledir)
-
 AM_CPPFLAGS = \
 	$(XORG_INCS)
 
 AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 
-libglamor_la_LDFLAGS = -avoid-version
+libglamor_la_LDFLAGS = -version-info 0:0:0
 
 libglamor_la_SOURCES = \
 	compat-api.h \
@@ -65,7 +63,8 @@ if EGL
 LIBGLAMOREGL = libglamoregl.la
 module_LTLIBRARIES = $(LIBGLAMOREGL)
 libglamoregl_la_DEPENDENCIES = libglamor.la
-libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor $(GLX_SYS_LIBS)
+libglamoregl_la_LDFLAGS = -avoid-version -module
+libglamoregl_la_LIBADD = $(EGL_LIBS) $(GLX_SYS_LIBS) libglamor.la
 libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
 libglamoregl_la_CFLAGS = $(AM_CFLAGS) $(GLX_DEFINES) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
 endif
commit b0318b6de7a2f8c5d9e75b55211dcc0b12f811fc
Author: Armin K <krejzi at email.com>
Date:   Wed Mar 13 18:28:58 2013 +0100

    Properly dist necesary headers
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2140b81..0879287 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -31,6 +31,7 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_glext.h \
 	glamor_glyphs.c \
 	glamor_polyfillrect.c \
 	glamor_polylines.c \
commit fc179bb863778c03288bebaa258358ccbdb6aa0c
Author: Armin K <krejzi at email.com>
Date:   Wed Mar 13 18:28:57 2013 +0100

    Silence Automake 1.13 warnings
    
    warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 55721f6..2140b81 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -12,7 +12,7 @@ endif
 
 instdir = $(moduledir)
 
-INCLUDES = \
+AM_CPPFLAGS = \
 	$(XORG_INCS)
 
 AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
commit 97416e3f144606728a963aa2a337b1283e156ad2
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Mar 13 17:15:33 2013 +0100

    glamoregl: Use xf86ScreenToScrn()
    
    Fixes crashes when glamor is used for a GPU screen with xserver 1.13 or
    newer.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57200#c17
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a248aa2..cd0bdc0 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -116,7 +116,7 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 _X_EXPORT void
 glamor_egl_make_current(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 
@@ -139,7 +139,7 @@ glamor_egl_make_current(ScreenPtr screen)
 _X_EXPORT void
 glamor_egl_restore_context(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 
@@ -221,7 +221,7 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
 Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl;
 	PixmapPtr	screen_pixmap;
 
@@ -245,7 +245,7 @@ glamor_egl_create_textured_screen_ext(ScreenPtr screen,
 				      int stride,
 				      PixmapPtr *back_pixmap)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl;
 
 	glamor_egl = glamor_egl_get_screen_private(scrn);
@@ -272,7 +272,7 @@ Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl;
 	EGLImageKHR image;
 	GLuint texture;
@@ -318,7 +318,7 @@ done:
 static void
 _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
 	EGLImageKHR image;
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
@@ -338,7 +338,7 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
-	ScrnInfoPtr scrn = xf86Screens[front->drawable.pScreen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 	EGLImageKHR old_front_image;
@@ -371,7 +371,7 @@ glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 	PixmapPtr screen_pixmap;
 	EGLImageKHR back_image;
 
-	scrn = xf86Screens[screen->myNum];
+	scrn = xf86ScreenToScrn(screen);
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 	screen_pixmap = screen->GetScreenPixmap(screen);
 
@@ -417,7 +417,7 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
 void
 glamor_egl_screen_init(ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 
@@ -588,7 +588,7 @@ glamor_gl_dispatch_init(ScreenPtr screen,
 			struct glamor_gl_dispatch *dispatch,
 			int gl_version)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 	if (!glamor_gl_dispatch_init_impl
commit 4c5bfd529f6f182a3f0ac1b9bb5c3170a297f460
Author: Dave Airlie <airlied at redhat.com>
Date:   Sat Dec 29 06:42:30 2012 +0000

    glamor_utils: fix unlikely define use
    
    using a define across a split line expression is failure, compiling
    with warnings shows this up.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 36beb49..d307838 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -80,8 +80,7 @@
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
    do {								\
-	if (unlikely(_priv_ && (_priv_)->type				\
-		== GLAMOR_TEXTURE_LARGE)) {			\
+	if (unlikely(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) {  \
 		*(_xoff_) = - (_priv_)->large.box.x1;	\
 		*(_yoff_) = - (_priv_)->large.box.y1;	\
 	} else {						\
commit 6b954880c25af353dd4679cfdad6664b107d4df6
Author: Dave Airlie <airlied at redhat.com>
Date:   Sat Dec 29 06:42:10 2012 +0000

    glamor: add compiler.h
    
    This is also required for distchecking.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index e1ee86d..55721f6 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -21,6 +21,7 @@ libglamor_la_LDFLAGS = -avoid-version
 
 libglamor_la_SOURCES = \
 	compat-api.h \
+	compiler.h \
 	glamor.c \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
commit efbdc9e90f36494b07508aeaba40c9eb01eab398
Author: Dave Airlie <airlied at redhat.com>
Date:   Sat Dec 29 06:28:17 2012 +0000

    glamor: fix make distcheck part 1
    
    This just adds the headers, then it falls over on the sdk_HEADERS
    as it overrides proper install paths by the looks of it.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 766aac7..e1ee86d 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -20,10 +20,13 @@ AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 libglamor_la_LDFLAGS = -avoid-version
 
 libglamor_la_SOURCES = \
+	compat-api.h \
 	glamor.c \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
 	glamor_core.c \
+	glamor_debug.h \
+	glamor_gl_dispatch.h \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
@@ -42,6 +45,7 @@ libglamor_la_SOURCES = \
 	glamor_copyplane.c\
 	glamor_glyphblt.c\
 	glamor_polyops.c\
+	glamor_priv.h\
 	glamor_pixmap.c\
 	glamor_largepixmap.c\
 	glamor_picture.c\
@@ -49,7 +53,9 @@ libglamor_la_SOURCES = \
 	glamor_gl_dispatch.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
-	glamor.h
+	glamor_utils.h\
+	glamor.h\
+	glapi.h
 
 sdk_HEADERS = glamor.h
 
commit 80f5e21daeed79654d6e1976f2766eb528f01d47
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Nov 13 10:08:02 2012 +0800

    glamor_compositerects: Need to initialize region before fallback.
    
    As we need to call DamageRegionAppend even for fallback path,
    we must initialize the region before do that. Pointed by
    Igor Vagulin.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=56940
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 5fe1bbf..f1564a2 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -131,16 +131,6 @@ glamor_composite_rectangles(CARD8	 op,
 		return;
 	}
 
-	pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
-	priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
-		goto fallback;
-	if (dst->alphaMap) {
-		DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__);
-		goto fallback;
-	}
-
 	if ((color->red|color->green|color->blue|color->alpha) <= 0x00ff) {
 		switch (op) {
 		case PictOpOver:
@@ -204,6 +194,16 @@ glamor_composite_rectangles(CARD8	 op,
 		return;
 	}
 
+	pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+	priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
+		goto fallback;
+	if (dst->alphaMap) {
+		DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__);
+		goto fallback;
+	}
+
 	need_free_region = TRUE;
 
 	DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n",
commit 14e02f5132d7b4f50c8d9f8e5c6a0f285a3f3c14
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Oct 31 16:56:00 2012 +0100

    Don't use glBlitFramebufferEXT for overlapping copies.
    
    According to the GL_EXT_framebuffer_blit spec, the result of doing so is
    undefined. But we need well-defined results. :)
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 7d06833..4e6f953 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -318,7 +318,8 @@ __glamor_copy_n_to_n(DrawablePtr src,
 		dx, dy,
 		src_pixmap, dst_pixmap);
 #ifndef GLAMOR_GLES2
-	if ((overlaped || glamor_priv->state != RENDER_STATE
+	if (!overlaped &&
+	    (glamor_priv->state != RENDER_STATE
 	     || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
 	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
 					   dy)) {
commit e846f48f489e33e270db682b1b6c8e6f03fdf313
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 8 20:43:38 2012 +0800

    Increase vbo size to 64K verts.
    
    This commit will benefit vertex stressing cases such as
    aa10text/rgb10text, and can get about 15% performance gain.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Acked-by: Junyan <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 1d81aea..2f08d72 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -220,7 +220,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 		}
 	}
 
-#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
 	if (unlikely(nbox > 1))
 		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 03ef6cc..6e80ebd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -191,7 +191,7 @@ enum glamor_gl_flavor {
 
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
-#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
 
 typedef struct {
 	PicturePtr picture;	/* Where the glyphs of the cache are stored */
commit b8f0a2188295f6cc2c997b6639b6928323eae617
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 8 20:11:43 2012 +0800

    Silence compilation warnings.
    
    After increase to gcc4.7, it reports more warnings, now
    fix them.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Tested-by: Junyan He<junyan.he at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 2994179..7d06833 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -392,14 +392,12 @@ _glamor_copy_n_to_n(DrawablePtr src,
 		    Bool upsidedown, Pixel bitplane,
 		    void *closure, Bool fallback)
 {
-	glamor_access_t dst_access;
 	PixmapPtr dst_pixmap, src_pixmap;
 	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
 	BoxPtr extent;
 	RegionRec region;
-	ScreenPtr screen;
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
 	Bool ok = FALSE;
 	int force_clip = 0;
@@ -410,7 +408,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 	src_pixmap = glamor_get_drawable_pixmap(src);
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	screen = dst_pixmap->drawable.pScreen;
 
 	glamor_priv = glamor_get_screen_private(dst->pScreen);
 
@@ -612,11 +609,6 @@ fall_back:
 			glamor_get_drawable_location(src),
 			glamor_get_drawable_location(dst));
 
-	if (gc && gc->alu != GXcopy)
-		dst_access = GLAMOR_ACCESS_RW;
-	else
-		dst_access = GLAMOR_ACCESS_WO;
-
 	if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
 		if (dst == src
 		    || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
index 6487ff7..3f2652a 100644
--- a/glamor/glamor_copyplane.c
+++ b/glamor/glamor_copyplane.c
@@ -33,15 +33,12 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		   int srcx, int srcy, int w, int h, int dstx, int dsty,
 		   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
 {
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pSrc)
 	    && glamor_ddx_fallback_check_pixmap(pDst))
 		goto fail;
 
-	glamor_priv = glamor_get_screen_private(pDst->pScreen);
 	glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
 	glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
 	*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 8ba3347..22065bc 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -566,15 +566,13 @@ glamor_bitmap_to_region(PixmapPtr pixmap)
 
 /* Borrow from cairo. */
 Bool
-glamor_gl_has_extension(char *extension)
+glamor_gl_has_extension(const char *extension)
 {
-	const char *gl_extensions;
-	char *pext;
+	const char *pext;
 	int ext_len;
 	ext_len = strlen(extension);
 
-	gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
-	pext = (char *) gl_extensions;
+	pext = (const char*)glGetString(GL_EXTENSIONS);
 
 	if (pext == NULL || extension == NULL)
 		return FALSE;
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a9a92a7..a248aa2 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -335,8 +335,6 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 	}
 }
 
-extern void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
-
 _X_EXPORT void
 glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 {
@@ -399,16 +397,13 @@ static Bool
 glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
 			 const char *extension)
 {
-	const char *egl_extensions;
-	char *pext;
+	const char *pext;
 	int ext_len;
-	ext_len = strlen(extension);
 
-	egl_extensions =
+	ext_len = strlen(extension);
+	pext =
 	    (const char *) eglQueryString(glamor_egl->display,
 					  EGL_EXTENSIONS);
-	pext = (char *) egl_extensions;
-
 	if (pext == NULL || extension == NULL)
 		return FALSE;
 	while ((pext = strstr(pext, extension)) != NULL) {
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 046f4de..9a0dec9 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -31,10 +31,10 @@
 #include "config.h"
 #endif
 
+#include <xorg-server.h>
 #define GLAMOR_FOR_XORG
-#include "glamor.h"
 #include <xf86Module.h>
-#include <xorg-server.h>
+#include "glamor.h"
 
 static XF86ModuleVersionInfo VersRec = {
 	GLAMOR_EGL_MODULE_NAME,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 4af831d..a46a740 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -258,7 +258,6 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry, *tmp;
 	int i,j,k;
-	int empty_cache = TRUE;
 
 	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
 		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
@@ -266,7 +265,6 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 				cache = &glamor_priv->fbo_cache[i][j][k];
 				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
 					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
-						empty_cache = FALSE;
 						break;
 					}
 
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 6598249..35e881f 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -36,11 +36,8 @@ _glamor_fill_spans(DrawablePtr drawable,
 	BoxPtr pbox;
 	int x1, x2, y;
 	RegionPtr pClip = fbGetCompositeClip(gc);
-	glamor_screen_private *glamor_priv;
 	Bool ret = FALSE;
 
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-
 	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 		goto fail;
 
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index f549904..fc361df 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -222,7 +222,7 @@ get_mask_cache(struct glamor_glyph_mask_cache *maskcache, int blocks)
 {
 	int free_cleared_bit, idx = -1;
 	int retry_cnt = 0;
-	unsigned int bits_mask;
+	unsigned int bits_mask = 0;
 
 	if (maskcache->free_bitmap == 0)
 		return NULL;
@@ -514,20 +514,20 @@ glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
 			     PicturePtr glyph_picture)
 {
 	PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
-	struct glamor_pixmap_private *pixmap_priv;
 	int j;
-	unsigned long long left_x1_map, left_x2_map, right_x1_map, right_x2_map;
+	unsigned long long left_x1_map = 0, left_x2_map = 0;
+	unsigned long long right_x1_map = 0, right_x2_map = 0;
 	int bitsPerPixel;
 	int stride;
 	void *bits;
 	int width;
-	unsigned int left_x1_data, left_x2_data, right_x1_data, right_x2_data;
+	unsigned int left_x1_data = 0, left_x2_data = 0;
+	unsigned int right_x1_data = 0, right_x2_data = 0;
 
 	bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
 	stride = glyph_pixmap->devKind;
 	bits = glyph_pixmap->devPrivate.ptr;
 	width = glyph->info.width;
-	pixmap_priv = glamor_get_pixmap_private(glyph_pixmap);
 
 	if (glyph_pixmap->drawable.width < 2
 	    || !(glyph_pixmap->drawable.depth == 8
@@ -662,12 +662,6 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
 			fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
 		} else
 			fixed_list->list[0].len = cur_pos - *head_pos - n_off;
-		while(list_cnt--) {
-			DEBUGF("new fixed list type %d entry len %d x %d y %d"
-				"head_pos %d pos %d list %d has %d glyphs.\n",
-				fixed_list->type, fixed_list->nlist,
-				cur_x, cur_y, *head_pos, cur_pos, i, fixed_list->list[i++].len);
-		}
 		(*fixed_cnt)++;
 	}
 
@@ -712,9 +706,9 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 	Bool first = TRUE, first_list = TRUE;
 	Bool need_free_list_region = FALSE;
 	Bool need_free_fixed_list = FALSE;
-	struct glamor_glyph *priv;
+	struct glamor_glyph *priv = NULL;
 	Bool in_non_intersected_list = -1;
-	GlyphListPtr head_list, saved_list;
+	GlyphListPtr head_list;
 	int head_x, head_y, head_pos;
 	int fixed_cnt = 0;
 	GlyphPtr *head_glyphs;
@@ -732,9 +726,10 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 
 	extents = pixman_region_extents(&current_region);
 
-	saved_list = list;
 	x = 0;
 	y = 0;
+	x1 = x2 = y1 = y2 = 0;
+	n = 0;
 	extents->x1 = 0;
 	extents->y1 = 0;
 	extents->x2 = 0;
@@ -743,10 +738,10 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 	head_list = list;
 	DEBUGF("has %d lists.\n", nlist);
 	while (nlist--) {
-		BoxRec left_box, right_box;
+		BoxRec left_box, right_box = {0};
 		Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
 		Bool left_to_right;
-		struct glamor_glyph *left_priv, *right_priv;
+		struct glamor_glyph *left_priv = NULL, *right_priv = NULL;
 
 		x += list->xOff;
 		y += list->yOff;
@@ -1146,7 +1141,7 @@ glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
 	*out_y = priv->y;
 	return cache->picture;
 }
-typedef void (*glyphs_flush)(void * arg);
+typedef void (*glyphs_flush_func)(void * arg);
 struct glyphs_flush_dst_arg {
 	CARD8 op;
 	PicturePtr src;
@@ -1223,7 +1218,7 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
 		    int x_glyph, int y_glyph,
 		    int dx, int dy, int w, int h,
 		    int glyphs_dst_mode,
-		    glyphs_flush glyphs_flush, void *flush_arg)
+		    glyphs_flush_func glyphs_flush, void *flush_arg)
 {
 	ScreenPtr screen = glamor_priv->screen;
 	glamor_composite_rect_t *rect;
@@ -1327,7 +1322,7 @@ glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
 			 int glyph_dx, int glyph_dy,
 			 int width, int height,
 			 int glyphs_mode,
-			 glyphs_flush flush_func,
+			 glyphs_flush_func flush_func,
 			 void *arg
 			 )
 {
@@ -1490,24 +1485,24 @@ retry:
 			glyph = *glyphs++;
 			if (glyph->info.width > 0
 			    && glyph->info.height > 0) {
-				glyphs_flush flush_func;
-				void *arg;
+				glyphs_flush_func flush_func;
+				void *temp_arg;
 				if (need_free_mask) {
 					if (pmask_buffer->count)
-						flush_func = (glyphs_flush)glamor_glyphs_flush_mask;
+						flush_func = (glyphs_flush_func)glamor_glyphs_flush_mask;
 					else
 						flush_func = NULL;
-					arg = pmask_arg;
+					temp_arg = pmask_arg;
 				} else {
 					/* If we are using global mask cache, then we need to
 					 * flush dst instead of mask. As some dst depends on the
 					 * previous mask result. Just flush mask can't get all previous's
 					 * overlapped glyphs.*/
 					if (dst_buffer.count || mask_buffer.count)
-						flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+						flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
 					else
 						flush_func = NULL;
-					arg = &dst_arg;
+					temp_arg = &dst_arg;
 				}
 				glamor_buffer_glyph(glamor_priv, pmask_buffer,
 						    mask_format->format,
@@ -1516,7 +1511,7 @@ retry:
 						    glyph->info.width, glyph->info.height,
 						    glyphs_dst_mode,
 						    flush_func,
-						    (void*)arg);
+						    (void*)temp_arg);
 			}
 			x += glyph->info.xOff;
 			y += glyph->info.yOff;
@@ -1538,7 +1533,7 @@ retry:
 		glamor_destroy_pixmap(mask_pixmap);
 	} else {
 		struct glamor_glyph priv;
-		glyphs_flush flush_func;
+		glyphs_flush_func flush_func;
 		BoxPtr rects;
 		int nrect;
 
@@ -1570,7 +1565,7 @@ retry:
 		y += dst->pDrawable->y;
 
 		if (dst_buffer.count || mask_buffer.count)
-			flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+			flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
 		else
 			flush_func = NULL;
 
@@ -1633,10 +1628,10 @@ glamor_glyphs_to_dst(CARD8 op,
 
 			if (glyph->info.width > 0
 			    && glyph->info.height > 0) {
-				glyphs_flush flush_func;
+				glyphs_flush_func flush_func;
 
 				if (dst_buffer.count || mask_buffer.count)
-					flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+					flush_func = (glyphs_flush_func)glamor_glyphs_flush_dst;
 				else
 					flush_func = NULL;
 				glamor_buffer_glyph_clip(glamor_priv,
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 444ba6c..4abc82d 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -51,36 +51,36 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	char *gradient_fs = NULL;
 	GLint fs_getcolor_prog;
 
-	const char *gradient_fs_getcolor =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform int n_stop;\n"
-	    "uniform float stops[%d];\n"
-	    "uniform vec4 stop_colors[%d];\n"
-	    "vec4 get_color(float stop_len)\n"
-	    "{\n"
-	    "    int i = 0;\n"
-	    "    float new_alpha; \n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    for(i = 0; i < n_stop - 1; i++) {\n"
-	    "        if(stop_len < stops[i])\n"
-	    "            break; \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(stops[i] - stops[i-1] > 2.0)\n"
-	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
-	    "    else if(stops[i] - stops[i-1] < 0.000001)\n"
-	    "        percentage = 0.0;\n"
-	    "    else \n"
-	    "        percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
-	    "    new_alpha = percentage * stop_colors[i].a + \n"
-	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
-	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
-	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
-	    "    \n"
-	    "    return gradient_color;\n"
-	    "}\n";
+	#define gradient_fs_getcolor\
+	    GLAMOR_DEFAULT_PRECISION\
+	    "uniform int n_stop;\n"\
+	    "uniform float stops[%d];\n"\
+	    "uniform vec4 stop_colors[%d];\n"\
+	    "vec4 get_color(float stop_len)\n"\
+	    "{\n"\
+	    "    int i = 0;\n"\
+	    "    float new_alpha; \n"\
+	    "    vec4 gradient_color;\n"\
+	    "    float percentage; \n"\
+	    "    for(i = 0; i < n_stop - 1; i++) {\n"\
+	    "        if(stop_len < stops[i])\n"\
+	    "            break; \n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    if(stops[i] - stops[i-1] > 2.0)\n"\
+	    "        percentage = 0.0;\n" /*For comply with pixman, walker->stepper overflow.*/\
+	    "    else if(stops[i] - stops[i-1] < 0.000001)\n"\
+	    "        percentage = 0.0;\n"\
+	    "    else \n"\
+	    "        percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"\
+	    "    new_alpha = percentage * stop_colors[i].a + \n"\
+	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"\
+	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"\
+	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"\
+	    "                          new_alpha);\n"\
+	    "    \n"\
+	    "    return gradient_color;\n"\
+	    "}\n"
 
 	/* Because the array access for shader is very slow, the performance is very low
 	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
@@ -238,111 +238,111 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy
 	 *     radius associated to it is negative (or it falls outside the valid t range)
 	 */
 
-	const char *gradient_fs_template =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform mat3 transform_mat;\n"
-	    "uniform int repeat_type;\n"
-	    "uniform float A_value;\n"
-	    "uniform vec2 c1;\n"
-	    "uniform float r1;\n"
-	    "uniform vec2 c2;\n"
-	    "uniform float r2;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len);\n"
-	    "\n"
-	    "int t_invalid;\n"
-	    "\n"
-	    "float get_stop_len()\n"
-	    "{\n"
-	    "    float t = 0.0;\n"
-	    "    float sqrt_value;\n"
-	    "    int revserse = 0;\n"
-	    "    t_invalid = 0;\n"
-	    "    \n"
-	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
-	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
-	    "    source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"
-	    "    float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"
-	    "                     + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"
-	    "                     + r1 * (r2 - r1);\n"
-	    "    float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"
-	    "                     + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"
-	    "                     - r1*r1;\n"
-	    "    if(abs(A_value) < 0.00001) {\n"
-	    "        if(B_value == 0.0) {\n"
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "        t = 0.5 * C_value / B_value;"
-	    "    } else {\n"
-	    "        sqrt_value = B_value * B_value - A_value * C_value;\n"
-	    "        if(sqrt_value < 0.0) {\n"
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "        sqrt_value = sqrt(sqrt_value);\n"
-	    "        t = (B_value + sqrt_value) / A_value;\n"
-	    "    }\n"
-	    "    if(repeat_type == %d) {\n" // RepeatNone case.
-	    "        if((t <= 0.0) || (t > 1.0))\n"
-	    //           try another if first one invalid
-	    "            t = (B_value - sqrt_value) / A_value;\n"
-	    "        \n"
-	    "        if((t <= 0.0) || (t > 1.0)) {\n" //still invalid, return.
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "    } else {\n"
-	    "        if(t * (r2 - r1) <= -1.0 * r1)\n"
-	    //           try another if first one invalid
-	    "            t = (B_value - sqrt_value) / A_value;\n"
-	    "        \n"
-	    "        if(t * (r2 -r1) <= -1.0 * r1) {\n" //still invalid, return.
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d){\n" // repeat normal
-	    "        while(t > 1.0) \n"
-	    "            t = t - 1.0; \n"
-	    "        while(t < 0.0) \n"
-	    "            t = t + 1.0; \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d) {\n" // repeat reflect
-	    "        while(t > 1.0) {\n"
-	    "            t = t - 1.0; \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        while(t < 0.0) {\n"
-	    "            t = t + 1.0; \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        if(revserse == 1) {\n"
-	    "            t = 1.0 - t; \n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    return t;\n"
+	#define gradient_radial_fs_template\
+	    GLAMOR_DEFAULT_PRECISION\
+	    "uniform mat3 transform_mat;\n"\
+	    "uniform int repeat_type;\n"\
+	    "uniform float A_value;\n"\
+	    "uniform vec2 c1;\n"\
+	    "uniform float r1;\n"\
+	    "uniform vec2 c2;\n"\
+	    "uniform float r2;\n"\
+	    "varying vec2 source_texture;\n"\
+	    "\n"\
+	    "vec4 get_color(float stop_len);\n"\
+	    "\n"\
+	    "int t_invalid;\n"\
+	    "\n"\
+	    "float get_stop_len()\n"\
+	    "{\n"\
+	    "    float t = 0.0;\n"\
+	    "    float sqrt_value;\n"\
+	    "    int revserse = 0;\n"\
+	    "    t_invalid = 0;\n"\
+	    "    \n"\
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"\
+	    "    source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"\
+	    "    float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"\
+	    "                     + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"\
+	    "                     + r1 * (r2 - r1);\n"\
+	    "    float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"\
+	    "                     + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"\
+	    "                     - r1*r1;\n"\
+	    "    if(abs(A_value) < 0.00001) {\n"\
+	    "        if(B_value == 0.0) {\n"\
+	    "            t_invalid = 1;\n"\
+	    "            return t;\n"\
+	    "        }\n"\
+	    "        t = 0.5 * C_value / B_value;"\
+	    "    } else {\n"\
+	    "        sqrt_value = B_value * B_value - A_value * C_value;\n"\
+	    "        if(sqrt_value < 0.0) {\n"\
+	    "            t_invalid = 1;\n"\
+	    "            return t;\n"\
+	    "        }\n"\
+	    "        sqrt_value = sqrt(sqrt_value);\n"\
+	    "        t = (B_value + sqrt_value) / A_value;\n"\
+	    "    }\n"\
+	    "    if(repeat_type == %d) {\n" /* RepeatNone case. */\
+	    "        if((t <= 0.0) || (t > 1.0))\n"\
+	    /*           try another if first one invalid*/\
+	    "            t = (B_value - sqrt_value) / A_value;\n"\
+	    "        \n"\
+	    "        if((t <= 0.0) || (t > 1.0)) {\n" /*still invalid, return.*/\
+	    "            t_invalid = 1;\n"\
+	    "            return t;\n"\
+	    "        }\n"\
+	    "    } else {\n"\
+	    "        if(t * (r2 - r1) <= -1.0 * r1)\n"\
+	    /*           try another if first one invalid*/\
+	    "            t = (B_value - sqrt_value) / A_value;\n"\
+	    "        \n"\
+	    "        if(t * (r2 -r1) <= -1.0 * r1) {\n" /*still invalid, return.*/\
+	    "            t_invalid = 1;\n"\
+	    "            return t;\n"\
+	    "        }\n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    if(repeat_type == %d){\n" /* repeat normal*/\
+	    "        while(t > 1.0) \n"\
+	    "            t = t - 1.0; \n"\
+	    "        while(t < 0.0) \n"\
+	    "            t = t + 1.0; \n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    if(repeat_type == %d) {\n" /* repeat reflect*/\
+	    "        while(t > 1.0) {\n"\
+	    "            t = t - 1.0; \n"\
+	    "            if(revserse == 0)\n"\
+	    "                revserse = 1;\n"\
+	    "            else\n"\
+	    "                revserse = 0;\n"\
+	    "        }\n"\
+	    "        while(t < 0.0) {\n"\
+	    "            t = t + 1.0; \n"\
+	    "            if(revserse == 0)\n"\
+	    "                revserse = 1;\n"\
+	    "            else\n"\
+	    "                revserse = 0;\n"\
+	    "        }\n"\
+	    "        if(revserse == 1) {\n"\
+	    "            t = 1.0 - t; \n"\
+	    "        }\n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    return t;\n"\
+	    "}\n"\
+	    "\n"\
+	    "void main()\n"\
+	    "{\n"\
+	    "    float stop_len = get_stop_len();\n"\
+	    "    if(t_invalid == 1) {\n"\
+	    "        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"\
+	    "    } else {\n"\
+	    "        gl_FragColor = get_color(stop_len);\n"\
+	    "    }\n"\
 	    "}\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    float stop_len = get_stop_len();\n"
-	    "    if(t_invalid == 1) {\n"
-	    "        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
-	    "    } else {\n"
-	    "        gl_FragColor = get_color(stop_len);\n"
-	    "    }\n"
-	    "}\n";
 
 	glamor_priv = glamor_get_screen_private(screen);
 
@@ -376,7 +376,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy
 	                                   GL_VERTEX_SHADER, gradient_vs);
 
 	XNFasprintf(&gradient_fs,
-	            gradient_fs_template,
+	            gradient_radial_fs_template,
 	            PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
 
 	fs_main_prog = glamor_compile_glsl_prog(dispatch,
@@ -486,89 +486,88 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 	 *		before and after it. Use the interpolation fomula to compute RGBA.
 	 */
 
-	const char *gradient_fs_template =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform mat3 transform_mat;\n"
-	    "uniform int repeat_type;\n"
-	    "uniform int hor_ver;\n"
-	    "uniform float pt_slope;\n"
-	    "uniform float cos_val;\n"
-	    "uniform float p1_distance;\n"
-	    "uniform float pt_distance;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len);\n"
-	    "\n"
-	    "float get_stop_len()\n"
-	    "{\n"
-	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
-	    "    float len_percentage;\n"
-	    "    float distance;\n"
-	    "    float _p1_distance;\n"
-	    "    float _pt_distance;\n"
-	    "    float y_dist;\n"
-	    "    float stop_after;\n"
-	    "    float stop_before;\n"
-	    "    vec4 stop_color_before;\n"
-	    "    vec4 stop_color_after;\n"
-	    "    float new_alpha; \n"
-	    "    int revserse = 0;\n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
-	    "    \n"
-	    "    if(hor_ver == 0) { \n" //Normal case.
-	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
-	    "        distance = y_dist * cos_val;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "        \n"
-	    "    } else if (hor_ver == 1) {\n"//horizontal case.
-	    "        distance = source_texture_trans.x;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } \n"
-	    "    \n"
-	    "    distance = distance - _p1_distance; \n"
-	    "    \n"
-	    "    if(repeat_type == %d){\n" // repeat normal
-	    "        while(distance > _pt_distance) \n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "        while(distance < 0.0) \n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d) {\n" // repeat reflect
-	    "        while(distance > _pt_distance) {\n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        while(distance < 0.0) {\n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        if(revserse == 1) {\n"
-	    "            distance = (_pt_distance) - distance; \n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    len_percentage = distance/(_pt_distance);\n"
-	    "    \n"
-	    "    return len_percentage;\n"
+	#define gradient_fs_template	\
+	    GLAMOR_DEFAULT_PRECISION\
+	    "uniform mat3 transform_mat;\n"\
+	    "uniform int repeat_type;\n"\
+	    "uniform int hor_ver;\n"\
+	    "uniform float pt_slope;\n"\
+	    "uniform float cos_val;\n"\
+	    "uniform float p1_distance;\n"\
+	    "uniform float pt_distance;\n"\
+	    "varying vec2 source_texture;\n"\
+	    "\n"\
+	    "vec4 get_color(float stop_len);\n"\
+	    "\n"\
+	    "float get_stop_len()\n"\
+	    "{\n"\
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\
+	    "    float len_percentage;\n"\
+	    "    float distance;\n"\
+	    "    float _p1_distance;\n"\
+	    "    float _pt_distance;\n"\
+	    "    float y_dist;\n"\
+	    "    float stop_after;\n"\
+	    "    float stop_before;\n"\
+	    "    vec4 stop_color_before;\n"\
+	    "    vec4 stop_color_after;\n"\
+	    "    float new_alpha; \n"\
+	    "    int revserse = 0;\n"\
+	    "    vec4 gradient_color;\n"\
+	    "    float percentage; \n"\
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"\
+	    "    \n"\
+	    "    if(hor_ver == 0) { \n" /*Normal case.*/\
+	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"\
+	    "        distance = y_dist * cos_val;\n"\
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"\
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"\
+	    "        \n"\
+	    "    } else if (hor_ver == 1) {\n"/*horizontal case.*/\
+	    "        distance = source_texture_trans.x;\n"\
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"\
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"\
+	    "    } \n"\
+	    "    \n"\
+	    "    distance = distance - _p1_distance; \n"\
+	    "    \n"\
+	    "    if(repeat_type == %d){\n" /* repeat normal*/\
+	    "        while(distance > _pt_distance) \n"\
+	    "            distance = distance - (_pt_distance); \n"\
+	    "        while(distance < 0.0) \n"\
+	    "            distance = distance + (_pt_distance); \n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    if(repeat_type == %d) {\n" /* repeat reflect*/\
+	    "        while(distance > _pt_distance) {\n"\
+	    "            distance = distance - (_pt_distance); \n"\
+	    "            if(revserse == 0)\n"\
+	    "                revserse = 1;\n"\
+	    "            else\n"\
+	    "                revserse = 0;\n"\
+	    "        }\n"\
+	    "        while(distance < 0.0) {\n"\
+	    "            distance = distance + (_pt_distance); \n"\
+	    "            if(revserse == 0)\n"\
+	    "                revserse = 1;\n"\
+	    "            else\n"\
+	    "                revserse = 0;\n"\
+	    "        }\n"\
+	    "        if(revserse == 1) {\n"\
+	    "            distance = (_pt_distance) - distance; \n"\
+	    "        }\n"\
+	    "    }\n"\
+	    "    \n"\
+	    "    len_percentage = distance/(_pt_distance);\n"\
+	    "    \n"\
+	    "    return len_percentage;\n"\
+	    "}\n"\
+	    "\n"\
+	    "void main()\n"\
+	    "{\n"\
+	    "    float stop_len = get_stop_len();\n"\
+	    "    gl_FragColor = get_color(stop_len);\n"\
 	    "}\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    float stop_len = get_stop_len();\n"
-	    "    gl_FragColor = get_color(stop_len);\n"
-	    "}\n";
-
 
 	glamor_priv = glamor_get_screen_private(screen);
 
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 44e1e40..7d5ffbb 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -73,13 +73,10 @@ glamor_create_picture(PicturePtr picture)
 {
 	PixmapPtr pixmap;
 	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv;
 
 	if (!picture || !picture->pDrawable)
 		return 0;
 
-	glamor_priv =
-	    glamor_get_screen_private(picture->pDrawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (!pixmap_priv) {
@@ -112,13 +109,10 @@ glamor_destroy_picture(PicturePtr picture)
 {
 	PixmapPtr pixmap;
 	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv;
 
 	if (!picture || !picture->pDrawable)
 		return;
 
-	glamor_priv =
-	    glamor_get_screen_private(picture->pDrawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f3a2a87..9bbc989 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -926,7 +926,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
 	glamor_pixmap_private *pixmap_priv;
 	GLenum gl_access = 0, gl_usage = 0;
 	void *data, *read;
-	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
@@ -936,7 +935,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
 	int fbo_x_off, fbo_y_off;
 
 	data = bits;
-	screen = pixmap->drawable.pScreen;
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return NULL;
@@ -1193,13 +1191,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	    glamor_get_pixmap_private(pixmap);
 	unsigned int stride;
 	void *data = NULL, *dst;
-	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	int pbo = 0;
 
-	screen = pixmap->drawable.pScreen;
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return TRUE;
 
@@ -1259,7 +1255,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 Bool
 glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 {
-	glamor_screen_private *glamor_priv;
 	glamor_pixmap_fbo *old_fbo;
 	glamor_pixmap_fbo *new_fbo = NULL;
 	PixmapPtr scratch = NULL;
@@ -1274,7 +1269,6 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 		return	TRUE;
 
 	old_fbo = pixmap_priv->base.fbo;
-	glamor_priv = pixmap_priv->base.glamor_priv;
 
 	if (!old_fbo)
 		return FALSE;
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 738e8eb..4e1f7b3 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -43,9 +43,6 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	register BoxPtr pbox;
 	RegionPtr pClip = fbGetCompositeClip(gc);
 	Bool ret = FALSE;
-	glamor_screen_private *glamor_priv;
-
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
 	xorg = drawable->x;
 	yorg = drawable->y;
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 70dd6c1..e723e95 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -45,7 +45,6 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	xRectangle *rects;
 	int x1, x2, y1, y2;
 	int i;
-	glamor_screen_private *glamor_priv;
 
 	/* Don't try to do wide lines or non-solid fill style. */
 	if (gc->lineWidth != 0) {
@@ -105,7 +104,6 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	    && glamor_ddx_fallback_check_gc(gc))
 		return FALSE;
 
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 	if (gc->lineWidth == 0) {
 		if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 			if (glamor_prepare_access_gc(gc)) {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1830b56..03ef6cc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -549,9 +549,6 @@ extern int glamor_debug_level;
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
-PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
-			       unsigned int usage);
-
 Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 
 glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
@@ -568,16 +565,12 @@ void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
 Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
 void glamor_fbo_expire(glamor_screen_private *glamor_priv);
-void glamor_init_pixmap_fbo(ScreenPtr screen);
-void glamor_fini_pixmap_fbo(ScreenPtr screen);
 
 glamor_pixmap_fbo *
 glamor_create_fbo_array(glamor_screen_private *glamor_priv,
 			int w, int h, GLenum format, int flag,
 			int block_w, int block_h, glamor_pixmap_private *);
 
-Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
-
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
@@ -603,7 +596,6 @@ void glamor_fini_finish_access_shaders(ScreenPtr screen);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
 				int *x, int *y);
-Bool glamor_create_gc(GCPtr gc);
 Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
 		    unsigned char alu, unsigned long planemask,
@@ -636,7 +628,7 @@ Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch,
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
-Bool glamor_gl_has_extension(char *extension);
+Bool glamor_gl_has_extension(const char *extension);
 int glamor_gl_get_version(void);
 
 #define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
@@ -683,7 +675,6 @@ void glamor_glyphs(CARD8 op,
 		   INT16 ySrc, int nlist, GlyphListPtr list,
 		   GlyphPtr * glyphs);
 
-void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		      DDXPointPtr points, int *widths, int n, int sorted);
@@ -947,9 +938,6 @@ void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access);
 
 void glamor_destroy_picture(PicturePtr picture);
 
-enum glamor_pixmap_status
- glamor_upload_picture_to_texture(PicturePtr picture);
-
 /* fixup a fbo to the exact size as the pixmap. */
 Bool
 glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 9b80295..27d5dc5 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -43,6 +43,7 @@
 //#define DEBUGRegionPrint(x) do {} while (0)
 #define DEBUGRegionPrint RegionPrint
 #endif
+
 static struct blendinfo composite_op_info[] = {
 	[PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
 	[PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
@@ -1715,7 +1716,7 @@ _glamor_composite(CARD8 op,
 	    glamor_get_screen_private(screen);
 	Bool ret = TRUE;
 	RegionRec region;
-	BoxPtr box, extent;
+	BoxPtr extent;
 	int nbox, ok = FALSE;
 	PixmapPtr sub_dest_pixmap = NULL;
 	PixmapPtr sub_source_pixmap = NULL;
@@ -1778,7 +1779,6 @@ _glamor_composite(CARD8 op,
 		goto done;
 	}
 
-	box = REGION_RECTS(&region);
 	nbox = REGION_NUM_RECTS(&region);
 	DEBUGF("first clipped when compositing.\n");
 	DEBUGRegionPrint(&region);
@@ -1833,6 +1833,7 @@ _glamor_composite(CARD8 op,
 						     x_dest, y_dest);
 
 	REGION_UNINIT(dest->pDrawable->pScreen, &region);
+
 	if (ok)
 		goto done;
 fail:
@@ -1886,7 +1887,7 @@ fail:
 		GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
 	if (mask && mask->pDrawable && !mask->transform)
 		GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
-full_fallback:
+
 	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
 		if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
 		    (source, GLAMOR_ACCESS_RO)) {
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 7bb75f5..57a178c 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -81,12 +81,16 @@ _glamor_lines_crossfixedY (xLineFixed *l, xLineFixed *r)
 	xFixed dy2 = r->p2.y - r->p1.y;
 	xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1;
 	xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x);
+	xFixed_32_32 dividend2;
+	xFixed_32_32 dividend3;
+	xFixed_32_32 divisor;
+
 	tmp = (xFixed_32_32) dx1 * dy2;
-	xFixed_32_32 dividend2 = (tmp >> 32) * l->p1.y;
+	dividend2 = (tmp >> 32) * l->p1.y;
 	tmp = (xFixed_32_32) dy1 * dx2;
-	xFixed_32_32 dividend3 = (tmp >> 32) * r->p1.y;
-	xFixed_32_32 divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
-	                           - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
+	dividend3 = (tmp >> 32) * r->p1.y;
+	divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
+	            - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
 
 	if (divisor)
 		return (xFixed)((dividend2 - dividend1 - dividend3) / divisor);
@@ -1363,7 +1367,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	glamor_pixmap_private *pixmap_priv;
 	PixmapPtr pixmap = NULL;
 	GLint trapezoid_prog;
-	float width, height;
 	GLfloat xscale, yscale;
 	float left_slope, right_slope;
 	xTrapezoid *ptrap;
@@ -1399,9 +1402,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 
 	pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
 
-	width = (float)(bounds->x2 - bounds->x1);
-	height = (float)(bounds->y2 - bounds->y1);
-
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
@@ -1604,11 +1604,11 @@ glamor_create_mask_picture(ScreenPtr screen,
 static int
 _glamor_trapezoid_bounds (int ntrap, xTrapezoid *traps, BoxPtr box)
 {
+	int has_large_trapezoid = 0;
 	box->y1 = MAXSHORT;
 	box->y2 = MINSHORT;
 	box->x1 = MAXSHORT;
 	box->x2 = MINSHORT;
-	int has_large_trapezoid = 0;
 
 	for (; ntrap; ntrap--, traps++) {
 		INT16 x1, y1, x2, y2;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 6eef722..36beb49 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -39,12 +39,12 @@
 #define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
-#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)\
-  do {                                                                 \
-    int w,h;                                                           \
-    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h);                  \
-    *(_pxscale_) = 1.0 / w;                                            \
-    *(_pyscale_) = 1.0 / h;                                            \
+#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)  \
+  do {                                                                   \
+    int _w_,_h_;                                                         \
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, _w_, _h_);                \
+    *(_pxscale_) = 1.0 / _w_;                                            \
+    *(_pyscale_) = 1.0 / _h_;                                            \
    } while(0)
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
@@ -302,14 +302,14 @@
 
 #define glamor_transform_point(matrix, tx, ty, x, y)			\
   do {									\
-    int i;								\
-    float result[4];							\
-    for (i = 0; i < 3; i++) {						\
-      result[i] = (matrix)[i * 3] * (x) + (matrix)[i * 3 + 1] * (y)	\
-	+ (matrix)[i * 3 + 2];						\
+    int _i_;								\
+    float _result_[4];							\
+    for (_i_ = 0; _i_ < 3; _i_++) {					\
+      _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y)	\
+	+ (matrix)[_i_ * 3 + 2];					\
     }									\
-    tx = result[0] / result[2];						\
-    ty = result[1] / result[2];						\
+    tx = _result_[0] / _result_[2];					\
+    ty = _result_[1] / _result_[2];					\
   } while(0)
 
 #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_,	\
@@ -734,10 +734,10 @@
 
 #define glamor_set_const_ext(params, nparam, vertices, nverts, stride)	\
     do {								\
-	int i = 0, j = 0;						\
-	for(; i < nverts; i++) {					\
-	    for(j = 0; j < nparam; j++) {				\
-		vertices[stride*i + j] = params[j];			\
+	int _i_ = 0, _j_ = 0;						\
+	for(; _i_ < nverts; _i_++) {					\
+	    for(_j_ = 0; _j_ < nparam; _j_++) {				\
+		vertices[stride*_i_ + _j_] = params[_j_];		\
 	    }								\
 	}								\
     } while(0)
commit 50614451adafc816ae5ffbe9c2a97a58f493b927
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 8 20:08:12 2012 +0800

    glamor_largepixmap: Fixed a bug in repeat clipping.
    
    If the repeat direction only has one block, then we need to set the
    dx/dy to cover all the extent. This commit also silence some compilation
    warnings.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index f07095a..91ee8f2 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -35,7 +35,6 @@ __glamor_compute_clipped_regions(int block_w,
 	int loop_end_block_x, loop_end_block_y;
 	int loop_block_stride;
 	int i, j, delta_i, delta_j;
-	int width, height;
 	RegionRec temp_region;
 	RegionPtr current_region;
 	int block_idx;
@@ -60,8 +59,6 @@ __glamor_compute_clipped_regions(int block_w,
 		return NULL;
 	}
 
-	width = end_x - start_x;
-	height = end_y - start_y;
 	start_block_x = (start_x  - x)/ block_w;
 	start_block_y = (start_y - y)/ block_h;
 	end_block_x = (end_x - x)/ block_w;
@@ -327,7 +324,6 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 	glamor_pixmap_clipped_regions * clipped_regions;
 	BoxPtr extent;
 	int i, j;
-	int width, height;
 	RegionPtr current_region;
 	int pixmap_width, pixmap_height;
 	int m;
@@ -400,8 +396,6 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 	}
 
 	extent = RegionExtents(region);
-	width = extent->x2 - extent->x1;
-	height = extent->y2 - extent->y1;
 	/* Tile a large pixmap to another large pixmap.
 	 * We can't use the target large pixmap as the
 	 * loop variable, instead we need to loop for all
@@ -462,13 +456,15 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 			/* Construct a rect to clip the target region. */
 			repeat_box.x1 = shift_x + priv->box_array[idx].x1;
 			repeat_box.y1 = shift_y + priv->box_array[idx].y1;
-			if (priv->block_wcnt == 1)
+			if (priv->block_wcnt == 1) {
 				repeat_box.x2 = extent->x2;
-			else
+				dx = extent->x2 - repeat_box.x1;
+			} else
 				repeat_box.x2 = shift_x + priv->box_array[idx].x2;
-			if (priv->block_hcnt == 1)
+			if (priv->block_hcnt == 1) {
 				repeat_box.y2 = extent->y2;
-			else
+				dy = extent->y2 - repeat_box.y1;
+			} else
 				repeat_box.y2 = shift_y + priv->box_array[idx].y2;
 
 			current_region = RegionCreate(NULL, 4);
@@ -980,16 +976,8 @@ glamor_composite_largepixmap_region(CARD8 op,
 	glamor_pixmap_private * need_free_source_pixmap_priv = NULL;
 	glamor_pixmap_private * need_free_mask_pixmap_priv = NULL;
 	int source_repeat_type = 0, mask_repeat_type = 0;
-	PixmapPtr source_pixmap = NULL;
-	PixmapPtr mask_pixmap = NULL;
 	int ok = TRUE;
 
-	if (source_pixmap_priv)
-		source_pixmap = source_pixmap_priv->base.pixmap;
-
-	if (mask_pixmap_priv)
-		mask_pixmap = mask_pixmap_priv->base.pixmap;
-
 	if (source->repeat)
 		source_repeat_type = source->repeatType;
 	else
commit 7eb434918bd7d58162c53fac9316aceda136cb6f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Aug 7 18:16:58 2012 +0200

    Prefer KHR_surfaceless_context EGL extension over KHR_surfaceless_opengl/gles2.
    
    Current Mesa Git only advertises the former instead of the latter.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 596470c..a9a92a7 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -397,7 +397,7 @@ glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 
 static Bool
 glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
-			 char *extension)
+			 const char *extension)
 {
 	const char *egl_extensions;
 	char *pext;
@@ -512,12 +512,19 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 		return FALSE;  \
 	}
 
+#define GLAMOR_CHECK_EGL_EXTENSIONS(EXT1, EXT2)	 \
+	if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT1) &&  \
+	    !glamor_egl_has_extension(glamor_egl, "EGL_" #EXT2)) {  \
+		ErrorF("EGL_" #EXT1 " or EGL_" #EXT2 " required.\n");  \
+		return FALSE;  \
+	}
+
 	GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
 	GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
 #ifdef GLAMOR_GLES2
-	GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
+	GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_gles2);
 #else
-	GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
+	GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_opengl);
 #endif
 
 	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
commit 59653fa08a67a0694b3408407f5f92af99470739
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Aug 7 18:13:32 2012 +0200

    Print space between name of missing EGL extension and 'required'.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index da9283b..596470c 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -508,7 +508,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 
 #define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
 	if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
-		ErrorF("EGL_" #EXT "required.\n");  \
+		ErrorF("EGL_" #EXT " required.\n");  \
 		return FALSE;  \
 	}
 
commit c3096c5a568c9c7b5f8a68ca882d866b8fb8e3ad
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue Aug 7 05:01:59 2012 +0800

    Fallback to pixman when trapezoid mask is big.
    
     The trapezoid generating speed of the shader is relatively
     slower when the trapezoid area is big. We fallback when
     the trapezoid's width and height is bigger enough.
     The big traps number will also slow down the render because
     of the VBO size. We fallback if ntrap > 256
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Reviewed-By: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 11d09c4..1830b56 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -1016,7 +1016,7 @@ glamor_composite_rectangles(CARD8	 op,
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #define GLAMOR_GRADIENT_SHADER
-//#define GLAMOR_TRAPEZOID_SHADER
+#define GLAMOR_TRAPEZOID_SHADER
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #define WALKAROUND_LARGE_TEXTURE_MAP
 #if 0
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 7813d82..7bb75f5 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -36,6 +36,28 @@
 #include "mipict.h"
 #include "fbpict.h"
 
+static xFixed
+_glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+	xFixed dx = l->p2.x - l->p1.x;
+	xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+	xFixed dy = l->p2.y - l->p1.y;
+	if (ceil)
+		ex += (dy - 1);
+	return l->p1.x + (xFixed) (ex / dy);
+}
+
+static xFixed
+_glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
+{
+	xFixed dy = l->p2.y - l->p1.y;
+	xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
+	xFixed dx = l->p2.x - l->p1.x;
+	if (ceil)
+		ey += (dx - 1);
+	return l->p1.y + (xFixed) (ey / dx);
+}
+
 #ifdef GLAMOR_TRAPEZOID_SHADER
 
 #define GLAMOR_VERTEX_TOP_BOTTOM  (GLAMOR_VERTEX_SOURCE + 1)
@@ -72,28 +94,6 @@ _glamor_lines_crossfixedY (xLineFixed *l, xLineFixed *r)
 	return 0xFFFFFFFF;
 }
 
-static xFixed
-_glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil)
-{
-	xFixed dx = l->p2.x - l->p1.x;
-	xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
-	xFixed dy = l->p2.y - l->p1.y;
-	if (ceil)
-		ex += (dy - 1);
-	return l->p1.x + (xFixed) (ex / dy);
-}
-
-static xFixed
-_glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
-{
-	xFixed dy = l->p2.y - l->p1.y;
-	xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
-	xFixed dx = l->p2.x - l->p1.x;
-	if (ceil)
-		ey += (dx - 1);
-	return l->p1.y + (xFixed) (ey / dx);
-}
-
 static Bool
 point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
 {
@@ -1601,6 +1601,45 @@ glamor_create_mask_picture(ScreenPtr screen,
 	return picture;
 }
 
+static int
+_glamor_trapezoid_bounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+	box->y1 = MAXSHORT;
+	box->y2 = MINSHORT;
+	box->x1 = MAXSHORT;
+	box->x2 = MINSHORT;
+	int has_large_trapezoid = 0;
+
+	for (; ntrap; ntrap--, traps++) {
+		INT16 x1, y1, x2, y2;
+
+		if (!xTrapezoidValid(traps))
+			continue;
+		y1 = xFixedToInt (traps->top);
+		if (y1 < box->y1)
+			box->y1 = y1;
+
+		y2 = xFixedToInt (xFixedCeil (traps->bottom));
+		if (y2 > box->y2)
+			box->y2 = y2;
+
+		x1 = xFixedToInt (min (_glamor_linefixedX (&traps->left, traps->top, FALSE),
+		                  _glamor_linefixedX (&traps->left, traps->bottom, FALSE)));
+		if (x1 < box->x1)
+			box->x1 = x1;
+
+		x2 = xFixedToInt (xFixedCeil (max (_glamor_linefixedX (&traps->right, traps->top, TRUE),
+		                  _glamor_linefixedX (&traps->right, traps->bottom, TRUE))));
+		if (x2 > box->x2)
+			box->x2 = x2;
+
+		if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32)
+			has_large_trapezoid = 1;
+	}
+
+	return has_large_trapezoid;
+}
+
 /**
  * glamor_trapezoids will first try to create a trapezoid mask using shader,
  * if failed, miTrapezoids will generate trapezoid mask accumulating in
@@ -1621,6 +1660,7 @@ _glamor_trapezoids(CARD8 op,
 	PixmapPtr pixmap;
 	pixman_image_t *image = NULL;
 	int ret = 0;
+	int has_large_trapezoid;
 
 	/* If a mask format wasn't provided, we get to choose, but behavior should
 	 * be as if there was no temporary mask the traps were accumulated into.
@@ -1638,10 +1678,10 @@ _glamor_trapezoids(CARD8 op,
 		return TRUE;
 	}
 
-	miTrapezoidBounds(ntrap, traps, &bounds);
+	has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds);
 	DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
-	       "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2,
-	       bounds.y1, bounds.y2);
+	       "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1,
+	       bounds.x2, bounds.y1, bounds.y2, ntrap);
 
 	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
 		return TRUE;
@@ -1666,16 +1706,20 @@ _glamor_trapezoids(CARD8 op,
 	   When the depth is not 1, AA is needed and we use a shader to generate
 	   a temp mask pixmap.
 	 */
-	if(mask_format->depth == 1) {
+	if (mask_format->depth == 1) {
 		ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format,
 		                                     x_src, y_src, ntrap, traps);
 		if(ret)
 			return TRUE;
 	} else {
-		/*  The precise mode is that we sample the trapezoid on the centre points of
-		    an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
-		    and we use inside area ratio to replace it if the polymode == Imprecise. */
-		if(dst->polyMode == PolyModeImprecise) {
+		if (has_large_trapezoid || ntrap > 256) {
+			/* The shader speed is relative slower than pixman when generating big chunk
+			   trapezoid mask. We fallback to pixman to improve the performance. */
+			;
+		} else if (dst->polyMode == PolyModeImprecise) {
+			/*  The precise mode is that we sample the trapezoid on the centre points of
+			    an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
+			    and we use inside area ratio to replace it if the polymode == Imprecise. */
 			picture = glamor_create_mask_picture(screen, dst, mask_format,
 			          width, height, 1);
 			if (!picture)
commit f62f4d53ef91ba05cc9456b1468cd1b24252454f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Aug 2 18:07:07 2012 +0800

    glamor_glyphs: When dst arg point to a NULL buffer, dont't flush.
    
    This is a corner case, when we render glyphs via mask cache, and
    when we need to upload new glyphs cache, we need to flush both the
    mask and dest buffer. But we the dest arg may point to a NULL buffer
    at that time, we need to check it firstly. If the dest buffer is NULL.
    Then we don't need to flush both the dest and mask buffer.
    
    This commit fix a potential crash.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index bab2c24..f549904 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -1193,6 +1193,9 @@ glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
 static void
 glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg)
 {
+	if (!arg->buffer)
+		return;
+
 	if (mask_buffer.count > 0) {
 		glamor_glyphs_flush_mask(&mask_arg);
 	}
commit e7af7cb76dade31b9e40cede7ac21d32bc95831c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 1 18:27:29 2012 +0800

    glamor_trapezoid: workaround a glsl like problem.
    
    It seems that the following statement cann't run as expected on SNB.
    bool trap_left_vertical = (abs(trap_left_vertical_f - 1.0) <= 0.0001);
    
    Have to rewrite it to another style to let the vertical edge trapezoid
    to be rendered correctly.
    
    Reviewed-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index fd63062..7813d82 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1068,8 +1068,6 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "varying float trap_right_vertical_f;  \n"
 	    "float x_per_pix = 1.0;"
 	    "float y_per_pix = 1.0;"
-	    "bool trap_left_vertical = (abs(trap_left_vertical_f - 1.0) <= 0.0001);\n"
-	    "bool trap_right_vertical = (abs(trap_right_vertical_f - 1.0) <= 0.0001);\n"
 	    "\n"
 	    "float get_alpha_val() \n"
 	    "{  \n"
@@ -1077,6 +1075,16 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "    float x_bottom_cut_left;  \n"
 	    "    float x_up_cut_right;  \n"
 	    "    float x_bottom_cut_right;  \n"
+	    "    bool trap_left_vertical;\n"
+	    "    bool trap_right_vertical;\n"
+	    "	 if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n"
+	    "		trap_left_vertical = true;\n"
+	    "	 else\n"
+	    "		trap_left_vertical = false;\n"
+	    "	 if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n"
+	    "		trap_right_vertical = true;\n"
+	    "	 else\n"
+	    "		trap_right_vertical = false;\n"
 	    "    \n"
 	    "    if(trap_left_vertical == true) {  \n"
 	    "        x_up_cut_left = trap_left_x;  \n"
commit 5512c14e346a988f6eb8cdf9385a868ef705450c
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Jul 20 05:52:57 2012 +0800

    Fix the problem of VBO leak.
    
     In some cases we allocate the VBO but have no vertex to
     emit, which cause the VBO fail to be released. Fix it.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6dacd44..9b80295 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -826,9 +826,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 
-	if (!glamor_priv->render_nr_verts)
-		return;
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
@@ -840,6 +837,9 @@ glamor_flush_composite_rects(ScreenPtr screen)
 				       glamor_priv->vb, GL_DYNAMIC_DRAW);
 	}
 
+	if (!glamor_priv->render_nr_verts)
+		return;
+
 	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 				 GL_UNSIGNED_SHORT, NULL);
 	glamor_put_dispatch(glamor_priv);
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 5c02a8c..fd63062 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -199,9 +199,6 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 
-	if (!glamor_priv->render_nr_verts)
-		return;
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
@@ -213,6 +210,9 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 		        glamor_priv->vb, GL_DYNAMIC_DRAW);
 	}
 
+	if (!glamor_priv->render_nr_verts)
+		return;
+
 	dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
 	glamor_put_dispatch(glamor_priv);
 }
commit 9f78e22fa62d8f1a08d6a0688e2eafba35206a3b
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Jul 20 05:52:50 2012 +0800

    Just use the shader to generate trapezoid if PolyMode == Imprecise
    
     The precise mode of trapezoid rendering need to sample the trapezoid on
     the centre points of an (2*n+1)x(2*n-1) subpixel grid. It is computationally
     expensive in shader, and we use inside area ratio to replace it.
     The result has some difference, and we just use it if the polymode == Imprecise.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index d7bba66..5c02a8c 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1664,15 +1664,20 @@ _glamor_trapezoids(CARD8 op,
 		if(ret)
 			return TRUE;
 	} else {
-		picture = glamor_create_mask_picture(screen, dst, mask_format,
-		          width, height, 1);
-		if (!picture)
-			return TRUE;
-
-		ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
-
-		if (!ret)
-			FreePicture(picture, 0);
+		/*  The precise mode is that we sample the trapezoid on the centre points of
+		    an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
+		    and we use inside area ratio to replace it if the polymode == Imprecise. */
+		if(dst->polyMode == PolyModeImprecise) {
+			picture = glamor_create_mask_picture(screen, dst, mask_format,
+			          width, height, 1);
+			if (!picture)
+				return TRUE;
+
+			ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
+
+			if (!ret)
+				FreePicture(picture, 0);
+		}
 	}
 #endif
 
commit fe024a78220a6d61c6b1df89166da953b19b633a
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Jul 20 05:52:43 2012 +0800

    Change the trapezoid render to use VBO.
    
     Because some uniform variables need to be set for every
     trapezoid rendering, we can not use vbo to render multi
     trapezoids one time, which have performance big loss.
     We now add attributes which contain the same value to bypass
     the uniform variable problem. The uniform value for one
     trapezoid will be set to the same value to all the vertex
     of that trapezoid as an attribute, then in FS, it is still
     a constant.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 5dd2792..d7bba66 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -38,6 +38,10 @@
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
 
+#define GLAMOR_VERTEX_TOP_BOTTOM  (GLAMOR_VERTEX_SOURCE + 1)
+#define GLAMOR_VERTEX_LEFT_PARAM  (GLAMOR_VERTEX_SOURCE + 2)
+#define GLAMOR_VERTEX_RIGHT_PARAM (GLAMOR_VERTEX_SOURCE + 3)
+
 #define DEBUG_CLIP_VTX 0
 
 #define POINT_INSIDE_CLIP_RECT(point, rect)	\
@@ -112,10 +116,10 @@ point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
 		ret = FALSE;
 		if (DEBUG_CLIP_VTX) {
 			ErrorF("Out of Trap top, point[1] = %d(0x%x)), "
-			     "top = %d(0x%x)\n",
-			     (unsigned int)xFixedToInt(point[1]), point[1],
-			     (unsigned int)xFixedToInt(trap->top),
-			     (unsigned int)trap->top);
+			       "top = %d(0x%x)\n",
+			       (unsigned int)xFixedToInt(point[1]), point[1],
+			       (unsigned int)xFixedToInt(trap->top),
+			       (unsigned int)trap->top);
 		}
 
 		return ret;
@@ -556,6 +560,99 @@ _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
 	return TRUE;
 }
 
+static void
+glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch;
+	int stride;
+	int vert_size;
+
+	glamor_priv->render_nr_verts = 0;
+
+	/* For GLAMOR_VERTEX_POS */
+	glamor_priv->vb_stride = 2 * sizeof(float);
+
+	/* For GLAMOR_GLAMOR_VERTEX_SOURCE */
+	glamor_priv->vb_stride += 2 * sizeof(float);
+
+	/* For GLAMOR_VERTEX_TOP_BOTTOM */
+	glamor_priv->vb_stride += 2 * sizeof(float);
+
+	/* For GLAMOR_VERTEX_LEFT_PARAM */
+	glamor_priv->vb_stride += 4 * sizeof(float);
+
+	/* For GLAMOR_VERTEX_RIGHT_PARAM */
+	glamor_priv->vb_stride += 4 * sizeof(float);
+
+	vert_size = n_verts * glamor_priv->vb_stride;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
+			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
+				glamor_priv->vb_stride;
+			glamor_priv->vbo_offset = 0;
+			dispatch->glBufferData(GL_ARRAY_BUFFER,
+					       glamor_priv->vbo_size,
+					       NULL, GL_STREAM_DRAW);
+		}
+
+		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+		                                             glamor_priv->vbo_offset,
+		                                             vert_size,
+		                                             GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+
+		assert(glamor_priv->vb != NULL);
+		glamor_priv->vb -= glamor_priv->vbo_offset;
+	} else {
+		glamor_priv->vbo_offset = 0;
+	}
+
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+	/* Set the vertex pointer. */
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+	        GL_FALSE, glamor_priv->vb_stride,
+	        (void *) ((long)glamor_priv->vbo_offset));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	stride = 2;
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+	        GL_FALSE, glamor_priv->vb_stride,
+	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	stride += 2;
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
+	        GL_FALSE, glamor_priv->vb_stride,
+	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+	stride += 2;
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
+	        GL_FALSE, glamor_priv->vb_stride,
+	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+	stride += 4;
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
+	        GL_FALSE, glamor_priv->vb_stride,
+	        (void *) ((long)glamor_priv->vbo_offset + stride * sizeof(float)));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
+
+	glamor_put_dispatch(glamor_priv);
+}
+
 static Bool
 _glamor_trapezoids_with_shader(CARD8 op,
         PicturePtr src, PicturePtr dst,
@@ -565,6 +662,8 @@ _glamor_trapezoids_with_shader(CARD8 op,
 	ScreenPtr screen = dst->pDrawable->pScreen;
 	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 	struct shader_key key;
+	glamor_composite_shader *shader = NULL;
+	struct blendinfo op_info;
 	PictFormatShort saved_source_format = 0;
 	PixmapPtr source_pixmap = NULL;
 	PixmapPtr dest_pixmap = NULL;
@@ -707,7 +806,7 @@ _glamor_trapezoids_with_shader(CARD8 op,
 		goto TRAPEZOID_RESET_GL;
 	}
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, op_info);
+	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
 	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
 	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
 	        key.mask != SHADER_MASK_SOLID);
@@ -888,13 +987,45 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	const char *trapezoid_vs =
 	    GLAMOR_DEFAULT_PRECISION
 	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord;\n"
+	    "attribute vec2 v_texcoord;\n"
+	    /* v_top_bottom, v_left_param and v_right_param contain the
+	       constant value for all the vertex of one rect. Using uniform
+	       is more suitable but we need to reset the uniform variables
+	       for every rect rendering and can not use the vbo, which causes
+	       performance loss. So we set these attributes to same value
+	       for every vertex of one rect and so it is also a constant in FS */
+	    "attribute vec2 v_top_bottom;\n"
+	    "attribute vec4 v_left_param;\n"
+	    "attribute vec4 v_right_param;\n"
+	    "\n"
 	    "varying vec2 source_texture;\n"
+	    "varying float trap_top;\n"
+	    "varying float trap_bottom;\n"
+	    "varying float trap_left_x;\n"
+	    "varying float trap_left_y;\n"
+	    "varying float trap_left_slope;\n"
+	    "varying float trap_left_vertical_f;\n"
+	    "varying float trap_right_x;\n"
+	    "varying float trap_right_y;\n"
+	    "varying float trap_right_slope;\n"
+	    "varying float trap_right_vertical_f;\n"
 	    "\n"
 	    "void main()\n"
 	    "{\n"
 	    "    gl_Position = v_position;\n"
 	    "    source_texture = v_texcoord.xy;\n"
+	    "    trap_top = v_top_bottom.x;\n"
+	    "    trap_bottom = v_top_bottom.y;\n"
+	    "    \n"
+	    "    trap_left_x = v_left_param.x;\n"
+	    "    trap_left_y = v_left_param.y;\n"
+	    "    trap_left_slope = v_left_param.z;\n"
+	    "    trap_left_vertical_f = v_left_param.w;\n"
+	    "    \n"
+	    "    trap_right_x = v_right_param.x;\n"
+	    "    trap_right_y = v_right_param.y;\n"
+	    "    trap_right_slope = v_right_param.z;\n"
+	    "    trap_right_vertical_f = v_right_param.w;\n"
 	    "}\n";
 
 	/*
@@ -925,18 +1056,20 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	const char *trapezoid_fs =
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 source_texture;  \n"
-	    "uniform float x_per_pix;  \n"
-	    "uniform float y_per_pix;  \n"
-	    "uniform float trap_top;  \n"
-	    "uniform float trap_bottom;  \n"
-	    "uniform float trap_left_x;  \n"
-	    "uniform float trap_left_y;  \n"
-	    "uniform float trap_left_slope;  \n"
-	    "uniform int trap_left_vertical;  \n"
-	    "uniform float trap_right_x;  \n"
-	    "uniform float trap_right_y;  \n"
-	    "uniform float trap_right_slope;  \n"
-	    "uniform int trap_right_vertical;  \n"
+	    "varying float trap_top;  \n"
+	    "varying float trap_bottom;  \n"
+	    "varying float trap_left_x;  \n"
+	    "varying float trap_left_y;  \n"
+	    "varying float trap_left_slope;  \n"
+	    "varying float trap_left_vertical_f;  \n"
+	    "varying float trap_right_x;  \n"
+	    "varying float trap_right_y;  \n"
+	    "varying float trap_right_slope;  \n"
+	    "varying float trap_right_vertical_f;  \n"
+	    "float x_per_pix = 1.0;"
+	    "float y_per_pix = 1.0;"
+	    "bool trap_left_vertical = (abs(trap_left_vertical_f - 1.0) <= 0.0001);\n"
+	    "bool trap_right_vertical = (abs(trap_right_vertical_f - 1.0) <= 0.0001);\n"
 	    "\n"
 	    "float get_alpha_val() \n"
 	    "{  \n"
@@ -945,7 +1078,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "    float x_up_cut_right;  \n"
 	    "    float x_bottom_cut_right;  \n"
 	    "    \n"
-	    "    if(trap_left_vertical == 1) {  \n"
+	    "    if(trap_left_vertical == true) {  \n"
 	    "        x_up_cut_left = trap_left_x;  \n"
 	    "        x_bottom_cut_left = trap_left_x;  \n"
 	    "    } else {  \n"
@@ -957,7 +1090,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "              / trap_left_slope;  \n"
 	    "    }  \n"
 	    "    \n"
-	    "    if(trap_right_vertical == 1) {  \n"
+	    "    if(trap_right_vertical == true) {  \n"
 	    "        x_up_cut_right = trap_right_x;  \n"
 	    "        x_bottom_cut_right = trap_right_x;  \n"
 	    "    } else {  \n"
@@ -1002,12 +1135,12 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "        \n"
 	    "        percent = (bottom - up) / y_per_pix;  \n"
 	    "        \n"
-	    "	     if(trap_left_vertical == 1) {  \n"
+	    "	     if(trap_left_vertical == true) {  \n"
 	    "            if(trap_left_x > source_texture.x - x_per_pix/2.0 &&  \n"
 	    "                     trap_left_x < source_texture.x + x_per_pix/2.0)  \n"
 	    "                left = trap_left_x;  \n"
 	    "        }  \n"
-	    "	     if(trap_right_vertical == 1) {  \n"
+	    "	     if(trap_right_vertical == true) {  \n"
 	    "            if(trap_right_x > source_texture.x - x_per_pix/2.0 &&  \n"
 	    "                     trap_right_x < source_texture.x + x_per_pix/2.0)  \n"
 	    "                right = trap_right_x;  \n"
@@ -1016,10 +1149,10 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "            return 0.0;  \n"
 	    "        \n"
 	    "        percent = percent * ((right - left)/x_per_pix);  \n"
-	    "        if(trap_left_vertical == 1 && trap_right_vertical == 1)  \n"
+	    "        if(trap_left_vertical == true && trap_right_vertical == true)  \n"
 	    "            return percent;  \n"
 	    "        \n"
-	    "        if(trap_left_vertical != 1) {  \n"
+	    "        if(trap_left_vertical != true) {  \n"
 	    "            float area;  \n"
 	    //           the slope should never be 0.0 here
 	    "            float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope;  \n"
@@ -1090,7 +1223,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	    "            }  \n"
 	    "        }  \n"
 	    "        \n"
-	    "        if(trap_right_vertical != 1) {  \n"
+	    "        if(trap_right_vertical != true) {  \n"
 	    "            float area;  \n"
 	    //           the slope should never be 0.0 here
 	    "            float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope;  \n"
@@ -1184,9 +1317,15 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
 	dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
 
 	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	                               GLAMOR_VERTEX_POS, "v_positionsition");
+	        GLAMOR_VERTEX_POS, "v_positionsition");
+	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+	        GLAMOR_VERTEX_SOURCE, "v_texcoord");
+	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+	        GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
+	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+	        GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
 	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
-	                               GLAMOR_VERTEX_SOURCE, "v_texcoord");
+	        GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
 
 	glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog);
 
@@ -1215,28 +1354,16 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_private *pixmap_priv;
 	PixmapPtr pixmap = NULL;
-	GLint x_per_pix_uniform_location;
-	GLint y_per_pix_uniform_location;
-	GLint trap_top_uniform_location;
-	GLint trap_bottom_uniform_location;
-	GLint trap_left_x_uniform_location;
-	GLint trap_left_y_uniform_location;
-	GLint trap_left_slope_uniform_location;
-	GLint trap_right_x_uniform_location;
-	GLint trap_right_y_uniform_location;
-	GLint trap_right_slope_uniform_location;
-	GLint trap_left_vertical_uniform_location;
-	GLint trap_right_vertical_uniform_location;
 	GLint trapezoid_prog;
 	float width, height;
-	xFixed width_fix, height_fix;
 	GLfloat xscale, yscale;
 	float left_slope, right_slope;
 	xTrapezoid *ptrap;
 	BoxRec one_trap_bound;
-	float vertices[8];
-	float tex_vertices[8];
-	int i;
+	int nrect_max;
+	int i, j;
+	float *vertices;
+	float params[4];
 
 	glamor_priv = glamor_get_screen_private(screen);
 	trapezoid_prog = glamor_priv->trapezoid_prog;
@@ -1245,7 +1372,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)
-	   || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */
+	     || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */
 		DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n");
 		return FALSE;
 	}
@@ -1260,155 +1387,153 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 
-	/* Bind all the uniform vars .*/
-	x_per_pix_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "x_per_pix");
-	y_per_pix_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "y_per_pix");
-	trap_top_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_top");
-	trap_bottom_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_bottom");
-	trap_left_x_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_x");
-	trap_left_y_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_y");
-	trap_left_slope_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_slope");
-	trap_left_vertical_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_vertical");
-	trap_right_x_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_x");
-	trap_right_y_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_y");
-	trap_right_slope_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_slope");
-	trap_right_vertical_uniform_location =
-	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_vertical");
-
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
 	pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
 
 	width = (float)(bounds->x2 - bounds->x1);
 	height = (float)(bounds->y2 - bounds->y1);
-	width_fix = IntToxFixed((bounds->x2 - bounds->x1));
-	height_fix = IntToxFixed((bounds->y2 - bounds->y1));
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
 	/* Now draw the Trapezoid mask. */
 	dispatch->glUseProgram(trapezoid_prog);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-	        GL_FALSE, 0, vertices);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-	        GL_FALSE, 0, tex_vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
 	dispatch->glEnable(GL_BLEND);
 	dispatch->glBlendFunc(GL_ONE, GL_ONE);
 
-	for (i = 0; i < ntrap; i++) {
-		ptrap = traps + i;
-
-		DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
-		       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
-		       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
-		       xFixedToInt(ptrap->top), ptrap->top,
-		       xFixedToInt(ptrap->bottom), ptrap->bottom,
-		       xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x,
-		       xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y,
-		       xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x,
-		       xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y,
-		       xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x,
-		       xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y,
-		       xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x,
-		       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
-
-		miTrapezoidBounds(1, ptrap, &one_trap_bound);
-		glamor_set_tcoords_tri_strip((pixmap_priv->base.pixmap->drawable.width),
-		                             (pixmap_priv->base.pixmap->drawable.height),
-		                             (one_trap_bound.x1),
-		                             (one_trap_bound.y1),
-		                             (one_trap_bound.x2),
-		                             (one_trap_bound.y2),
-		                             glamor_priv->yInverted, tex_vertices);
-
-		/* Need to rebase. */
-		one_trap_bound.x1 -= bounds->x1;
-		one_trap_bound.x2 -= bounds->x1;
-		one_trap_bound.y1 -= bounds->y1;
-		one_trap_bound.y2 -= bounds->y1;
-		glamor_set_normalize_vcoords_tri_strip(xscale, yscale,
-		        one_trap_bound.x1, one_trap_bound.y1,
-		        one_trap_bound.x2, one_trap_bound.y2,
-		        glamor_priv->yInverted, vertices);
-
-		DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
-		       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-		       vertices[0], vertices[1], vertices[2], vertices[3],
-		       vertices[4], vertices[5], vertices[6], vertices[7]);
-		DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
-		       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-		       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
-		       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
-
-		if (ptrap->left.p1.x == ptrap->left.p2.x) {
-			left_slope = 0.0;
-			dispatch->glUniform1i(trap_left_vertical_uniform_location, 1);
-		} else {
-			left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y))
-			             / ((float)(ptrap->left.p1.x - ptrap->left.p2.x));
-			dispatch->glUniform1i(trap_left_vertical_uniform_location, 0);
+	nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
+
+	for (i = 0; i < ntrap;) {
+		int mrect;
+		int stride;
+
+		mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i);
+		glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
+		stride = glamor_priv->vb_stride / sizeof(float);
+
+		for (j = 0; j < mrect; j++) {
+			ptrap = traps + i + j;
+
+			DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
+			       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
+			       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
+			       xFixedToInt(ptrap->top), ptrap->top,
+			       xFixedToInt(ptrap->bottom), ptrap->bottom,
+			       xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x,
+			       xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y,
+			       xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x,
+			       xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y,
+			       xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x,
+			       xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y,
+			       xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x,
+			       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
+
+			miTrapezoidBounds(1, ptrap, &one_trap_bound);
+
+			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset) + 2;
+			glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
+			        (pixmap_priv->base.pixmap->drawable.height),
+			        (one_trap_bound.x1),
+			        (one_trap_bound.y1),
+			        (one_trap_bound.x2),
+			        (one_trap_bound.y2),
+			        glamor_priv->yInverted, vertices, stride);
+			DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+			       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+			       vertices[0], vertices[1],
+			       vertices[1*stride], vertices[1*stride + 1],
+			       vertices[2*stride], vertices[2*stride + 1],
+			       vertices[3*stride], vertices[3*stride + 1]);
+
+			/* Need to rebase. */
+			one_trap_bound.x1 -= bounds->x1;
+			one_trap_bound.x2 -= bounds->x1;
+			one_trap_bound.y1 -= bounds->y1;
+			one_trap_bound.y2 -= bounds->y1;
+
+			vertices -= 2;
+
+			glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale,
+			        one_trap_bound.x1, one_trap_bound.y1,
+			        one_trap_bound.x2, one_trap_bound.y2,
+			        glamor_priv->yInverted, vertices, stride);
+			DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+			       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+			       vertices[0], vertices[1],
+			       vertices[1*stride], vertices[1*stride + 1],
+			       vertices[2*stride], vertices[2*stride + 1],
+			       vertices[3*stride], vertices[3*stride + 1]);
+			vertices += 4;
+
+			/* Set the top and bottom. */
+			params[0] = ((float)ptrap->top) / 65536;
+			params[1] = ((float)ptrap->bottom) / 65536;
+			glamor_set_const_ext(params, 2, vertices, 4, stride);
+			vertices += 2;
+
+			/* Set the left params. */
+			params[0] = ((float)ptrap->left.p1.x) / 65536;
+			params[1] = ((float)ptrap->left.p1.y) / 65536;
+
+			if (ptrap->left.p1.x == ptrap->left.p2.x) {
+				left_slope = 0.0;
+				params[3] = 1.0;
+			} else {
+				left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y))
+				             / ((float)(ptrap->left.p1.x - ptrap->left.p2.x));
+				params[3] = 0.0;
+			}
+			params[2] = left_slope;
+			glamor_set_const_ext(params, 4, vertices, 4, stride);
+			vertices += 4;
+
+			/* Set the left params. */
+			params[0] = ((float)ptrap->right.p1.x) / 65536;
+			params[1] = ((float)ptrap->right.p1.y) / 65536;
+
+			if (ptrap->right.p1.x == ptrap->right.p2.x) {
+				right_slope = 0.0;
+				params[3] = 1.0;
+			} else {
+				right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y))
+				              / ((float)(ptrap->right.p1.x - ptrap->right.p2.x));
+				params[3] = 0.0;
+			}
+			params[2] = right_slope;
+			glamor_set_const_ext(params, 4, vertices, 4, stride);
+
+			DEBUGF("trap_top = %f, trap_bottom = %f, "
+			       "trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
+			       "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n",
+			       ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536,
+			       ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536,
+			       left_slope,
+			       ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536,
+			       right_slope);
+
+			glamor_priv->render_nr_verts += 4;
+			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
 		}
-		dispatch->glUniform1f(trap_left_slope_uniform_location, left_slope);
 
-		if (ptrap->right.p1.x == ptrap->right.p2.x) {
-			right_slope = 0.0;
-			dispatch->glUniform1i(trap_right_vertical_uniform_location, 1);
-		} else {
-			right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y))
-			              / ((float)(ptrap->right.p1.x - ptrap->right.p2.x));
-			dispatch->glUniform1i(trap_right_vertical_uniform_location, 0);
-		}
-		dispatch->glUniform1f(trap_right_slope_uniform_location, right_slope);
-
-		dispatch->glUniform1f(x_per_pix_uniform_location,
-		        ((float)width_fix) / (65536 * width));
-		dispatch->glUniform1f(y_per_pix_uniform_location,
-		        ((float)height_fix) / (65536 * height));
-
-		dispatch->glUniform1f(trap_top_uniform_location,
-		        ((float)ptrap->top) / 65536);
-		dispatch->glUniform1f(trap_bottom_uniform_location,
-		        ((float)ptrap->bottom) / 65536);
-
-		dispatch->glUniform1f(trap_left_x_uniform_location,
-		        ((float)ptrap->left.p1.x) / 65536);
-		dispatch->glUniform1f(trap_left_y_uniform_location,
-		        ((float)ptrap->left.p1.y) / 65536);
-		dispatch->glUniform1f(trap_right_x_uniform_location,
-		        ((float)ptrap->right.p1.x) / 65536);
-		dispatch->glUniform1f(trap_right_y_uniform_location,
-		        ((float)ptrap->right.p1.y) / 65536);
-
-		DEBUGF("x_per_pix = %f, y_per_pix = %f, trap_top = %f, trap_bottom = %f, "
-		       "trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
-		       "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n",
-		       ((float)width_fix) / (65536*width), ((float)height_fix) / (65536*height),
-		       ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536,
-		       ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536,
-		       left_slope,
-		       ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536,
-		       right_slope);
+		i += mrect;
 
 		/* Now rendering. */
-		dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+		if (!glamor_priv->render_nr_verts)
+			continue;
+
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+		else {
+			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+			dispatch->glBufferData(GL_ARRAY_BUFFER,
+			        glamor_priv->vbo_offset,
+			        glamor_priv->vb, GL_DYNAMIC_DRAW);
+		}
+
+		dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
+		        GL_UNSIGNED_SHORT, NULL);
 	}
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1417,6 +1542,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	dispatch->glDisable(GL_BLEND);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 	dispatch->glUseProgram(0);
 	glamor_put_dispatch(glamor_priv);
 	return TRUE;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index eb2e202..6eef722 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -629,6 +629,25 @@
 	(vertices)[7] = (vertices)[5];				\
     } while(0)
 
+#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2,	\
+			       yInverted, vertices, stride)	\
+    do {							\
+	(vertices)[0] = (x1);					\
+	(vertices)[1*stride] = (x2);				\
+	(vertices)[2*stride] = (vertices)[1*stride];		\
+	(vertices)[3*stride] = (vertices)[0];			\
+	if (likely(yInverted)) {				\
+	    (vertices)[1] = (y1);				\
+	    (vertices)[2*stride + 1] = (y2);			\
+	}							\
+	else {							\
+	    (vertices)[1] = height - (y2);			\
+	    (vertices)[2*stride + 1] = height - (y1);		\
+	}							\
+	(vertices)[1*stride + 1] = (vertices)[1];		\
+	(vertices)[3*stride + 1] = (vertices)[2*stride + 1];	\
+    } while(0)
+
 #define glamor_set_normalize_one_vcoord(xscale, yscale, x, y,		\
 					yInverted, vertices)		\
     do {								\
@@ -713,6 +732,16 @@
                                      yInverted, vertices, 2);		\
   } while(0)
 
+#define glamor_set_const_ext(params, nparam, vertices, nverts, stride)	\
+    do {								\
+	int i = 0, j = 0;						\
+	for(; i < nverts; i++) {					\
+	    for(j = 0; j < nparam; j++) {				\
+		vertices[stride*i + j] = params[j];			\
+	    }								\
+	}								\
+    } while(0)
+
 #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale,		\
 					       x1, y1, x2, y2,		\
 					       yInverted, vertices)	\
commit 9dff3378e5c39b346985924f9ab6291069cc7b6e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jul 16 17:27:22 2012 +0800

    Added the missed header file for xorg 1.13 compat.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/compat-api.h b/glamor/compat-api.h
new file mode 100644
index 0000000..1608478
--- /dev/null
+++ b/glamor/compat-api.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Author: Dave Airlie <airlied at redhat.com>
+ */
+
+/* this file provides API compat between server post 1.13 and pre it,
+   it should be reused inside as many drivers as possible */
+#ifndef COMPAT_API_H
+#define COMPAT_API_H
+
+#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR
+#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum]
+#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p
+#endif
+
+#ifndef XF86_HAS_SCRN_CONV
+#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum]
+#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex]
+#endif
+
+#ifndef XF86_SCRN_INTERFACE
+
+#define SCRN_ARG_TYPE int
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = xf86Screens[(arg1)]
+
+#define SCREEN_ARG_TYPE int
+#define SCREEN_PTR(arg1) ScreenPtr screen = screenInfo.screens[(arg1)]
+
+#define SCREEN_INIT_ARGS_DECL int scrnIndex, ScreenPtr screen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer timeout, pointer read_mask
+#define BLOCKHANDLER_ARGS arg, blockData, timeout, read_mask
+
+#define WAKEUPHANDLER_ARGS_DECL int arg, pointer wakeupData, unsigned long result, pointer read_mask
+#define WAKEUPHANDLER_ARGS arg, wakeupData, result, read_mask
+
+#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr screen
+#define CLOSE_SCREEN_ARGS scrnIndex, screen
+
+#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags
+#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0
+
+#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags
+#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0
+
+#define FREE_SCREEN_ARGS_DECL int arg, int flags
+#define FREE_SCREEN_ARGS	arg, flags
+
+#define VT_FUNC_ARGS_DECL int arg, int flags
+#define VT_FUNC_ARGS(flags) scrn->scrnIndex, (flags)
+
+#define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex)
+
+#else
+#define SCRN_ARG_TYPE ScrnInfoPtr
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = (arg1)
+
+#define SCREEN_ARG_TYPE ScreenPtr
+#define SCREEN_PTR(arg1) ScreenPtr screen = (arg1)
+
+#define SCREEN_INIT_ARGS_DECL ScreenPtr screen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer timeout, pointer read_mask
+#define BLOCKHANDLER_ARGS arg, timeout, read_mask
+
+#define WAKEUPHANDLER_ARGS_DECL ScreenPtr arg, unsigned long result, pointer read_mask
+#define WAKEUPHANDLER_ARGS arg, result, read_mask
+
+#define CLOSE_SCREEN_ARGS_DECL ScreenPtr screen
+#define CLOSE_SCREEN_ARGS screen
+
+#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y
+#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y
+
+#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode
+#define SWITCH_MODE_ARGS(arg, m) arg, m
+
+#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg
+#define FREE_SCREEN_ARGS	arg
+
+#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg
+#define VT_FUNC_ARGS(flags) scrn
+
+#define XF86_ENABLEDISABLEFB_ARG(x) (x)
+
+#endif
+#endif
commit bc1b412b3b0bb716702ec89ae512f2b5ec62c17a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jul 16 11:25:09 2012 +0800

    Synch with xorg 1.13 change.
    
    As xorg 1.13 change the scrn interaces and remove those
    global arrays. Some API change cause we can't build. Now
    fix it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8b7dc93..d51811e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -491,7 +491,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
 }
 
 Bool
-glamor_close_screen(int idx, ScreenPtr screen)
+glamor_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
 	glamor_screen_private *glamor_priv;
 	PixmapPtr screen_pixmap;
@@ -533,7 +533,7 @@ glamor_close_screen(int idx, ScreenPtr screen)
 
 	glamor_release_screen_priv(screen);
 
-	return screen->CloseScreen(idx, screen);
+	return screen->CloseScreen(CLOSE_SCREEN_ARGS);
 }
 
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index fe3e4f8..bafd543 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -30,9 +30,8 @@
 #define GLAMOR_H
 
 #include <scrnintstr.h>
-#ifdef GLAMOR_FOR_XORG
+#include <xf86.h>
 #include <xf86str.h>
-#endif
 #include <pixmapstr.h>
 #include <gcstruct.h>
 #include <picturestr.h>
@@ -117,7 +116,11 @@ extern _X_EXPORT void glamor_fini(ScreenPtr screen);
  * screen pixmap which must be a glamor pixmap and requires
  * the internal data structure still exist at that time.
  * Otherwise, the glamor internal structure will not be freed.*/
-extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen);
+#ifndef XF86_SCRN_INTERFACE
+extern _X_EXPORT Bool glamor_close_screen(int scrnIndex, ScreenPtr screen);
+#else
+extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen);
+#endif
 
 
 /* Let glamor to know the screen's fbo. The low level
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 07acf1a..da9283b 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -59,6 +59,7 @@
 #include <EGL/eglext.h>
 
 #include "glamor.h"
+#include "compat-api.h"
 #include "glamor_gl_dispatch.h"
 #ifdef GLX_USE_SHARED_DISPATCH
 #include "glapi.h"
@@ -365,7 +366,7 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 }
 
 static Bool
-glamor_egl_close_screen(int idx, ScreenPtr screen)
+glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 {
 	ScrnInfoPtr scrn;
 	struct glamor_egl_screen_private *glamor_egl;
@@ -391,7 +392,7 @@ glamor_egl_close_screen(int idx, ScreenPtr screen)
 
 	screen->CloseScreen = glamor_egl->saved_close_screen;
 
-	return screen->CloseScreen(idx, screen);
+	return screen->CloseScreen(CLOSE_SCREEN_ARGS);
 }
 
 static Bool
@@ -430,10 +431,15 @@ glamor_egl_screen_init(ScreenPtr screen)
 }
 
 static void
-glamor_egl_free_screen(int scrnIndex, int flags)
+glamor_egl_free_screen(FREE_SCREEN_ARGS_DECL)
 {
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	ScrnInfoPtr scrn;
 	struct glamor_egl_screen_private *glamor_egl;
+#ifndef XF86_SCRN_INTERFACE
+	scrn = xf86Screens[arg];
+#else
+	scrn = arg;
+#endif
 
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 	if (glamor_egl != NULL) {
@@ -447,7 +453,7 @@ glamor_egl_free_screen(int scrnIndex, int flags)
 #endif
 		scrn->FreeScreen = glamor_egl->saved_free_screen;
 		free(glamor_egl);
-		scrn->FreeScreen(scrnIndex, flags);
+		scrn->FreeScreen(FREE_SCREEN_ARGS);
 	}
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3b64c31..11d09c4 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -38,6 +38,7 @@
 #define NDEBUG
 #endif
 #include "glamor.h"
+#include "compat-api.h"
 
 #define GL_GLEXT_PROTOTYPES
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index a282985..eb2e202 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -798,7 +798,10 @@ region_is_empty(pixman_region16_t *region)
 	return region->data && region->data->numRects == 0;
 }
 
+#ifndef ARRAY_SIZE
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 #define MAX(a,b)	((a) > (b) ? (a) : (b))
commit 4c27ca4700e4ba4ae19d77377a7776eb32f74647
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jul 13 09:20:02 2012 +0800

    gles2: Fixed the compilation problem and some bugs.
    
    Previous patch doesn't set the offset to zero for GLESv2
    path. Now fix it.
    
    This patch also fix a minor problem in pixmap uploading
    preparation. If the revert is not REVERT_NORMAL, then we
    don't need to prepare a fbo for it. As current mesa i965
    gles2 driver doesn't support to set a A8 texture as a fbo
    target, we must fix this problem. As some A1/A8 picture
    need to be uploaded, this is the only place a A8 texture
    may be attached to a fbo.
    
    This patch also enable the shader gradient for GLESv2.
    The reason we disable it before is that some glsl linker
    doesn't support link different objects which have cross
    reference. Now we don't have that problem.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h
index d60c696..1f7206b 100644
--- a/glamor/glamor_glext.h
+++ b/glamor/glamor_glext.h
@@ -57,5 +57,8 @@
 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
 
 #define GL_PACK_INVERT_MESA               0x8758
+#define GL_MAP_UNSYNCHRONIZED_BIT         0x0020
+#define GL_MAP_READ_BIT                   0x0001
+#define GL_MAP_WRITE_BIT                  0x0002
 
 #endif
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 10066a6..f3a2a87 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -612,7 +612,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 		return 0;
 
 	if (!(no_alpha
-	      || (revert != REVERT_NONE)
+	      || (revert == REVERT_NORMAL)
 	      || (swap_rb != SWAP_NONE_UPLOADING)
 	      || !glamor_priv->yInverted)) {
 		/* We don't need a fbo, a simple texture uploading should work. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0703c07..3b64c31 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -1014,10 +1014,8 @@ glamor_composite_rectangles(CARD8	 op,
  * this will increase performance obviously. */
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-#ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
 //#define GLAMOR_TRAPEZOID_SHADER
-#endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #define WALKAROUND_LARGE_TEXTURE_MAP
 #if 0
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b504686..6dacd44 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -753,7 +753,9 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 							     GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
 		assert(glamor_priv->vb != NULL);
 		glamor_priv->vb -= glamor_priv->vbo_offset;
-	}
+	} else
+		glamor_priv->vbo_offset = 0;
+
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
commit 006fe0e66df4b214ca5c50241b3cca22d31161df
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Jul 12 18:57:06 2012 +0800

    Stream vertex data to VBOs.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d986e9a..b504686 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -725,34 +725,34 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 	int vert_size;
-	Bool need_new_buffer = FALSE;
 
-	glamor_priv->vbo_offset = 0;
 	glamor_priv->render_nr_verts = 0;
-	vert_size = n_verts * sizeof(float) * 2;
-
-	if (glamor_priv->vbo_size < vert_size) {
-		glamor_priv->vbo_size = vert_size;
-		need_new_buffer = TRUE;
-	}
-
 	glamor_priv->vb_stride = 2 * sizeof(float);
 	if (glamor_priv->has_source_coords)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 	if (glamor_priv->has_mask_coords)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 
+	vert_size = n_verts * glamor_priv->vb_stride;
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		if (need_new_buffer)
+		if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
+			glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
+				glamor_priv->vb_stride;
+			glamor_priv->vbo_offset = 0;
 			dispatch->glBufferData(GL_ARRAY_BUFFER,
-					       vert_size,
-					       NULL, GL_DYNAMIC_DRAW);
-		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, 0,
-						vert_size,
-						GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+					       glamor_priv->vbo_size,
+					       NULL, GL_STREAM_DRAW);
+		}
+
+		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER,
+							     glamor_priv->vbo_offset,
+							     vert_size,
+							     GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
 		assert(glamor_priv->vb != NULL);
+		glamor_priv->vb -= glamor_priv->vbo_offset;
 	}
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
commit 551ca11c77d0524ceb37eb26caf0c25e4d7d806f
Author: Michel D=C3=A4nzer <michel.daenzer at amd.com>
Date:   Wed Jul 11 15:01:15 2012 +0800

    Fix translation of clip region for composite fallback.
    
    Fixes incorrectly clipped rendering. E.g. the cursor in Evolution
    composer windows became invisible.
    
    Signed-off-by: Michel Daenzer <michel.daenzer at amd.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 60fc2f6..d986e9a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1869,13 +1869,13 @@ fail:
 					      width, height, access);			\
 	if (sub_ ##p ##_pixmap != NULL) {						\
 		saved_ ##p ##_drawable = p->pDrawable;					\
-		p->pDrawable = &sub_ ##p ##_pixmap->drawable;				\
 		saved_ ##p ##_x = x_ ##p;						\
 		saved_ ##p ##_y = y_ ##p;						\
 		if (p->pCompositeClip)							\
 			pixman_region_translate (p->pCompositeClip,			\
 						 -p->pDrawable->x - x_ ##p,		\
 						 -p->pDrawable->y - y_ ##p);		\
+		p->pDrawable = &sub_ ##p ##_pixmap->drawable;				\
 		x_ ##p = 0;								\
 		y_ ##p = 0;								\
 	} } while(0)
@@ -1910,11 +1910,11 @@ full_fallback:
 	if (sub_ ##p ##_pixmap != NULL) {					\
 		x_ ##p = saved_ ##p ##_x;					\
 		y_ ##p = saved_ ##p ##_y;					\
+		p->pDrawable = saved_ ##p ##_drawable;				\
 		if (p->pCompositeClip)						\
 			pixman_region_translate (p->pCompositeClip,		\
 						 p->pDrawable->x + x_ ##p,	\
 						 p->pDrawable->y + y_ ##p);	\
-		p->pDrawable = saved_ ##p ##_drawable;				\
 		glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap,		\
 				      x_ ##p + p ##_x_off + p->pDrawable->x,	\
 				      y_ ##p + p ##_y_off + p->pDrawable->y,	\
commit 88c317fb1e6a9056acab4a76c0ee0bf283e001ce
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 4 17:59:25 2012 +0800

    glamor_glyphs: Don't merge extents for different lists.
    
    If we merge all lists's extent together, than we may have
    some fail overlap checking. Here is a simple:
    A E
    B F
    C
    D
    
    The first list has vertical "ABCD". And the second list
    has two char "EF". When detecting E, it can successfully
    find it doesn't overlap with previous glyphs. But after
    that, the original code will merge the previous extent with
    E's extent, then the extent will cover "F", so when detecting
    F, it will be treated as overlapped.
    
    We can simply solve this issue by not merge extent from different
    list. We can union different list's extent to a global region.
    And then do the intersect checkint between that region and
    current glyph extent, then we can avoid that fail checking.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index f63feac..bab2c24 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -616,7 +616,6 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
 		     int *head_y,
 		     int *fixed_cnt,
 		     int type,
-		     GlyphListPtr prev_list,
 		     BoxPtr prev_extents
 		     )
 {
@@ -708,26 +707,39 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 	int x1, x2, y1, y2;
 	int n;
 	int x, y;
-	BoxRec extents, prev_extents;
-	Bool first = TRUE;
+	BoxPtr extents;
+	BoxRec prev_extents;
+	Bool first = TRUE, first_list = TRUE;
+	Bool need_free_list_region = FALSE;
 	Bool need_free_fixed_list = FALSE;
 	struct glamor_glyph *priv;
 	Bool in_non_intersected_list = -1;
-	GlyphListPtr head_list, prev_list, saved_list;
+	GlyphListPtr head_list, saved_list;
 	int head_x, head_y, head_pos;
 	int fixed_cnt = 0;
 	GlyphPtr *head_glyphs;
 	GlyphListPtr cur_list = list;
+	RegionRec list_region;
+	RegionRec current_region;
+	BoxRec current_box;
+
+	if (nlist > 1) {
+		pixman_region_init(&list_region);
+		need_free_list_region = TRUE;
+	}
+
+	pixman_region_init(&current_region);
+
+	extents = pixman_region_extents(&current_region);
 
 	saved_list = list;
 	x = 0;
 	y = 0;
-	extents.x1 = 0;
-	extents.y1 = 0;
-	extents.x2 = 0;
-	extents.y2 = 0;
-	prev_extents = extents;
-	prev_list = list;
+	extents->x1 = 0;
+	extents->y1 = 0;
+	extents->x2 = 0;
+	extents->y2 = 0;
+
 	head_list = list;
 	DEBUGF("has %d lists.\n", nlist);
 	while (nlist--) {
@@ -742,6 +754,18 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 		left_to_right = TRUE;
 		cur_list = list++;
 
+		if (unlikely(!first_list)) {
+			pixman_region_init_with_extents(&current_region, extents);
+			pixman_region_union(&list_region, &list_region, &current_region);
+			first = TRUE;
+		} else {
+			head_list = cur_list;
+			head_pos = cur_list->len - n;
+			head_x = x;
+			head_y = y;
+			head_glyphs = glyphs;
+		}
+
 		DEBUGF("current list %p has %d glyphs\n", cur_list, n);
 		while (n--) {
 			GlyphPtr glyph = *glyphs++;
@@ -777,17 +801,14 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 				y2 = MAXSHORT;
 
 			if (first) {
-				extents.x1 = x1;
-				extents.y1 = y1;
-				extents.x2 = x2;
-				extents.y2 = y2;
+				extents->x1 = x1;
+				extents->y1 = y1;
+				extents->x2 = x2;
+				extents->y2 = y2;
+
+				prev_extents = *extents;
 
 				first = FALSE;
-				head_list = cur_list;
-				head_pos = cur_list->len - n - 1;
-				head_x = x;
-				head_y = y;
-				head_glyphs = glyphs - 1;
 				if (check_fake_overlap && priv
 				    && priv->has_edge_map && glyph->info.yOff == 0) {
 					left_box.x1 = x1;
@@ -802,10 +823,20 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 					has_right_edge_box = TRUE;
 				}
 			} else {
+				if (unlikely(!first_list)) {
+					current_box.x1 = x1;
+					current_box.y1 = y1;
+					current_box.x2 = x2;
+					current_box.y2 = y2;
+					if (pixman_region_contains_rectangle(&list_region, &current_box) != PIXMAN_REGION_OUT) {
+						need_free_fixed_list = TRUE;
+						goto done;
+					}
+				}
 
-				if (x1 < extents.x2 && x2 > extents.x1
-				    && y1 < extents.y2
-				    && y2 > extents.y1) {
+				if (x1 < extents->x2 && x2 > extents->x1
+				    && y1 < extents->y2
+				    && y2 > extents->y1) {
 
 					if (check_fake_overlap && (has_left_edge_box || has_right_edge_box)
 					    && priv->has_edge_map && glyph->info.yOff == 0) {
@@ -814,7 +845,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 
 						left_dx = has_left_edge_box ? 1 : 0;
 						right_dx = has_right_edge_box ? 1 : 0;
-						if (x1 + 1 < extents.x2 - right_dx && x2 - 1 > extents.x1 + left_dx)
+						if (x1 + 1 < extents->x2 - right_dx && x2 - 1 > extents->x1 + left_dx)
 							goto real_intersected;
 
 						if (left_to_right && has_right_edge_box) {
@@ -851,7 +882,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 									goto real_intersected;
 							}
 						} else {
-							if (x1 < extents.x2 && x1 + 2 > extents.x1)
+							if (x1 < extents->x2 && x1 + 2 > extents->x1)
 								goto real_intersected;
 						}
 						goto non_intersected;
@@ -874,7 +905,6 @@ real_intersected:
 									     &head_x,
 									     &head_y, &fixed_cnt,
 									     NON_INTERSECTED,
-									     prev_list,
 									     &prev_extents
 									     )){
 								need_free_fixed_list = TRUE;
@@ -904,7 +934,6 @@ non_intersected:
 								     &head_x,
 								     &head_y, &fixed_cnt,
 								     INTERSECTED,
-								     prev_list,
 								     &prev_extents
 								     )) {
 							need_free_fixed_list = TRUE;
@@ -913,12 +942,12 @@ non_intersected:
 					}
 					in_non_intersected_list = 1;
 				}
-				prev_extents = extents;
+				prev_extents = *extents;
 			}
 
 			if (check_fake_overlap && priv
 			    && priv->has_edge_map && glyph->info.yOff == 0) {
-				if (!has_left_edge_box || x1 < extents.x1) {
+				if (!has_left_edge_box || x1 < extents->x1) {
 					left_box.x1 = x1;
 					left_box.x2 = x1 + 1;
 					left_box.y1 = y1;
@@ -926,7 +955,7 @@ non_intersected:
 					left_priv = priv;
 				}
 
-				if (!has_right_edge_box || x2 > extents.x2) {
+				if (!has_right_edge_box || x2 > extents->x2) {
 					right_box.x1 = x2 - 2;
 					right_box.x2 = x2 - 1;
 					right_box.y1 = y1;
@@ -935,20 +964,20 @@ non_intersected:
 				}
 			}
 
-			if (x1 < extents.x1)
-				extents.x1 = x1;
-			if (x2 > extents.x2)
-				extents.x2 = x2;
+			if (x1 < extents->x1)
+				extents->x1 = x1;
+			if (x2 > extents->x2)
+				extents->x2 = x2;
 
-			if (y1 < extents.y1)
-				extents.y1 = y1;
-			if (y2 > extents.y2)
-				extents.y2 = y2;
+			if (y1 < extents->y1)
+				extents->y1 = y1;
+			if (y2 > extents->y2)
+				extents->y2 = y2;
 
 			x += glyph->info.xOff;
 			y += glyph->info.yOff;
-			prev_list = cur_list;
 		}
+		first_list = FALSE;
 	}
 
 	if (in_non_intersected_list == 0 && fixed_cnt == 0) {
@@ -973,7 +1002,6 @@ non_intersected:
 				     &head_x,
 				     &head_y, &fixed_cnt,
 				     (!in_non_intersected_list) | 0x80,
-				     prev_list,
 				     &prev_extents
 				     )) {
 			need_free_fixed_list = TRUE;
@@ -982,6 +1010,10 @@ non_intersected:
 	}
 
 done:
+	if (need_free_list_region)
+		pixman_region_fini(&list_region);
+	pixman_region_fini(&current_region);
+
 	if (need_free_fixed_list && fixed_cnt >= 0) {
 		while(fixed_cnt--) {
 			free(fixed_list[fixed_cnt].list);
commit 32a7438bf79573100862ad91c5722d12623a8bf9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jul 3 18:24:07 2012 +0800

    glamor_copyarea: Use blitcopy if current state is not render.
    
    Practically, for pure 2D blit, the blit copy is much faster
    than textured copy. For the x11perf copywinwin100, it's about
    3x faster. But if we have heavy rendering/compositing, then use
    textured copy will get much better (>30%)performance for most
    of the cases.
    
    So we simply add a data element to track current state. For
    rendering state we use textured copy, otherwise, we use blit
    copy.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 01f6a9a..8b7dc93 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -225,6 +225,11 @@ glamor_block_handler(ScreenPtr screen)
 	dispatch->glFlush();
 	glamor_fbo_expire(glamor_priv);
 	glamor_put_dispatch(glamor_priv);
+	if (glamor_priv->state == RENDER_STATE
+	    && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
+		glamor_priv->state = IDLE_STATE;
+		glamor_priv->render_idle_cnt = 0;
+	}
 }
 
 static void
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index ee6f812..2994179 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -137,6 +137,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 		}
 	}
 	glamor_put_dispatch(glamor_priv);
+	glamor_priv->state = BLIT_STATE;
 	return TRUE;
 }
 #endif
@@ -257,6 +258,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	dispatch->glUseProgram(0);
 	/* The source texture is bound to a fbo, we have to flush it here. */
 	glamor_put_dispatch(glamor_priv);
+	glamor_priv->state = RENDER_STATE;
+	glamor_priv->render_idle_cnt = 0;
 	return TRUE;
 }
 
@@ -315,7 +318,7 @@ __glamor_copy_n_to_n(DrawablePtr src,
 		dx, dy,
 		src_pixmap, dst_pixmap);
 #ifndef GLAMOR_GLES2
-	if ((overlaped
+	if ((overlaped || glamor_priv->state != RENDER_STATE
 	     || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
 	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
 					   dy)) {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 2163c94..1d81aea 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -259,47 +259,8 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
 	glamor_put_dispatch(glamor_priv);
-}
-
-static void
-_glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	      float *color)
-{
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch;
-	int x1 = x;
-	int x2 = x + width;
-	int y1 = y;
-	int y2 = y + height;
-	float vertices[8];
-	GLfloat xscale, yscale;
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glUseProgram(glamor_priv->solid_prog);
-
-	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
-			       1, color);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
-
-	glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
-				     x1, y1,
-				     x2, y2,
-				     glamor_priv->yInverted, vertices);
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
+	glamor_priv->state = RENDER_STATE;
+	glamor_priv->render_idle_cnt = 0;
 }
 
 Bool
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a7d4fe7..0703c07 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -199,7 +199,6 @@ typedef struct {
 	uint16_t evict;
 } glamor_glyph_cache_t;
 
-
 #include "glamor_gl_dispatch.h"
 
 struct glamor_saved_procs { 
@@ -235,6 +234,11 @@ struct glamor_saved_procs {
 #define GLAMOR_TICK_AFTER(t0, t1) 	\
 	(((int)(t1) - (int)(t0)) < 0)
 
+#define IDLE_STATE 0
+#define RENDER_STATE 1
+#define BLIT_STATE 2
+#define RENDER_IDEL_MAX 32
+
 typedef struct glamor_screen_private {
 	struct glamor_gl_dispatch _dispatch;
 	int yInverted;
@@ -296,6 +300,8 @@ typedef struct glamor_screen_private {
 	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
 	int delayed_fallback_pending;
 	int flags;
+	int state;
+	unsigned int render_idle_cnt;
 	ScreenPtr screen;
 } glamor_screen_private;
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b82c7c3..60fc2f6 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1444,6 +1444,8 @@ glamor_composite_with_shader(CARD8 op,
 #endif
 	DEBUGF("finish rendering.\n");
 	dispatch->glUseProgram(0);
+	glamor_priv->state = RENDER_STATE;
+	glamor_priv->render_idle_cnt = 0;
 	if (saved_source_format)
 		source->format = saved_source_format;
 	glamor_put_dispatch(glamor_priv);
@@ -1665,6 +1667,7 @@ glamor_composite_clipped_region(CARD8 op,
 			prect[i].y_dst = box[i].y1;
 			prect[i].width = box[i].x2 - box[i].x1;
 			prect[i].height = box[i].y2 - box[i].y1;
+			DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
 		}
 		ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
 						  temp_src_priv, temp_mask_priv,
@@ -1722,7 +1725,6 @@ _glamor_composite(CARD8 op,
 	DrawablePtr saved_source_drawable;
 	DrawablePtr saved_mask_drawable;
 	int force_clip = 0;
-
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
 	if (source->pDrawable) {
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 7809e8b..60486cf 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -185,6 +185,9 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
 	glamor_put_dispatch(glamor_priv);
+
+	glamor_priv->state = RENDER_STATE;
+	glamor_priv->render_idle_cnt = 0;
 }
 
 Bool
commit 0706423bcfd7a589bab3b41fe9f13d0b636ecdef
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jul 3 18:11:12 2012 +0800

    glamor_glyphs: Use cache picture to store mask picture if possible.
    
     By default, mask picture is newly created, and each time we need to
     clear the whole mask picture, and then composite glyphs to the mask
     picture and then composite the mask picture to destination.
    
     Testing results shows that the filling of the mask picture takes a
     big portion of the rendering time. As we don't really need to clear
     the whole region, we just need to clear the real overlapped region.
    
     This commit is to solve this issue. We split a large glyphs list to
     serval lists and each list is non-overlapped or overlapped.
    
     we can reduce the length of overlapped glyphs to do the glyphs_via_mask
     to 2 or 3 glyphs one time for most cases. Thus it give us a case to allocate a
     small portion of the corresponding cache directly as the mask picture.
     Then we can rendering the glyphs to this mask picture, and latter we
     can accumulate the second steps, composite the mask to the dest with
     the other non-overlapped glyphs's rendering process.
     It also make us implement a batch mask cache blocks clearing
     algorithm to avoid too frequently small region clearing.
    
     If there is no any overlapping, this method will not get performance gain.
     If there is some overlapping, then this algorithm can get about 15% performance
     gain.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index c2a750d..f63feac 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -64,8 +64,11 @@
 
 #define CACHE_PICTURE_SIZE 1024
 #define GLYPH_MIN_SIZE 8
-#define GLYPH_MAX_SIZE 64
-#define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
+#define GLYPH_MAX_SIZE	64
+#define GLYPH_CACHE_SIZE ((CACHE_PICTURE_SIZE) * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
+#define MASK_CACHE_MAX_SIZE 32
+#define MASK_CACHE_WIDTH (CACHE_PICTURE_SIZE / MASK_CACHE_MAX_SIZE)
+#define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1)
 
 typedef struct {
 	PicturePtr source;
@@ -78,7 +81,7 @@ struct glamor_glyph {
 	uint16_t x, y;
 	uint16_t size, pos;
 	unsigned long long left_x1_map, left_x2_map;
-	unsigned long long right_x1_map, right_x2_map;  /* Use to check real pixel overlap or not. */
+	unsigned long long right_x1_map, right_x2_map;  /* Use to check real intersect or not. */
 	Bool has_edge_map;
 	Bool cached;
 };
@@ -89,8 +92,6 @@ typedef enum {
 	GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
 } glamor_glyph_cache_result_t;
 
-
-
 #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
 static DevPrivateKeyRec glamor_glyph_key;
 
@@ -100,6 +101,163 @@ glamor_glyph_get_private(GlyphPtr glyph)
 	return (struct glamor_glyph*)glyph->devPrivates;
 }
 
+/*
+ * Mask cache is located at the corresponding cache picture's last row.
+ * and is deadicated for the mask picture when do the glyphs_via_mask.
+ *
+ * As we split the glyphs list according to its overlapped or non-overlapped,
+ * we can reduce the length of glyphs to do the glyphs_via_mask to 2 or 3
+ * glyphs one time for most cases. Thus it give us a case to allocate a
+ * small portion of the corresponding cache directly as the mask picture.
+ * Then we can rendering the glyphs to this mask picture, and latter we
+ * can accumulate the second steps, composite the mask to the dest with
+ * the other non-overlapped glyphs's rendering process.
+ * Another major benefit is we now only need to clear a relatively small mask
+ * region then before. It also make us implement a bunch mask picture clearing
+ * algorithm to avoid too frequently small region clearing.
+ *
+ * If there is no any overlapping, this method will not get performance gain.
+ * If there is some overlapping, then this algorithm can get about 15% performance
+ * gain.
+ */
+
+struct glamor_glyph_mask_cache_entry {
+	int idx;
+	int width;
+	int height;
+	int x;
+	int y;
+};
+
+static struct glamor_glyph_mask_cache {
+	PixmapPtr pixmap;
+	struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
+	unsigned int free_bitmap;
+	unsigned int cleared_bitmap;
+}*mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS] = {NULL};
+
+static void
+clear_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache,
+		     unsigned int clear_mask_bits)
+{
+	unsigned int i = 0;
+	BoxRec box[MASK_CACHE_WIDTH];
+	int box_cnt = 0;
+
+	assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0);
+	for(i = 0; i < MASK_CACHE_WIDTH;i++)
+	{
+		if (clear_mask_bits & (1 << i)) {
+			box[box_cnt].x1 = maskcache->mcache[i].x;
+			box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE;
+			box[box_cnt].y1 = maskcache->mcache[i].y;
+			box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE;
+			box_cnt++;
+		}
+	}
+	glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0);
+	maskcache->cleared_bitmap |= clear_mask_bits;
+}
+
+static void
+clear_mask_cache(struct glamor_glyph_mask_cache *maskcache)
+{
+	int x = 0;
+	int cnt = MASK_CACHE_WIDTH;
+	unsigned int i = 0;
+	struct glamor_glyph_mask_cache_entry *mce;
+	glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
+		     MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0);
+	mce = &maskcache->mcache[0];
+	while(cnt--) {
+		mce->width = 0;
+		mce->height = 0;
+		mce->x = x;
+		mce->y = CACHE_PICTURE_SIZE;
+		mce->idx = i++;
+		x += MASK_CACHE_MAX_SIZE;
+		mce++;
+	}
+	maskcache->free_bitmap = MASK_CACHE_MASK;
+	maskcache->cleared_bitmap = MASK_CACHE_MASK;
+}
+
+static int
+find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask)
+{
+	int idx = 0;
+	unsigned int bits_mask;
+	bits_mask = ((1LL << bits_cnt) - 1);
+
+	if (unlikely(bits_cnt > 56)) {
+		while(bits) {
+			if ((bits & bits_mask) == bits_mask) {
+				*pbits_mask = bits_mask << idx;
+				return idx;
+			}
+			bits >>= 1;
+			idx++;
+		}
+	} else {
+		idx = __fls(bits);
+		while(bits) {
+			unsigned int temp_bits;
+			temp_bits = bits_mask << (idx - bits_cnt + 1);
+			if ((bits & temp_bits) == temp_bits) {
+				*pbits_mask = temp_bits;
+				return (idx - bits_cnt + 1);
+			}
+			/* Find first zero. And clear the tested bit.*/
+			bits &= ~(1LL<<idx);
+			idx = __fls(~bits);
+			bits &= ~((1LL << idx) - 1);
+			idx--;
+		}
+	}
+	return -1;
+}
+
+static struct glamor_glyph_mask_cache_entry *
+get_mask_cache(struct glamor_glyph_mask_cache *maskcache, int blocks)
+{
+	int free_cleared_bit, idx = -1;
+	int retry_cnt = 0;
+	unsigned int bits_mask;
+
+	if (maskcache->free_bitmap == 0)
+		return NULL;
+retry:
+	free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap;
+	if (free_cleared_bit && blocks == 1) {
+		idx = __fls(free_cleared_bit);
+		bits_mask = 1 << idx;
+	} else if (free_cleared_bit && blocks > 1) {
+		idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask);
+	}
+
+	if (idx < 0) {
+		clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap);
+		if (retry_cnt++ > 2)
+			return NULL;
+		goto retry;
+	}
+
+	maskcache->cleared_bitmap &= ~bits_mask;
+	maskcache->free_bitmap &= ~bits_mask;
+	DEBUGF("get idx %d free %x clear %x \n",
+		idx, maskcache->free_bitmap, maskcache->cleared_bitmap);
+	return &maskcache->mcache[idx];
+}
+
+static void
+put_mask_cache_bitmap(struct glamor_glyph_mask_cache *maskcache,
+		       unsigned int bitmap)
+{
+	maskcache->free_bitmap |= bitmap;
+	DEBUGF("put bitmap %x free %x clear %x \n",
+		bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap);
+}
+
 static void
 glamor_unrealize_glyph_caches(ScreenPtr pScreen)
 {
@@ -117,6 +275,9 @@ glamor_unrealize_glyph_caches(ScreenPtr pScreen)
 
 		if (cache->glyphs)
 			free(cache->glyphs);
+
+		if (mask_cache[i])
+			free(mask_cache[i]);
 	}
 	glamor->glyph_cache_initialized = FALSE;
 }
@@ -136,6 +297,7 @@ glamor_glyphs_fini(ScreenPtr pScreen)
  * This function allocates the storage pixmap, and then fills in the
  * rest of the allocated structures for all caches with the given format.
  */
+
 static Bool
 glamor_realize_glyph_caches(ScreenPtr pScreen)
 {
@@ -167,7 +329,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 		/* Now allocate the pixmap and picture */
 		pixmap = pScreen->CreatePixmap(pScreen,
 					      CACHE_PICTURE_SIZE,
-					      CACHE_PICTURE_SIZE, depth,
+					      CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, depth,
 					      0);
 		if (!pixmap)
 			goto bail;
@@ -189,6 +351,9 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 			goto bail;
 
 		cache->evict = rand() % GLYPH_CACHE_SIZE;
+		mask_cache[i] = calloc(1, sizeof(*mask_cache[i]));
+		mask_cache[i]->pixmap = pixmap;
+		clear_mask_cache(mask_cache[i]);
 	}
 	assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
 
@@ -422,43 +587,166 @@ glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
 	return;
 }
 
-
-
 /**
  * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
  * bounding box, which appears to be good enough to catch most cases at least.
  */
+
+#define INTERSECTED_TYPE_MASK 1
+#define NON_INTERSECTED 0
+#define INTERSECTED 1
+
+struct glamor_glyph_list {
+	int nlist;
+	GlyphListPtr list;
+	GlyphPtr *glyphs;
+	int type;
+};
+
 static Bool
+glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
+		     GlyphPtr *cur_glyphs,
+		     GlyphPtr **head_glyphs,
+		     GlyphListPtr cur_list,
+		     int cur_pos, int cur_x, int cur_y,
+		     int x1, int y1, int x2, int y2,
+		     GlyphListPtr *head_list,
+		     int *head_pos,
+		     int *head_x,
+		     int *head_y,
+		     int *fixed_cnt,
+		     int type,
+		     GlyphListPtr prev_list,
+		     BoxPtr prev_extents
+		     )
+{
+	int x_off = 0;
+	int y_off = 0;
+	int n_off = 0;
+	int list_cnt;
+	if (type == NON_INTERSECTED) {
+		if (x1 < prev_extents->x2 && x2 > prev_extents->x1
+		    && y1 < prev_extents->y2 && y2 > prev_extents->y1)
+			return FALSE;
+		x_off = (*(cur_glyphs-1))->info.xOff;
+		y_off = (*(cur_glyphs-1))->info.yOff;
+		n_off = 1;
+	}
+
+	list_cnt = cur_list - *head_list + 1;
+	if (cur_pos <= n_off) {
+		DEBUGF("break at %d n_off %d\n", cur_pos, n_off);
+		list_cnt--;
+		if (cur_pos < n_off) {
+		/* we overlap with previous list's last glyph. */
+			x_off += cur_list->xOff;
+			y_off += cur_list->yOff;
+			cur_list--;
+			cur_pos = cur_list->len;
+			if (cur_pos <= n_off) {
+				list_cnt--;
+			}
+		}
+	}
+	DEBUGF("got %d lists\n", list_cnt);
+	if (list_cnt != 0) {
+		fixed_list->list = malloc(list_cnt * sizeof(*cur_list));
+		memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
+		fixed_list->list[0].xOff = *head_x;
+		fixed_list->list[0].yOff = *head_y;
+		fixed_list->glyphs = *head_glyphs;
+		fixed_list->type = type & INTERSECTED_TYPE_MASK;
+		fixed_list->nlist = list_cnt;
+		if (cur_list != *head_list) {
+			fixed_list->list[0].len = (*head_list)->len - *head_pos;
+			if (cur_pos != n_off)
+			fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
+		} else
+			fixed_list->list[0].len = cur_pos - *head_pos - n_off;
+		while(list_cnt--) {
+			DEBUGF("new fixed list type %d entry len %d x %d y %d"
+				"head_pos %d pos %d list %d has %d glyphs.\n",
+				fixed_list->type, fixed_list->nlist,
+				cur_x, cur_y, *head_pos, cur_pos, i, fixed_list->list[i++].len);
+		}
+		(*fixed_cnt)++;
+	}
+
+	if (type <= INTERSECTED) {
+		*head_list = cur_list;
+		*head_pos = cur_pos - n_off;
+		*head_x = cur_x - x_off;
+		*head_y = cur_y - y_off;
+		*head_glyphs = cur_glyphs - n_off;
+	}
+	return TRUE;
+}
+
+/*
+ * This function detects glyph lists's overlapping.
+ *
+ * If check_fake_overlap is set, then it will check the glyph's left
+ * and right small boxes's real overlapping pixels. And if there is
+ * no real pixel overlapping, then it will not be treated as overlapped
+ * case. And we also can configured it to ignore less than 2 pixels
+ * overlappig.
+ *
+ * This function analyzes all the lists and split the list to multiple
+ * lists which are pure overlapped glyph lists or pure non-overlapped
+ * list if the overlapping only ocurr on the two adjacent glyphs.
+ * Otherwise, it return -1.
+ *
+ **/
+
+static int
 glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 			PictFormatShort mask_format,
-			ScreenPtr screen, Bool check_fake_overlap)
+			ScreenPtr screen, Bool check_fake_overlap,
+			struct glamor_glyph_list * fixed_list,
+			int fixed_size)
 {
 	int x1, x2, y1, y2;
 	int n;
 	int x, y;
-	BoxRec extents;
+	BoxRec extents, prev_extents;
 	Bool first = TRUE;
+	Bool need_free_fixed_list = FALSE;
 	struct glamor_glyph *priv;
-
+	Bool in_non_intersected_list = -1;
+	GlyphListPtr head_list, prev_list, saved_list;
+	int head_x, head_y, head_pos;
+	int fixed_cnt = 0;
+	GlyphPtr *head_glyphs;
+	GlyphListPtr cur_list = list;
+
+	saved_list = list;
 	x = 0;
 	y = 0;
 	extents.x1 = 0;
 	extents.y1 = 0;
 	extents.x2 = 0;
 	extents.y2 = 0;
+	prev_extents = extents;
+	prev_list = list;
+	head_list = list;
+	DEBUGF("has %d lists.\n", nlist);
 	while (nlist--) {
 		BoxRec left_box, right_box;
 		Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
-		Bool left_to_right = TRUE;
+		Bool left_to_right;
 		struct glamor_glyph *left_priv, *right_priv;
 
 		x += list->xOff;
 		y += list->yOff;
 		n = list->len;
-		list++;
+		left_to_right = TRUE;
+		cur_list = list++;
+
+		DEBUGF("current list %p has %d glyphs\n", cur_list, n);
 		while (n--) {
 			GlyphPtr glyph = *glyphs++;
 
+			DEBUGF("the %dth glyph\n", cur_list->len - n - 1);
 			if (glyph->info.width == 0
 			    || glyph->info.height == 0) {
 				x += glyph->info.xOff;
@@ -466,8 +754,11 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 				continue;
 			}
 			if (mask_format
-			    && mask_format != GlyphPicture(glyph)[screen->myNum]->format)
-				return TRUE;
+			    && mask_format != GlyphPicture(glyph)[screen->myNum]->format) {
+				need_free_fixed_list = TRUE;
+				goto done;
+			}
+
 			x1 = x - glyph->info.x;
 			if (x1 < MINSHORT)
 				x1 = MINSHORT;
@@ -476,6 +767,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 				y1 = MINSHORT;
 			if (check_fake_overlap)
 				priv = glamor_glyph_get_private(glyph);
+
 			x2 = x1 + glyph->info.width;
 			y2 = y1 + glyph->info.height;
 
@@ -490,6 +782,12 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 				extents.x2 = x2;
 				extents.y2 = y2;
 
+				first = FALSE;
+				head_list = cur_list;
+				head_pos = cur_list->len - n - 1;
+				head_x = x;
+				head_y = y;
+				head_glyphs = glyphs - 1;
 				if (check_fake_overlap && priv
 				    && priv->has_edge_map && glyph->info.yOff == 0) {
 					left_box.x1 = x1;
@@ -503,30 +801,28 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 					has_left_edge_box = TRUE;
 					has_right_edge_box = TRUE;
 				}
-
-				first = FALSE;
 			} else {
 
 				if (x1 < extents.x2 && x2 > extents.x1
 				    && y1 < extents.y2
 				    && y2 > extents.y1) {
-					if (check_fake_overlap && priv
+
+					if (check_fake_overlap && (has_left_edge_box || has_right_edge_box)
 					    && priv->has_edge_map && glyph->info.yOff == 0) {
 						int left_dx, right_dx;
 						unsigned long long intersected;
 
 						left_dx = has_left_edge_box ? 1 : 0;
 						right_dx = has_right_edge_box ? 1 : 0;
-
 						if (x1 + 1 < extents.x2 - right_dx && x2 - 1 > extents.x1 + left_dx)
-							return TRUE;
+							goto real_intersected;
 
 						if (left_to_right && has_right_edge_box) {
 							if (x1 == right_box.x1) {
 								intersected = ((priv->left_x1_map & right_priv->right_x1_map)
 										| (priv->left_x2_map & right_priv->right_x2_map));
 								if (intersected)
-									return TRUE;
+									goto real_intersected;
 							} else if (x1 == right_box.x2) {
 								intersected = (priv->left_x1_map & right_priv->right_x2_map);
 								if (intersected) {
@@ -535,7 +831,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 									intersected &= ~(1<<__fls(intersected));
 									if ((intersected & (intersected - 1)))
 								#endif
-										return TRUE;
+										goto real_intersected;
 								}
 							}
 						} else if (!left_to_right && has_left_edge_box) {
@@ -547,20 +843,77 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 									intersected &= ~(1<<__fls(intersected));
 									if ((intersected & (intersected - 1)))
 								#endif
-										return TRUE;
+										goto real_intersected;
 								}
 							} else if (x2 - 1 == right_box.x2) {
 								if ((priv->right_x1_map & left_priv->left_x1_map)
 								   || (priv->right_x2_map & left_priv->left_x2_map))
-										return TRUE;
+									goto real_intersected;
 							}
 						} else {
 							if (x1 < extents.x2 && x1 + 2 > extents.x1)
-								return TRUE;
+								goto real_intersected;
+						}
+						goto non_intersected;
+					} else {
+real_intersected:
+						DEBUGF("overlap with previous glyph.\n");
+						if (in_non_intersected_list == 1) {
+							if (fixed_cnt >= fixed_size) {
+								need_free_fixed_list = TRUE;
+								goto done;
+							}
+							if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+									     glyphs - 1,
+									     &head_glyphs,
+									     cur_list,
+									     cur_list->len - (n + 1), x, y,
+									     x1, y1, x2, y2,
+									     &head_list,
+									     &head_pos,
+									     &head_x,
+									     &head_y, &fixed_cnt,
+									     NON_INTERSECTED,
+									     prev_list,
+									     &prev_extents
+									     )){
+								need_free_fixed_list = TRUE;
+								goto done;
+							}
 						}
-					} else
-						return TRUE;
+
+						in_non_intersected_list = 0;
+
+					}
+				} else {
+non_intersected:
+					DEBUGF("doesn't overlap with previous glyph.\n");
+					if (in_non_intersected_list == 0) {
+						if (fixed_cnt >= fixed_size) {
+							need_free_fixed_list = TRUE;
+							goto done;
+						}
+						if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+								     glyphs - 1,
+								     &head_glyphs,
+								     cur_list,
+								     cur_list->len - (n + 1), x, y,
+								     x1, y1, x2, y2,
+								     &head_list,
+								     &head_pos,
+								     &head_x,
+								     &head_y, &fixed_cnt,
+								     INTERSECTED,
+								     prev_list,
+								     &prev_extents
+								     )) {
+							need_free_fixed_list = TRUE;
+							goto done;
+						}
+					}
+					in_non_intersected_list = 1;
 				}
+				prev_extents = extents;
 			}
 
 			if (check_fake_overlap && priv
@@ -571,11 +924,11 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 					left_box.y1 = y1;
 					has_left_edge_box = TRUE;
 					left_priv = priv;
-			}
+				}
 
-			if (!has_right_edge_box || x2 > extents.x2) {
-				right_box.x1 = x2 - 2;
-				right_box.x2 = x2 - 1;
+				if (!has_right_edge_box || x2 > extents.x2) {
+					right_box.x1 = x2 - 2;
+					right_box.x2 = x2 - 1;
 					right_box.y1 = y1;
 					has_right_edge_box = TRUE;
 					right_priv = priv;
@@ -594,10 +947,49 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
 
 			x += glyph->info.xOff;
 			y += glyph->info.yOff;
+			prev_list = cur_list;
 		}
 	}
 
-	return FALSE;
+	if (in_non_intersected_list == 0 && fixed_cnt == 0) {
+		fixed_cnt = -1;
+		goto done;
+	}
+
+	if ((in_non_intersected_list != -1
+		|| head_pos != n) && (fixed_cnt > 0)) {
+		if (fixed_cnt >= fixed_size) {
+			need_free_fixed_list = TRUE;
+			goto done;
+		}
+		if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
+				     glyphs - 1,
+				     &head_glyphs,
+				     cur_list,
+				     cur_list->len - (n + 1), x, y,
+				     x1, y1, x2, y2,
+				     &head_list,
+				     &head_pos,
+				     &head_x,
+				     &head_y, &fixed_cnt,
+				     (!in_non_intersected_list) | 0x80,
+				     prev_list,
+				     &prev_extents
+				     )) {
+			need_free_fixed_list = TRUE;
+			goto done;
+		}
+	}
+
+done:
+	if (need_free_fixed_list && fixed_cnt >= 0) {
+		while(fixed_cnt--) {
+			free(fixed_list[fixed_cnt].list);
+		}
+	}
+
+	DEBUGF("Got %d fixed list \n", fixed_cnt);
+	return fixed_cnt;
 }
 
 static inline unsigned int
@@ -690,6 +1082,7 @@ glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
 		cache->evict = rand() % GLYPH_CACHE_SIZE;
 	}
 
+
 	cache->glyphs[pos] = glyph;
 
 	priv->cache = cache;
@@ -722,29 +1115,95 @@ glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
 	return cache->picture;
 }
 typedef void (*glyphs_flush)(void * arg);
+struct glyphs_flush_dst_arg {
+	CARD8 op;
+	PicturePtr src;
+	PicturePtr dst;
+	glamor_glyph_buffer_t * buffer;
+	int x_src,y_src;
+	int x_dst, y_dst;
+};
+
+static struct glyphs_flush_dst_arg dst_arg;
+static struct glyphs_flush_mask_arg mask_arg;
+static glamor_glyph_buffer_t dst_buffer;
+static glamor_glyph_buffer_t mask_buffer;
+unsigned long long mask_glyphs_cnt = 0;
+unsigned long long dst_glyphs_cnt = 0;
+#define GLYPHS_DST_MODE_VIA_MASK		0
+#define GLYPHS_DST_MODE_VIA_MASK_CACHE		1
+#define GLYPHS_DST_MODE_TO_DST			2
+#define GLYPHS_DST_MODE_MASK_TO_DST		3
+
+struct glyphs_flush_mask_arg {
+	PicturePtr mask;
+	glamor_glyph_buffer_t *buffer;
+	struct glamor_glyph_mask_cache *maskcache;
+	unsigned int used_bitmap;
+};
+
+static void
+glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
+{
+	if (arg->buffer->count>0) {
+#ifdef RENDER
+	glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
+				     NULL, arg->mask,
+				     arg->buffer->count,
+				     arg->buffer->rects);
+#endif
+	}
+	arg->buffer->count = 0;
+	arg->buffer->source = NULL;
+
+}
+
+static void
+glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg)
+{
+	if (mask_buffer.count > 0) {
+		glamor_glyphs_flush_mask(&mask_arg);
+	}
+	if (mask_arg.used_bitmap) {
+		put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap);
+		mask_arg.used_bitmap = 0;
+	}
+
+	if (arg->buffer->count > 0) {
+		glamor_composite_glyph_rects(arg->op, arg->src,
+					arg->buffer->source, arg->dst,
+					arg->buffer->count,
+					&arg->buffer->rects[0]);
+		arg->buffer->count = 0;
+		arg->buffer->source = NULL;
+	}
+}
+
 
 static glamor_glyph_cache_result_t
 glamor_buffer_glyph(glamor_screen_private *glamor_priv,
 		    glamor_glyph_buffer_t * buffer,
-		    GlyphPtr glyph, int x_glyph, int y_glyph,
+		    PictFormatShort format,
+		    GlyphPtr glyph, struct glamor_glyph *priv,
+		    int x_glyph, int y_glyph,
 		    int dx, int dy, int w, int h,
+		    int glyphs_dst_mode,
 		    glyphs_flush glyphs_flush, void *flush_arg)
 {
 	ScreenPtr screen = glamor_priv->screen;
-	unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format;
 	glamor_composite_rect_t *rect;
 	PicturePtr source;
-	struct glamor_glyph *priv;
 	int x, y;
-	PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
 	glamor_glyph_cache_t *cache;
 
+	if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST)
+		priv = glamor_glyph_get_private(glyph);
+
 	if (PICT_FORMAT_BPP(format) == 1)
 		format = PICT_a8;
 
 	cache =
-	    &glamor_priv->glyphCaches[PICT_FORMAT_RGB
-					(glyph_picture->format) != 0];
+	    &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0];
 
 	if (buffer->source
 	    && buffer->source != cache->picture
@@ -759,25 +1218,36 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
 		glyphs_flush = NULL;
 	}
 
-	priv = glamor_glyph_get_private(glyph);
-
 	if (priv && priv->cached) {
 		rect = &buffer->rects[buffer->count++];
 		rect->x_src = priv->x + dx;
 		rect->y_src = priv->y + dy;
 		if (buffer->source == NULL)
 			buffer->source = priv->cache->picture;
-		assert(priv->cache->glyphs[priv->pos] == glyph);
+		if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE)
+			assert(priv->cache->glyphs[priv->pos] == glyph);
 	} else {
+		assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST);
 		if (glyphs_flush)
 			(*glyphs_flush)(flush_arg);
 		source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
+
 		if (source != NULL) {
 			rect = &buffer->rects[buffer->count++];
 			rect->x_src = x + dx;
 			rect->y_src = y + dy;
 			if (buffer->source == NULL)
 				buffer->source = source;
+			if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
+				glamor_gl_dispatch *dispatch;
+				/* mode 1 means we are using global mask cache,
+				 * thus we have to composite from the cache picture
+				 * to the cache picture, we need a flush here to make
+				 * sure latter we get the corret glyphs data.*/
+				dispatch = glamor_get_dispatch(glamor_priv);
+				dispatch->glFlush();
+				glamor_put_dispatch(glamor_priv);
+			}
 		} else {
 	/* Couldn't find the glyph in the cache, use the glyph picture directly */
 			source = GlyphPicture(glyph)[screen->myNum];
@@ -794,31 +1264,78 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
 		priv = glamor_glyph_get_private(glyph);
 	}
 
-	rect->x_dst = x_glyph - glyph->info.x;
-	rect->y_dst = y_glyph - glyph->info.y;
+	rect->x_dst = x_glyph;
+	rect->y_dst = y_glyph;
+	if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) {
+		rect->x_dst -= glyph->info.x;
+		rect->y_dst -= glyph->info.y;
+	}
 	rect->width = w;
 	rect->height = h;
+	if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) {
+		rect->x_mask = rect->x_src;
+		rect->y_mask = rect->y_src;
+		rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst;
+		rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst;
+	}
+
 	return GLAMOR_GLYPH_SUCCESS;
 }
 
-struct glyphs_flush_mask_arg {
-	PicturePtr mask;
-	glamor_glyph_buffer_t *buffer;
-};
 
 static void
-glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
+glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
+			 BoxPtr rects,
+			 int nrect, PictFormatShort format,
+			 GlyphPtr glyph, struct glamor_glyph *priv,
+			 int glyph_x, int glyph_y,
+			 int glyph_dx, int glyph_dy,
+			 int width, int height,
+			 int glyphs_mode,
+			 glyphs_flush flush_func,
+			 void *arg
+			 )
 {
-#ifdef RENDER
-	glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
-				     NULL, arg->mask,
-				     arg->buffer->count,
-				     arg->buffer->rects);
-#endif
-	arg->buffer->count = 0;
-	arg->buffer->source = NULL;
+	int i;
+	for (i = 0; i < nrect; i++) {
+		int dst_x, dst_y;
+		int dx, dy;
+		int x2, y2;
+
+		dst_x = glyph_x - glyph_dx;
+		dst_y = glyph_y - glyph_dy;
+		x2 = dst_x + width;
+		y2 = dst_y + height;
+		dx = dy = 0;
+		if (rects[i].y1 >= y2)
+			break;
+
+		if (dst_x < rects[i].x1)
+			dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
+		if (x2 > rects[i].x2)
+			x2 = rects[i].x2;
+		if (dst_y < rects[i].y1)
+			dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
+		if (y2 > rects[i].y2)
+			y2 = rects[i].y2;
+		if (dst_x < x2 && dst_y < y2) {
+
+			glamor_buffer_glyph(glamor_priv,
+					    &dst_buffer,
+					    format,
+					    glyph, priv,
+					    dst_x + glyph_dx,
+					    dst_y + glyph_dy,
+					    dx, dy,
+					    x2 - dst_x, y2 - dst_y,
+			    		    glyphs_mode,
+					    flush_func,
+					    arg);
+		}
+	}
 }
 
+
 static void
 glamor_glyphs_via_mask(CARD8 op,
 		       PicturePtr src,
@@ -826,7 +1343,8 @@ glamor_glyphs_via_mask(CARD8 op,
 		       PictFormatPtr mask_format,
 		       INT16 x_src,
 		       INT16 y_src,
-		       int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+		       int nlist, GlyphListPtr list, GlyphPtr * glyphs,
+		       Bool use_mask_cache)
 {
 	PixmapPtr mask_pixmap = 0;
 	PicturePtr mask;
@@ -839,11 +1357,16 @@ glamor_glyphs_via_mask(CARD8 op,
 	int error;
 	BoxRec extents = { 0, 0, 0, 0 };
 	XID component_alpha;
+	glamor_screen_private *glamor_priv;
+	int need_free_mask = FALSE;
 	glamor_glyph_buffer_t buffer;
-	xRectangle fill_rect;
 	struct glyphs_flush_mask_arg arg;
-	GCPtr gc;
-	glamor_screen_private *glamor_priv;
+	glamor_glyph_buffer_t *pmask_buffer;
+	struct glyphs_flush_mask_arg *pmask_arg;
+	struct glamor_glyph_mask_cache_entry *mce = NULL;
+	struct glamor_glyph_mask_cache *maskcache;
+	glamor_glyph_cache_t *cache;
+	int glyphs_dst_mode;
 
 	glamor_glyph_extents(nlist, list, glyphs, &extents);
 
@@ -861,113 +1384,173 @@ glamor_glyphs_via_mask(CARD8 op,
 			mask_format = a8Format;
 	}
 
-	mask_pixmap = screen->CreatePixmap(screen, width, height,
-					   mask_format->depth,
-					   CREATE_PIXMAP_USAGE_SCRATCH);
-	if (!mask_pixmap)
-		return;
-	component_alpha = NeedsComponent(mask_format->format);
-	mask = CreatePicture(0, &mask_pixmap->drawable,
-			     mask_format, CPComponentAlpha,
-			     &component_alpha, serverClient, &error);
-	if (!mask) {
-		screen->DestroyPixmap(mask_pixmap);
-		return;
-	}
-	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
-	ValidateGC(&mask_pixmap->drawable, gc);
-	gc->fillStyle = FillSolid;
-	//glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height, TRUE);
-	fill_rect.x = 0;
-	fill_rect.y = 0;
-	fill_rect.width = width;
-	fill_rect.height = height;
-	gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &fill_rect);
-	FreeScratchGC(gc);
+	cache = &glamor_priv->glyphCaches
+			[PICT_FORMAT_RGB(mask_format->format) != 0];
+	maskcache = mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0];
+
 	x = -extents.x1;
 	y = -extents.y1;
+	if (!use_mask_cache
+	    || width > (CACHE_PICTURE_SIZE/4)
+	    || height > MASK_CACHE_MAX_SIZE) {
+new_mask_pixmap:
+		mask_pixmap = glamor_create_pixmap(screen, width, height,
+						   mask_format->depth,
+						   CREATE_PIXMAP_USAGE_SCRATCH);
+		if (!mask_pixmap) {
+			glamor_destroy_pixmap(mask_pixmap);
+			return;
+		}
+		glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0);
+		component_alpha = NeedsComponent(mask_format->format);
+		mask = CreatePicture(0, &mask_pixmap->drawable,
+				     mask_format, CPComponentAlpha,
+				     &component_alpha, serverClient, &error);
+		if (!mask)
+			return;
+		need_free_mask = TRUE;
+		pmask_arg = &arg;
+		pmask_buffer = &buffer;
+		pmask_buffer->count = 0;
+		pmask_buffer->source = NULL;
+		pmask_arg->used_bitmap = 0;
+		glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK;
+	} else {
+		int retry_cnt = 0;
+retry:
+	   	mce = get_mask_cache(maskcache,
+				     (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE);
+
+		if (mce == NULL) {
+			glamor_glyphs_flush_dst(&dst_arg);
+			retry_cnt++;
+			if (retry_cnt > 2) {
+				assert(0);
+				goto new_mask_pixmap;
+			}
+			goto retry;
+		}
 
-	buffer.count = 0;
-	buffer.source = NULL;
+		mask = cache->picture;
+		x += mce->x;
+		y += mce->y;
+		mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE;
+		mce->height = 1;
+		if (mask_arg.mask && mask_arg.mask != mask
+			&& mask_buffer.count != 0)
+			glamor_glyphs_flush_dst(&dst_arg);
+		pmask_arg = &mask_arg;
+		pmask_buffer = &mask_buffer;
+		pmask_arg->maskcache = maskcache;
+		glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE;
+	}
+	pmask_arg->mask = mask;
+	pmask_arg->buffer = pmask_buffer;
 	while (nlist--) {
 		x += list->xOff;
 		y += list->yOff;
 		n = list->len;
+		mask_glyphs_cnt += n;
 		while (n--) {
 			glyph = *glyphs++;
 			if (glyph->info.width > 0
 			    && glyph->info.height > 0) {
 				glyphs_flush flush_func;
-				if (buffer.count) {
-					arg.mask = mask;
-					arg.buffer = &buffer;
-					flush_func = (glyphs_flush)glamor_glyphs_flush_mask;
+				void *arg;
+				if (need_free_mask) {
+					if (pmask_buffer->count)
+						flush_func = (glyphs_flush)glamor_glyphs_flush_mask;
+					else
+						flush_func = NULL;
+					arg = pmask_arg;
+				} else {
+					/* If we are using global mask cache, then we need to
+					 * flush dst instead of mask. As some dst depends on the
+					 * previous mask result. Just flush mask can't get all previous's
+					 * overlapped glyphs.*/
+					if (dst_buffer.count || mask_buffer.count)
+						flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+					else
+						flush_func = NULL;
+					arg = &dst_arg;
 				}
-				else
-					flush_func = NULL;
-
-				glamor_buffer_glyph(glamor_priv, &buffer,
-						    glyph, x, y,
+				glamor_buffer_glyph(glamor_priv, pmask_buffer,
+						    mask_format->format,
+						    glyph, NULL, x, y,
 						    0, 0,
 						    glyph->info.width, glyph->info.height,
+						    glyphs_dst_mode,
 						    flush_func,
-						    (void*)&arg);
+						    (void*)arg);
 			}
-
 			x += glyph->info.xOff;
 			y += glyph->info.yOff;
 		}
 		list++;
 	}
 
-	if (buffer.count) {
-		arg.mask = mask;
-		arg.buffer = &buffer;
-		glamor_glyphs_flush_mask(&arg);
-	}
-
 	x = extents.x1;
 	y = extents.y1;
-	CompositePicture(op,
-			 src,
-			 mask,
-			 dst,
-			 x_src + x - x_dst,
-			 y_src + y - y_dst, 0, 0, x, y, width, height);
-	FreePicture(mask, 0);
-	screen->DestroyPixmap(mask_pixmap);
-}
-
-struct glyphs_flush_dst_arg {
-	CARD8 op;
-	PicturePtr src;
-	PicturePtr dst;
-	glamor_glyph_buffer_t * buffer;
-	INT16 x_src;
-	INT16 y_src;
-	INT16 x_dst;
-	INT16 y_dst;
-};
+	if (need_free_mask) {
+		glamor_glyphs_flush_mask(pmask_arg);
+		CompositePicture(op,
+				 src,
+				 mask,
+				 dst,
+				 x_src + x - x_dst,
+				 y_src + y - y_dst, 0, 0, x, y, width, height);
+		FreePicture(mask, 0);
+		glamor_destroy_pixmap(mask_pixmap);
+	} else {
+		struct glamor_glyph priv;
+		glyphs_flush flush_func;
+		BoxPtr rects;
+		int nrect;
+
+		priv.cache = cache;
+		priv.x = mce->x;
+		priv.y = mce->y;
+		priv.cached = TRUE;
+		rects = REGION_RECTS(dst->pCompositeClip);
+		nrect = REGION_NUM_RECTS(dst->pCompositeClip);
+
+		pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx;
+		dst_arg.op = op;
+		dst_arg.src = src;
+		dst_arg.dst = dst;
+		dst_arg.buffer = &dst_buffer;
+		dst_arg.x_src = x_src;
+		dst_arg.y_src = y_src;
+		dst_arg.x_dst = x_dst;
+		dst_arg.y_dst = y_dst;
+
+		if (dst_buffer.source == NULL) {
+			dst_buffer.source = cache->picture;
+		} else if (dst_buffer.source != cache->picture) {
+			glamor_glyphs_flush_dst(&dst_arg);
+			dst_buffer.source = cache->picture;
+		}
 
-static void
-glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg)
-{
-	int i;
-	glamor_composite_rect_t *rect = &arg->buffer->rects[0];
-	for (i = 0; i < arg->buffer->count; i++, rect++) {
-		rect->x_mask = rect->x_src;
-		rect->y_mask = rect->y_src;
-		rect->x_src = arg->x_src + rect->x_dst - arg->x_dst;
-		rect->y_src = arg->y_src + rect->y_dst - arg->y_dst;
+		x += dst->pDrawable->x;
+		y += dst->pDrawable->y;
+
+		if (dst_buffer.count || mask_buffer.count)
+			flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+		else
+			flush_func = NULL;
+
+		glamor_buffer_glyph_clip(glamor_priv,
+					 rects, nrect,
+					 mask_format->format,
+					 NULL, &priv,
+					 x, y,
+					 0, 0,
+					 width, height,
+					 GLYPHS_DST_MODE_MASK_TO_DST,
+					 flush_func,
+					 (void *)&dst_arg
+					 );
 	}
-
-	glamor_composite_glyph_rects(arg->op, arg->src,
-				arg->buffer->source, arg->dst,
-				arg->buffer->count,
-				&arg->buffer->rects[0]);
-
-	arg->buffer->count = 0;
-	arg->buffer->source = NULL;
 }
 
 static void
@@ -984,82 +1567,54 @@ glamor_glyphs_to_dst(CARD8 op,
 	int x_dst = list->xOff, y_dst = list->yOff;
 	int n;
 	GlyphPtr glyph;
-	glamor_glyph_buffer_t buffer;
-	struct glyphs_flush_dst_arg arg;
 	BoxPtr rects;
 	int nrect;
 	glamor_screen_private *glamor_priv;
 
-	buffer.count = 0;
-	buffer.source = NULL;
-
 	rects = REGION_RECTS(dst->pCompositeClip);
 	nrect = REGION_NUM_RECTS(dst->pCompositeClip);
 
 	glamor_priv = glamor_get_screen_private(screen);
 
-	arg.op = op;
-	arg.src = src;
-	arg.dst = dst;
-	arg.buffer = &buffer;
-	arg.x_src = x_src;
-	arg.y_src = y_src;
-	arg.x_dst = x_dst;
-	arg.y_dst = y_dst;
+	dst_arg.op = op;
+	dst_arg.src = src;
+	dst_arg.dst = dst;
+	dst_arg.buffer = &dst_buffer;
+	dst_arg.x_src = x_src;
+	dst_arg.y_src = y_src;
+	dst_arg.x_dst = x_dst;
+	dst_arg.y_dst = y_dst;
 
+	x = dst->pDrawable->x;
+	y = dst->pDrawable->y;
 
 	while (nlist--) {
 		x += list->xOff;
 		y += list->yOff;
 		n = list->len;
+		dst_glyphs_cnt += n;
 		while (n--) {
-			int i;
 			glyph = *glyphs++;
 
 			if (glyph->info.width > 0
 			    && glyph->info.height > 0) {
 				glyphs_flush flush_func;
 
-				if (buffer.count)
+				if (dst_buffer.count || mask_buffer.count)
 					flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
 				else
 					flush_func = NULL;
-
-				for (i = 0; i < nrect; i++) {
-					int dst_x, dst_y;
-					int dx, dy;
-					int x2, y2;
-
-					dst_x = x - glyph->info.x;
-					dst_y = y - glyph->info.y;
-					x2 = dst_x + glyph->info.width;
-					y2 = dst_y + glyph->info.height;
-					dx = dy = 0;
-					if (rects[i].y1 >= y2)
-						break;
-
-					if (dst_x < rects[i].x1)
-						dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
-					if (x2 > rects[i].x2)
-						x2 = rects[i].x2;
-					if (dst_y < rects[i].y1)
-						dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
-					if (y2 > rects[i].y2)
-						y2 = rects[i].y2;
-
-					if (dst_x < x2 && dst_y < y2) {
-
-						glamor_buffer_glyph(glamor_priv,
-								    &buffer,
-								    glyph,
-								    dst_x + glyph->info.x,
-								    dst_y + glyph->info.y,
-								    dx, dy,
-								    x2 - dst_x, y2 - dst_y,
-								    flush_func,
-								    (void*)&arg);
-					}
-				}
+				glamor_buffer_glyph_clip(glamor_priv,
+							 rects, nrect,
+							 (GlyphPicture(glyph)[screen->myNum])->format,
+							 glyph, NULL,
+							 x, y,
+							 glyph->info.x, glyph->info.y,
+							 glyph->info.width, glyph->info.height,
+							 GLYPHS_DST_MODE_TO_DST,
+							 flush_func,
+							 (void *)&dst_arg
+							 );
 			}
 
 			x += glyph->info.xOff;
@@ -1067,9 +1622,13 @@ glamor_glyphs_to_dst(CARD8 op,
 		}
 		list++;
 	}
-
-	if (buffer.count)
-		glamor_glyphs_flush_dst(&arg);
+}
+#define MAX_FIXED_SIZE
+static void
+glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer)
+{
+	buffer->count = 0;
+	buffer->source = NULL;
 }
 
 static Bool
@@ -1081,8 +1640,10 @@ _glamor_glyphs(CARD8 op,
 	       INT16 y_src, int nlist, GlyphListPtr list,
 	       GlyphPtr * glyphs, Bool fallback)
 {
-	Bool intersected = FALSE;
 	PictFormatShort format;
+	int fixed_size, fixed_cnt = 0;
+	struct glamor_glyph_list *fixed_list = NULL;
+	Bool need_free_list = FALSE;
 #ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
 	Bool check_fake_overlap = TRUE;
 	if (!(op == PictOpOver
@@ -1098,39 +1659,93 @@ _glamor_glyphs(CARD8 op,
 #else
 	Bool check_fake_overlap = FALSE;
 #endif
+	if (mask_format)
+		format = mask_format->depth << 24 | mask_format->format;
+	else
+		format = 0;
+
+	fixed_size = 32;
+	glamor_glyphs_reset_buffer(&dst_buffer);
 
 	if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
 	    && (dst->format == ((mask_format->depth << 24) | mask_format->format)))) {
 		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
 				     list, glyphs);
-		return TRUE;
+		goto last_flush;
 	}
 
-	if (mask_format)
-		format = mask_format->depth << 24 | mask_format->format;
-	else
-		format = 0;
+	glamor_glyphs_reset_buffer(&mask_buffer);
 
-	intersected = glamor_glyphs_intersect(nlist, list, glyphs,
+	/* We have mask_format. Need to check the real overlap or not.*/
+	format = mask_format->depth << 24 | mask_format->format;
+
+	fixed_list = calloc(fixed_size, sizeof(*fixed_list));
+	if (unlikely(fixed_list == NULL))
+		fixed_size = 0;
+	fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
 				format, dst->pDrawable->pScreen,
-				check_fake_overlap);
+				check_fake_overlap,
+				fixed_list, fixed_size);
+	if (fixed_cnt == 0)
+		mask_format = NULL;
+	need_free_list = TRUE;
+
+	if (fixed_cnt <= 0) {
+		if (mask_format == NULL) {
+			glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
+					     list, glyphs);
+			goto last_flush;
+		} else {
+			glamor_glyphs_via_mask(op, src, dst, mask_format,
+					       x_src, y_src, nlist, list, glyphs,
+					       FALSE);
+			goto free_fixed_list;
+		}
+	} else {
 
-	if (!intersected) {
-		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
-				     list, glyphs);
-		return TRUE;
+		/* We have splitted the original list to serval list, some are overlapped
+		 * and some are non-overlapped. For the non-overlapped, we render it to
+		 * dst directly. For the overlapped, we render it to mask picture firstly,
+		 * then render the mask to dst. If we can use mask cache which is in the
+		 * glyphs cache's last row, we can accumulate the rendering of mask to dst
+		 * with the other dst_buffer's rendering operations thus can reduce the call
+		 * of glDrawElements.
+		 *
+		 * */
+		struct glamor_glyph_list *saved_list;
+
+		saved_list = fixed_list;
+		mask_arg.used_bitmap = 0;
+		while(fixed_cnt--) {
+			if (fixed_list->type == NON_INTERSECTED) {
+				glamor_glyphs_to_dst(op, src, dst,
+						     x_src, y_src,
+						     fixed_list->nlist,
+						     fixed_list->list,
+						     fixed_list->glyphs);
+			}
+			else
+				glamor_glyphs_via_mask(op, src, dst,
+						       mask_format, x_src, y_src,
+						       fixed_list->nlist,
+						       fixed_list->list,
+						       fixed_list->glyphs, TRUE);
+
+			free(fixed_list->list);
+			fixed_list++;
+		}
+		free(saved_list);
+		need_free_list = FALSE;
 	}
 
-	if (mask_format)
-		glamor_glyphs_via_mask(op, src, dst, mask_format,
-				       x_src, y_src, nlist, list, glyphs);
-	else {
-		/* No mask_format and has intersect and glyphs have different format.
-		 * XXX do we need to implement a new glyphs rendering function for
-		 * this case?*/
-		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs);
+last_flush:
+	if (dst_buffer.count || mask_buffer.count)
+		glamor_glyphs_flush_dst(&dst_arg);
+free_fixed_list:
+	if(need_free_list) {
+		assert(fixed_cnt <= 0);
+		free(fixed_list);
 	}
-
 	return TRUE;
 }
 
commit 4d1a2173f2e5a200d1535a4a459fffd75cd5f779
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 27 12:53:40 2012 +0800

    glamor_compositerects: Implement optimized version.
    
    Don't call miCompositeRects. Use glamor_composite_clipped_region
    to render those boxes at once.
    Also add a new function glamor_solid_boxes to fill boxes at once.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index e29f918..766aac7 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -48,6 +48,7 @@ libglamor_la_SOURCES = \
 	glamor_window.c\
 	glamor_gl_dispatch.c\
 	glamor_fbo.c\
+	glamor_compositerects.c\
 	glamor.h
 
 sdk_HEADERS = glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index a0046f9..01f6a9a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -383,6 +383,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		glamor_priv->saved_procs.composite = ps->Composite;
 		ps->Composite = glamor_composite;
 
+
 		glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
 		ps->Trapezoids = glamor_trapezoids;
 
@@ -395,6 +396,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
 	}
 
+	glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
+	ps->CompositeRects = glamor_composite_rectangles;
+
 	glamor_priv->saved_procs.glyphs = ps->Glyphs;
 	ps->Glyphs = glamor_glyphs;
 
@@ -510,10 +514,12 @@ glamor_close_screen(int idx, ScreenPtr screen)
 
 		ps->Composite = glamor_priv->saved_procs.composite;
 		ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
-		ps->Glyphs = glamor_priv->saved_procs.glyphs;
 		ps->Triangles = glamor_priv->saved_procs.triangles;
 		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
 	}
+	ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
+	ps->Glyphs = glamor_priv->saved_procs.glyphs;
+	ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
 #endif
 	screen_pixmap = screen->GetScreenPixmap(screen);
 	glamor_set_pixmap_private(screen_pixmap, NULL);
diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
new file mode 100644
index 0000000..5fe1bbf
--- /dev/null
+++ b/glamor/glamor_compositerects.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ * 	Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ * 	original author is Chris Wilson at sna.
+ *
+ */
+
+#include "glamor_priv.h"
+#include "mipict.h"
+#include "damage.h"
+
+/** @file glamor_compositerects.
+ *
+ * compositeRects acceleration implementation
+ */
+
+static int16_t bound(int16_t a, uint16_t b)
+{
+	int v = (int)a + (int)b;
+	if (v > MAXSHORT)
+		return MAXSHORT;
+	return v;
+}
+
+static Bool
+_pixman_region_init_clipped_rectangles(pixman_region16_t *region,
+				       unsigned int num_rects,
+				       xRectangle *rects,
+				       int tx, int ty,
+				       BoxPtr extents)
+{
+	pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
+	pixman_bool_t ret;
+	unsigned int i, j;
+
+	if (num_rects > ARRAY_SIZE(stack_boxes)) {
+		boxes = malloc(sizeof(pixman_box16_t) * num_rects);
+		if (boxes == NULL)
+			return FALSE;
+	}
+
+	for (i = j = 0; i < num_rects; i++) {
+		boxes[j].x1 = rects[i].x + tx;
+		if (boxes[j].x1 < extents->x1)
+			boxes[j].x1 = extents->x1;
+
+		boxes[j].y1 = rects[i].y + ty;
+		if (boxes[j].y1 < extents->y1)
+			boxes[j].y1 = extents->y1;
+
+		boxes[j].x2 = bound(rects[i].x + tx, rects[i].width);
+		if (boxes[j].x2 > extents->x2)
+			boxes[j].x2 = extents->x2;
+
+		boxes[j].y2 = bound(rects[i].y + ty, rects[i].height);
+		if (boxes[j].y2 > extents->y2)
+			boxes[j].y2 = extents->y2;
+
+		if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1)
+			j++;
+	}
+
+	ret = FALSE;
+	if (j)
+	    ret = pixman_region_init_rects(region, boxes, j);
+
+	if (boxes != stack_boxes)
+		free(boxes);
+
+	DEBUGF("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n",
+	     __FUNCTION__, num_rects,
+	     region->extents.x1, region->extents.y1,
+	     region->extents.x2, region->extents.y2,
+	     j);
+	return ret;
+}
+
+
+void
+glamor_composite_rectangles(CARD8	 op,
+			 PicturePtr	 dst,
+			 xRenderColor	*color,
+			 int		 num_rects,
+			 xRectangle	*rects)
+{
+	PixmapPtr pixmap;
+	struct glamor_pixmap_private *priv;
+	pixman_region16_t region;
+	pixman_box16_t *boxes;
+	int dst_x, dst_y;
+	int num_boxes;
+	PicturePtr source = NULL;
+	Bool need_free_region = FALSE;
+
+	DEBUGF("%s(op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n",
+	     __FUNCTION__, op,
+	     (color->alpha >> 8 << 24) |
+	     (color->red   >> 8 << 16) |
+	     (color->green >> 8 << 8) |
+	     (color->blue  >> 8 << 0),
+	     num_rects,
+	     rects[0].x, rects[0].y, rects[0].width, rects[0].height);
+
+	if (!num_rects)
+		return;
+
+	if (region_is_empty(dst->pCompositeClip)) {
+		DEBUGF("%s: empty clip, skipping\n", __FUNCTION__);
+		return;
+	}
+
+	pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+	priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
+		goto fallback;
+	if (dst->alphaMap) {
+		DEBUGF("%s: fallback, dst has an alpha-map\n", __FUNCTION__);
+		goto fallback;
+	}
+
+	if ((color->red|color->green|color->blue|color->alpha) <= 0x00ff) {
+		switch (op) {
+		case PictOpOver:
+		case PictOpOutReverse:
+		case PictOpAdd:
+			return;
+		case  PictOpInReverse:
+		case  PictOpSrc:
+			op = PictOpClear;
+			break;
+		case  PictOpAtopReverse:
+			op = PictOpOut;
+			break;
+		case  PictOpXor:
+			op = PictOpOverReverse;
+			break;
+		}
+	}
+	if (color->alpha <= 0x00ff) {
+		switch (op) {
+		case PictOpOver:
+		case PictOpOutReverse:
+			return;
+		case  PictOpInReverse:
+			op = PictOpClear;
+			break;
+		case  PictOpAtopReverse:
+			op = PictOpOut;
+			break;
+		case  PictOpXor:
+			op = PictOpOverReverse;
+			break;
+		}
+	} else if (color->alpha >= 0xff00) {
+		switch (op) {
+		case PictOpOver:
+			op = PictOpSrc;
+			break;
+		case PictOpInReverse:
+			return;
+		case PictOpOutReverse:
+			op = PictOpClear;
+			break;
+		case  PictOpAtopReverse:
+			op = PictOpOverReverse;
+			break;
+		case  PictOpXor:
+			op = PictOpOut;
+			break;
+		}
+	}
+	DEBUGF("%s: converted to op %d\n", __FUNCTION__, op);
+
+	if (!_pixman_region_init_clipped_rectangles(&region,
+						    num_rects, rects,
+						    dst->pDrawable->x,
+						    dst->pDrawable->y,
+						    &dst->pCompositeClip->extents))
+	{
+		DEBUGF("%s: allocation failed for region\n", __FUNCTION__);
+		return;
+	}
+
+	need_free_region = TRUE;
+
+	DEBUGF("%s: drawable extents (%d, %d),(%d, %d) x %d\n",
+	     __FUNCTION__,
+	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+	     RegionExtents(&region)->x2, RegionExtents(&region)->y2,
+	     RegionNumRects(&region));
+
+	if (dst->pCompositeClip->data &&
+	    (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
+	     region_is_empty(&region))) {
+		DEBUGF(("%s: zero-intersection between rectangles and clip\n",
+		     __FUNCTION__));
+		pixman_region_fini(&region);
+		return;
+	}
+
+	DEBUGF("%s: clipped extents (%d, %d),(%d, %d) x %d\n",
+	     __FUNCTION__,
+	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+	     RegionExtents(&region)->x2, RegionExtents(&region)->y2,
+	     RegionNumRects(&region));
+
+	glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
+	pixman_region_translate(&region, dst_x, dst_y);
+
+	DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
+	     __FUNCTION__, dst_x, dst_y,
+	     RegionExtents(&region)->x1, RegionExtents(&region)->y1,
+	     RegionExtents(&region)->x2, RegionExtents(&region)->y2);
+
+
+	boxes = pixman_region_rectangles(&region, &num_boxes);
+	if (op == PictOpSrc || op == PictOpClear) {
+		CARD32 pixel;
+		if (op == PictOpClear)
+			pixel = 0;
+		else
+			miRenderColorToPixel(dst->pFormat, color, &pixel);
+		glamor_solid_boxes(pixmap, boxes, num_boxes, pixel);
+
+		goto done;
+	} else {
+		if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {
+			int error;
+
+			source = CreateSolidPicture(0, color, &error);
+			if (!source)
+				goto done;
+			if (glamor_composite_clipped_region(op, source,
+						NULL, dst,
+						NULL, NULL, priv,
+						&region,
+						0,0,0,0,0,0))
+				goto done;
+		}
+	}
+fallback:
+	miCompositeRects(op, dst, color, num_rects, rects);
+done:
+	/* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must
+	 * manually append the damaged regions ourselves.
+	 */
+	DamageRegionAppend(&pixmap->drawable, &region);
+	DamageRegionProcessPending(&pixmap->drawable);
+
+	if (need_free_region)
+		pixman_region_fini(&region);
+	if (source)
+		FreePicture(source, 0);
+	return;
+}
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index e371148..2163c94 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -181,6 +181,87 @@ glamor_fini_solid_shader(ScreenPtr screen)
 }
 
 static void
+_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch;
+	GLfloat xscale, yscale;
+	float vertices[32];
+	float *pvertices = vertices;
+	int valid_nbox = ARRAY_SIZE(vertices);
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	dispatch->glUseProgram(glamor_priv->solid_prog);
+
+	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
+			       1, color);
+
+	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+
+	if (unlikely(nbox*4*2 > ARRAY_SIZE(vertices))) {
+		int allocated_box;
+
+		if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) {
+			allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
+		} else
+			allocated_box = nbox;
+		pvertices = malloc(allocated_box * 4 * 2 * sizeof(float));
+		if (pvertices)
+			valid_nbox = allocated_box;
+		else {
+			pvertices = vertices;
+			valid_nbox = ARRAY_SIZE(vertices) / (4*2);
+		}
+	}
+
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
+	if (unlikely(nbox > 1))
+		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					pvertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+	while(nbox) {
+		int box_cnt, i;
+		float *valid_vertices;
+		valid_vertices = pvertices;
+		box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
+		for (i = 0; i < box_cnt; i++) {
+			glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
+						     box[i].x1, box[i].y1,
+						     box[i].x2, box[i].y2,
+						     glamor_priv->yInverted,
+						     valid_vertices);
+			valid_vertices += 4*2;
+		}
+		if (box_cnt == 1)
+			dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
+		else
+			dispatch->glDrawElements(GL_TRIANGLES,
+						 box_cnt * 6,
+						 GL_UNSIGNED_SHORT,
+						 NULL);
+		nbox -= box_cnt;
+		box += box_cnt;
+	}
+
+	if (pvertices != vertices)
+		free(pvertices);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+}
+
+static void
 _glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	      float *color)
 {
@@ -222,15 +303,11 @@ _glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 }
 
 Bool
-glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	     unsigned char alu, unsigned long planemask,
-	     unsigned long fg_pixel)
+glamor_solid_boxes(PixmapPtr pixmap,
+		   BoxPtr box, int nbox,
+		   unsigned long fg_pixel)
 {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
 	glamor_pixmap_private *pixmap_priv;
-	glamor_gl_dispatch *dispatch;
 	GLfloat color[4];
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -238,69 +315,81 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return FALSE;
 
-	if (!glamor_set_planemask(pixmap, planemask)) {
-		glamor_fallback
-		    ("Failedto set planemask  in glamor_solid.\n");
-		return FALSE;
-	}
-
 	glamor_get_rgba_from_pixel(fg_pixel,
 				   &color[0],
 				   &color[1],
 				   &color[2],
 				   &color[3], format_for_pixmap(pixmap));
 
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, alu)) {
-		if (alu == GXclear)
-			color[0] = color[1] = color[2] = color[3] = 0.0;
-		else {
-			glamor_fallback("unsupported alu %x\n", alu);
-			glamor_put_dispatch(glamor_priv);
-			return FALSE;
-		}
-	}
-
 	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
 		RegionRec region;
-		BoxRec box;
 		int n_region;
 		glamor_pixmap_clipped_regions *clipped_regions;
-		int i,j;
+		int i;
 
-		box.x1 = x;
-		box.y1 = y;
-		box.x2 = x + width;
-		box.y2 = y + height;
-		RegionInitBoxes(&region, &box, 1);
+		RegionInitBoxes(&region, box, nbox);
 		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
 		for(i = 0; i < n_region; i++)
 		{
-			BoxPtr boxes;
-			int nbox;
+			BoxPtr inner_box;
+			int inner_nbox;
 			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
 
-			boxes = RegionRects(clipped_regions[i].region);
-			nbox = RegionNumRects(clipped_regions[i].region);
-			for(j = 0; j < nbox; j++)
-			{
-				_glamor_solid(pixmap, boxes[j].x1, boxes[j].y1,
-					      boxes[j].x2 - boxes[j].x1,
-					      boxes[j].y2 - boxes[j].y1, color);
-			}
+			inner_box = RegionRects(clipped_regions[i].region);
+			inner_nbox = RegionNumRects(clipped_regions[i].region);
+			_glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
 			RegionDestroy(clipped_regions[i].region);
 		}
 		free(clipped_regions);
 		RegionUninit(&region);
 	} else
-		_glamor_solid(pixmap,
-			      x,
-			      y,
-			      width, height,
-			      color);
+		_glamor_solid_boxes(pixmap, box, nbox, color);
+
+	return TRUE;
+}
+
+Bool
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+	     unsigned char alu, unsigned long planemask,
+	     unsigned long fg_pixel)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_pixmap_private *pixmap_priv;
+	glamor_gl_dispatch *dispatch;
+	BoxRec box;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return FALSE;
+
+	if (!glamor_set_planemask(pixmap, planemask)) {
+		glamor_fallback
+		    ("Failedto set planemask  in glamor_solid.\n");
+		return FALSE;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	if (!glamor_set_alu(dispatch, alu)) {
+		if (alu == GXclear)
+			fg_pixel = 0;
+		else {
+			glamor_fallback("unsupported alu %x\n", alu);
+			glamor_put_dispatch(glamor_priv);
+			return FALSE;
+		}
+	}
+	box.x1 = x;
+	box.y1 = y;
+	box.x2 = x + width;
+	box.y2 = y + height;
+	glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
 
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_put_dispatch(glamor_priv);
 
 	return TRUE;
 }
+
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 61551df..a7d4fe7 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -210,6 +210,7 @@ struct glamor_saved_procs {
 	GetSpansProcPtr get_spans;
 	GetImageProcPtr get_image;
 	CompositeProcPtr composite;
+	CompositeRectsProcPtr composite_rects;
 	TrapezoidsProcPtr trapezoids;
 	GlyphsProcPtr glyphs;
 	ChangeWindowAttributesProcPtr change_window_attributes;
@@ -644,8 +645,10 @@ Bool glamor_fill(DrawablePtr drawable,
 Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		  unsigned char alu, unsigned long planemask,
 		  unsigned long fg_pixel);
-void glamor_solid_fail_region(PixmapPtr pixmap,
-			      int x, int y, int width, int height);
+Bool
+glamor_solid_boxes(PixmapPtr pixmap,
+		   BoxPtr box, int nbox,
+		   unsigned long fg_pixel);
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
@@ -988,6 +991,13 @@ void
 glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		 DDXPointPtr ppt);
 
+void
+glamor_composite_rectangles(CARD8	 op,
+			 PicturePtr	 dst,
+			 xRenderColor	*color,
+			 int		 num_rects,
+			 xRectangle	*rects);
+
 #include"glamor_utils.h"
 
 /* Dynamic pixmap upload to texture if needed. 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 88c6616..a282985 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -792,6 +792,12 @@ glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 	}
 }
 
+static inline Bool
+region_is_empty(pixman_region16_t *region)
+{
+	return region->data && region->data->numRects == 0;
+}
+
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
commit dd7924339803b51332e3fe94d36eb48549e9d24d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 20:00:21 2012 +0800

    optimize: Use likely and unlikely.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/compiler.h b/glamor/compiler.h
new file mode 100644
index 0000000..fa28959
--- /dev/null
+++ b/glamor/compiler.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Chris Wilson <chris at chris-wilson.co.uk>
+ *
+ *    Copied from sna 
+ *
+ */
+
+#ifndef _GLAMOR_COMPILER_H_
+#define _GLAMOR_COMPILER_H_
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define likely(expr) (__builtin_expect (!!(expr), 1))
+#define unlikely(expr) (__builtin_expect (!!(expr), 0))
+#define noinline __attribute__((noinline))
+#define fastcall __attribute__((regparm(3)))
+#define must_check __attribute__((warn_unused_result))
+#define constant __attribute__((const))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#define noinline
+#define fastcall
+#define must_check
+#define constant
+#endif
+
+#ifdef HAVE_VALGRIND
+#define VG(x) x
+#else
+#define VG(x)
+#endif
+
+#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
+
+#define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)]))
+
+#endif /* _SNA_COMPILER_H_ */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 642aff6..61551df 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,6 +31,8 @@
 #include "config.h"
 #endif
 
+#include "compiler.h"
+
 #include <xorg-server.h>
 #ifndef DEBUG
 #define NDEBUG
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index ab91f31..88c6616 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -59,7 +59,7 @@
 
 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h)			\
   do {								\
-	if (priv->type == GLAMOR_TEXTURE_LARGE) {		\
+	if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {		\
 		w = priv->large.box.x2 - priv->large.box.x1;	\
 		h = priv->large.box.y2 - priv->large.box.y1;	\
 	} else {						\
@@ -80,8 +80,8 @@
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
    do {								\
-	if (_priv_ && (_priv_)->type				\
-		== GLAMOR_TEXTURE_LARGE) {			\
+	if (unlikely(_priv_ && (_priv_)->type				\
+		== GLAMOR_TEXTURE_LARGE)) {			\
 		*(_xoff_) = - (_priv_)->large.box.x1;	\
 		*(_yoff_) = - (_priv_)->large.box.y1;	\
 	} else {						\
@@ -316,7 +316,7 @@
 				     texcoord, yInverted)		\
   do {									\
 	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
-	if (yInverted)							\
+	if (likely(yInverted))						\
 		(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
 	else								\
 		(texcoord)[1] = t_from_x_coord_y(yscale, _ty_);		\
@@ -339,7 +339,7 @@
     tx += fbo_x_off;							\
     ty += fbo_y_off;							\
     (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
-    if (yInverted)							\
+    if (likely(yInverted))							\
       (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty);		\
     else								\
       (texcoord)[1] = t_from_x_coord_y(yscale, ty);			\
@@ -436,14 +436,12 @@
 							 texcoords,	\
 							 stride)	\
   do {									\
-    if (priv->type != GLAMOR_TEXTURE_LARGE) {				\
+    if (likely(priv->type != GLAMOR_TEXTURE_LARGE)) {			\
 	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
 						 yscale, _x1_, _y1_,	\
 						 _x2_, _y2_, yInverted,	\
 						 texcoords, stride);	\
     } else {								\
-	/* For a large pixmap, if both transform and repeat are set,
-	 * the transform must only has x and y scale factor.*/		\
     float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;			\
     float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4;		\
     DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_);	\
@@ -512,7 +510,7 @@
     (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    if (yInverted) {							\
+    if (likely(yInverted)) {							\
       (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1);	\
       (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\
     }									\
@@ -528,7 +526,7 @@
 				     x1, y1, x2, y2,			\
                                      yInverted, vertices, stride)	\
   do {									\
-     if (priv->type == GLAMOR_TEXTURE_LARGE) {				\
+     if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {				\
 	float tx1, tx2, ty1, ty2;					\
 	int fbo_x_off, fbo_y_off;					\
 	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
@@ -559,7 +557,7 @@
 					    _x1_, _y1_, _x2_, _y2_,	\
 	                                    yInverted, vertices, stride)\
   do {									\
-     if (priv->type == GLAMOR_TEXTURE_LARGE) {				\
+     if (unlikely(priv->type == GLAMOR_TEXTURE_LARGE)) {				\
 	float tx1, tx2, ty1, ty2;					\
 	if (repeat_type == RepeatPad) {					\
 		tx1 = _x1_ - priv->large.box.x1;			\
@@ -600,7 +598,7 @@
 	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (yInverted) {						\
+	if (likely(yInverted)) {						\
 	    (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);	\
 	    (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2);	\
 	}								\
@@ -619,7 +617,7 @@
 	(vertices)[2] = (x2);					\
 	(vertices)[4] = (vertices)[2];				\
 	(vertices)[6] = (vertices)[0];				\
-	if (yInverted) {					\
+	if (likely(yInverted)) {					\
 	    (vertices)[1] = (y1);				\
 	    (vertices)[5] = (y2);				\
 	}							\
@@ -635,7 +633,7 @@
 					yInverted, vertices)		\
     do {								\
 	(vertices)[0] = v_from_x_coord_x(xscale, x);			\
-	if (yInverted) {						\
+	if (likely(yInverted)) {						\
 	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y);	\
 	} else {							\
 	    (vertices)[1] = v_from_x_coord_y(yscale, y);		\
@@ -663,7 +661,7 @@
 	(vertices)[2] = (x2);						\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (yInverted) {						\
+	if (likely(yInverted)) {						\
 	    (vertices)[1] = (y1);					\
 	    (vertices)[7] = (y2);					\
 	}								\
@@ -689,7 +687,7 @@
 					x2 + fbo_x_off);		\
     (vertices)[2 * stride] = _t2_;					\
     (vertices)[3 * stride] = _t0_;					\
-    if (yInverted) {							\
+    if (likely(yInverted)) {							\
       (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale,		\
 				y1 + fbo_y_off);			\
       (vertices)[2 * stride + 1] = _t5_ =				\
@@ -723,7 +721,7 @@
 	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
 	(vertices)[6] = (vertices)[2];					\
 	(vertices)[4] = (vertices)[0];					\
-	if (yInverted) {						\
+	if (likely(yInverted)) {						\
 	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);	\
 	    (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2);	\
 	}								\
@@ -739,7 +737,7 @@
                                 yInverted, pt)			\
     do {							\
         (pt)[0] = t_from_x_coord_x(xscale, x);			\
-        if (yInverted) {					\
+        if (likely(yInverted)) {					\
             (pt)[1] = t_from_x_coord_y_inverted(yscale, y);	\
         } else {						\
             (pt)[1] = t_from_x_coord_y(yscale, y);		\
@@ -750,7 +748,7 @@
 				 yInverted, c)		\
     do {						\
         (c)[0] = (float)x;				\
-        if (yInverted) {				\
+        if (likely(yInverted)) {				\
             (c)[1] = (float)y;				\
         } else {					\
             (c)[1] = (float)height - (float)y;		\
commit d5f03ba0109bc50e159c82d3d67cffa8fc174134
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 19:56:27 2012 +0800

    create_pixmap: use texture for large glyphs.
    
    As we only cache glyphs smaller than 64x64, we need to use
    texutre for the large glyphs.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0f93e98..a0046f9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -142,7 +142,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		return NullPixmap;
 
 	if ((usage == GLAMOR_CREATE_PIXMAP_CPU
-	     || usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE
+	     || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
 		|| (w == 0 && h == 0)
 		|| !glamor_check_pixmap_fbo_depth(depth))
 	    || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
commit 90dd6ddbab864aa6c3add55c46a85d7db2c125f6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 17:19:16 2012 +0800

    glamor_copyarea: Fixed a bug introduced by 996194...
    
    Default return value should be FALSE.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 243c1f2..ee6f812 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -398,7 +398,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	RegionRec region;
 	ScreenPtr screen;
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
-	Bool ok = TRUE;
+	Bool ok = FALSE;
 	int force_clip = 0;
 
 	if (nbox == 0)
@@ -426,7 +426,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 		dispatch = glamor_get_dispatch(glamor_priv);
 		if (!glamor_set_alu(dispatch, gc->alu)) {
 			glamor_put_dispatch(glamor_priv);
-			ok = FALSE;
 			goto fail;
 		}
 		glamor_put_dispatch(glamor_priv);
@@ -549,6 +548,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
 							goto fail;
 						}
 					}
+
+					if (n_src_region == 0)
+						ok = TRUE;
 					free(clipped_src_regions);
 				} else {
 					RegionTranslate(clipped_dst_regions[i].region,
@@ -571,6 +573,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
 				}
 				RegionDestroy(clipped_dst_regions[i].region);
 			}
+		if (n_dst_region == 0)
+			ok = TRUE;
 		free(clipped_dst_regions);
 		RegionUninit(&region);
 	} else {
commit b8dd2a597de455ae985302d1b93d865ef9f37c7b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 16:24:32 2012 +0800

    glamor_glyphs: Slightly performance tuning.
    
    As glamor_glyphs never fallback, we don't need to keep the
    underlying glyphs routines, just override the ps->glys
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d087b82..0f93e98 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -386,8 +386,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
 		ps->Trapezoids = glamor_trapezoids;
 
-		glamor_priv->saved_procs.glyphs = ps->Glyphs;
-		ps->Glyphs = glamor_glyphs;
 
 		glamor_priv->saved_procs.triangles = ps->Triangles;
 		ps->Triangles = glamor_triangles;
@@ -395,9 +393,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		glamor_priv->saved_procs.addtraps = ps->AddTraps;
 		ps->AddTraps = glamor_add_traps;
 
-		glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
-		ps->UnrealizeGlyph = glamor_glyph_unrealize;
 	}
+
+	glamor_priv->saved_procs.glyphs = ps->Glyphs;
+	ps->Glyphs = glamor_glyphs;
+
+	glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
+	ps->UnrealizeGlyph = glamor_glyph_unrealize;
+
 	glamor_priv->saved_procs.create_picture = ps->CreatePicture;
 	ps->CreatePicture = glamor_create_picture;
 
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index fa8b55f..c2a750d 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -97,16 +97,9 @@ static DevPrivateKeyRec glamor_glyph_key;
 static inline struct glamor_glyph *
 glamor_glyph_get_private(GlyphPtr glyph)
 {
-	return dixGetPrivate(&glyph->devPrivates, &glamor_glyph_key);
+	return (struct glamor_glyph*)glyph->devPrivates;
 }
 
-static inline void
-glamor_glyph_set_private(GlyphPtr glyph, struct glamor_glyph *priv)
-{
-	dixSetPrivate(&glyph->devPrivates, &glamor_glyph_key, priv);
-}
-
-
 static void
 glamor_unrealize_glyph_caches(ScreenPtr pScreen)
 {
@@ -210,7 +203,8 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 Bool
 glamor_glyphs_init(ScreenPtr pScreen)
 {
-	if (!dixRegisterPrivateKey(&glamor_glyph_key, PRIVATE_GLYPH, 0))
+	if (!dixRegisterPrivateKey(&glamor_glyph_key,
+		PRIVATE_GLYPH, sizeof(struct glamor_glyph)))
 		return FALSE;
 
 	/* Skip pixmap creation if we don't intend to use it. */
@@ -299,15 +293,10 @@ glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 	struct glamor_glyph *priv;
 
 	/* Use Lookup in case we have not attached to this glyph. */
-	priv = dixLookupPrivate(&glyph->devPrivates, &glamor_glyph_key);
-	if (priv == NULL)
-		return;
+	priv = glamor_glyph_get_private(glyph);
 
 	if (priv->cached)
 		priv->cache->glyphs[priv->pos] = NULL;
-
-	glamor_glyph_set_private(glyph, NULL);
-	free(priv);
 }
 
 /* Cut and paste from render/glyph.c - probably should export it instead */
@@ -632,10 +621,10 @@ glamor_glyph_size_to_mask(int size)
 }
 
 static PicturePtr
-glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
+glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
 		   int *out_y)
 {
-	glamor_screen_private *glamor = glamor_get_screen_private(screen);
+	ScreenPtr screen = glamor->screen;
 	PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
 	glamor_glyph_cache_t *cache =
 	    &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) !=
@@ -701,14 +690,6 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 		cache->evict = rand() % GLYPH_CACHE_SIZE;
 	}
 
-	if (priv == NULL) {
-		priv = malloc(sizeof(struct glamor_glyph));
-		if (priv == NULL)
-			return NULL;
-		glamor_glyph_set_private(glyph, priv);
-		priv->has_edge_map = FALSE;
-	}
-
 	cache->glyphs[pos] = glyph;
 
 	priv->cache = cache;
@@ -743,14 +724,13 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 typedef void (*glyphs_flush)(void * arg);
 
 static glamor_glyph_cache_result_t
-glamor_buffer_glyph(ScreenPtr screen,
+glamor_buffer_glyph(glamor_screen_private *glamor_priv,
 		    glamor_glyph_buffer_t * buffer,
 		    GlyphPtr glyph, int x_glyph, int y_glyph,
 		    int dx, int dy, int w, int h,
 		    glyphs_flush glyphs_flush, void *flush_arg)
 {
-	glamor_screen_private *glamor_screen =
-	    glamor_get_screen_private(screen);
+	ScreenPtr screen = glamor_priv->screen;
 	unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format;
 	glamor_composite_rect_t *rect;
 	PicturePtr source;
@@ -763,7 +743,7 @@ glamor_buffer_glyph(ScreenPtr screen,
 		format = PICT_a8;
 
 	cache =
-	    &glamor_screen->glyphCaches[PICT_FORMAT_RGB
+	    &glamor_priv->glyphCaches[PICT_FORMAT_RGB
 					(glyph_picture->format) != 0];
 
 	if (buffer->source
@@ -791,7 +771,7 @@ glamor_buffer_glyph(ScreenPtr screen,
 	} else {
 		if (glyphs_flush)
 			(*glyphs_flush)(flush_arg);
-		source = glamor_glyph_cache(screen, glyph, &x, &y);
+		source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
 		if (source != NULL) {
 			rect = &buffer->rects[buffer->count++];
 			rect->x_src = x + dx;
@@ -863,11 +843,13 @@ glamor_glyphs_via_mask(CARD8 op,
 	xRectangle fill_rect;
 	struct glyphs_flush_mask_arg arg;
 	GCPtr gc;
+	glamor_screen_private *glamor_priv;
 
 	glamor_glyph_extents(nlist, list, glyphs, &extents);
 
 	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
 		return;
+	glamor_priv = glamor_get_screen_private(screen);
 	width = extents.x2 - extents.x1;
 	height = extents.y2 - extents.y1;
 
@@ -924,7 +906,7 @@ glamor_glyphs_via_mask(CARD8 op,
 				else
 					flush_func = NULL;
 
-				glamor_buffer_glyph(screen, &buffer,
+				glamor_buffer_glyph(glamor_priv, &buffer,
 						    glyph, x, y,
 						    0, 0,
 						    glyph->info.width, glyph->info.height,
@@ -1006,6 +988,7 @@ glamor_glyphs_to_dst(CARD8 op,
 	struct glyphs_flush_dst_arg arg;
 	BoxPtr rects;
 	int nrect;
+	glamor_screen_private *glamor_priv;
 
 	buffer.count = 0;
 	buffer.source = NULL;
@@ -1013,6 +996,18 @@ glamor_glyphs_to_dst(CARD8 op,
 	rects = REGION_RECTS(dst->pCompositeClip);
 	nrect = REGION_NUM_RECTS(dst->pCompositeClip);
 
+	glamor_priv = glamor_get_screen_private(screen);
+
+	arg.op = op;
+	arg.src = src;
+	arg.dst = dst;
+	arg.buffer = &buffer;
+	arg.x_src = x_src;
+	arg.y_src = y_src;
+	arg.x_dst = x_dst;
+	arg.y_dst = y_dst;
+
+
 	while (nlist--) {
 		x += list->xOff;
 		y += list->yOff;
@@ -1025,17 +1020,9 @@ glamor_glyphs_to_dst(CARD8 op,
 			    && glyph->info.height > 0) {
 				glyphs_flush flush_func;
 
-				if (buffer.count) {
-					arg.op = op;
-					arg.src = src;
-					arg.dst = dst;
-					arg.buffer = &buffer;
-					arg.x_src = x_src;
-					arg.y_src = y_src;
-					arg.x_dst = x_dst;
-					arg.y_dst = y_dst;
+				if (buffer.count)
 					flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
-				} else
+				else
 					flush_func = NULL;
 
 				for (i = 0; i < nrect; i++) {
@@ -1062,7 +1049,7 @@ glamor_glyphs_to_dst(CARD8 op,
 
 					if (dst_x < x2 && dst_y < y2) {
 
-						glamor_buffer_glyph(screen,
+						glamor_buffer_glyph(glamor_priv,
 								    &buffer,
 								    glyph,
 								    dst_x + glyph->info.x,
@@ -1081,17 +1068,8 @@ glamor_glyphs_to_dst(CARD8 op,
 		list++;
 	}
 
-	if (buffer.count) {
-		arg.op = op;
-		arg.src = src;
-		arg.dst = dst;
-		arg.buffer = &buffer;
-		arg.x_src = x_src;
-		arg.y_src = y_src;
-		arg.x_dst = x_dst;
-		arg.y_dst = y_dst;
+	if (buffer.count)
 		glamor_glyphs_flush_dst(&arg);
-	}
 }
 
 static Bool
commit 3873d412f018b975feaa000cb7ef337feaeee37d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 15:39:24 2012 +0800

    glamor_render: Don't allocate buffer for vbo each time.
    
    We can reuse the last one if the last one is big enough
    to contain current vertext data. In the meantime, Use
    MapBufferRange instead of MapBuffer.
    
    Testing shows, this patch brings some benefit for
    aa10text/rgb10text. Not too much, but indeed faster.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 5e5ae78..b82c7c3 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -724,10 +724,17 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
+	int vert_size;
+	Bool need_new_buffer = FALSE;
 
 	glamor_priv->vbo_offset = 0;
 	glamor_priv->render_nr_verts = 0;
-	glamor_priv->vbo_size = n_verts * sizeof(float) * 2;
+	vert_size = n_verts * sizeof(float) * 2;
+
+	if (glamor_priv->vbo_size < vert_size) {
+		glamor_priv->vbo_size = vert_size;
+		need_new_buffer = TRUE;
+	}
 
 	glamor_priv->vb_stride = 2 * sizeof(float);
 	if (glamor_priv->has_source_coords)
@@ -738,10 +745,14 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glBufferData(GL_ARRAY_BUFFER,
-				       n_verts * sizeof(float) * 2,
-				       NULL, GL_DYNAMIC_DRAW);
-		glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
+		if (need_new_buffer)
+			dispatch->glBufferData(GL_ARRAY_BUFFER,
+					       vert_size,
+					       NULL, GL_DYNAMIC_DRAW);
+		glamor_priv->vb = dispatch->glMapBufferRange(GL_ARRAY_BUFFER, 0,
+						vert_size,
+						GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+		assert(glamor_priv->vb != NULL);
 	}
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
commit 682f5d2989306856c0c193b0b4abd8c104a9ba92
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 26 13:09:05 2012 +0800

    glamor_largepixmap: Walkaround for large texture's upload.
    
    I met a problem with large texture (larger than 7000x7000)'s
    uploading on SNB platform. The map_gtt get back a mapped VA
    without error, but write to that virtual address triggers
    BUS error. This work around is to avoid that direct uploading.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index ce243ab..10066a6 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -497,7 +497,11 @@ ready_to_upload:
 	if (no_alpha == 0
 	    && revert == REVERT_NONE
 	    && swap_rb == SWAP_NONE_UPLOADING
-	    && !need_flip) {
+	    && !need_flip
+#ifdef WALKAROUND_LARGE_TEXTURE_MAP
+	    && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
+#endif
+		) {
 		int fbo_x_off, fbo_y_off;
 		assert(pixmap_priv->base.fbo->tex);
 		pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4fad5cd..642aff6 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -1001,6 +1001,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 //#define GLAMOR_TRAPEZOID_SHADER
 #endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
+#define WALKAROUND_LARGE_TEXTURE_MAP
 #if 0
 #define MAX_FBO_SIZE 32 /* For test purpose only. */
 #endif
commit 37d4022f01483eefe06b5f12e13ca2ed4003c8f0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 25 23:24:37 2012 +0800

    glamor_render: Optimize the two pass ca rendering.
    
    For the componentAlpha with PictOpOver, we use two pass
    rendering to implement it. Previous implementation call
    two times the glamor_composite_... independently which is
    very inefficient. Now we change the control flow, and do
    the two pass internally and avoid duplicate works.
    
    For the x11perf -rgb10text, this optimization can get about
    30% improvement.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 989bacc..4fad5cd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -72,6 +72,7 @@
 #define xorg_list_init list_init
 #endif
 
+struct glamor_pixmap_private;
 
 typedef struct glamor_composite_shader {
 	GLuint prog;
@@ -84,25 +85,22 @@ typedef struct glamor_composite_shader {
 	GLint mask_wh;
 	GLint source_repeat_mode;
 	GLint mask_repeat_mode;
-} glamor_composite_shader;
-
-typedef struct {
-	INT16 x_src;
-	INT16 y_src;
-	INT16 x_mask;
-	INT16 y_mask;
-	INT16 x_dst;
-	INT16 y_dst;
-	INT16 width;
-	INT16 height;
-} glamor_composite_rect_t;
-
+	union {
+		float source_solid_color[4];
+		struct {
+			struct glamor_pixmap_private *source_priv;
+			PicturePtr source;
+		};
+	};
 
-enum glamor_vertex_type {
-	GLAMOR_VERTEX_POS,
-	GLAMOR_VERTEX_SOURCE,
-	GLAMOR_VERTEX_MASK
-};
+	union {
+		float mask_solid_color[4];
+		struct {
+			struct glamor_pixmap_private *mask_priv;
+			PicturePtr mask;
+		};
+	};
+} glamor_composite_shader;
 
 enum shader_source {
 	SHADER_SOURCE_SOLID,
@@ -133,6 +131,32 @@ struct shader_key {
 	enum shader_in in;
 };
 
+struct blendinfo {
+	Bool dest_alpha;
+	Bool source_alpha;
+	GLenum source_blend;
+	GLenum dest_blend;
+};
+
+typedef struct {
+	INT16 x_src;
+	INT16 y_src;
+	INT16 x_mask;
+	INT16 y_mask;
+	INT16 x_dst;
+	INT16 y_dst;
+	INT16 width;
+	INT16 height;
+} glamor_composite_rect_t;
+
+
+enum glamor_vertex_type {
+	GLAMOR_VERTEX_POS,
+	GLAMOR_VERTEX_SOURCE,
+	GLAMOR_VERTEX_MASK
+};
+
+
 enum gradient_shader {
 	SHADER_GRADIENT_LINEAR,
 	SHADER_GRADIENT_RADIAL,
@@ -463,7 +487,6 @@ typedef enum glamor_pixmap_status {
 	GLAMOR_UPLOAD_FAILED
 } glamor_pixmap_status_t;
 
-
 extern DevPrivateKey glamor_screen_private_key;
 extern DevPrivateKey glamor_pixmap_private_key;
 static inline glamor_screen_private *
@@ -716,6 +739,7 @@ PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
                                            PicturePtr source,
                                            int x_source,
                                            int y_source, int width, int height);
+
 Bool glamor_composite_choose_shader(CARD8 op,
                                     PicturePtr source,
                                     PicturePtr mask,
@@ -724,7 +748,16 @@ Bool glamor_composite_choose_shader(CARD8 op,
 			     	    glamor_pixmap_private *mask_pixmap_priv,
 			     	    glamor_pixmap_private *dest_pixmap_priv,
                                     struct shader_key *s_key,
+				    glamor_composite_shader **shader, 
+				    struct blendinfo *op_info,
                                     PictFormatShort *psaved_source_format);
+
+void
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+				  struct shader_key *key,
+				  glamor_composite_shader *shader,
+				  struct blendinfo *op_info);
+
 void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
 void glamor_emit_composite_vert(ScreenPtr screen,
                                 const float *src_coords,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e2be4d7..5e5ae78 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -43,14 +43,6 @@
 //#define DEBUGRegionPrint(x) do {} while (0)
 #define DEBUGRegionPrint RegionPrint
 #endif
-
-struct blendinfo {
-	Bool dest_alpha;
-	Bool source_alpha;
-	GLenum source_blend;
-	GLenum dest_blend;
-};
-
 static struct blendinfo composite_op_info[] = {
 	[PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
 	[PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
@@ -481,13 +473,11 @@ glamor_fini_composite_shaders(ScreenPtr screen)
 
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
-			CARD8 op, PicturePtr dest, PicturePtr mask)
+			CARD8 op, struct blendinfo *op_info_result,
+			PicturePtr dest, PicturePtr mask)
 {
 	GLenum source_blend, dest_blend;
 	struct blendinfo *op_info;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
 
 	if (op >= ARRAY_SIZE(composite_op_info)) {
 		glamor_fallback("unsupported render op %d \n", op);
@@ -518,25 +508,20 @@ glamor_set_composite_op(ScreenPtr screen,
 			dest_blend = GL_ONE_MINUS_SRC_COLOR;
 	}
 
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
-		dispatch->glDisable(GL_BLEND);
-	} else {
-		dispatch->glEnable(GL_BLEND);
-		dispatch->glBlendFunc(source_blend, dest_blend);
-	}
-	glamor_put_dispatch(glamor_priv);
+	op_info_result->source_blend = source_blend;
+	op_info_result->dest_blend = dest_blend;
+	op_info_result->source_alpha = op_info->source_alpha;
+	op_info_result->dest_alpha = op_info->dest_alpha;
+
 	return TRUE;
 }
 
 static void
-glamor_set_composite_texture(ScreenPtr screen, int unit,
+glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv,
 			     GLuint wh_location, GLuint repeat_location)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 	float wh[4];
 	int repeat_type;
@@ -956,10 +941,11 @@ Bool glamor_composite_choose_shader(CARD8 op,
 			     	    glamor_pixmap_private *mask_pixmap_priv,
 			     	    glamor_pixmap_private *dest_pixmap_priv,
                                     struct shader_key *s_key,
+				    glamor_composite_shader **shader,
+				    struct blendinfo *op_info,
                                     PictFormatShort *psaved_source_format)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
 	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
 	PixmapPtr source_pixmap = NULL;
 	PixmapPtr mask_pixmap = NULL;
@@ -969,8 +955,6 @@ Bool glamor_composite_choose_shader(CARD8 op,
 	struct shader_key key;
 	GLfloat source_solid_color[4];
 	GLfloat mask_solid_color[4];
-	glamor_composite_shader *shader = NULL;
-	glamor_gl_dispatch *dispatch = NULL;
 	Bool ret = FALSE;
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@@ -1175,54 +1159,93 @@ Bool glamor_composite_choose_shader(CARD8 op,
 			goto fail;
 	}
 
-	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 
-	if (!glamor_set_composite_op(screen, op, dest, mask)) {
+	if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
 		goto fail;
-	}
 
-	shader = glamor_lookup_composite_shader(screen, &key);
-	if (shader->prog == 0) {
+	*shader = glamor_lookup_composite_shader(screen, &key);
+	if ((*shader)->prog == 0) {
 		glamor_fallback("no shader program for this"
 		                "render acccel mode\n");
 		goto fail;
 	}
 
+	if (key.source == SHADER_SOURCE_SOLID)
+		memcpy(&(*shader)->source_solid_color[0],
+			source_solid_color, 4*sizeof(float));
+	else {
+		(*shader)->source_priv = source_pixmap_priv;
+		(*shader)->source = source;
+	}
+
+	if (key.mask == SHADER_MASK_SOLID)
+		memcpy(&(*shader)->mask_solid_color[0],
+			mask_solid_color, 4*sizeof(float));
+	else {
+		(*shader)->mask_priv = mask_pixmap_priv;
+		(*shader)->mask = mask;
+	}
+
+	ret = TRUE;
+	memcpy(s_key, &key, sizeof(key));
+	*psaved_source_format = saved_source_format;
+	goto done;
+
+fail:
+	if (saved_source_format)
+		source->format = saved_source_format;
+done:
+	return ret;
+}
+
+void
+glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+				  struct shader_key *key,
+				  glamor_composite_shader *shader,
+				  struct blendinfo *op_info)
+{
+	glamor_gl_dispatch *dispatch;
+	glamor_screen_private *glamor_priv;
+
+	glamor_priv = dest_priv->base.glamor_priv;
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glUseProgram(shader->prog);
 
-	if (key.source == SHADER_SOURCE_SOLID) {
-		glamor_set_composite_solid(dispatch, source_solid_color,
+	if (key->source == SHADER_SOURCE_SOLID) {
+		glamor_set_composite_solid(dispatch,
+			shader->source_solid_color,
 		        shader->source_uniform_location);
 	} else {
-		glamor_set_composite_texture(screen, 0, source,
-		        source_pixmap_priv, shader->source_wh,
+		glamor_set_composite_texture(glamor_priv, 0,
+			shader->source,
+		        shader->source_priv, shader->source_wh,
 		        shader->source_repeat_mode);
 	}
 
-	if (key.mask != SHADER_MASK_NONE) {
-		if (key.mask == SHADER_MASK_SOLID) {
+	if (key->mask != SHADER_MASK_NONE) {
+		if (key->mask == SHADER_MASK_SOLID) {
 			glamor_set_composite_solid(dispatch,
-			        mask_solid_color,
+			        shader->mask_solid_color,
 			        shader->mask_uniform_location);
 		} else {
-			glamor_set_composite_texture(screen, 1, mask,
-			        mask_pixmap_priv, shader->mask_wh,
+			glamor_set_composite_texture(glamor_priv, 1,
+				shader->mask,
+			        shader->mask_priv, shader->mask_wh,
 			        shader->mask_repeat_mode);
 		}
 	}
 
-	glamor_put_dispatch(glamor_priv);
-	ret = TRUE;
-	memcpy(s_key, &key, sizeof(key));
-	*psaved_source_format = saved_source_format;
-	goto done;
+	if (op_info->source_blend == GL_ONE
+	    && op_info->dest_blend == GL_ZERO) {
+		dispatch->glDisable(GL_BLEND);
+	} else {
+		dispatch->glEnable(GL_BLEND);
+		dispatch->glBlendFunc(op_info->source_blend,
+				      op_info->dest_blend);
+	}
 
-fail:
-	if (saved_source_format)
-		source->format = saved_source_format;
-done:
-	return ret;
+	glamor_put_dispatch(glamor_priv);
 }
 
 static Bool
@@ -1233,7 +1256,8 @@ glamor_composite_with_shader(CARD8 op,
 			     glamor_pixmap_private *source_pixmap_priv,
 			     glamor_pixmap_private *mask_pixmap_priv,
 			     glamor_pixmap_private *dest_pixmap_priv,
-			     int nrect, glamor_composite_rect_t * rects)
+			     int nrect, glamor_composite_rect_t * rects,
+			     Bool two_pass_ca)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
@@ -1244,7 +1268,7 @@ glamor_composite_with_shader(CARD8 op,
 	GLfloat dst_xscale, dst_yscale;
 	GLfloat mask_xscale = 1, mask_yscale = 1,
 	        src_xscale = 1, src_yscale = 1;
-	struct shader_key key;
+	struct shader_key key, key_ca;
 	float *vertices;
 	int dest_x_off, dest_y_off;
 	int source_x_off, source_y_off;
@@ -1255,14 +1279,30 @@ glamor_composite_with_shader(CARD8 op,
 	int vert_stride = 4;
 	int nrect_max;
 	Bool ret = FALSE;
+	glamor_composite_shader *shader = NULL, *shader_ca = NULL;
+	struct blendinfo op_info, op_info_ca;
 
 	if(!glamor_composite_choose_shader(op, source, mask, dest,
 					   source_pixmap_priv, mask_pixmap_priv,
 					   dest_pixmap_priv,
-	                                   &key, &saved_source_format)) {
+	                                   &key, &shader, &op_info,
+					   &saved_source_format)) {
 		glamor_fallback("glamor_composite_choose_shader failed\n");
 		return ret;
 	}
+	if (two_pass_ca) {
+		if(!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+						   source_pixmap_priv, mask_pixmap_priv,
+						   dest_pixmap_priv,
+						   &key_ca, &shader_ca, &op_info_ca,
+						   &saved_source_format)) {
+			glamor_fallback("glamor_composite_choose_shader failed\n");
+			return ret;
+		}
+	}
+
+	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 
@@ -1277,8 +1317,7 @@ glamor_composite_with_shader(CARD8 op,
 	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	if (glamor_priv->has_source_coords) {
-		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		source_pixmap = source_pixmap_priv->base.pixmap;
 		glamor_get_drawable_deltas(source->pDrawable,
 					   source_pixmap, &source_x_off,
 					   &source_y_off);
@@ -1292,8 +1331,7 @@ glamor_composite_with_shader(CARD8 op,
 	}
 
 	if (glamor_priv->has_mask_coords) {
-		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		mask_pixmap = mask_pixmap_priv->base.pixmap;
 		glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
 					   &mask_x_off, &mask_y_off);
 		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
@@ -1369,6 +1407,16 @@ glamor_composite_with_shader(CARD8 op,
 		}
 		glamor_flush_composite_rects(screen);
 		nrect -= rect_processed;
+		if (two_pass_ca) {
+			glamor_composite_set_shader_blend(dest_pixmap_priv,
+							&key_ca, shader_ca,
+							&op_info_ca);
+			glamor_flush_composite_rects(screen);
+			if (nrect)
+				glamor_composite_set_shader_blend(dest_pixmap_priv,
+								&key, shader,
+								&op_info);
+		}
 	}
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1475,7 +1523,6 @@ glamor_composite_clipped_region(CARD8 op,
 	glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
 	glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
 	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
-
 	BoxPtr extent;
 	glamor_composite_rect_t rect[10];
 	glamor_composite_rect_t *prect = rect;
@@ -1486,6 +1533,8 @@ glamor_composite_clipped_region(CARD8 op,
 	int height;
 	BoxPtr box;
 	int nbox;
+	Bool two_pass_ca = FALSE;
+
 	extent = RegionExtents(region);
 	box = RegionRects(region);
 	nbox = RegionNumRects(region);
@@ -1557,23 +1606,8 @@ glamor_composite_clipped_region(CARD8 op,
 
 	if (mask && mask->componentAlpha) {
 		if (op == PictOpOver) {
-			glamor_composite_clipped_region(PictOpOutReverse,
-							temp_src, temp_mask, dest,
-							temp_src_priv, temp_mask_priv, dest_pixmap_priv,
-							region,
-							x_temp_src, y_temp_src,
-							x_temp_mask, y_temp_mask,
-							x_dest, y_dest);
-
-			glamor_composite_clipped_region(PictOpAdd,
-							temp_src, temp_mask, dest,
-							temp_src_priv, temp_mask_priv, dest_pixmap_priv,
-							region,
-							x_temp_src, y_temp_src,
-							x_temp_mask, y_temp_mask,
-							x_dest, y_dest);
-			ok = TRUE;
-			goto out;
+			two_pass_ca = TRUE;
+			op = PictOpOutReverse;
 		}
 	}
 
@@ -1624,7 +1658,7 @@ glamor_composite_clipped_region(CARD8 op,
 		ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
 						  temp_src_priv, temp_mask_priv,
 						  dest_pixmap_priv,
-						  box_cnt, prect);
+						  box_cnt, prect, two_pass_ca);
 		if (!ok)
 			break;
 		nbox -= box_cnt;
@@ -1959,7 +1993,6 @@ glamor_composite_glyph_rects(CARD8 op,
 	int n;
 	PicturePtr temp_src = NULL;
 	glamor_composite_rect_t *r;
-	Bool ok;
 
 	ValidatePicture(src);
 	ValidatePicture(dst);
@@ -2004,27 +2037,18 @@ glamor_composite_glyph_rects(CARD8 op,
 
 		if (mask && mask->componentAlpha) {
 			if (op == PictOpOver) {
-				ok = glamor_composite_with_shader(PictOpOutReverse,
-						 temp_src, mask, dst, temp_src_priv,
-						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
-				if (!ok) {
-					goto fallback;
-				}
-				ok |= glamor_composite_with_shader(PictOpAdd,
+				if (glamor_composite_with_shader(PictOpOutReverse,
 						 temp_src, mask, dst, temp_src_priv,
-						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
-				if (ok)
+						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects,
+						 TRUE))
 					goto done;
-				assert(0);
 			}
 		} else {
 				if (glamor_composite_with_shader(op, temp_src, mask, dst, temp_src_priv,
-						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
+						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects, FALSE))
 					goto done;
 		}
 	}
-
-
 fallback:
 	n = nrect;
 	r = rects;
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 3ad9e50..5dd2792 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -701,12 +701,13 @@ _glamor_trapezoids_with_shader(CARD8 op,
 
 	ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
 					     temp_src_priv, NULL, dest_pixmap_priv,
-					     &key, &saved_source_format);
+					     &key, &shader, &op_info, &saved_source_format);
 	if (ret == FALSE) {
 		DEBUGF("can not set the shader program for composite\n");
 		goto TRAPEZOID_RESET_GL;
 	}
-
+	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+	glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, op_info);
 	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
 	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
 	        key.mask != SHADER_MASK_SOLID);
commit 21916cf84f0cd9ada8701650d39b5cf67646eaf7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 25 16:37:22 2012 +0800

    glamor_composite_glyph: Optimize glyphs with non-solid pattern.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b33d969..e2be4d7 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1916,12 +1916,48 @@ glamor_composite_nf(CARD8 op,
 				 FALSE);
 }
 
+static void
+glamor_get_src_rect_extent(int nrect,
+			   glamor_composite_rect_t *rects,
+			   BoxPtr extent)
+{
+	extent->x1 = MAXSHORT;
+	extent->y1 = MAXSHORT;
+	extent->x2 = MINSHORT;
+	extent->y2 = MINSHORT;
+
+	while(nrect--) {
+		if (extent->x1 > rects->x_src)
+			extent->x1 = rects->x_src;
+		if (extent->y1 > rects->y_src)
+			extent->y1 = rects->y_src;
+		if (extent->x2 < rects->x_src + rects->width)
+			extent->x2 = rects->x_src + rects->width;
+		if (extent->y2 < rects->y_src + rects->height)
+			extent->y2 = rects->y_src + rects->height;
+		rects++;
+	}
+}
+
+static void
+glamor_composite_src_rect_translate(int nrect,
+				    glamor_composite_rect_t *rects,
+				    int x, int y)
+{
+	while(nrect--) {
+		rects->x_src += x;
+		rects->y_src += y;
+		rects++;
+	}
+}
+
 void
 glamor_composite_glyph_rects(CARD8 op,
 			     PicturePtr src, PicturePtr mask, PicturePtr dst,
 			     int nrect, glamor_composite_rect_t * rects)
 {
 	int n;
+	PicturePtr temp_src = NULL;
 	glamor_composite_rect_t *r;
 	Bool ok;
 
@@ -1933,41 +1969,69 @@ glamor_composite_glyph_rects(CARD8 op,
 		glamor_pixmap_private *src_pixmap_priv = NULL;
 		glamor_pixmap_private *mask_pixmap_priv = NULL;
 		glamor_pixmap_private *dst_pixmap_priv;
+		glamor_pixmap_private *temp_src_priv = NULL;
+		BoxRec src_extent;
+
+		dst_pixmap_priv = glamor_get_pixmap_private
+					(glamor_get_drawable_pixmap(dst->pDrawable));
 
-		dst_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(dst->pDrawable));
 		if (mask && mask->pDrawable)
-			mask_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(mask->pDrawable));
+			mask_pixmap_priv = glamor_get_pixmap_private
+						(glamor_get_drawable_pixmap(mask->pDrawable));
 		if (src->pDrawable)
-			src_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(src->pDrawable));
+			src_pixmap_priv = glamor_get_pixmap_private
+						(glamor_get_drawable_pixmap(src->pDrawable));
+
+		if (!src->pDrawable
+		    && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
+			glamor_get_src_rect_extent(nrect, rects, &src_extent);
+			temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
+						    src,
+						    src_extent.x1, src_extent.y1,
+						    src_extent.x2 - src_extent.x1,
+						    src_extent.y2 - src_extent.y1);
+			if (!temp_src)
+				goto fallback;
+
+			temp_src_priv = glamor_get_pixmap_private
+						((PixmapPtr)(temp_src->pDrawable));
+			glamor_composite_src_rect_translate(nrect, rects,
+							-src_extent.x1, -src_extent.y1);
+		} else {
+			temp_src = src;
+			temp_src_priv = src_pixmap_priv;
+		}
 
 		if (mask && mask->componentAlpha) {
 			if (op == PictOpOver) {
 				ok = glamor_composite_with_shader(PictOpOutReverse,
-						 src, mask, dst, src_pixmap_priv,
+						 temp_src, mask, dst, temp_src_priv,
 						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
-				if (!ok)
+				if (!ok) {
 					goto fallback;
+				}
 				ok |= glamor_composite_with_shader(PictOpAdd,
-						 src, mask, dst, src_pixmap_priv,
+						 temp_src, mask, dst, temp_src_priv,
 						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
 				if (ok)
-					return;
+					goto done;
 				assert(0);
 			}
 		} else {
-				if (glamor_composite_with_shader(op, src, mask, dst, src_pixmap_priv,
+				if (glamor_composite_with_shader(op, temp_src, mask, dst, temp_src_priv,
 						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
-			return;
+					goto done;
 		}
 	}
 
+
 fallback:
 	n = nrect;
 	r = rects;
 
 	while (n--) {
 		CompositePicture(op,
-				 src,
+				 temp_src ? temp_src : src,
 				 mask,
 				 dst,
 				 r->x_src, r->y_src,
@@ -1975,6 +2039,10 @@ fallback:
 				 r->x_dst, r->y_dst, r->width, r->height);
 		r++;
 	}
+
+done:
+	if (temp_src && temp_src != src)
+		FreePicture(temp_src, 0);
 }
 
 static Bool
commit c1bd50d58d2c7b39e2b5c529bd86fde1ab14d8e6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 21 19:30:51 2012 +0800

    glamor_glyphs: Detect fake or real glyphs overlap.
    
    To split a glyph's extent region to three sub-boxes
    as below.
    
    left box   2 x h
    center box (w-4) x h
    right box  2 x h
    
    Take a simple glyph A as an example:
         *
      __* *__
       *****
      *     *
      ~~   ~~
    
    The left box and right boxes are both 2 x 2. The center box
    is 2 x 4.
    
    The left box has two bitmaps 0001'b and 0010'b to indicate
    the real inked area.
    The right box also has two bitmaps 0010'b and 0001'b.
    
    And then we can check the inked area in left and right boxes with
    previous glyph. If the direction is from left to right, then we
    need to check the previous right bitmap with current left bitmap.
    
    And if we found the center box has overlapped or we overlap with
    not only the previous glyph, we will treat it as real overlapped
    and will render the glyphs via mask.
    
    If we only intersect with previous glyph on the left/right edge.
    Then we further compute the real overlapped bits. We set a loose
    check criteria here, if it has less than two pixel overlapping, we
    treat it as non-overlapping.
    
    With this patch, The aa10text boost fom 1660000 to 320000.
    Almost double the performance! And the cairo test result is the
    same as without this patch.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d3b9009..4af831d 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -51,30 +51,6 @@
          &pos->member != (head);                                        \
          pos = tmp, tmp = __container_of(pos->member.prev, tmp, member))
 
-#ifdef __i386__
-static inline unsigned long __fls(unsigned long x)
-{
-        asm("bsr %1,%0"
-            : "=r" (x)
-            : "rm" (x));
-        return x;
-}
-#else
-static inline unsigned long __fls(unsigned long x)
-{
-   int n;
-
-   if (x == 0) return(0);
-   n = 0;
-   if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
-   if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
-   if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
-   if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
-   if (x <= 0x7FFFFFFF) {n = n + 1;}
-   return 31 - n;
-}
-#endif
-
 inline static int cache_wbucket(int size)
 {
 	int order = __fls(size / 32);
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 362e46f..fa8b55f 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -16,7 +16,7 @@
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
  * 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 
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -33,7 +33,7 @@
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
  * 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 
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * Author: Owen Taylor <otaylor at fishsoup.net>
@@ -69,7 +69,7 @@
 
 typedef struct {
 	PicturePtr source;
-	glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE];
+	glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4];
 	int count;
 } glamor_glyph_buffer_t;
 
@@ -77,6 +77,10 @@ struct glamor_glyph {
 	glamor_glyph_cache_t *cache;
 	uint16_t x, y;
 	uint16_t size, pos;
+	unsigned long long left_x1_map, left_x2_map;
+	unsigned long long right_x1_map, right_x2_map;  /* Use to check real pixel overlap or not. */
+	Bool has_edge_map;
+	Bool cached;
 };
 
 typedef enum {
@@ -253,8 +257,8 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 					  PictureMatchFormat
 					  (screen,
 					   pCachePixmap->
-				   drawable.depth,
-				   cache->picture->format),
+					   drawable.depth,
+					   cache->picture->format),
 					  0, NULL, serverClient,
 				  &error);
 			if (picture) {
@@ -264,7 +268,7 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 					      NULL, picture,
 					      0, 0, 0, 0, 0,
 					      0,
-				      glyph->info.width,
+					      glyph->info.width,
 					      glyph->info.height);
 				FreePicture(picture, 0);
 			}
@@ -299,7 +303,8 @@ glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 	if (priv == NULL)
 		return;
 
-	priv->cache->glyphs[priv->pos] = NULL;
+	if (priv->cached)
+		priv->cache->glyphs[priv->pos] = NULL;
 
 	glamor_glyph_set_private(glyph, NULL);
 	free(priv);
@@ -350,18 +355,101 @@ glamor_glyph_extents(int nlist,
 	extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
 }
 
+static void
+glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
+			     PicturePtr glyph_picture)
+{
+	PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
+	struct glamor_pixmap_private *pixmap_priv;
+	int j;
+	unsigned long long left_x1_map, left_x2_map, right_x1_map, right_x2_map;
+	int bitsPerPixel;
+	int stride;
+	void *bits;
+	int width;
+	unsigned int left_x1_data, left_x2_data, right_x1_data, right_x2_data;
+
+	bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
+	stride = glyph_pixmap->devKind;
+	bits = glyph_pixmap->devPrivate.ptr;
+	width = glyph->info.width;
+	pixmap_priv = glamor_get_pixmap_private(glyph_pixmap);
+
+	if (glyph_pixmap->drawable.width < 2
+	    || !(glyph_pixmap->drawable.depth == 8
+		|| glyph_pixmap->drawable.depth == 1
+		|| glyph_pixmap->drawable.depth == 32)) {
+		priv->has_edge_map = FALSE;
+		return;
+	}
+
+	left_x1_map = left_x2_map = 0;
+	right_x1_map = right_x2_map = 0;
+
+	for(j = 0; j < glyph_pixmap->drawable.height; j++)
+	{
+		if (bitsPerPixel == 8) {
+			unsigned char *data;
+			data =	(unsigned char*)((unsigned char*)bits + stride * j);
+			left_x1_data = *data++;
+			left_x2_data = *data;
+			data =	(unsigned char*)((unsigned char*)bits + stride * j + width - 2);
+			right_x1_data = *data++;
+			right_x2_data = *data;
+		} else if (bitsPerPixel == 32) {
+			left_x1_data = *((unsigned int*)bits + stride/4 * j);
+			left_x2_data = *((unsigned int*)bits + stride/4 * j + 1);
+			right_x1_data = *((unsigned int*)bits + stride/4 * j + width - 2);
+			right_x2_data = *((unsigned int*)bits + stride/4 * j + width - 1);
+		} else if (bitsPerPixel == 1) {
+			unsigned char temp;
+			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
+				+ glyph_pixmap->devKind * j) & 0x3;
+			left_x1_data = temp & 0x1;
+			left_x2_data = temp & 0x2;
+
+			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
+				+ glyph_pixmap->devKind * j
+				+ (glyph_pixmap->drawable.width - 2)/8);
+			right_x1_data = temp
+				    & (1 << ((glyph_pixmap->drawable.width - 2) % 8));
+			temp = *((unsigned char*)glyph_pixmap->devPrivate.ptr
+				+ glyph_pixmap->devKind * j
+				+ (glyph_pixmap->drawable.width - 1)/8);
+			right_x2_data = temp
+				   & (1 << ((glyph_pixmap->drawable.width - 1) % 8));
+		}
+		left_x1_map |= (left_x1_data !=0) << j;
+		left_x2_map |= (left_x2_data !=0) << j;
+		right_x1_map |= (right_x1_data !=0) << j;
+		right_x2_map |= (right_x2_data !=0) << j;
+	}
+
+	priv->left_x1_map = left_x1_map;
+	priv->left_x2_map = left_x2_map;
+	priv->right_x1_map = right_x1_map;
+	priv->right_x2_map = right_x2_map;
+	priv->has_edge_map = TRUE;
+	return;
+}
+
+
+
 /**
  * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
  * bounding box, which appears to be good enough to catch most cases at least.
  */
 static Bool
-glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
+			PictFormatShort mask_format,
+			ScreenPtr screen, Bool check_fake_overlap)
 {
 	int x1, x2, y1, y2;
 	int n;
 	int x, y;
 	BoxRec extents;
 	Bool first = TRUE;
+	struct glamor_glyph *priv;
 
 	x = 0;
 	y = 0;
@@ -370,6 +458,11 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 	extents.x2 = 0;
 	extents.y2 = 0;
 	while (nlist--) {
+		BoxRec left_box, right_box;
+		Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
+		Bool left_to_right = TRUE;
+		struct glamor_glyph *left_priv, *right_priv;
+
 		x += list->xOff;
 		y += list->yOff;
 		n = list->len;
@@ -383,17 +476,22 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 				y += glyph->info.yOff;
 				continue;
 			}
-
+			if (mask_format
+			    && mask_format != GlyphPicture(glyph)[screen->myNum]->format)
+				return TRUE;
 			x1 = x - glyph->info.x;
 			if (x1 < MINSHORT)
 				x1 = MINSHORT;
 			y1 = y - glyph->info.y;
 			if (y1 < MINSHORT)
 				y1 = MINSHORT;
+			if (check_fake_overlap)
+				priv = glamor_glyph_get_private(glyph);
 			x2 = x1 + glyph->info.width;
+			y2 = y1 + glyph->info.height;
+
 			if (x2 > MAXSHORT)
 				x2 = MAXSHORT;
-			y2 = y1 + glyph->info.height;
 			if (y2 > MAXSHORT)
 				y2 = MAXSHORT;
 
@@ -402,23 +500,109 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 				extents.y1 = y1;
 				extents.x2 = x2;
 				extents.y2 = y2;
+
+				if (check_fake_overlap && priv
+				    && priv->has_edge_map && glyph->info.yOff == 0) {
+					left_box.x1 = x1;
+					left_box.x2 = x1 + 1;
+					left_box.y1 = y1;
+
+					right_box.x1 = x2 - 2;
+					right_box.x2 = x2 - 1;
+					right_box.y1 = y1;
+					left_priv = right_priv = priv;
+					has_left_edge_box = TRUE;
+					has_right_edge_box = TRUE;
+				}
+
 				first = FALSE;
 			} else {
+
 				if (x1 < extents.x2 && x2 > extents.x1
 				    && y1 < extents.y2
 				    && y2 > extents.y1) {
-					return TRUE;
+					if (check_fake_overlap && priv
+					    && priv->has_edge_map && glyph->info.yOff == 0) {
+						int left_dx, right_dx;
+						unsigned long long intersected;
+
+						left_dx = has_left_edge_box ? 1 : 0;
+						right_dx = has_right_edge_box ? 1 : 0;
+
+						if (x1 + 1 < extents.x2 - right_dx && x2 - 1 > extents.x1 + left_dx)
+							return TRUE;
+
+						if (left_to_right && has_right_edge_box) {
+							if (x1 == right_box.x1) {
+								intersected = ((priv->left_x1_map & right_priv->right_x1_map)
+										| (priv->left_x2_map & right_priv->right_x2_map));
+								if (intersected)
+									return TRUE;
+							} else if (x1 == right_box.x2) {
+								intersected = (priv->left_x1_map & right_priv->right_x2_map);
+								if (intersected) {
+								#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
+								/* tolerate with two pixels overlap. */
+									intersected &= ~(1<<__fls(intersected));
+									if ((intersected & (intersected - 1)))
+								#endif
+										return TRUE;
+								}
+							}
+						} else if (!left_to_right && has_left_edge_box) {
+							if (x2 - 1 == left_box.x1) {
+								intersected = (priv->right_x2_map & left_priv->left_x1_map);
+								if (intersected) {
+								#ifdef  GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
+								/* tolerate with two pixels overlap. */
+									intersected &= ~(1<<__fls(intersected));
+									if ((intersected & (intersected - 1)))
+								#endif
+										return TRUE;
+								}
+							} else if (x2 - 1 == right_box.x2) {
+								if ((priv->right_x1_map & left_priv->left_x1_map)
+								   || (priv->right_x2_map & left_priv->left_x2_map))
+										return TRUE;
+							}
+						} else {
+							if (x1 < extents.x2 && x1 + 2 > extents.x1)
+								return TRUE;
+						}
+					} else
+						return TRUE;
 				}
+			}
 
-				if (x1 < extents.x1)
-					extents.x1 = x1;
-				if (x2 > extents.x2)
-					extents.x2 = x2;
-				if (y1 < extents.y1)
-					extents.y1 = y1;
-				if (y2 > extents.y2)
-					extents.y2 = y2;
+			if (check_fake_overlap && priv
+			    && priv->has_edge_map && glyph->info.yOff == 0) {
+				if (!has_left_edge_box || x1 < extents.x1) {
+					left_box.x1 = x1;
+					left_box.x2 = x1 + 1;
+					left_box.y1 = y1;
+					has_left_edge_box = TRUE;
+					left_priv = priv;
 			}
+
+			if (!has_right_edge_box || x2 > extents.x2) {
+				right_box.x1 = x2 - 2;
+				right_box.x2 = x2 - 1;
+					right_box.y1 = y1;
+					has_right_edge_box = TRUE;
+					right_priv = priv;
+				}
+			}
+
+			if (x1 < extents.x1)
+				extents.x1 = x1;
+			if (x2 > extents.x2)
+				extents.x2 = x2;
+
+			if (y1 < extents.y1)
+				extents.y1 = y1;
+			if (y2 > extents.y2)
+				extents.y2 = y2;
+
 			x += glyph->info.xOff;
 			y += glyph->info.yOff;
 		}
@@ -427,7 +611,6 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 	return FALSE;
 }
 
-
 static inline unsigned int
 glamor_glyph_size_to_count(int size)
 {
@@ -457,7 +640,7 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 	glamor_glyph_cache_t *cache =
 	    &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) !=
 				 0];
-	struct glamor_glyph *priv = NULL;
+	struct glamor_glyph *priv = NULL, *evicted_priv = NULL;
 	int size, mask, pos, s;
 
 	if (glyph->info.width > GLYPH_MAX_SIZE
@@ -472,6 +655,8 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 	s = glamor_glyph_size_to_count(size);
 	mask = glamor_glyph_count_to_mask(s);
 	pos = (cache->count + s - 1) & mask;
+
+	priv = glamor_glyph_get_private(glyph);
 	if (pos < GLYPH_CACHE_SIZE) {
 		cache->count = pos + s;
 	} else {
@@ -482,34 +667,35 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 			if (evicted == NULL)
 				continue;
 
-			priv = glamor_glyph_get_private(evicted);
-			if (priv->size >= s) {
+			evicted_priv = glamor_glyph_get_private(evicted);
+			assert(evicted_priv->pos == i);
+			if (evicted_priv->size >= s) {
 				cache->glyphs[i] = NULL;
-				glamor_glyph_set_private(evicted, NULL);
+				evicted_priv->cached = FALSE;
 				pos = cache->evict &
 				    glamor_glyph_size_to_mask(size);
 			} else
-				priv = NULL;
+				evicted_priv = NULL;
 			break;
 		}
-		if (priv == NULL) {
+		if (evicted_priv == NULL) {
 			int count = glamor_glyph_size_to_count(size);
 			mask = glamor_glyph_count_to_mask(count);
 			pos = cache->evict & mask;
 			for (s = 0; s < count; s++) {
 				GlyphPtr evicted = cache->glyphs[pos + s];
 				if (evicted != NULL) {
-					if (priv != NULL)
-						free(priv);
 
-					priv =
+					evicted_priv =
 					    glamor_glyph_get_private
 					    (evicted);
-					glamor_glyph_set_private(evicted,
-								 NULL);
+
+					assert(evicted_priv->pos == pos + s);
+					evicted_priv->cached = FALSE;
 					cache->glyphs[pos + s] = NULL;
 				}
 			}
+
 		}
 		/* And pick a new eviction position */
 		cache->evict = rand() % GLYPH_CACHE_SIZE;
@@ -519,9 +705,10 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 		priv = malloc(sizeof(struct glamor_glyph));
 		if (priv == NULL)
 			return NULL;
+		glamor_glyph_set_private(glyph, priv);
+		priv->has_edge_map = FALSE;
 	}
 
-	glamor_glyph_set_private(glyph, priv);
 	cache->glyphs[pos] = glyph;
 
 	priv->cache = cache;
@@ -543,6 +730,11 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 
 	glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x,
 					priv->y);
+#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
+	if (priv->has_edge_map == FALSE && glyph->info.width >= 2)
+		glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture);
+#endif
+	priv->cached = TRUE;
 
 	*out_x = priv->x;
 	*out_y = priv->y;
@@ -554,6 +746,7 @@ static glamor_glyph_cache_result_t
 glamor_buffer_glyph(ScreenPtr screen,
 		    glamor_glyph_buffer_t * buffer,
 		    GlyphPtr glyph, int x_glyph, int y_glyph,
+		    int dx, int dy, int w, int h,
 		    glyphs_flush glyphs_flush, void *flush_arg)
 {
 	glamor_screen_private *glamor_screen =
@@ -588,23 +781,25 @@ glamor_buffer_glyph(ScreenPtr screen,
 
 	priv = glamor_glyph_get_private(glyph);
 
-	if (priv) {
+	if (priv && priv->cached) {
 		rect = &buffer->rects[buffer->count++];
-		rect->x_src = priv->x;
-		rect->y_src = priv->y;
+		rect->x_src = priv->x + dx;
+		rect->y_src = priv->y + dy;
 		if (buffer->source == NULL)
 			buffer->source = priv->cache->picture;
+		assert(priv->cache->glyphs[priv->pos] == glyph);
 	} else {
 		if (glyphs_flush)
 			(*glyphs_flush)(flush_arg);
 		source = glamor_glyph_cache(screen, glyph, &x, &y);
 		if (source != NULL) {
 			rect = &buffer->rects[buffer->count++];
-			rect->x_src = x;
-			rect->y_src = y;
+			rect->x_src = x + dx;
+			rect->y_src = y + dy;
 			if (buffer->source == NULL)
 				buffer->source = source;
 		} else {
+	/* Couldn't find the glyph in the cache, use the glyph picture directly */
 			source = GlyphPicture(glyph)[screen->myNum];
 			if (buffer->source
 			    && buffer->source != source
@@ -613,18 +808,16 @@ glamor_buffer_glyph(ScreenPtr screen,
 			buffer->source = source;
 
 			rect = &buffer->rects[buffer->count++];
-			rect->x_src = 0;
-			rect->y_src = 0;
+			rect->x_src = 0 + dx;
+			rect->y_src = 0 + dy;
 		}
+		priv = glamor_glyph_get_private(glyph);
 	}
 
 	rect->x_dst = x_glyph - glyph->info.x;
 	rect->y_dst = y_glyph - glyph->info.y;
-	rect->width = glyph->info.width;
-	rect->height = glyph->info.height;
-
-	/* Couldn't find the glyph in the cache, use the glyph picture directly */
-
+	rect->width = w;
+	rect->height = h;
 	return GLAMOR_GLYPH_SUCCESS;
 }
 
@@ -708,7 +901,6 @@ glamor_glyphs_via_mask(CARD8 op,
 	fill_rect.width = width;
 	fill_rect.height = height;
 	gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &fill_rect);
-	
 	FreeScratchGC(gc);
 	x = -extents.x1;
 	y = -extents.y1;
@@ -734,6 +926,8 @@ glamor_glyphs_via_mask(CARD8 op,
 
 				glamor_buffer_glyph(screen, &buffer,
 						    glyph, x, y,
+						    0, 0,
+						    glyph->info.width, glyph->info.height,
 						    flush_func,
 						    (void*)&arg);
 			}
@@ -800,7 +994,8 @@ glamor_glyphs_to_dst(CARD8 op,
 		     PicturePtr dst,
 		     INT16 x_src,
 		     INT16 y_src,
-		     int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+		     int nlist, GlyphListPtr list,
+		     GlyphPtr * glyphs)
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
 	int x = 0, y = 0;
@@ -809,14 +1004,21 @@ glamor_glyphs_to_dst(CARD8 op,
 	GlyphPtr glyph;
 	glamor_glyph_buffer_t buffer;
 	struct glyphs_flush_dst_arg arg;
+	BoxPtr rects;
+	int nrect;
 
 	buffer.count = 0;
 	buffer.source = NULL;
+
+	rects = REGION_RECTS(dst->pCompositeClip);
+	nrect = REGION_NUM_RECTS(dst->pCompositeClip);
+
 	while (nlist--) {
 		x += list->xOff;
 		y += list->yOff;
 		n = list->len;
 		while (n--) {
+			int i;
 			glyph = *glyphs++;
 
 			if (glyph->info.width > 0
@@ -836,12 +1038,41 @@ glamor_glyphs_to_dst(CARD8 op,
 				} else
 					flush_func = NULL;
 
-				glamor_buffer_glyph(screen,
-						    &buffer,
-						    glyph, x, y,
-						    flush_func,
-						    (void*)&arg);
-
+				for (i = 0; i < nrect; i++) {
+					int dst_x, dst_y;
+					int dx, dy;
+					int x2, y2;
+
+					dst_x = x - glyph->info.x;
+					dst_y = y - glyph->info.y;
+					x2 = dst_x + glyph->info.width;
+					y2 = dst_y + glyph->info.height;
+					dx = dy = 0;
+					if (rects[i].y1 >= y2)
+						break;
+
+					if (dst_x < rects[i].x1)
+						dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
+					if (x2 > rects[i].x2)
+						x2 = rects[i].x2;
+					if (dst_y < rects[i].y1)
+						dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
+					if (y2 > rects[i].y2)
+						y2 = rects[i].y2;
+
+					if (dst_x < x2 && dst_y < y2) {
+
+						glamor_buffer_glyph(screen,
+								    &buffer,
+								    glyph,
+								    dst_x + glyph->info.x,
+								    dst_y + glyph->info.y,
+								    dx, dy,
+								    x2 - dst_x, y2 - dst_y,
+								    flush_func,
+								    (void*)&arg);
+					}
+				}
 			}
 
 			x += glyph->info.xOff;
@@ -869,39 +1100,59 @@ _glamor_glyphs(CARD8 op,
 	       PicturePtr dst,
 	       PictFormatPtr mask_format,
 	       INT16 x_src,
-	       INT16 y_src, int nlist, GlyphListPtr list, 
+	       INT16 y_src, int nlist, GlyphListPtr list,
 	       GlyphPtr * glyphs, Bool fallback)
 {
-	/* If we don't have a mask format but all the glyphs have the same format
-	 * and don't intersect, use the glyph format as mask format for the full
-	 * benefits of the glyph cache.
-	 */
-	if (!mask_format) {
-		Bool same_format = TRUE;
-		int i;
-
-		mask_format = list[0].format;
-
-		for (i = 0; i < nlist; i++) {
-			if (mask_format->format != list[i].format->format) {
-				same_format = FALSE;
-				break;
-			}
-		}
+	Bool intersected = FALSE;
+	PictFormatShort format;
+#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
+	Bool check_fake_overlap = TRUE;
+	if (!(op == PictOpOver
+	    || op == PictOpAdd
+	    || op == PictOpXor)) {
+	/* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)).
+	 * For those op, (A IN (C ADD D)) OP B !=  (A IN D) OP ((A IN C) OP B)
+	 *		or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B)
+	 * We need to split the faked regions to three or two, and composite the disoverlapped small
+	 * boxes one by one. For other Ops, it's safe to composite the whole box.  */
+		check_fake_overlap = FALSE;
+	}
+#else
+	Bool check_fake_overlap = FALSE;
+#endif
 
-		if (!same_format || (mask_format->depth != 1 &&
-				     glamor_glyphs_intersect(nlist, list,
-							     glyphs))) {
-			mask_format = NULL;
-		}
+	if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
+	    && (dst->format == ((mask_format->depth << 24) | mask_format->format)))) {
+		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
+				     list, glyphs);
+		return TRUE;
 	}
 
 	if (mask_format)
-		glamor_glyphs_via_mask(op, src, dst, mask_format,
-				       x_src, y_src, nlist, list, glyphs);
+		format = mask_format->depth << 24 | mask_format->format;
 	else
+		format = 0;
+
+	intersected = glamor_glyphs_intersect(nlist, list, glyphs,
+				format, dst->pDrawable->pScreen,
+				check_fake_overlap);
+
+	if (!intersected) {
 		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
 				     list, glyphs);
+		return TRUE;
+	}
+
+	if (mask_format)
+		glamor_glyphs_via_mask(op, src, dst, mask_format,
+				       x_src, y_src, nlist, list, glyphs);
+	else {
+		/* No mask_format and has intersect and glyphs have different format.
+		 * XXX do we need to implement a new glyphs rendering function for
+		 * this case?*/
+		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs);
+	}
+
 	return TRUE;
 }
 
@@ -913,7 +1164,7 @@ glamor_glyphs(CARD8 op,
 	      INT16 x_src,
 	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-	_glamor_glyphs(op, src, dst, mask_format, x_src, 
+	_glamor_glyphs(op, src, dst, mask_format, x_src,
 		       y_src, nlist, list, glyphs, TRUE);
 }
 
@@ -923,10 +1174,10 @@ glamor_glyphs_nf(CARD8 op,
 		 PicturePtr dst,
 		 PictFormatPtr mask_format,
 		 INT16 x_src,
-		 INT16 y_src, int nlist, 
+		 INT16 y_src, int nlist,
 		 GlyphListPtr list, GlyphPtr * glyphs)
 {
-	return _glamor_glyphs(op, src, dst, mask_format, x_src, 
+	return _glamor_glyphs(op, src, dst, mask_format, x_src,
 			      y_src, nlist, list, glyphs, FALSE);
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 055077c..989bacc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -971,5 +971,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #if 0
 #define MAX_FBO_SIZE 32 /* For test purpose only. */
 #endif
+//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
+#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 4d86636..ab91f31 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1732,6 +1732,30 @@ static inline void glamor_compare_pictures( ScreenPtr screen,
 	return;
 }
 
+#ifdef __i386__
+static inline unsigned long __fls(unsigned long x)
+{
+        asm("bsr %1,%0"
+            : "=r" (x)
+            : "rm" (x));
+        return x;
+}
+#else
+static inline unsigned long __fls(unsigned long x)
+{
+   int n;
+
+   if (x == 0) return(0);
+   n = 0;
+   if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
+   if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
+   if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
+   if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
+   if (x <= 0x7FFFFFFF) {n = n + 1;}
+   return 31 - n;
+}
+#endif
+
 static inline void glamor_make_current(ScreenPtr screen)
 {
 	glamor_egl_make_current(screen);
commit ea4c22716ca1544e924c7462db6a2797afebff59
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 21 19:29:06 2012 +0800

    glamor_render: Don't fallback when rendering glyphs with OpOver.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6f83c4d..b33d969 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -996,7 +996,8 @@ Bool glamor_composite_choose_shader(CARD8 op,
 							   &source_solid_color[2],
 							   &source_solid_color[3],
 							   PICT_a8r8g8b8);
-		}
+		} else
+			goto fail;
 	} else {
 		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
 	}
@@ -1012,7 +1013,8 @@ Bool glamor_composite_choose_shader(CARD8 op,
 				     &mask_solid_color[1],
 				     &mask_solid_color[2],
 				     &mask_solid_color[3], PICT_a8r8g8b8);
-			}
+			} else
+				goto fail;
 		} else {
 			key.mask = SHADER_MASK_TEXTURE_ALPHA;
 		}
@@ -1921,6 +1923,7 @@ glamor_composite_glyph_rects(CARD8 op,
 {
 	int n;
 	glamor_composite_rect_t *r;
+	Bool ok;
 
 	ValidatePicture(src);
 	ValidatePicture(dst);
@@ -1936,10 +1939,29 @@ glamor_composite_glyph_rects(CARD8 op,
 			mask_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(mask->pDrawable));
 		if (src->pDrawable)
 			src_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(src->pDrawable));
-		if (glamor_composite_with_shader(op, src, mask, dst, src_pixmap_priv,
+
+		if (mask && mask->componentAlpha) {
+			if (op == PictOpOver) {
+				ok = glamor_composite_with_shader(PictOpOutReverse,
+						 src, mask, dst, src_pixmap_priv,
+						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
+				if (!ok)
+					goto fallback;
+				ok |= glamor_composite_with_shader(PictOpAdd,
+						 src, mask, dst, src_pixmap_priv,
+						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects);
+				if (ok)
+					return;
+				assert(0);
+			}
+		} else {
+				if (glamor_composite_with_shader(op, src, mask, dst, src_pixmap_priv,
 						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
 			return;
+		}
 	}
+
+fallback:
 	n = nrect;
 	r = rects;
 
commit 7acbe895618837305cf4050731ccd1cd3bc11589
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 21 19:27:07 2012 +0800

    glamor_create_pixmap: Allocate glyphs pixmap in memory.
    
    As we have glyphs atlas cache, we don't need to hold each
    glyphs on GPU. And for the subsequent optimization, we need
    to store the original glyphs pixmap on system memory.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e491783..d087b82 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -142,6 +142,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		return NullPixmap;
 
 	if ((usage == GLAMOR_CREATE_PIXMAP_CPU
+	     || usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE
 		|| (w == 0 && h == 0)
 		|| !glamor_check_pixmap_fbo_depth(depth))
 	    || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
commit 1e4fc85a71cc6498a7e11872026062fceb5bbdf1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 21 19:26:28 2012 +0800

    glamor_fbo: fix a memory leak for large pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 1ab7686..d3b9009 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -553,8 +553,9 @@ glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
 		fbo = glamor_pixmap_detach_fbo(priv);
 		if (fbo)
 			glamor_destroy_fbo(fbo);
-		free(priv);
 	}
+
+	free(priv);
 }
 
 Bool
commit 2122e60bf9027b63ddc59c0aa2a441af3687cb3a
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Jun 15 09:00:15 2012 +0800

    Fix a bug for trapezoid clip
    
     We find in some cases the trapezoid will be render as a triangle and
     the left edge and right edge will cross with each other just bellow
     the top or over the bottom. The distance between the cross poind and
     the top or bottom is less than pixman_fixed_1_minus_e, so after the
     fixed converted to int, the cross point has the same value with the
     top or botton and the triangle should not be affected. But in our
     clip logic, the cross point will be clipped out. So add a logic
     to fix this problem.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index cc6a706..3ad9e50 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -38,6 +38,8 @@
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
 
+#define DEBUG_CLIP_VTX 0
+
 #define POINT_INSIDE_CLIP_RECT(point, rect)	\
     (point[0] >= IntToxFixed(rect->x1)		\
      && point[0] <= IntToxFixed(rect->x2) 	\
@@ -45,6 +47,28 @@
      && point[1] <= IntToxFixed(rect->y2))
 
 static xFixed
+_glamor_lines_crossfixedY (xLineFixed *l, xLineFixed *r)
+{
+	xFixed dx1 = l->p2.x - l->p1.x;
+	xFixed dx2 = r->p2.x - r->p1.x;
+	xFixed dy1 = l->p2.y - l->p1.y;
+	xFixed dy2 = r->p2.y - r->p1.y;
+	xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1;
+	xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x);
+	tmp = (xFixed_32_32) dx1 * dy2;
+	xFixed_32_32 dividend2 = (tmp >> 32) * l->p1.y;
+	tmp = (xFixed_32_32) dy1 * dx2;
+	xFixed_32_32 dividend3 = (tmp >> 32) * r->p1.y;
+	xFixed_32_32 divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
+	                           - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
+
+	if (divisor)
+		return (xFixed)((dividend2 - dividend1 - dividend3) / divisor);
+
+	return 0xFFFFFFFF;
+}
+
+static xFixed
 _glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil)
 {
 	xFixed dx = l->p2.x - l->p1.x;
@@ -67,22 +91,86 @@ _glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
 }
 
 static Bool
-point_inside_trapezoid(int point[2], xTrapezoid * trap)
+point_inside_trapezoid(int point[2], xTrapezoid * trap, xFixed cut_y)
 {
 	int ret = TRUE;
 	int tmp;
-	if (point[1] > trap->bottom
-	     || point[1] < trap->top)
+	if (point[1] > trap->bottom) {
 		ret = FALSE;
+		if (DEBUG_CLIP_VTX) {
+			ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), "
+			       "bottom = %d(0x%x)\n",
+			       (unsigned int)xFixedToInt(point[1]), point[1],
+			       (unsigned int)xFixedToInt(trap->bottom),
+			       (unsigned int)trap->bottom);
+		}
+
+		return ret;
+	}
+
+	if (point[1] < trap->top) {
+		ret = FALSE;
+		if (DEBUG_CLIP_VTX) {
+			ErrorF("Out of Trap top, point[1] = %d(0x%x)), "
+			     "top = %d(0x%x)\n",
+			     (unsigned int)xFixedToInt(point[1]), point[1],
+			     (unsigned int)xFixedToInt(trap->top),
+			     (unsigned int)trap->top);
+		}
+
+		return ret;
+	}
 
 	tmp = _glamor_linefixedX (&trap->left, point[1], FALSE);
-	if (point[0] < tmp)
+	if (point[0] < tmp) {
 		ret = FALSE;
 
+		if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
+		           abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
+		           tmp - point[0] < pixman_fixed_1_minus_e) {
+			ret = TRUE;
+		} else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
+		           point[1] - trap->bottom < pixman_fixed_1_minus_e &&
+		           tmp - point[0] < pixman_fixed_1_minus_e) {
+			ret = TRUE;
+		}
+
+		if (DEBUG_CLIP_VTX && !ret) {
+			ErrorF("Out of Trap left, point[0] = %d(0x%x)), "
+			       "left = %d(0x%x)\n",
+			       (unsigned int)xFixedToInt(point[0]), point[0],
+			       (unsigned int)xFixedToInt(tmp), (unsigned int)tmp);
+		}
+
+		if (!ret)
+			return ret;
+	}
+
 	tmp = _glamor_linefixedX (&trap->right, point[1], TRUE);
-	if (point[0] > tmp)
+	if (point[0] > tmp) {
 		ret = FALSE;
 
+		if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
+		           abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
+		           point[0] - tmp < pixman_fixed_1_minus_e) {
+			ret = TRUE;
+		} else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
+		           abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e &&
+		           point[0] - tmp < pixman_fixed_1_minus_e) {
+			ret = TRUE;
+		}
+
+		if (DEBUG_CLIP_VTX && !ret) {
+			ErrorF("Out of Trap right, point[0] = %d(0x%x)), "
+			       "right = %d(0x%x)\n",
+			       (unsigned int)xFixedToInt(point[0]), point[0],
+			       (unsigned int)xFixedToInt(tmp), (unsigned int)tmp);
+		}
+
+		if (!ret)
+			return ret;
+	}
+
 	return ret;
 }
 
@@ -125,12 +213,11 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 	glamor_put_dispatch(glamor_priv);
 }
 
-#define DEBUG_CLIP_VTX 0
-
 static Bool
 _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
         int vertex[6], int *num)
 {
+	xFixed edge_cross_y = 0xFFFFFFFF;
 	int tl[2];
 	int bl[2];
 	int tr[2];
@@ -217,7 +304,7 @@ _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
 
 #define ADD_VERTEX_IF_INSIDE(vtx)				\
 	if(POINT_INSIDE_CLIP_RECT(vtx, pbox)			\
-	   && point_inside_trapezoid(vtx, trap)){		\
+	   && point_inside_trapezoid(vtx, trap, edge_cross_y)){	\
 	    tmp_vtx[vertex_num] = xFixedToInt(vtx[0]);		\
 	    tmp_vtx[vertex_num + 1] = xFixedToInt(vtx[1]);	\
 	    vertex_num += 2;					\
@@ -239,6 +326,18 @@ _glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
 		       "the Rect\n");				\
 	}
 
+	/*Trap's right edge cut right edge. */
+	if((!IS_TRAP_EDGE_VERTICAL((&trap->left))) ||
+	        (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) {
+		edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right));
+		if (DEBUG_CLIP_VTX) {
+			ErrorF("Trap's left edge cut right edge at %d(0x%x), "
+			       "trap_top = %x, trap_bottom = %x\n",
+			       xFixedToInt(edge_cross_y), edge_cross_y,
+			       (unsigned int)trap->top, (unsigned int)trap->bottom);
+		}
+	}
+
 	/*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */
 	CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left));
 	CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left));
commit 6ed418d17b5143f32b3b415103f3157a1b05e3db
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 15 13:31:30 2012 +0800

    gles2_largepixmap: force clip for a non-large pixmap.
    
    One case we need force clip when download/upload a drm_texture
    pixmap. Actually, this is only meaningful for testing purpose.
    As we may set the max_fbo_size to a very small value, but the
    drm texture may exceed this value but the drm texture pixmap
    is not largepixmap. This is not a problem with OpenGL. But for
    GLES2, we may need to call glamor_es2_pixmap_read_prepare to
    create a temporary fbo to do the color conversion. Then we have
    to force clip the drm pixmap here to avoid large pixmap handling
    at glamor_es2_pixmap_read_prepare.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 10d6df3..ce243ab 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -684,6 +684,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 	GLenum format, type;
 	int no_alpha, revert, swap_rb;
 	glamor_pixmap_private *pixmap_priv;
+	Bool force_clip;
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
@@ -699,7 +700,10 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 		return FALSE;
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+	force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+			&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
 		RegionRec region;
 		BoxRec box;
 		int n_region;
@@ -715,7 +719,12 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 		box.x2 = x + w;
 		box.y2 = y + h;
 		RegionInitBoxes(&region, &box, 1);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
+		if (!force_clip)
+			clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
+		else
+			clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
+							pixmap_priv->base.glamor_priv->max_fbo_size,
+							pixmap_priv->base.glamor_priv->max_fbo_size, 0, 0);
 		DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
 		for(i = 0; i < n_region; i++)
 		{
@@ -1058,13 +1067,14 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	GLenum format, type;
 	int no_alpha, revert, swap_rb;
 	glamor_pixmap_private *pixmap_priv;
+	Bool force_clip;
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
 						   &type,
 						   &no_alpha,
 						   &revert,
-						   &swap_rb, 1)) {
+						   &swap_rb, 0)) {
 		glamor_fallback("Unknown pixmap depth %d.\n",
 				pixmap->drawable.depth);
 		return NULL;
@@ -1074,7 +1084,10 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return NULL;
 
-	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+	force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+			&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
 
 		RegionRec region;
 		BoxRec box;
@@ -1091,7 +1104,14 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		box.x2 = x + w;
 		box.y2 = y + h;
 		RegionInitBoxes(&region, &box, 1);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
+
+		if (!force_clip)
+			clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
+		else
+			clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
+							pixmap_priv->base.glamor_priv->max_fbo_size,
+							pixmap_priv->base.glamor_priv->max_fbo_size, 0, 0);
+
 		DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
 		for(i = 0; i < n_region; i++)
 		{
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e2059b1..6f83c4d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -602,8 +602,10 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	/* XXX may be we can eaxctly check whether we need to touch
-	 * the out-of-box area then determine whether we need to fix.
+
+	/*
+	 *  GLES2 doesn't support RepeatNone. We need to fix it anyway.
+	 *
 	 **/
 	if (repeat_type != RepeatNone)
 		repeat_type += RepeatFix;
@@ -615,7 +617,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	}
 	if (repeat_type >= RepeatFix) {
 		glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
-		if (wh[0] != 1.0 || wh[1] != 1.0)
+		if ((wh[0] != 1.0 || wh[1] != 1.0 )
+		     || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+			  && repeat_type == RepeatFix))
 			dispatch->glUniform4fv(wh_location, 1, wh);
 		else
 			repeat_type -= RepeatFix;
commit c41d5c79e7d8772be38b77122817fb872f2d721d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 15 09:03:42 2012 +0800

    glamor_emit_composite_vert: Optimize to don't do two times vert coping.
    
    We change some macros to put the vert to the vertex buffer
    directly when we cacluating it. This way, we can get about
    4% performance gain.
    
    This commit also fixed one RepeatPad bug, when we RepeatPad
    a not eaxct size fbo. We need to calculate the edge. The edge
    should be 1.0 - half point, not 1.0.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a228a22..e2059b1 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -82,20 +82,20 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform int 			mask_repeat_mode;\n";
 	const char *relocate_texture =
 	    GLAMOR_DEFAULT_PRECISION
-	    "vec2 rel_tex_coord(vec2 texture, vec2 wh, int repeat) \n"
+	    "vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
 	    "{\n"
 	    "   vec2 rel_tex; \n"
-	    "   rel_tex = texture * wh; \n"
+	    "   rel_tex = texture * wh.xy; \n"
 	    "	if (repeat == RepeatNone)\n"
 	    "		return rel_tex; \n"
 	    "   else if (repeat == RepeatNormal) \n"
-	    "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+	    "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); 	\n"
 	    "   else if(repeat == RepeatPad) { \n"
-	    "           if (rel_tex.x > 1.0) rel_tex.x = 1.0;		  \n"
-	    "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;		  \n"
-	    "           if (rel_tex.y > 1.0) rel_tex.y = 1.0;		  \n"
+	    "           if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.;  	\n"
+	    "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;	  	\n"
+	    "           if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.;	\n"
 	    "		else if(rel_tex.y < 0.0) rel_tex.y = 0.0;	\n"
-	    "   	rel_tex = rel_tex / wh; \n"
+	    "   	rel_tex = rel_tex / wh.xy; \n"
 	    "    } \n"
 	    "   else if(repeat == RepeatReflect) {\n"
 	    "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
@@ -112,14 +112,14 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	/* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
 	 * rel_sampler will recalculate the texture coords.*/
 	const char *rel_sampler =
-	    " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec2 wh, int repeat, int set_alpha)\n"
+	    " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
 	    "{\n"
 	    "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
 	    "   if (repeat == RepeatFix) {\n"
-	    "		if (!(tex.x >= 0.0 && tex.x <= 1.0 \n"
-	    "		    && tex.y >= 0.0 && tex.y <= 1.0))\n"
+	    "		if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
+	    "		    && tex.y >= 0.0 && tex.y < 1.0))\n"
 	    "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
-	    "		tex = (fract(tex) / wh);\n"
+	    "		tex = (fract(tex) / wh.xy);\n"
 	    "	}\n"
 	    "	if (set_alpha != 1)\n"
 	    "		return texture2D(tex_image, tex);\n"
@@ -135,7 +135,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 source_texture;\n"
 	    "uniform sampler2D source_sampler;\n"
-	    "uniform vec2 source_wh;"
+	    "uniform vec4 source_wh;"
 	    "vec4 get_source()\n"
 	    "{\n"
 	    "   if (source_repeat_mode < RepeatFix)\n"
@@ -147,7 +147,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
 	    "uniform sampler2D source_sampler;\n"
-	    "uniform vec2 source_wh;\n"
+	    "uniform vec4 source_wh;\n"
 	    "vec4 get_source()\n"
 	    "{\n"
 	    "   if (source_repeat_mode < RepeatFix) \n"
@@ -162,7 +162,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	const char *mask_alpha_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
 	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec2 mask_wh;\n"
+	    "uniform vec4 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
 	    "   if (mask_repeat_mode < RepeatFix) \n"
@@ -174,7 +174,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
 	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec2 mask_wh;\n"
+	    "uniform vec4 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
 	    "   if (mask_repeat_mode < RepeatFix) \n"
@@ -538,7 +538,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
-	float wh[2];
+	float wh[4];
 	int repeat_type;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
@@ -605,19 +605,20 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	/* XXX may be we can eaxctly check whether we need to touch
 	 * the out-of-box area then determine whether we need to fix.
 	 **/
-	/*if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE)*/ {
-		if (repeat_type != RepeatNone)
+	if (repeat_type != RepeatNone)
+		repeat_type += RepeatFix;
+	else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+		 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		if (picture->transform
+		   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
 			repeat_type += RepeatFix;
-		else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-			 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-			if (picture->transform
-			   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
-				repeat_type += RepeatFix;
-		}
-		if (repeat_type >= RepeatFix) {
-			glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
-			dispatch->glUniform2fv(wh_location, 1, wh);
-		}
+	}
+	if (repeat_type >= RepeatFix) {
+		glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
+		if (wh[0] != 1.0 || wh[1] != 1.0)
+			dispatch->glUniform4fv(wh_location, 1, wh);
+		else
+			repeat_type -= RepeatFix;
 	}
 	dispatch->glUniform1i(repeat_location, repeat_type);
 	glamor_put_dispatch(glamor_priv);
@@ -751,7 +752,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 		dispatch->glBufferData(GL_ARRAY_BUFFER,
 				       n_verts * sizeof(float) * 2,
 				       NULL, GL_DYNAMIC_DRAW);
-		glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+		glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
 	}
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
@@ -814,6 +815,8 @@ glamor_emit_composite_vert(ScreenPtr screen,
 	glamor_priv->vbo_offset += glamor_priv->vb_stride;
 }
 
+
+
 static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
@@ -840,22 +843,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	glamor_put_dispatch(glamor_priv);
 }
 
-static void
-glamor_emit_composite_rect(ScreenPtr screen,
-			   const float *src_coords,
-			   const float *mask_coords,
-			   const float *dst_coords)
-{
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 0);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 1);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 2);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 3);
-}
-
 int pict_format_combine_tab[][3] = {
 	{PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
 	{PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
@@ -926,34 +913,35 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
 				     float *matrix,
 				     float xscale, float yscale,
 				     int x1, int y1, int x2, int y2,
-				     int yInverted, float *texcoords)
+				     int yInverted, float *texcoords,
+				     int stride)
 {
 	if (!matrix && repeat_type == RepeatNone)
-		glamor_set_normalize_tcoords(priv, xscale, yscale,
+		glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
 					     x1, y1,
 					     x2, y2,
 					     yInverted,
-					     texcoords);
+					     texcoords, stride);
 	else if (matrix && repeat_type == RepeatNone)
-		glamor_set_transformed_normalize_tcoords(priv, matrix, xscale,
+		glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
 							 yscale, x1, y1,
 							 x2, y2,
 							 yInverted,
-							 texcoords);
+							 texcoords, stride);
 	else if (!matrix && repeat_type != RepeatNone)
-		glamor_set_repeat_normalize_tcoords(priv, repeat_type,
+		glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
 						    xscale, yscale,
 						    x1, y1,
 						    x2, y2,
 						    yInverted,
-						    texcoords);
+						    texcoords, stride);
 	else if (matrix && repeat_type != RepeatNone)
-		glamor_set_repeat_transformed_normalize_tcoords(priv, repeat_type,
+		glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
 								matrix, xscale, yscale,
 								x1, y1,
 								x2, y2,
 								yInverted,
-								texcoords);
+								texcoords, stride);
 }
 
 Bool glamor_composite_choose_shader(CARD8 op,
@@ -1251,7 +1239,7 @@ glamor_composite_with_shader(CARD8 op,
 	GLfloat mask_xscale = 1, mask_yscale = 1,
 	        src_xscale = 1, src_yscale = 1;
 	struct shader_key key;
-	float vertices[8], source_texcoords[8], mask_texcoords[8];
+	float *vertices;
 	int dest_x_off, dest_y_off;
 	int source_x_off, source_y_off;
 	int mask_x_off, mask_y_off;
@@ -1316,11 +1304,12 @@ glamor_composite_with_shader(CARD8 op,
 
 	while(nrect) {
 		int mrect, rect_processed;
+		int vb_stride;
 
 		mrect = nrect > nrect_max ? nrect_max : nrect ;
 		glamor_setup_composite_vbo(screen, mrect * vert_stride);
 		rect_processed = mrect;
-
+		vb_stride = glamor_priv->vb_stride/sizeof(float);
 		while (mrect--) {
 			INT16 x_source;
 			INT16 y_source;
@@ -1342,33 +1331,34 @@ glamor_composite_with_shader(CARD8 op,
 
 			DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
 				x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height);
-
-			glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
+			vertices = (float*)(glamor_priv->vb + glamor_priv->vbo_offset);
+			assert(glamor_priv->vbo_offset < glamor_priv->vbo_size - glamor_priv->vb_stride);
+			glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
 						     dst_yscale,
 						     x_dest, y_dest,
 						     x_dest + width, y_dest + height,
 						     glamor_priv->yInverted,
-						     vertices);
-
-			if (key.source != SHADER_SOURCE_SOLID)
+						     vertices, vb_stride);
+			vertices += 2;
+			if (key.source != SHADER_SOURCE_SOLID) {
 				glamor_set_normalize_tcoords_generic(
 					source_pixmap_priv, source->repeatType, psrc_matrix,
 					src_xscale, src_yscale, x_source, y_source,
 					x_source + width, y_source + height,
-					glamor_priv->yInverted, source_texcoords);
+					glamor_priv->yInverted, vertices, vb_stride);
+				vertices += 2;
+			}
 
 			if (key.mask != SHADER_MASK_NONE
-			    && key.mask != SHADER_MASK_SOLID)
+			    && key.mask != SHADER_MASK_SOLID) {
 				glamor_set_normalize_tcoords_generic(
 					mask_pixmap_priv, mask->repeatType, pmask_matrix,
 					mask_xscale, mask_yscale, x_mask, y_mask,
 					x_mask + width, y_mask + height,
-					glamor_priv->yInverted, mask_texcoords);
-
-			glamor_emit_composite_rect(screen,
-						   source_texcoords,
-						   mask_texcoords,
-						   vertices);
+					glamor_priv->yInverted, vertices, vb_stride);
+			}
+			glamor_priv->render_nr_verts += 4;
+			glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
 			rects++;
 		}
 		glamor_flush_composite_rects(screen);
@@ -1500,6 +1490,7 @@ glamor_composite_clipped_region(CARD8 op,
 	y_temp_src = y_source;
 	x_temp_mask = x_mask;
 	y_temp_mask = y_mask;
+
 	DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
 		x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
 
@@ -1929,7 +1920,6 @@ glamor_composite_glyph_rects(CARD8 op,
 
 	ValidatePicture(src);
 	ValidatePicture(dst);
-
 	if (!(glamor_is_large_picture(src)
 	    || (mask && glamor_is_large_picture(mask))
 	    || glamor_is_large_picture(dst))) {
@@ -1946,7 +1936,6 @@ glamor_composite_glyph_rects(CARD8 op,
 						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
 			return;
 	}
-
 	n = nrect;
 	r = rects;
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 206485f..7809e8b 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -124,7 +124,7 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
 	glamor_pixmap_private *src_pixmap_priv;
 	glamor_pixmap_private *dst_pixmap_priv;
-	float wh[2];
+	float wh[4];
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 51a5b0e..4d86636 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -74,6 +74,8 @@
 	PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h);	\
 	wh[0] = (float)priv->base.fbo->width / actual_w;	\
 	wh[1] = (float)priv->base.fbo->height / actual_h;	\
+	wh[2] = 1.0 / priv->base.fbo->width;			\
+	wh[3] = 1.0 / priv->base.fbo->height;			\
   } while(0)
 
 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
@@ -245,16 +247,11 @@
 			ty1 = d - priv->box.y1;			\
 			ty2 = ty1 + ((_y2_) - (_y1_));		\
 		}						\
-	} else if (repeat_type == RepeatNormal) {		\
+	} else { /* RepeatNormal*/				\
 		tx1 = (c - priv->box.x1);  			\
 		ty1 = (d - priv->box.y1);			\
 		tx2 = tx1 + ((_x2_) - (_x1_));			\
 		ty2 = ty1 + ((_y2_) - (_y1_));			\
-	} else {						\
-		tx1 = _x1_ - priv->box.x1;			\
-		ty1 = _y1_ - priv->box.y1;			\
-		tx2 = tx1 + ((_x2_) - (_x1_));			\
-		ty2 = ty1 + ((_y2_) - (_y1_));			\
 	}							\
    } while(0)
 
@@ -368,27 +365,46 @@
 				     yInverted);			\
     } while (0)
 
-#define glamor_set_transformed_normalize_tcoords( priv,			\
+#define glamor_set_transformed_normalize_tcoords_ext( priv,		\
 						  matrix,		\
 						  xscale,		\
 						  yscale,		\
                                                   tx1, ty1, tx2, ty2,   \
-                                                  yInverted, texcoords)	\
+                                                  yInverted, texcoords,	\
+						  stride)		\
   do {									\
     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
 				 texcoords, tx1, ty1,			\
 				 yInverted);				\
     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
-				 texcoords + 2, tx2, ty1,		\
+				 texcoords + 1 * stride, tx2, ty1,	\
 				 yInverted);				\
     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
-				 texcoords + 4, tx2, ty2,		\
+				 texcoords + 2 * stride, tx2, ty2,	\
 				 yInverted);				\
     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
-				 texcoords + 6, tx1, ty2,		\
+				 texcoords + 3 * stride, tx1, ty2,	\
 				 yInverted);				\
   } while (0)
 
+#define glamor_set_transformed_normalize_tcoords( priv,			\
+						  matrix,		\
+						  xscale,		\
+						  yscale,		\
+                                                  tx1, ty1, tx2, ty2,   \
+                                                  yInverted, texcoords)	\
+  do {									\
+	glamor_set_transformed_normalize_tcoords_ext( priv,		\
+						  matrix,		\
+						  xscale,		\
+						  yscale,		\
+                                                  tx1, ty1, tx2, ty2,   \
+                                                  yInverted, texcoords,	\
+						  2);			\
+  } while (0)
+
+
+
 #define glamor_set_normalize_tri_tcoords(xscale,		\
 					 yscale,		\
 					 vtx,			\
@@ -409,7 +425,7 @@
 				yInverted);			\
     } while (0)
 
-#define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
+#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv,	\
 							 repeat_type,	\
 							 matrix,	\
 							 xscale,	\
@@ -417,13 +433,14 @@
 							 _x1_, _y1_,	\
 							 _x2_, _y2_,   	\
 							 yInverted,	\
-							 texcoords)	\
+							 texcoords,	\
+							 stride)	\
   do {									\
     if (priv->type != GLAMOR_TEXTURE_LARGE) {				\
-	glamor_set_transformed_normalize_tcoords(priv, matrix, xscale,	\
+	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
 						 yscale, _x1_, _y1_,	\
 						 _x2_, _y2_, yInverted,	\
-						 texcoords);		\
+						 texcoords, stride);	\
     } else {								\
 	/* For a large pixmap, if both transform and repeat are set,
 	 * the transform must only has x and y scale factor.*/		\
@@ -453,54 +470,115 @@
     _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1,		\
 				 texcoords, yInverted);			\
     _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2,		\
-				 texcoords + 2, yInverted);		\
+				 texcoords + 1 * stride, yInverted);	\
     _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3,		\
-				 texcoords + 4, yInverted);		\
+				 texcoords + 2 * stride, yInverted);	\
     _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4,		\
-				 texcoords + 6, yInverted);		\
+				 texcoords + 3 * stride, yInverted);	\
    }									\
   } while (0)
 
+
+#define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
+							 repeat_type,	\
+							 matrix,	\
+							 xscale,	\
+							 yscale,	\
+							 _x1_, _y1_,	\
+							 _x2_, _y2_,   	\
+							 yInverted,	\
+							 texcoords)	\
+  do {									\
+	glamor_set_repeat_transformed_normalize_tcoords_ext( priv,	\
+							 repeat_type,	\
+							 matrix,	\
+							 xscale,	\
+							 yscale,	\
+							 _x1_, _y1_,	\
+							 _x2_, _y2_,   	\
+							 yInverted,	\
+							 texcoords,	\
+							 2);	\
+  } while (0)
+
 #define _glamor_set_normalize_tcoords(xscale, yscale, tx1,		\
 				      ty1, tx2, ty2,			\
-				      yInverted, vertices)		\
+				      yInverted, vertices, stride)	\
   do {									\
-    (vertices)[0] = t_from_x_coord_x(xscale, tx1);			\
-    (vertices)[2] = t_from_x_coord_x(xscale, tx2);			\
-    (vertices)[4] = (vertices)[2];					\
-    (vertices)[6] = (vertices)[0];					\
+    /* vertices may be write-only, so we use following			\
+     * temporary variable. */ 						\
+    float _t0_, _t1_, _t2_, _t5_;					\
+    (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1);		\
+    (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
+    (vertices)[2 * stride] = _t2_;					\
+    (vertices)[3 * stride] = _t0_;					\
     if (yInverted) {							\
-      (vertices)[1] = t_from_x_coord_y_inverted(yscale, ty1);		\
-      (vertices)[5] = t_from_x_coord_y_inverted(yscale, ty2);		\
+      (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1);	\
+      (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\
     }									\
     else {								\
-      (vertices)[1] = t_from_x_coord_y(yscale, ty1);			\
-      (vertices)[5] = t_from_x_coord_y(yscale, ty2);			\
+      (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1);		\
+      (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\
     }									\
-    (vertices)[3] = (vertices)[1];					\
-    (vertices)[7] = (vertices)[5];					\
-    DEBUGF("texture %f %f %f %f\n", tx1, ty1, tx2, ty2);		\
-    DEBUGF("texture %f %f %f %f\n", (vertices)[0], (vertices)[1],	\
-	(vertices)[2], (vertices)[3]);					\
-    DEBUGF("texture %f %f %f %f\n", (vertices)[4], (vertices)[5],	\
-	(vertices)[6], (vertices)[7]);					\
+    (vertices)[1 * stride + 1] = _t1_;					\
+    (vertices)[3 * stride + 1] = _t5_;					\
   } while(0)
 
+#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     yInverted, vertices, stride)	\
+  do {									\
+     if (priv->type == GLAMOR_TEXTURE_LARGE) {				\
+	float tx1, tx2, ty1, ty2;					\
+	int fbo_x_off, fbo_y_off;					\
+	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
+	tx1 = x1 + fbo_x_off; 						\
+	tx2 = x2 + fbo_x_off;						\
+	ty1 = y1 + fbo_y_off;						\
+	ty2 = y2 + fbo_y_off;						\
+	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
+				   tx2, ty2, yInverted, vertices,	\
+				   stride);				\
+     } else								\
+	_glamor_set_normalize_tcoords(xscale, yscale, x1, y1,		\
+				   x2, y2, yInverted, vertices, stride);\
+ } while(0)
+
+
 #define glamor_set_normalize_tcoords(priv, xscale, yscale,		\
 				     x1, y1, x2, y2,			\
                                      yInverted, vertices)		\
   do {									\
-     float tx1, tx2, ty1, ty2;						\
-     int fbo_x_off, fbo_y_off;						\
-     pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
-     tx1 = x1 + fbo_x_off; 						\
-     tx2 = x2 + fbo_x_off;						\
-     ty1 = y1 + fbo_y_off;						\
-     ty2 = y2 + fbo_y_off;						\
-     _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
-				   tx2, ty2, yInverted, vertices);	\
+	glamor_set_normalize_tcoords_ext(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     yInverted, vertices, 2);		\
  } while(0)
 
+#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,	\
+					    xscale, yscale,		\
+					    _x1_, _y1_, _x2_, _y2_,	\
+	                                    yInverted, vertices, stride)\
+  do {									\
+     if (priv->type == GLAMOR_TEXTURE_LARGE) {				\
+	float tx1, tx2, ty1, ty2;					\
+	if (repeat_type == RepeatPad) {					\
+		tx1 = _x1_ - priv->large.box.x1;			\
+		ty1 = _y1_ - priv->large.box.y1;			\
+		tx2 = tx1 + ((_x2_) - (_x1_));				\
+		ty2 = ty1 + ((_y2_) - (_y1_));				\
+	} else {							\
+	glamor_get_repeat_coords((&priv->large), repeat_type,		\
+				 tx1, ty1, tx2, ty2,			\
+				 _x1_, _y1_, _x2_, _y2_);		\
+	}								\
+	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
+				   tx2, ty2, yInverted, vertices,	\
+				   stride);				\
+     } else								\
+	_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_,	\
+				   _x2_, _y2_, yInverted, vertices,	\
+				   stride);				\
+ } while(0)
 
 
 #define glamor_set_repeat_normalize_tcoords(priv, repeat_type,		\
@@ -508,16 +586,10 @@
 					    _x1_, _y1_, _x2_, _y2_,	\
 	                                    yInverted, vertices)	\
   do {									\
-     float tx1, tx2, ty1, ty2;						\
-     if (priv->type == GLAMOR_TEXTURE_LARGE)				\
-	glamor_get_repeat_coords((&priv->large), repeat_type,		\
-				 tx1, ty1, tx2, ty2,			\
-				 _x1_, _y1_, _x2_, _y2_);		\
-     else {								\
-	tx1 = _x1_; tx2 = _x2_; ty1 = _y1_; ty2 = _y2_;			\
-     }									\
-     _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
-				   tx2, ty2, yInverted, vertices);	\
+	glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,	\
+					    xscale, yscale,		\
+					    _x1_, _y1_, _x2_, _y2_,	\
+	                                    yInverted, vertices, 2);	\
  } while(0)
 
 #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale,		\
@@ -603,26 +675,44 @@
 	(vertices)[5] = (vertices)[7];					\
     } while(0)
 
-#define glamor_set_normalize_vcoords(priv, xscale, yscale,		\
+#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale,		\
 				     x1, y1, x2, y2,			\
-                                     yInverted, vertices)		\
+                                     yInverted, vertices, stride)	\
   do {									\
     int fbo_x_off, fbo_y_off;						\
+    /* vertices may be write-only, so we use following			\
+     * temporary variable. */						\
+    float _t0_, _t1_, _t2_, _t5_;					\
     pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
-    (vertices)[0] = v_from_x_coord_x(xscale, x1 + fbo_x_off);		\
-    (vertices)[2] = v_from_x_coord_x(xscale, x2 + fbo_x_off);		\
-    (vertices)[4] = (vertices)[2];					\
-    (vertices)[6] = (vertices)[0];					\
+    (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off);	\
+    (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale,		\
+					x2 + fbo_x_off);		\
+    (vertices)[2 * stride] = _t2_;					\
+    (vertices)[3 * stride] = _t0_;					\
     if (yInverted) {							\
-      (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1 + fbo_y_off);\
-      (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2 + fbo_y_off);\
+      (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale,		\
+				y1 + fbo_y_off);			\
+      (vertices)[2 * stride + 1] = _t5_ =				\
+			v_from_x_coord_y_inverted(yscale,		\
+					y2 + fbo_y_off);		\
     }									\
     else {								\
-      (vertices)[1] = v_from_x_coord_y(yscale, y1 + fbo_y_off);		\
-      (vertices)[5] = v_from_x_coord_y(yscale, y2 + fbo_y_off);		\
+      (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off);	\
+      (vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale,	\
+					y2 + fbo_y_off);		\
     }									\
-    (vertices)[3] = (vertices)[1];					\
-    (vertices)[7] = (vertices)[5];					\
+    (vertices)[1 * stride + 1] = _t1_;					\
+    (vertices)[3 * stride + 1] = _t5_;					\
+  } while(0)
+
+
+#define glamor_set_normalize_vcoords(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     yInverted, vertices)		\
+  do {									\
+	glamor_set_normalize_vcoords_ext(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     yInverted, vertices, 2);		\
   } while(0)
 
 #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale,		\
commit 8656ddbbe7a38e5cd15e6d006bba19778e34e9e9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 15 08:46:24 2012 +0800

    glamor_glyphs: Before get upload to cache flush is needed.
    
    When we can't get a cache hit and have to evict one cache
    entry to upload new picture, we need to flush the previous
    buffer. Otherwise, we may get corrupt glyphs rendering result.
    
    This is the reason why user-font-proxy may fail sometimes.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index dd3b4c6..362e46f 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -226,6 +226,7 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 	PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
 	PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
 	PixmapPtr scratch;
+	BoxRec box;
 	GCPtr gc;
 
 	gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
@@ -236,54 +237,51 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 
 	scratch = pGlyphPixmap;
 	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
+
 		scratch = glamor_create_pixmap(screen,
 					       glyph->info.width,
 					       glyph->info.height,
 					       pCachePixmap->
 					       drawable.depth, 0);
 		if (scratch) {
-			if (pGlyphPixmap->drawable.depth !=
-			    pCachePixmap->drawable.depth) {
-				PicturePtr picture;
-				int error;
-
-				picture =
-				    CreatePicture(0,
-						  &scratch->drawable,
-						  PictureMatchFormat
-						  (screen,
-						   pCachePixmap->
-						   drawable.depth,
-						   cache->picture->format),
-						  0, NULL, serverClient,
-						  &error);
-				if (picture) {
-					ValidatePicture(picture);
-					glamor_composite(PictOpSrc,
-						      pGlyphPicture,
-						      NULL, picture,
-						      0, 0, 0, 0, 0,
-						      0,
-						      glyph->info.width,
-						      glyph->info.height);
-					FreePicture(picture, 0);
-				}
-			} else {
-				glamor_copy_area(&pGlyphPixmap->drawable,
-						 &scratch->drawable,
-						 gc, 0, 0,
-						 glyph->info.width,
-						 glyph->info.height, 0, 0);
+			PicturePtr picture;
+			int error;
+
+			picture =
+			    CreatePicture(0,
+					  &scratch->drawable,
+					  PictureMatchFormat
+					  (screen,
+					   pCachePixmap->
+				   drawable.depth,
+				   cache->picture->format),
+					  0, NULL, serverClient,
+				  &error);
+			if (picture) {
+				ValidatePicture(picture);
+				glamor_composite(PictOpSrc,
+					      pGlyphPicture,
+					      NULL, picture,
+					      0, 0, 0, 0, 0,
+					      0,
+				      glyph->info.width,
+					      glyph->info.height);
+				FreePicture(picture, 0);
 			}
 		} else {
 			scratch = pGlyphPixmap;
 		}
 	}
 
-	(*gc->ops->CopyArea)(&scratch->drawable, &pCachePixmap->drawable, gc,
-			     0, 0, glyph->info.width, glyph->info.height, x,
-			     y);
-
+	box.x1 = x;
+	box.y1 = y;
+	box.x2 = x + glyph->info.width;
+	box.y2 = y + glyph->info.height;
+	glamor_copy_n_to_n_nf(&scratch->drawable,
+			    &pCachePixmap->drawable, NULL,
+			    &box, 1,
+			    -x, -y,
+			    FALSE, FALSE, 0, NULL);
 	if (scratch != pGlyphPixmap)
 		screen->DestroyPixmap(scratch);
 
@@ -550,11 +548,13 @@ glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
 	*out_y = priv->y;
 	return cache->picture;
 }
+typedef void (*glyphs_flush)(void * arg);
 
 static glamor_glyph_cache_result_t
 glamor_buffer_glyph(ScreenPtr screen,
 		    glamor_glyph_buffer_t * buffer,
-		    GlyphPtr glyph, int x_glyph, int y_glyph)
+		    GlyphPtr glyph, int x_glyph, int y_glyph,
+		    glyphs_flush glyphs_flush, void *flush_arg)
 {
 	glamor_screen_private *glamor_screen =
 	    glamor_get_screen_private(screen);
@@ -573,11 +573,18 @@ glamor_buffer_glyph(ScreenPtr screen,
 	    &glamor_screen->glyphCaches[PICT_FORMAT_RGB
 					(glyph_picture->format) != 0];
 
-	if (buffer->source && buffer->source != cache->picture)
-		return GLAMOR_GLYPH_NEED_FLUSH;
+	if (buffer->source
+	    && buffer->source != cache->picture
+	    && glyphs_flush) {
+		(*glyphs_flush)(flush_arg);
+		glyphs_flush = NULL;
+	}
 
-	if (buffer->count == GLYPH_BUFFER_SIZE)
-		return GLAMOR_GLYPH_NEED_FLUSH;
+	if (buffer->count == GLYPH_BUFFER_SIZE
+	    && glyphs_flush) {
+		(*glyphs_flush)(flush_arg);
+		glyphs_flush = NULL;
+	}
 
 	priv = glamor_glyph_get_private(glyph);
 
@@ -588,6 +595,8 @@ glamor_buffer_glyph(ScreenPtr screen,
 		if (buffer->source == NULL)
 			buffer->source = priv->cache->picture;
 	} else {
+		if (glyphs_flush)
+			(*glyphs_flush)(flush_arg);
 		source = glamor_glyph_cache(screen, glyph, &x, &y);
 		if (source != NULL) {
 			rect = &buffer->rects[buffer->count++];
@@ -597,8 +606,10 @@ glamor_buffer_glyph(ScreenPtr screen,
 				buffer->source = source;
 		} else {
 			source = GlyphPicture(glyph)[screen->myNum];
-			if (buffer->source && buffer->source != source)
-				return GLAMOR_GLYPH_NEED_FLUSH;
+			if (buffer->source
+			    && buffer->source != source
+			    && glyphs_flush)
+				(*glyphs_flush)(flush_arg);
 			buffer->source = source;
 
 			rect = &buffer->rects[buffer->count++];
@@ -617,16 +628,22 @@ glamor_buffer_glyph(ScreenPtr screen,
 	return GLAMOR_GLYPH_SUCCESS;
 }
 
+struct glyphs_flush_mask_arg {
+	PicturePtr mask;
+	glamor_glyph_buffer_t *buffer;
+};
 
 static void
-glamor_glyphs_flush_mask(PicturePtr mask, glamor_glyph_buffer_t * buffer)
+glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
 {
 #ifdef RENDER
-	glamor_composite_glyph_rects(PictOpAdd, buffer->source, NULL, mask,
-				     buffer->count, buffer->rects);
+	glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
+				     NULL, arg->mask,
+				     arg->buffer->count,
+				     arg->buffer->rects);
 #endif
-	buffer->count = 0;
-	buffer->source = NULL;
+	arg->buffer->count = 0;
+	arg->buffer->source = NULL;
 }
 
 static void
@@ -651,7 +668,7 @@ glamor_glyphs_via_mask(CARD8 op,
 	XID component_alpha;
 	glamor_glyph_buffer_t buffer;
 	xRectangle fill_rect;
-
+	struct glyphs_flush_mask_arg arg;
 	GCPtr gc;
 
 	glamor_glyph_extents(nlist, list, glyphs, &extents);
@@ -704,18 +721,21 @@ glamor_glyphs_via_mask(CARD8 op,
 		n = list->len;
 		while (n--) {
 			glyph = *glyphs++;
-
 			if (glyph->info.width > 0
-			    && glyph->info.height > 0
-			    && glamor_buffer_glyph(screen, &buffer,
-						   glyph, x,
-						   y) ==
-			    GLAMOR_GLYPH_NEED_FLUSH) {
-
-				glamor_glyphs_flush_mask(mask, &buffer);
+			    && glyph->info.height > 0) {
+				glyphs_flush flush_func;
+				if (buffer.count) {
+					arg.mask = mask;
+					arg.buffer = &buffer;
+					flush_func = (glyphs_flush)glamor_glyphs_flush_mask;
+				}
+				else
+					flush_func = NULL;
 
 				glamor_buffer_glyph(screen, &buffer,
-						    glyph, x, y);
+						    glyph, x, y,
+						    flush_func,
+						    (void*)&arg);
 			}
 
 			x += glyph->info.xOff;
@@ -724,8 +744,11 @@ glamor_glyphs_via_mask(CARD8 op,
 		list++;
 	}
 
-	if (buffer.count)
-		glamor_glyphs_flush_mask(mask, &buffer);
+	if (buffer.count) {
+		arg.mask = mask;
+		arg.buffer = &buffer;
+		glamor_glyphs_flush_mask(&arg);
+	}
 
 	x = extents.x1;
 	y = extents.y1;
@@ -739,27 +762,36 @@ glamor_glyphs_via_mask(CARD8 op,
 	screen->DestroyPixmap(mask_pixmap);
 }
 
+struct glyphs_flush_dst_arg {
+	CARD8 op;
+	PicturePtr src;
+	PicturePtr dst;
+	glamor_glyph_buffer_t * buffer;
+	INT16 x_src;
+	INT16 y_src;
+	INT16 x_dst;
+	INT16 y_dst;
+};
+
 static void
-glamor_glyphs_flush_dst(CARD8 op,
-			PicturePtr src,
-			PicturePtr dst,
-			glamor_glyph_buffer_t * buffer,
-			INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
+glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg * arg)
 {
 	int i;
-	glamor_composite_rect_t *rect = &buffer->rects[0];
-	for (i = 0; i < buffer->count; i++, rect++) {
+	glamor_composite_rect_t *rect = &arg->buffer->rects[0];
+	for (i = 0; i < arg->buffer->count; i++, rect++) {
 		rect->x_mask = rect->x_src;
 		rect->y_mask = rect->y_src;
-		rect->x_src = x_src + rect->x_dst - x_dst;
-		rect->y_src = y_src + rect->y_dst - y_dst;
+		rect->x_src = arg->x_src + rect->x_dst - arg->x_dst;
+		rect->y_src = arg->y_src + rect->y_dst - arg->y_dst;
 	}
 
-	glamor_composite_glyph_rects(op, src, buffer->source, dst,
-			       buffer->count, &buffer->rects[0]);
+	glamor_composite_glyph_rects(arg->op, arg->src,
+				arg->buffer->source, arg->dst,
+				arg->buffer->count,
+				&arg->buffer->rects[0]);
 
-	buffer->count = 0;
-	buffer->source = NULL;
+	arg->buffer->count = 0;
+	arg->buffer->source = NULL;
 }
 
 static void
@@ -776,6 +808,7 @@ glamor_glyphs_to_dst(CARD8 op,
 	int n;
 	GlyphPtr glyph;
 	glamor_glyph_buffer_t buffer;
+	struct glyphs_flush_dst_arg arg;
 
 	buffer.count = 0;
 	buffer.source = NULL;
@@ -787,17 +820,28 @@ glamor_glyphs_to_dst(CARD8 op,
 			glyph = *glyphs++;
 
 			if (glyph->info.width > 0
-			    && glyph->info.height > 0
-			    && glamor_buffer_glyph(screen, &buffer,
-						   glyph, x,
-						   y) ==
-			    GLAMOR_GLYPH_NEED_FLUSH) {
-				glamor_glyphs_flush_dst(op, src, dst,
-							&buffer, x_src,
-							y_src, x_dst,
-							y_dst);
-				glamor_buffer_glyph(screen, &buffer,
-						    glyph, x, y);
+			    && glyph->info.height > 0) {
+				glyphs_flush flush_func;
+
+				if (buffer.count) {
+					arg.op = op;
+					arg.src = src;
+					arg.dst = dst;
+					arg.buffer = &buffer;
+					arg.x_src = x_src;
+					arg.y_src = y_src;
+					arg.x_dst = x_dst;
+					arg.y_dst = y_dst;
+					flush_func = (glyphs_flush)glamor_glyphs_flush_dst;
+				} else
+					flush_func = NULL;
+
+				glamor_buffer_glyph(screen,
+						    &buffer,
+						    glyph, x, y,
+						    flush_func,
+						    (void*)&arg);
+
 			}
 
 			x += glyph->info.xOff;
@@ -806,9 +850,17 @@ glamor_glyphs_to_dst(CARD8 op,
 		list++;
 	}
 
-	if (buffer.count)
-		glamor_glyphs_flush_dst(op, src, dst, &buffer,
-					x_src, y_src, x_dst, y_dst);
+	if (buffer.count) {
+		arg.op = op;
+		arg.src = src;
+		arg.dst = dst;
+		arg.buffer = &buffer;
+		arg.x_src = x_src;
+		arg.y_src = y_src;
+		arg.x_dst = x_dst;
+		arg.y_dst = y_dst;
+		glamor_glyphs_flush_dst(&arg);
+	}
 }
 
 static Bool
commit 016995334e6acfad41574a9270b716db98ec697f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 15 08:43:37 2012 +0800

    copyarea: Cleanup the error handling logic.
    
    Should use ok rather than mixed ok or ret.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index bfd957a..243c1f2 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -398,8 +398,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	RegionRec region;
 	ScreenPtr screen;
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
-	Bool ret = FALSE;
-	int ok = TRUE;
+	Bool ok = TRUE;
 	int force_clip = 0;
 
 	if (nbox == 0)
@@ -423,10 +422,11 @@ _glamor_copy_n_to_n(DrawablePtr src,
 
 	if (gc) {
 		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-			goto fail;
+			goto fall_back;
 		dispatch = glamor_get_dispatch(glamor_priv);
 		if (!glamor_set_alu(dispatch, gc->alu)) {
 			glamor_put_dispatch(glamor_priv);
+			ok = FALSE;
 			goto fail;
 		}
 		glamor_put_dispatch(glamor_priv);
@@ -499,8 +499,10 @@ _glamor_copy_n_to_n(DrawablePtr src,
 							 * it. It's a little hacky, but avoid extra copy. */
 							temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0,
 												  src->depth, 0);
-							if (!temp_source_pixmap)
+							if (!temp_source_pixmap) {
+								ok = FALSE;
 								goto fail;
+							}
 							src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
 										      src_pixmap->drawable.width,
 										      src_pixmap->drawable.height,
@@ -619,12 +621,12 @@ fall_back:
 		}
 		glamor_finish_access(dst, GLAMOR_ACCESS_RW);
 	}
-	ret = TRUE;
+	ok = TRUE;
 
       done:
 	glamor_clear_delayed_fallbacks(src->pScreen);
 	glamor_clear_delayed_fallbacks(dst->pScreen);
-	return ret;
+	return ok;
 }
 
 RegionPtr
commit b4a499b7db068117801770b7ab80416014822101
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 12 18:21:10 2012 +0800

    trapezoid: Fallback to sw-rasterize for largepixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 2d26d79..cc6a706 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -524,7 +524,8 @@ _glamor_trapezoids_with_shader(CARD8 op,
 	dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)
+	    || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
 		/* Currently. Always fallback to cpu if destination is in CPU memory.*/
 		ret = FALSE;
 		DEBUGF("dst pixmap has no FBO.\n");
@@ -535,7 +536,9 @@ _glamor_trapezoids_with_shader(CARD8 op,
 		source_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
 		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 		temp_src_priv = source_pixmap_priv;
-		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) {
+		if (source_pixmap_priv
+		    && (source_pixmap_priv->type == GLAMOR_DRM_ONLY
+		       || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) {
 			ret = FALSE;
 			goto TRAPEZOID_OUT;
 		}
@@ -558,6 +561,11 @@ _glamor_trapezoids_with_shader(CARD8 op,
 	              source_pixmap->drawable.width * source_pixmap->drawable.height)
 	             || !glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width,
 	                     source_pixmap->drawable.height)))) {
+
+		if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) {
+			ret = FALSE;
+			goto TRAPEZOID_OUT;
+		}
 		temp_src = glamor_convert_gradient_picture(screen, src,
 		           x_src, y_src,
 		           src_width, src_height);
@@ -609,7 +617,7 @@ _glamor_trapezoids_with_shader(CARD8 op,
 	glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
 	        &dest_x_off, &dest_y_off);
 
-	pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	if (glamor_priv->has_source_coords) {
 		source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable);
@@ -1136,7 +1144,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)
+	   || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* should always have here. */
 		DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n");
 		return FALSE;
 	}
commit 8f31aed48ca9412f8f5df9c3d47d938c7c90bccb
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue Jun 5 03:21:03 2012 +0800

    Use the direct render path for A1
    
     Because when mask depth is 1, there is no Anti-Alias at all,
     in this case, the directly render can work well and it is faseter.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1b45a71..055077c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -965,7 +965,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
-#define GLAMOR_TRAPEZOID_SHADER
+//#define GLAMOR_TRAPEZOID_SHADER
 #endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #if 0
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 030e490..2d26d79 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1409,15 +1409,34 @@ _glamor_trapezoids(CARD8 op,
 	stride = PixmapBytePad(width, mask_format->depth);
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
-	picture = glamor_create_mask_picture(screen, dst, mask_format,
-	          width, height, 1);
-	if (!picture)
-		return TRUE;
+	/* We seperate the render to two paths.
+	   Some GL implemetation do not implement the Anti-Alias for triangles
+	   and polygen's filling. So when the edge is not vertical or horizontal,
+	   sawtooth will be obvious. The trapezoid is widely used to render wide
+	   lines and circles. In these case, the line or circle will be divided
+	   into a large number of small trapezoids to approximate it, so the sawtooth
+	   at the edge will cause the result not be acceptable.
+	   When the depth of the mask is 1, there is no Anti-Alias needed, so we
+	   use the clip logic to generate the result directly(fast path).
+	   When the depth is not 1, AA is needed and we use a shader to generate
+	   a temp mask pixmap.
+	 */
+	if(mask_format->depth == 1) {
+		ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format,
+		                                     x_src, y_src, ntrap, traps);
+		if(ret)
+			return TRUE;
+	} else {
+		picture = glamor_create_mask_picture(screen, dst, mask_format,
+		          width, height, 1);
+		if (!picture)
+			return TRUE;
 
-	ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
+		ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
 
-	if (!ret)
-		FreePicture(picture, 0);
+		if (!ret)
+			FreePicture(picture, 0);
+	}
 #endif
 
 	if (!ret) {
commit fa74a213ad175cb0920905a8011c62efdd348d45
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Mon Jun 4 07:52:05 2012 +0800

    Add the trapezoid direct render logic
    
     We firstly get the render area by clipping the trapezoid
     with the clip rect, then split the clipped area into small
     triangles and use the composite logic to generate the result
     directly. This manner is fast but have the problem that
     some implementation of GL do not implement the Anti-Alias
     of triangles fill, so the edge sometimes has sawtooth. It is
     not acceptable when use trapezoid to approximate circles and
     wide lines.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 362abae..1b45a71 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -716,6 +716,15 @@ PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
                                            PicturePtr source,
                                            int x_source,
                                            int y_source, int width, int height);
+Bool glamor_composite_choose_shader(CARD8 op,
+                                    PicturePtr source,
+                                    PicturePtr mask,
+                                    PicturePtr dest,
+			     	    glamor_pixmap_private *source_pixmap_priv,
+			     	    glamor_pixmap_private *mask_pixmap_priv,
+			     	    glamor_pixmap_private *dest_pixmap_priv,
+                                    struct shader_key *s_key,
+                                    PictFormatShort *psaved_source_format);
 void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
 void glamor_emit_composite_vert(ScreenPtr screen,
                                 const float *src_coords,
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index f0c0b8b..030e490 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -37,6 +37,739 @@
 #include "fbpict.h"
 
 #ifdef GLAMOR_TRAPEZOID_SHADER
+
+#define POINT_INSIDE_CLIP_RECT(point, rect)	\
+    (point[0] >= IntToxFixed(rect->x1)		\
+     && point[0] <= IntToxFixed(rect->x2) 	\
+     && point[1] >= IntToxFixed(rect->y1)	\
+     && point[1] <= IntToxFixed(rect->y2))
+
+static xFixed
+_glamor_linefixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+	xFixed dx = l->p2.x - l->p1.x;
+	xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+	xFixed dy = l->p2.y - l->p1.y;
+	if (ceil)
+		ex += (dy - 1);
+	return l->p1.x + (xFixed) (ex / dy);
+}
+
+static xFixed
+_glamor_linefixedY (xLineFixed *l, xFixed x, Bool ceil)
+{
+	xFixed dy = l->p2.y - l->p1.y;
+	xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
+	xFixed dx = l->p2.x - l->p1.x;
+	if (ceil)
+		ey += (dx - 1);
+	return l->p1.y + (xFixed) (ey / dx);
+}
+
+static Bool
+point_inside_trapezoid(int point[2], xTrapezoid * trap)
+{
+	int ret = TRUE;
+	int tmp;
+	if (point[1] > trap->bottom
+	     || point[1] < trap->top)
+		ret = FALSE;
+
+	tmp = _glamor_linefixedX (&trap->left, point[1], FALSE);
+	if (point[0] < tmp)
+		ret = FALSE;
+
+	tmp = _glamor_linefixedX (&trap->right, point[1], TRUE);
+	if (point[0] > tmp)
+		ret = FALSE;
+
+	return ret;
+}
+
+static void
+glamor_emit_composite_triangle(ScreenPtr screen,
+        const float *src_coords,
+        const float *mask_coords,
+        const float *dst_coords)
+{
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+	        dst_coords, 0);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+	        dst_coords, 1);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+	        dst_coords, 2);
+}
+
+static void
+glamor_flush_composite_triangles(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch;
+
+	if (!glamor_priv->render_nr_verts)
+		return;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+	else {
+
+		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+		dispatch->glBufferData(GL_ARRAY_BUFFER,
+		        glamor_priv->vbo_offset,
+		        glamor_priv->vb, GL_DYNAMIC_DRAW);
+	}
+
+	dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
+	glamor_put_dispatch(glamor_priv);
+}
+
+#define DEBUG_CLIP_VTX 0
+
+static Bool
+_glamor_clip_trapezoid_vertex(xTrapezoid * trap, BoxPtr pbox,
+        int vertex[6], int *num)
+{
+	int tl[2];
+	int bl[2];
+	int tr[2];
+	int br[2];
+	int left_cut_top[2];
+	int left_cut_left[2];
+	int left_cut_right[2];
+	int left_cut_bottom[2];
+	int right_cut_top[2];
+	int right_cut_left[2];
+	int right_cut_right[2];
+	int right_cut_bottom[2];
+	int tmp[2];
+	int tmp_vtx[20*2];
+	float tmp_vtx_slope[20];
+	BoxRec trap_bound;
+	int i = 0;
+	int vertex_num = 0;
+
+	if (DEBUG_CLIP_VTX) {
+		ErrorF("The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
+		       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
+		       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
+		       xFixedToInt(trap->top), (unsigned int)trap->top,
+		       xFixedToInt(trap->bottom), (unsigned int)trap->bottom,
+		       xFixedToInt(trap->left.p1.x), (unsigned int)trap->left.p1.x,
+		       xFixedToInt(trap->left.p1.y), (unsigned int)trap->left.p1.y,
+		       xFixedToInt(trap->left.p2.x), (unsigned int)trap->left.p2.x,
+		       xFixedToInt(trap->left.p2.y), (unsigned int)trap->left.p2.y,
+		       xFixedToInt(trap->right.p1.x), (unsigned int)trap->right.p1.x,
+		       xFixedToInt(trap->right.p1.y), (unsigned int)trap->right.p1.y,
+		       xFixedToInt(trap->right.p2.x), (unsigned int)trap->right.p2.x,
+		       xFixedToInt(trap->right.p2.y), (unsigned int)trap->right.p2.y);
+	}
+
+	miTrapezoidBounds(1, trap, &trap_bound);
+	if (DEBUG_CLIP_VTX)
+		ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, "
+		       "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2,
+		       trap_bound.y1, trap_bound.y2);
+
+	if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1)
+		return FALSE;
+	if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1)
+		return FALSE;
+
+#define IS_TRAP_EDGE_VERTICAL(edge)		\
+	(edge->p1.x == edge->p2.x)
+
+#define CACULATE_CUT_VERTEX(vtx, cal_x, ceil, vh_edge, edge)		\
+	do {								\
+	    if(cal_x) {							\
+		vtx[1] = (vh_edge);					\
+		vtx[0] = (_glamor_linefixedX(				\
+			      edge, vh_edge, ceil));			\
+		if(DEBUG_CLIP_VTX)					\
+		    ErrorF("The intersection point of line y=%d and "	\
+			   "line of p1:(%d,%d) -- p2 (%d,%d) "		\
+			   "is (%d, %d)\n",				\
+			   xFixedToInt(vh_edge),			\
+			   xFixedToInt(edge->p1.x),			\
+			   xFixedToInt(edge->p1.y),			\
+			   xFixedToInt(edge->p2.x),			\
+			   xFixedToInt(edge->p2.y),			\
+			   xFixedToInt(vtx[0]),				\
+			   xFixedToInt(vtx[1]));			\
+	    } else {							\
+		vtx[0] = (vh_edge);					\
+		vtx[1] = (_glamor_linefixedY(				\
+			      edge, vh_edge, ceil));			\
+		if(DEBUG_CLIP_VTX)					\
+		    ErrorF("The intersection point of line x=%d and "	\
+			   "line of p1:(%d,%d) -- p2 (%d,%d) "		\
+			   "is (%d, %d)\n",				\
+			   xFixedToInt(vh_edge),			\
+			   xFixedToInt(edge->p1.x),			\
+			   xFixedToInt(edge->p1.y),			\
+			   xFixedToInt(edge->p2.x),			\
+			   xFixedToInt(edge->p2.y),			\
+			   xFixedToInt(vtx[0]),				\
+			   xFixedToInt(vtx[1]));			\
+	    }								\
+	} while(0)
+
+#define ADD_VERTEX_IF_INSIDE(vtx)				\
+	if(POINT_INSIDE_CLIP_RECT(vtx, pbox)			\
+	   && point_inside_trapezoid(vtx, trap)){		\
+	    tmp_vtx[vertex_num] = xFixedToInt(vtx[0]);		\
+	    tmp_vtx[vertex_num + 1] = xFixedToInt(vtx[1]);	\
+	    vertex_num += 2;					\
+	    if(DEBUG_CLIP_VTX)					\
+		ErrorF("@ Point: (%d, %d) is inside "		\
+		       "the Rect and Trapezoid\n",		\
+		       xFixedToInt(vtx[0]),			\
+		       xFixedToInt(vtx[1]));			\
+	} else if(DEBUG_CLIP_VTX){				\
+	    ErrorF("X Point: (%d, %d) is outside "		\
+		   "the Rect and Trapezoid\t",			\
+		   xFixedToInt(vtx[0]),				\
+		   xFixedToInt(vtx[1]));			\
+	    if(POINT_INSIDE_CLIP_RECT(vtx, pbox))		\
+		ErrorF("The Point is outside "			\
+		       "the Trapezoid\n");			\
+	    else						\
+		ErrorF("The Point is outside "			\
+		       "the Rect\n");				\
+	}
+
+	/*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */
+	CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left));
+	CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left));
+	CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right));
+	CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right));
+
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n");
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Caculate the vertex of trapezoid:\n"
+		       "      (%3d, %3d)-------------------------(%3d, %3d)\n"
+		       "              /                           \\       \n"
+		       "             /                             \\      \n"
+		       "            /                               \\     \n"
+		       "  (%3d, %3d)---------------------------------(%3d, %3d)\n"
+		       "Clip with rect:\n"
+		       "  (%3d, %3d)------------------------(%3d, %3d)    \n"
+		       "           |                        |             \n"
+		       "           |                        |             \n"
+		       "           |                        |             \n"
+		       "  (%3d, %3d)------------------------(%3d, %3d)    \n",
+		       xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]),
+		       xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]),
+		       xFixedToInt(br[0]), xFixedToInt(br[1]),
+		       pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2,
+		       pbox->x2, pbox->y2);
+
+	ADD_VERTEX_IF_INSIDE(tl);
+	ADD_VERTEX_IF_INSIDE(bl);
+	ADD_VERTEX_IF_INSIDE(tr);
+	ADD_VERTEX_IF_INSIDE(br);
+
+	/*Trap's left edge cut Rect. */
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Trap's left edge cut Rect\n");
+	CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1), (&trap->left));
+	ADD_VERTEX_IF_INSIDE(left_cut_top);
+	if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
+		CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1), (&trap->left));
+		ADD_VERTEX_IF_INSIDE(left_cut_left);
+	}
+	CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2), (&trap->left));
+	ADD_VERTEX_IF_INSIDE(left_cut_bottom);
+	if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
+		CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2), (&trap->left));
+		ADD_VERTEX_IF_INSIDE(left_cut_right);
+	}
+
+	/*Trap's right edge cut Rect. */
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Trap's right edge cut Rect\n");
+	CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1), (&trap->right));
+	ADD_VERTEX_IF_INSIDE(right_cut_top);
+	if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
+		CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1), (&trap->right));
+		ADD_VERTEX_IF_INSIDE(right_cut_left);
+	}
+	CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2), (&trap->right));
+	ADD_VERTEX_IF_INSIDE(right_cut_bottom);
+	if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
+		CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2), (&trap->right));
+		ADD_VERTEX_IF_INSIDE(right_cut_right);
+	}
+
+	/* Trap's top cut Left and Right of rect. */
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Trap's top cut Left and Right of rect\n");
+	tmp[0] = IntToxFixed(pbox->x1);
+	tmp[1] = trap->top;
+	ADD_VERTEX_IF_INSIDE(tmp);
+	tmp[0] = IntToxFixed(pbox->x2);
+	tmp[1] = trap->top;
+	ADD_VERTEX_IF_INSIDE(tmp);
+
+	/* Trap's bottom cut Left and Right of rect. */
+	if (DEBUG_CLIP_VTX)
+		ErrorF("Trap's bottom cut Left and Right of rect\n");
+	tmp[0] = IntToxFixed(pbox->x1);
+	tmp[1] = trap->bottom;
+	ADD_VERTEX_IF_INSIDE(tmp);
+	tmp[0] = IntToxFixed(pbox->x2);
+	tmp[1] = trap->bottom;
+	ADD_VERTEX_IF_INSIDE(tmp);
+
+	/* The orginal 4 vertex of rect. */
+	if (DEBUG_CLIP_VTX)
+		ErrorF("The orginal 4 vertex of rect\n");
+	tmp[0] = IntToxFixed(pbox->x1);
+	tmp[1] = IntToxFixed(pbox->y1);
+	ADD_VERTEX_IF_INSIDE(tmp);
+	tmp[0] = IntToxFixed(pbox->x1);
+	tmp[1] = IntToxFixed(pbox->y2);
+	ADD_VERTEX_IF_INSIDE(tmp);
+	tmp[0] = IntToxFixed(pbox->x2);
+	tmp[1] = IntToxFixed(pbox->y2);
+	ADD_VERTEX_IF_INSIDE(tmp);
+	tmp[0] = IntToxFixed(pbox->x2);
+	tmp[1] = IntToxFixed(pbox->y1);
+	ADD_VERTEX_IF_INSIDE(tmp);
+
+	if (DEBUG_CLIP_VTX) {
+		ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2);
+		for (i = 0; i < vertex_num / 2; i++) {
+			ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]);
+		}
+		ErrorF("\n");
+	}
+
+	/* Sort the vertex by X and then Y. */
+	for (i = 0; i < vertex_num / 2; i++) {
+		int j;
+		for (j = 0; j < vertex_num / 2 - i - 1; j++) {
+			if (tmp_vtx[2*j] > tmp_vtx[2*(j+1)]
+			     || (tmp_vtx[2*j] == tmp_vtx[2*(j+1)]
+			         && tmp_vtx[2*j + 1] > tmp_vtx[2*(j+1) + 1])) {
+				tmp[0] = tmp_vtx[2*j];
+				tmp[1] = tmp_vtx[2*j + 1];
+				tmp_vtx[2*j] = tmp_vtx[2*(j+1)];
+				tmp_vtx[2*j + 1] = tmp_vtx[2*(j+1) + 1];
+				tmp_vtx[2*(j+1)] = tmp[0];
+				tmp_vtx[2*(j+1) + 1] = tmp[1];
+			}
+		}
+
+	}
+
+	if (DEBUG_CLIP_VTX) {
+		ErrorF("\nAfter sort vertex number is:\n");
+		for (i = 0; i < vertex_num / 2; i++) {
+			ErrorF("(%d, %d) ", tmp_vtx[2*i], tmp_vtx[2*i + 1]);
+		}
+		ErrorF("\n");
+	}
+
+	memset(vertex, -1, 2*6);
+	*num = 0;
+
+	for (i = 0; i < vertex_num / 2; i++) {
+		if (*num > 0 && vertex[2*(*num - 1)] == tmp_vtx[2*i]
+		     && vertex[2*(*num - 1) + 1] == tmp_vtx[2*i + 1]) {
+			/*same vertex.*/
+			if (DEBUG_CLIP_VTX)
+				ErrorF("X Point:(%d, %d) discard\n",
+				       tmp_vtx[2*i], tmp_vtx[2*i + 1]);
+			continue;
+		}
+
+		(*num)++;
+		if (*num > 6) {
+			if (DEBUG_CLIP_VTX)
+				FatalError("Trapezoid clip with Rect can never have vtx"
+				           "number bigger than 6\n");
+			else {
+				ErrorF("Trapezoid clip with Rect can never have vtx"
+				       "number bigger than 6\n");
+				*num = 6;
+				break;
+			}
+		}
+
+		vertex[2*(*num - 1)] = tmp_vtx[2*i];
+		vertex[2*(*num - 1) + 1] = tmp_vtx[2*i + 1];
+		if (DEBUG_CLIP_VTX)
+			ErrorF("@ Point:(%d, %d) select, num now is %d\n",
+			       tmp_vtx[2*i], tmp_vtx[2*i + 1], *num);
+	}
+
+	/* Now we need to arrange the vtx in the polygon's counter-clockwise
+	order. We first select the left and top point as the start point and
+	sort every vtx by the slope from vtx to the start vtx. */
+	for (i = 1; i < *num; i++) {
+		tmp_vtx_slope[i] = (vertex[2*i] != vertex[0] ?
+		                    (float)(vertex[2*i + 1] - vertex[1]) / (float)(vertex[2*i] - vertex[0])
+		                    : (float)INT_MAX);
+	}
+
+	if (DEBUG_CLIP_VTX) {
+		ErrorF("\nvtx number: %d, VTX and slope:\n", *num);
+		for (i = 0; i < *num; i++) {
+			ErrorF("(%d, %d):%f ",
+			       vertex[2*i], vertex[2*i + 1],
+			       tmp_vtx_slope[i]);
+		}
+		ErrorF("\n");
+	}
+
+	/* Sort the vertex by slope. */
+	for (i = 0; i < *num - 1; i++) {
+		int j;
+		float tmp_slope;
+		for (j = 1; j < *num - i - 1; j++) {
+			if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) {
+				tmp_slope = tmp_vtx_slope[j];
+				tmp_vtx_slope[j] = tmp_vtx_slope[j + 1];
+				tmp_vtx_slope[j + 1] = tmp_slope;
+				tmp[0] = vertex[2*j];
+				tmp[1] = vertex[2*j + 1];
+				vertex[2*j] = vertex[2*(j+1)];
+				vertex[2*j + 1] = vertex[2*(j+1) + 1];
+				vertex[2*(j+1)] = tmp[0];
+				vertex[2*(j+1) + 1] = tmp[1];
+			}
+		}
+	}
+
+	if (DEBUG_CLIP_VTX) {
+		ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num);
+		for (i = 0; i < *num; i++) {
+			ErrorF("(%d, %d):%f ",
+			       vertex[2*i], vertex[2*i + 1],
+			       tmp_vtx_slope[i]);
+		}
+		ErrorF("\n");
+	}
+
+	return TRUE;
+}
+
+static Bool
+_glamor_trapezoids_with_shader(CARD8 op,
+        PicturePtr src, PicturePtr dst,
+        PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+        int ntrap, xTrapezoid * traps)
+{
+	ScreenPtr screen = dst->pDrawable->pScreen;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	struct shader_key key;
+	PictFormatShort saved_source_format = 0;
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr dest_pixmap = NULL;
+	glamor_pixmap_private *source_pixmap_priv = NULL;
+	glamor_pixmap_private *dest_pixmap_priv = NULL;
+	glamor_pixmap_private *temp_src_priv = NULL;
+	int x_temp_src, y_temp_src;
+	int src_width, src_height;
+	int source_x_off, source_y_off;
+	GLfloat src_xscale = 1, src_yscale = 1;
+	int x_dst, y_dst;
+	int dest_x_off, dest_y_off;
+	GLfloat dst_xscale, dst_yscale;
+	BoxRec bounds;
+	PicturePtr temp_src = src;
+	glamor_gl_dispatch *dispatch = NULL;
+	int vert_stride = 3;
+	int ntriangle_per_loop;
+	int nclip_rect;
+	int mclip_rect;
+	int clip_processed;
+	int clipped_vtx[6*2];
+	RegionRec region;
+	BoxPtr box = NULL;
+	BoxPtr pbox = NULL;
+	int traps_count = 0;
+	int traps_not_completed = 0;
+	xTrapezoid * ptrap = NULL;
+	int nbox;
+	float src_matrix[9];
+	Bool ret = FALSE;
+
+	/* If a mask format wasn't provided, we get to choose, but behavior should
+	 * be as if there was no temporary mask the traps were accumulated into.
+	 */
+	if (!mask_format) {
+		if (dst->polyEdge == PolyEdgeSharp)
+			mask_format = PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			mask_format = PictureMatchFormat(screen, 8, PICT_a8);
+		for (; ntrap; ntrap--, traps++)
+			glamor_trapezoids(op, src, dst, mask_format, x_src,
+			                  y_src, 1, traps);
+		return TRUE;
+	}
+
+	miTrapezoidBounds(ntrap, traps, &bounds);
+	DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
+	       "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2,
+	       bounds.y1, bounds.y2);
+
+	/* No area need to render. */
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		return TRUE;
+
+	dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		/* Currently. Always fallback to cpu if destination is in CPU memory.*/
+		ret = FALSE;
+		DEBUGF("dst pixmap has no FBO.\n");
+		goto TRAPEZOID_OUT;
+	}
+
+	if (src->pDrawable) {
+		source_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		temp_src_priv = source_pixmap_priv;
+		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) {
+			ret = FALSE;
+			goto TRAPEZOID_OUT;
+		}
+	}
+
+	x_dst = bounds.x1;
+	y_dst = bounds.y1;
+
+	src_width = bounds.x2 - bounds.x1;
+	src_height = bounds.y2 - bounds.y1;
+
+	x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16);
+	y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16);
+
+	if ((!src->pDrawable &&
+	     (src->pSourcePict->type != SourcePictTypeSolidFill)) //1. The Gradient case.
+	     /* 2. Has no fbo but can upload.*/
+	     || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
+	         && ((src_width * src_height * 4 <
+	              source_pixmap->drawable.width * source_pixmap->drawable.height)
+	             || !glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width,
+	                     source_pixmap->drawable.height)))) {
+		temp_src = glamor_convert_gradient_picture(screen, src,
+		           x_src, y_src,
+		           src_width, src_height);
+		if (!temp_src) {
+			temp_src = src;
+			ret = FALSE;
+			DEBUGF("Convert gradient picture failed\n");
+			goto TRAPEZOID_OUT;
+		}
+		temp_src_priv = glamor_get_pixmap_private((PixmapPtr)temp_src->pDrawable);
+		x_temp_src = y_temp_src = 0;
+	}
+
+	x_dst += dst->pDrawable->x;
+	y_dst += dst->pDrawable->y;
+	if (temp_src->pDrawable) {
+		x_temp_src += temp_src->pDrawable->x;
+		y_temp_src += temp_src->pDrawable->y;
+	}
+
+	if (!miComputeCompositeRegion(&region,
+	        temp_src, NULL, dst,
+	        x_temp_src, y_temp_src,
+	        0, 0,
+	        x_dst, y_dst,
+	        src_width, src_height)) {
+		DEBUGF("All the regions are clipped out, do nothing\n");
+		goto TRAPEZOID_OUT;
+	}
+
+	box = REGION_RECTS(&region);
+	nbox = REGION_NUM_RECTS(&region);
+	pbox = box;
+
+	ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
+					     temp_src_priv, NULL, dest_pixmap_priv,
+					     &key, &saved_source_format);
+	if (ret == FALSE) {
+		DEBUGF("can not set the shader program for composite\n");
+		goto TRAPEZOID_RESET_GL;
+	}
+
+	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+	        key.mask != SHADER_MASK_SOLID);
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
+	        &dest_x_off, &dest_y_off);
+
+	pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+
+	if (glamor_priv->has_source_coords) {
+		source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		glamor_get_drawable_deltas(temp_src->pDrawable,
+		        source_pixmap,
+		        &source_x_off, &source_y_off);
+		pixmap_priv_get_scale(source_pixmap_priv,
+		        &src_xscale, &src_yscale);
+		glamor_picture_get_matrixf(temp_src, src_matrix);
+		vert_stride += 3;
+	}
+
+	if (glamor_priv->has_mask_coords) {
+		DEBUGF("Should never have mask coords here!\n");
+		ret = FALSE;
+		goto TRAPEZOID_RESET_GL;
+	}
+
+	/* A trapezoid clip with a rectangle will at most generate a hexagon,
+	   which can be devided	into 4 triangles to render. */
+	ntriangle_per_loop = (vert_stride * nbox * ntrap * 4) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
+	        (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nbox * ntrap * 4;
+	ntriangle_per_loop = (ntriangle_per_loop / 4) * 4;
+
+	nclip_rect = nbox;
+	while (nclip_rect) {
+		mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ?
+		             (ntriangle_per_loop / (4 * ntrap)) : nclip_rect;
+
+		if (!mclip_rect) {/* Maybe too many traps. */
+			mclip_rect = 1;
+			ptrap = traps;
+			traps_count = ntriangle_per_loop / 4;
+			traps_not_completed = ntrap - traps_count;
+		} else {
+			traps_count = ntrap;
+			ptrap = traps;
+			traps_not_completed = 0;
+		}
+
+NTRAPS_LOOP_AGAIN:
+
+		glamor_setup_composite_vbo(screen,  mclip_rect * traps_count * 4 * vert_stride);
+		clip_processed = mclip_rect;
+
+
+		while (mclip_rect--) {
+			while (traps_count--) {
+				int vtx_num;
+				int i;
+				float vertices[3*2], source_texcoords[3*2];
+
+				DEBUGF("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, "
+				       "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n",
+				       nclip_rect, mclip_rect, clip_processed, traps_count, traps_not_completed);
+
+				if (_glamor_clip_trapezoid_vertex(ptrap, pbox, clipped_vtx, &vtx_num)) {
+					for (i = 0; i < vtx_num - 2; i++) {
+						int clipped_vtx_tmp[3*2];
+
+						clipped_vtx_tmp[0] = clipped_vtx[0];
+						clipped_vtx_tmp[1] = clipped_vtx[1];
+						clipped_vtx_tmp[2] = clipped_vtx[(i+1)*2];
+						clipped_vtx_tmp[3] = clipped_vtx[(i+1)*2 + 1];
+						clipped_vtx_tmp[4] = clipped_vtx[(i+2)*2];
+						clipped_vtx_tmp[5] = clipped_vtx[(i+2)*2 + 1];
+						glamor_set_normalize_tri_vcoords(
+						    dst_xscale, dst_yscale, clipped_vtx_tmp,
+						    glamor_priv->yInverted, vertices);
+						DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
+						       "(%f X %f)\n", vertices[0], vertices[1],
+						       vertices[2], vertices[3], vertices[4], vertices[5]);
+
+
+						if (key.source != SHADER_SOURCE_SOLID) {
+							if (src->transform) {
+								glamor_set_transformed_normalize_tri_tcoords(
+								    source_pixmap_priv,
+								    src_matrix, src_xscale, src_yscale,
+								    clipped_vtx_tmp,
+								    glamor_priv->yInverted,
+								    source_texcoords);
+							} else {
+								glamor_set_normalize_tri_tcoords(
+								    src_xscale, src_yscale,
+								    clipped_vtx_tmp,
+								    glamor_priv->yInverted,
+								    source_texcoords);
+							}
+
+							DEBUGF("source_texcoords of triangle: (%f X %f), "
+							       "(%f X %f), (%f X %f)\n",
+							       source_texcoords[0], source_texcoords[1],
+							       source_texcoords[2], source_texcoords[3],
+							       source_texcoords[4], source_texcoords[5]);
+						}
+
+						glamor_emit_composite_triangle(screen, source_texcoords,
+						        NULL, vertices);
+					}
+				}
+
+				ptrap++;
+			}
+
+			if (traps_not_completed) { /* one loop of ntraps not completed */
+				mclip_rect = 1;
+				traps_count = traps_not_completed > (ntriangle_per_loop / 4) ?
+				              (ntriangle_per_loop / 4) : traps_not_completed;
+				traps_not_completed -= traps_count;
+				glamor_flush_composite_triangles(screen);
+				goto NTRAPS_LOOP_AGAIN;
+			}
+
+			pbox++;
+		}
+
+		glamor_flush_composite_triangles(screen);
+
+		nclip_rect -= clip_processed;
+	}
+
+	ret = TRUE;
+
+TRAPEZOID_RESET_GL:
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+	dispatch->glDisable(GL_BLEND);
+#ifndef GLAMOR_GLES2
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glActiveTexture(GL_TEXTURE1);
+	dispatch->glDisable(GL_TEXTURE_2D);
+#endif
+	dispatch->glUseProgram(0);
+
+TRAPEZOID_OUT:
+	if (box) {
+		REGION_UNINIT(dst->pDrawable->pScreen, &region);
+	}
+
+	if (temp_src != src) {
+		FreePicture(temp_src, 0);
+	} else {
+		if (saved_source_format) {
+			src->format = saved_source_format;
+		}
+	}
+
+	if (dispatch) {
+		glamor_put_dispatch(glamor_priv);
+	}
+
+	return ret;
+}
+
 void
 glamor_init_trapezoid_shader(ScreenPtr screen)
 {
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index dfe8e56..51a5b0e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -349,6 +349,25 @@
     DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]);	\
   } while(0)
 
+#define glamor_set_transformed_normalize_tri_tcoords(priv,		\
+						     matrix,		\
+						     xscale,		\
+						     yscale,		\
+						     vtx,		\
+						     yInverted,		\
+						     texcoords)		\
+    do {								\
+	glamor_set_transformed_point(priv, matrix, xscale, yscale,	\
+				     texcoords, (vtx)[0], (vtx)[1],	\
+				     yInverted);			\
+	glamor_set_transformed_point(priv, matrix, xscale, yscale,	\
+				     texcoords+2, (vtx)[2], (vtx)[3],	\
+				     yInverted);			\
+	glamor_set_transformed_point(priv, matrix, xscale, yscale,	\
+				     texcoords+4, (vtx)[4], (vtx)[5],	\
+				     yInverted);			\
+    } while (0)
+
 #define glamor_set_transformed_normalize_tcoords( priv,			\
 						  matrix,		\
 						  xscale,		\
@@ -370,6 +389,26 @@
 				 yInverted);				\
   } while (0)
 
+#define glamor_set_normalize_tri_tcoords(xscale,		\
+					 yscale,		\
+					 vtx,			\
+					 yInverted,		\
+					 texcoords)		\
+    do {							\
+	_glamor_set_normalize_tpoint(xscale, yscale,		\
+				(vtx)[0], (vtx)[1],		\
+				texcoords,			\
+				yInverted);			\
+	_glamor_set_normalize_tpoint(xscale, yscale,		\
+				(vtx)[2], (vtx)[3],		\
+				texcoords+2,			\
+				yInverted);			\
+	_glamor_set_normalize_tpoint(xscale, yscale,		\
+				(vtx)[4], (vtx)[5],		\
+				texcoords+4,			\
+				yInverted);			\
+    } while (0)
+
 #define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
 							 repeat_type,	\
 							 matrix,	\
@@ -520,6 +559,31 @@
 	(vertices)[7] = (vertices)[5];				\
     } while(0)
 
+#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y,		\
+					yInverted, vertices)		\
+    do {								\
+	(vertices)[0] = v_from_x_coord_x(xscale, x);			\
+	if (yInverted) {						\
+	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y);	\
+	} else {							\
+	    (vertices)[1] = v_from_x_coord_y(yscale, y);		\
+	}								\
+    } while(0)
+
+#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx,		\
+					 yInverted, vertices)		\
+    do {								\
+	glamor_set_normalize_one_vcoord(xscale, yscale,			\
+					(vtx)[0], (vtx)[1],		\
+					yInverted, vertices);		\
+	glamor_set_normalize_one_vcoord(xscale, yscale,			\
+					(vtx)[2], (vtx)[3],		\
+					yInverted, vertices+2);		\
+	glamor_set_normalize_one_vcoord(xscale, yscale,			\
+					(vtx)[4], (vtx)[5],		\
+					yInverted, vertices+4);		\
+    } while(0)
+
 #define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2,	\
 				     yInverted, vertices)		\
     do {								\
commit 5f1560c84aa386bb12dc6ec3daeb93e0f63c09c2
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Mon Jun 4 07:22:27 2012 +0800

    Modilfy the composite logic to two phases
    
     We seperate the composite to two phases, firstly to
     select the shader according to source type and logic
     op, setting the right parameters. Then we emit the
     vertex array to generate the dest result.
     The reason why we do this is that the shader may be
     used to composite no only rect, trapezoid and triangle
     render function can also use it to render triangles and
     polygens. The old function glamor_composite_with_shader
     do the whole two phases work and can not match the
     new request.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index e02c12c..444ba6c 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -788,7 +788,6 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	glamor_pixmap_private *pixmap_priv;
 	PixmapPtr pixmap = NULL;
 	glamor_gl_dispatch *dispatch = NULL;
-	float tmp;
 
 	pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b842d9b..362abae 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -127,6 +127,12 @@ enum shader_in {
 	SHADER_IN_COUNT,
 };
 
+struct shader_key {
+	enum shader_source source;
+	enum shader_mask mask;
+	enum shader_in in;
+};
+
 enum gradient_shader {
 	SHADER_GRADIENT_LINEAR,
 	SHADER_GRADIENT_RADIAL,
@@ -158,6 +164,8 @@ enum glamor_gl_flavor {
 
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
+
 typedef struct {
 	PicturePtr picture;	/* Where the glyphs of the cache are stored */
 	GlyphPtr *glyphs;
@@ -704,6 +712,15 @@ void glamor_composite_rects (CARD8         op,
 			     xRectangle    *rects);
 void glamor_init_trapezoid_shader(ScreenPtr screen);
 void glamor_fini_trapezoid_shader(ScreenPtr screen);
+PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
+                                           PicturePtr source,
+                                           int x_source,
+                                           int y_source, int width, int height);
+void glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
+void glamor_emit_composite_vert(ScreenPtr screen,
+                                const float *src_coords,
+                                const float *mask_coords,
+                                const float *dst_coords, int i);
 
 /* glamor_trapezoid.c */
 void glamor_trapezoids(CARD8 op,
@@ -939,10 +956,10 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
-//#define GLAMOR_TRAPEZOID_SHADER
+#define GLAMOR_TRAPEZOID_SHADER
 #endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
-#if 1
+#if 0
 #define MAX_FBO_SIZE 32 /* For test purpose only. */
 #endif
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index da9d847..a228a22 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -43,11 +43,6 @@
 //#define DEBUGRegionPrint(x) do {} while (0)
 #define DEBUGRegionPrint RegionPrint
 #endif
-struct shader_key {
-	enum shader_source source;
-	enum shader_mask mask;
-	enum shader_in in;
-};
 
 struct blendinfo {
 	Bool dest_alpha;
@@ -385,8 +380,6 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 	return shader;
 }
 
-#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
-
 static void
 glamor_init_eb(unsigned short *eb, int vert_cnt)
 {
@@ -735,7 +728,7 @@ cleanup_region:
 	return ret;
 }
 
-static void
+void
 glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
 	glamor_screen_private *glamor_priv =
@@ -795,7 +788,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	glamor_put_dispatch(glamor_priv);
 }
 
-static void
+void
 glamor_emit_composite_vert(ScreenPtr screen,
 			   const float *src_coords,
 			   const float *mask_coords,
@@ -963,44 +956,36 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
 								texcoords);
 }
 
-static Bool
-glamor_composite_with_shader(CARD8 op,
-			     PicturePtr source,
-			     PicturePtr mask,
-			     PicturePtr dest,
-			     glamor_pixmap_private *source_pixmap_priv,
-			     glamor_pixmap_private *mask_pixmap_priv,
-			     glamor_pixmap_private *dest_pixmap_priv,
-			     int nrect,
-			     glamor_composite_rect_t * rects)
+Bool glamor_composite_choose_shader(CARD8 op,
+                                    PicturePtr source,
+                                    PicturePtr mask,
+                                    PicturePtr dest,
+			     	    glamor_pixmap_private *source_pixmap_priv,
+			     	    glamor_pixmap_private *mask_pixmap_priv,
+			     	    glamor_pixmap_private *dest_pixmap_priv,
+                                    struct shader_key *s_key,
+                                    PictFormatShort *psaved_source_format)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
-	glamor_gl_dispatch *dispatch;
 	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
-	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-	GLfloat dst_xscale, dst_yscale;
-	GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
-	struct shader_key key;
-	glamor_composite_shader *shader;
-	float vertices[8], source_texcoords[8], mask_texcoords[8];
-	int dest_x_off, dest_y_off;
-	int source_x_off, source_y_off;
-	int mask_x_off, mask_y_off;
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr mask_pixmap = NULL;
 	enum glamor_pixmap_status source_status = GLAMOR_NONE;
 	enum glamor_pixmap_status mask_status = GLAMOR_NONE;
 	PictFormatShort saved_source_format = 0;
-	float src_matrix[9], mask_matrix[9];
-	float *psrc_matrix = NULL, *pmask_matrix = NULL;
-	GLfloat source_solid_color[4], mask_solid_color[4];
-	int vert_stride = 4;
-	int nrect_max;
+	struct shader_key key;
+	GLfloat source_solid_color[4];
+	GLfloat mask_solid_color[4];
+	glamor_composite_shader *shader = NULL;
+	glamor_gl_dispatch *dispatch = NULL;
 	Bool ret = FALSE;
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
 	}
+
 	memset(&key, 0, sizeof(key));
 	if (!source) {
 		key.source = SHADER_SOURCE_SOLID;
@@ -1023,10 +1008,11 @@ glamor_composite_with_shader(CARD8 op,
 	} else {
 		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
 	}
+
 	if (mask) {
 		if (!mask->pDrawable) {
 			if (mask->pSourcePict->type ==
-			    SourcePictTypeSolidFill) {
+			     SourcePictTypeSolidFill) {
 				key.mask = SHADER_MASK_SOLID;
 				glamor_get_rgba_from_pixel
 				    (mask->pSourcePict->solidFill.color,
@@ -1045,14 +1031,13 @@ glamor_composite_with_shader(CARD8 op,
 			if (op == PictOpClear)
 				key.mask = SHADER_MASK_NONE;
 			else if (op == PictOpSrc || op == PictOpAdd
-				 || op == PictOpIn || op == PictOpOut
-				 || op == PictOpOverReverse)
+			         || op == PictOpIn || op == PictOpOut
+			         || op == PictOpOverReverse)
 				key.in = SHADER_IN_CA_SOURCE;
 			else if (op == PictOpOutReverse || op == PictOpInReverse) {
 				key.in = SHADER_IN_CA_ALPHA;
 			} else {
-				glamor_fallback
-				    ("Unsupported component alpha op: %d\n", op);
+				glamor_fallback("Unsupported component alpha op: %d\n", op);
 				goto fail;
 			}
 		}
@@ -1069,6 +1054,7 @@ glamor_composite_with_shader(CARD8 op,
 		glamor_fallback("mask alphaMap\n");
 		goto fail;
 	}
+
 	if (key.source == SHADER_SOURCE_TEXTURE ||
 	    key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
 		source_pixmap = source_pixmap_priv->base.pixmap;
@@ -1090,6 +1076,7 @@ glamor_composite_with_shader(CARD8 op,
 #endif
 		}
 	}
+
 	if (key.mask == SHADER_MASK_TEXTURE ||
 	    key.mask == SHADER_MASK_TEXTURE_ALPHA) {
 		mask_pixmap = mask_pixmap_priv->base.pixmap;
@@ -1106,26 +1093,25 @@ glamor_composite_with_shader(CARD8 op,
 #endif
 		}
 	}
+
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 	if (source_status == GLAMOR_UPLOAD_PENDING
-	    && mask_status == GLAMOR_UPLOAD_PENDING
-	    && source_pixmap == mask_pixmap) {
+	     && mask_status == GLAMOR_UPLOAD_PENDING
+	     && source_pixmap == mask_pixmap) {
 
 		if (source->format != mask->format) {
 			saved_source_format = source->format;
 
-			if (!combine_pict_format
-			    (&source->format, source->format,
-			     mask->format, key.in)) {
-				glamor_fallback
-				    ("combine source %x mask %x failed.\n",
-				     source->format, mask->format);
+			if (!combine_pict_format(&source->format, source->format,
+			                         mask->format, key.in)) {
+				glamor_fallback("combine source %x mask %x failed.\n",
+				                source->format, mask->format);
 				goto fail;
 			}
 
 			if (source->format != saved_source_format) {
-				//glamor_picture_format_fixup(source,
-				//			    source_pixmap_priv);
+				glamor_picture_format_fixup(source,
+				        source_pixmap_priv);
 			}
 			/* XXX
 			 * By default, glamor_upload_picture_to_texture will wire alpha to 1
@@ -1144,11 +1130,11 @@ glamor_composite_with_shader(CARD8 op,
 			 *
 			 **/
 			if (!PICT_FORMAT_A(saved_source_format)
-			    && PICT_FORMAT_A(mask->format))
+			     && PICT_FORMAT_A(mask->format))
 				key.source = SHADER_SOURCE_TEXTURE;
 
 			if (!PICT_FORMAT_A(mask->format)
-			    && PICT_FORMAT_A(saved_source_format))
+			     && PICT_FORMAT_A(saved_source_format))
 				key.mask = SHADER_MASK_TEXTURE;
 
 			mask_status = GLAMOR_NONE;
@@ -1156,16 +1142,14 @@ glamor_composite_with_shader(CARD8 op,
 
 		source_status = glamor_upload_picture_to_texture(source);
 		if (source_status != GLAMOR_UPLOAD_DONE) {
-			glamor_fallback
-			    ("Failed to upload source texture.\n");
+			glamor_fallback("Failed to upload source texture.\n");
 			goto fail;
 		}
 	} else {
 		if (source_status == GLAMOR_UPLOAD_PENDING) {
 			source_status = glamor_upload_picture_to_texture(source);
 			if (source_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback
-				    ("Failed to upload source texture.\n");
+				glamor_fallback("Failed to upload source texture.\n");
 				goto fail;
 			}
 		}
@@ -1173,8 +1157,7 @@ glamor_composite_with_shader(CARD8 op,
 		if (mask_status == GLAMOR_UPLOAD_PENDING) {
 			mask_status = glamor_upload_picture_to_texture(mask);
 			if (mask_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback
-				    ("Failed to upload mask texture.\n");
+				glamor_fallback("Failed to upload mask texture.\n");
 				goto fail;
 			}
 		}
@@ -1206,8 +1189,8 @@ glamor_composite_with_shader(CARD8 op,
 
 	shader = glamor_lookup_composite_shader(screen, &key);
 	if (shader->prog == 0) {
-		glamor_fallback
-		    ("no shader program for this render acccel mode\n");
+		glamor_fallback("no shader program for this"
+		                "render acccel mode\n");
 		goto fail;
 	}
 
@@ -1216,33 +1199,92 @@ glamor_composite_with_shader(CARD8 op,
 
 	if (key.source == SHADER_SOURCE_SOLID) {
 		glamor_set_composite_solid(dispatch, source_solid_color,
-					   shader->source_uniform_location);
+		        shader->source_uniform_location);
 	} else {
 		glamor_set_composite_texture(screen, 0, source,
-					     source_pixmap_priv, shader->source_wh,
-					     shader->source_repeat_mode);
+		        source_pixmap_priv, shader->source_wh,
+		        shader->source_repeat_mode);
 	}
+
 	if (key.mask != SHADER_MASK_NONE) {
 		if (key.mask == SHADER_MASK_SOLID) {
 			glamor_set_composite_solid(dispatch,
-						   mask_solid_color,
-						   shader->mask_uniform_location);
+			        mask_solid_color,
+			        shader->mask_uniform_location);
 		} else {
 			glamor_set_composite_texture(screen, 1, mask,
-						     mask_pixmap_priv, shader->mask_wh,
-						     shader->mask_repeat_mode);
+			        mask_pixmap_priv, shader->mask_wh,
+			        shader->mask_repeat_mode);
 		}
 	}
 
+	glamor_put_dispatch(glamor_priv);
+	ret = TRUE;
+	memcpy(s_key, &key, sizeof(key));
+	*psaved_source_format = saved_source_format;
+	goto done;
+
+fail:
+	if (saved_source_format)
+		source->format = saved_source_format;
+done:
+	return ret;
+}
+
+static Bool
+glamor_composite_with_shader(CARD8 op,
+			     PicturePtr source,
+			     PicturePtr mask,
+			     PicturePtr dest,
+			     glamor_pixmap_private *source_pixmap_priv,
+			     glamor_pixmap_private *mask_pixmap_priv,
+			     glamor_pixmap_private *dest_pixmap_priv,
+			     int nrect, glamor_composite_rect_t * rects)
+{
+	ScreenPtr screen = dest->pDrawable->pScreen;
+	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
+	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr mask_pixmap = NULL;
+	glamor_gl_dispatch *dispatch = NULL;
+	GLfloat dst_xscale, dst_yscale;
+	GLfloat mask_xscale = 1, mask_yscale = 1,
+	        src_xscale = 1, src_yscale = 1;
+	struct shader_key key;
+	float vertices[8], source_texcoords[8], mask_texcoords[8];
+	int dest_x_off, dest_y_off;
+	int source_x_off, source_y_off;
+	int mask_x_off, mask_y_off;
+	PictFormatShort saved_source_format = 0;
+	float src_matrix[9], mask_matrix[9];
+	float *psrc_matrix = NULL, *pmask_matrix = NULL;
+	int vert_stride = 4;
+	int nrect_max;
+	Bool ret = FALSE;
+
+	if(!glamor_composite_choose_shader(op, source, mask, dest,
+					   source_pixmap_priv, mask_pixmap_priv,
+					   dest_pixmap_priv,
+	                                   &key, &saved_source_format)) {
+		glamor_fallback("glamor_composite_choose_shader failed\n");
+		return ret;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
 	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
 	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
 					key.mask != SHADER_MASK_SOLID);
 
+	dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
 				   &dest_x_off, &dest_y_off);
 	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	if (glamor_priv->has_source_coords) {
+		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 		glamor_get_drawable_deltas(source->pDrawable,
 					   source_pixmap, &source_x_off,
 					   &source_y_off);
@@ -1256,6 +1298,8 @@ glamor_composite_with_shader(CARD8 op,
 	}
 
 	if (glamor_priv->has_mask_coords) {
+		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 		glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
 					   &mask_x_off, &mask_y_off);
 		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
@@ -1350,16 +1394,10 @@ glamor_composite_with_shader(CARD8 op,
 	glamor_put_dispatch(glamor_priv);
 
 	ret = TRUE;
-	goto done;
-
-fail:
-	if (saved_source_format)
-		source->format = saved_source_format;
-done:
 	return ret;
 }
 
-static PicturePtr
+PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
                                 PicturePtr source,
                                 int x_source,
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index e65f7e3..f0c0b8b 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -395,7 +395,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	BoxRec one_trap_bound;
 	float vertices[8];
 	float tex_vertices[8];
-	float tmp;
 	int i;
 
 	glamor_priv = glamor_get_screen_private(screen);
@@ -410,8 +409,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 	}
 
 	/* First, clear all to zero */
-	if (!glamor_solid(pixmap, 0, 0, pixmap_priv->container->drawable.width,
-	                  pixmap_priv->container->drawable.height,
+	if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
+	                  pixmap_priv->base.pixmap->drawable.height,
 	                  GXclear, 0xFFFFFFFF, 0)) {
 		DEBUGF("glamor_solid failed, fallback\n");
 		return FALSE;
@@ -490,8 +489,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 		       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
 
 		miTrapezoidBounds(1, ptrap, &one_trap_bound);
-		glamor_set_tcoords_tri_strip((pixmap_priv->container->drawable.width),
-		                             (pixmap_priv->container->drawable.height),
+		glamor_set_tcoords_tri_strip((pixmap_priv->base.pixmap->drawable.width),
+		                             (pixmap_priv->base.pixmap->drawable.height),
 		                             (one_trap_bound.x1),
 		                             (one_trap_bound.y1),
 		                             (one_trap_bound.x2),
commit 0b0391765f3ca0192b00f4970c9453934d529397
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Mon Jun 4 03:18:40 2012 +0800

    Add macro of vertex setting for triangle stripe
    
      Add macro of vertex setting for triangle stripe draw,
      and make the code clear.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 09e33d7..e02c12c 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -806,25 +806,25 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	       *xscale, *yscale, x_source, y_source,
 	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
 
-	glamor_set_normalize_vcoords(pixmap_priv, *xscale, *yscale,
-	                             0, 0,
-	                             (INT16)(dst_picture->pDrawable->width),
-	                             (INT16)(dst_picture->pDrawable->height),
-	                             glamor_priv->yInverted, vertices);
+	glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale,
+	                  0, 0,
+	                  (INT16)(dst_picture->pDrawable->width),
+	                  (INT16)(dst_picture->pDrawable->height),
+	                  glamor_priv->yInverted, vertices);
 
 	if (tex_normalize) {
-		glamor_set_normalize_tcoords(pixmap_priv, *xscale, *yscale,
-		                             x_source, y_source,
-		                             (INT16)(dst_picture->pDrawable->width + x_source),
-		                             (INT16)(dst_picture->pDrawable->height + y_source),
-		                             glamor_priv->yInverted, tex_vertices);
+		glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
+		                x_source, y_source,
+		                (INT16)(dst_picture->pDrawable->width + x_source),
+		                (INT16)(dst_picture->pDrawable->height + y_source),
+		                glamor_priv->yInverted, tex_vertices);
 	} else {
-		glamor_set_tcoords((INT16)(dst_picture->pDrawable->width),
-		                   (INT16)(dst_picture->pDrawable->height),
-		                   x_source, y_source,
-		                   (INT16)(dst_picture->pDrawable->width) + x_source,
-		                   (INT16)(dst_picture->pDrawable->height) + y_source,
-		                   glamor_priv->yInverted, tex_vertices);
+		glamor_set_tcoords_tri_strip((INT16)(dst_picture->pDrawable->width),
+		                 (INT16)(dst_picture->pDrawable->height),
+		                 x_source, y_source,
+		                 (INT16)(dst_picture->pDrawable->width) + x_source,
+		                 (INT16)(dst_picture->pDrawable->height) + y_source,
+		                 glamor_priv->yInverted, tex_vertices);
 	}
 
 	DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
@@ -836,21 +836,6 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
 	       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
 
-	/* Swap the vtx for triangle render. */
-	tmp = vertices[4];
-	vertices[4] = vertices[6];
-	vertices[6] = tmp;
-	tmp = vertices[5];
-	vertices[5] = vertices[7];
-	vertices[7] = tmp;
-
-	tmp = tex_vertices[4];
-	tex_vertices[4] = tex_vertices[6];
-	tex_vertices[6] = tmp;
-	tmp = tex_vertices[5];
-	tex_vertices[5] = tex_vertices[7];
-	tex_vertices[7] = tmp;
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index d9682ba..e65f7e3 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -490,39 +490,24 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
 		       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
 
 		miTrapezoidBounds(1, ptrap, &one_trap_bound);
-		glamor_set_tcoords((pixmap_priv->container->drawable.width),
-		                   (pixmap_priv->container->drawable.height),
-		                   (one_trap_bound.x1),
-		                   (one_trap_bound.y1),
-		                   (one_trap_bound.x2),
-		                   (one_trap_bound.y2),
-		                   glamor_priv->yInverted, tex_vertices);
+		glamor_set_tcoords_tri_strip((pixmap_priv->container->drawable.width),
+		                             (pixmap_priv->container->drawable.height),
+		                             (one_trap_bound.x1),
+		                             (one_trap_bound.y1),
+		                             (one_trap_bound.x2),
+		                             (one_trap_bound.y2),
+		                             glamor_priv->yInverted, tex_vertices);
 
 		/* Need to rebase. */
 		one_trap_bound.x1 -= bounds->x1;
 		one_trap_bound.x2 -= bounds->x1;
 		one_trap_bound.y1 -= bounds->y1;
 		one_trap_bound.y2 -= bounds->y1;
-		glamor_set_normalize_vcoords(xscale, yscale,
+		glamor_set_normalize_vcoords_tri_strip(xscale, yscale,
 		        one_trap_bound.x1, one_trap_bound.y1,
 		        one_trap_bound.x2, one_trap_bound.y2,
 		        glamor_priv->yInverted, vertices);
 
-		/* Swap the vtx for triangle render. */
-		tmp = vertices[4];
-		vertices[4] = vertices[6];
-		vertices[6] = tmp;
-		tmp = vertices[5];
-		vertices[5] = vertices[7];
-		vertices[7] = tmp;
-
-		tmp = tex_vertices[4];
-		tex_vertices[4] = tex_vertices[6];
-		tex_vertices[6] = tmp;
-		tmp = tex_vertices[5];
-		tex_vertices[5] = tex_vertices[7];
-		tex_vertices[7] = tmp;
-
 		DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
 		       "rightbottom: %f X %f, leftbottom : %f X %f\n",
 		       vertices[0], vertices[1], vertices[2], vertices[3],
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 18f7f3b..dfe8e56 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -481,6 +481,25 @@
 				   tx2, ty2, yInverted, vertices);	\
  } while(0)
 
+#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale,		\
+						x1, y1, x2, y2,		\
+						yInverted, vertices)	\
+    do {								\
+	(vertices)[0] = t_from_x_coord_x(xscale, x1);			\
+	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
+	(vertices)[6] = (vertices)[2];					\
+	(vertices)[4] = (vertices)[0];					\
+	if (yInverted) {						\
+	    (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);	\
+	    (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2);	\
+	}								\
+	else {								\
+	    (vertices)[1] = t_from_x_coord_y(yscale, y1);		\
+	    (vertices)[7] = t_from_x_coord_y(yscale, y2);		\
+	}								\
+	(vertices)[3] = (vertices)[1];					\
+	(vertices)[5] = (vertices)[7];					\
+    } while(0)
 
 #define glamor_set_tcoords(width, height, x1, y1, x2, y2,	\
 			   yInverted, vertices)			\
@@ -501,6 +520,24 @@
 	(vertices)[7] = (vertices)[5];				\
     } while(0)
 
+#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2,	\
+				     yInverted, vertices)		\
+    do {								\
+	(vertices)[0] = (x1);						\
+	(vertices)[2] = (x2);						\
+	(vertices)[6] = (vertices)[2];					\
+	(vertices)[4] = (vertices)[0];					\
+	if (yInverted) {						\
+	    (vertices)[1] = (y1);					\
+	    (vertices)[7] = (y2);					\
+	}								\
+	else {								\
+	    (vertices)[1] = height - (y2);				\
+	    (vertices)[7] = height - (y1);				\
+	}								\
+	(vertices)[3] = (vertices)[1];					\
+	(vertices)[5] = (vertices)[7];					\
+    } while(0)
 
 #define glamor_set_normalize_vcoords(priv, xscale, yscale,		\
 				     x1, y1, x2, y2,			\
@@ -524,6 +561,26 @@
     (vertices)[7] = (vertices)[5];					\
   } while(0)
 
+#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale,		\
+					       x1, y1, x2, y2,		\
+					       yInverted, vertices)	\
+    do {								\
+	(vertices)[0] = v_from_x_coord_x(xscale, x1);			\
+	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
+	(vertices)[6] = (vertices)[2];					\
+	(vertices)[4] = (vertices)[0];					\
+	if (yInverted) {						\
+	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);	\
+	    (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2);	\
+	}								\
+	else {								\
+	    (vertices)[1] = v_from_x_coord_y(yscale, y1);		\
+	    (vertices)[7] = v_from_x_coord_y(yscale, y2);		\
+	}								\
+	(vertices)[3] = (vertices)[1];					\
+	(vertices)[5] = (vertices)[7];					\
+    } while(0)
+
 #define glamor_set_normalize_pt(xscale, yscale, x, y,		\
                                 yInverted, pt)			\
     do {							\
commit bd180be619c2ef469ca40cf95023340c59960540
Author: RobinHe <robinhe at robinhe-desktop.lan>
Date:   Sat Jun 2 22:00:09 2012 +0800

    Use shader to generate the temp trapezoid mask
    
     The old manner of trapezoid render uses pixman to
     generate a mask pixmap and upload it to the GPU.
     This effect the performance. We now use shader to
     generate the temp trapezoid mask to avoid the
     uploading of this pixmap.
     We implement a anti-alias manner in the shader
     according to pixman, which will caculate the area
     inside the trapezoid dividing total area for every
     pixel and assign it to the alpha value of that pixel.
     The pixman use a int-to-fix manner to approximate but
     the shader use float, so the result may have some
     difference.
     Because the array in the shader has optimization problem,
     we need to emit the vertex of every trapezoid every
     time, which will effect the performance a lot. Need to
     improve it.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 74b22d3..e491783 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -407,6 +407,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_init_pixmap_fbo(screen);
 	glamor_init_solid_shader(screen);
 	glamor_init_tile_shader(screen);
+#ifdef GLAMOR_TRAPEZOID_SHADER
+	glamor_init_trapezoid_shader(screen);
+#endif
 	glamor_init_putimage_shaders(screen);
 	glamor_init_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
@@ -437,6 +440,9 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_fini_pixmap_fbo(screen);
 	glamor_fini_solid_shader(screen);
 	glamor_fini_tile_shader(screen);
+#ifdef GLAMOR_TRAPEZOID_SHADER
+	glamor_fini_trapezoid_shader(screen);
+#endif
 	glamor_fini_putimage_shaders(screen);
 	glamor_fini_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 92aa3a3..b842d9b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -247,6 +247,9 @@ typedef struct glamor_screen_private {
 	GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
 	int radial_max_nstops;
 
+	/* glamor trapezoid shader. */
+	GLint trapezoid_prog;
+
 	/* glamor_putimage */
 	GLint put_image_xybitmap_prog;
 	GLint put_image_xybitmap_fg_uniform_location;
@@ -699,6 +702,8 @@ void glamor_composite_rects (CARD8         op,
 			     xRenderColor  *color,
 			     int           nRect,
 			     xRectangle    *rects);
+void glamor_init_trapezoid_shader(ScreenPtr screen);
+void glamor_fini_trapezoid_shader(ScreenPtr screen);
 
 /* glamor_trapezoid.c */
 void glamor_trapezoids(CARD8 op,
@@ -934,6 +939,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
+//#define GLAMOR_TRAPEZOID_SHADER
 #endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #if 1
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 08ee2d6..d9682ba 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -36,15 +36,576 @@
 #include "mipict.h"
 #include "fbpict.h"
 
+#ifdef GLAMOR_TRAPEZOID_SHADER
+void
+glamor_init_trapezoid_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	GLint fs_prog, vs_prog;
+
+	const char *trapezoid_vs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_Position = v_position;\n"
+	    "    source_texture = v_texcoord.xy;\n"
+	    "}\n";
+
+	/*
+	 * Because some GL fill function do not support the MultSample
+	 * anti-alias, we need to do the MSAA here. This manner like
+	 * pixman, will caculate the value of area in trapezoid dividing
+	 * the totol area for each pixel, as follow:
+	     |
+	 ----+------------------------------------------------------>
+	     |
+	     |              -------------
+	     |             /             \
+	     |            /               \
+	     |           /                 \
+	     |          /              +----------------+
+	     |         /               |.....\          |
+	     |        /                |......\         |
+	     |       /                 |.......\        |
+	     |      /                  |........\       |
+	     |     /-------------------+---------\      |
+	     |                         |                |
+	     |                         |                |
+	     |                         +----------------+
+	     |
+	    \|/
+
+	 */
+	const char *trapezoid_fs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "varying vec2 source_texture;  \n"
+	    "uniform float x_per_pix;  \n"
+	    "uniform float y_per_pix;  \n"
+	    "uniform float trap_top;  \n"
+	    "uniform float trap_bottom;  \n"
+	    "uniform float trap_left_x;  \n"
+	    "uniform float trap_left_y;  \n"
+	    "uniform float trap_left_slope;  \n"
+	    "uniform int trap_left_vertical;  \n"
+	    "uniform float trap_right_x;  \n"
+	    "uniform float trap_right_y;  \n"
+	    "uniform float trap_right_slope;  \n"
+	    "uniform int trap_right_vertical;  \n"
+	    "\n"
+	    "float get_alpha_val() \n"
+	    "{  \n"
+	    "    float x_up_cut_left;  \n"
+	    "    float x_bottom_cut_left;  \n"
+	    "    float x_up_cut_right;  \n"
+	    "    float x_bottom_cut_right;  \n"
+	    "    \n"
+	    "    if(trap_left_vertical == 1) {  \n"
+	    "        x_up_cut_left = trap_left_x;  \n"
+	    "        x_bottom_cut_left = trap_left_x;  \n"
+	    "    } else {  \n"
+	    "        x_up_cut_left = trap_left_x  \n"
+	    "            + (source_texture.y - y_per_pix/2.0 - trap_left_y)  \n"
+	    "              / trap_left_slope;  \n"
+	    "        x_bottom_cut_left = trap_left_x  \n"
+	    "            + (source_texture.y + y_per_pix/2.0 - trap_left_y)  \n"
+	    "              / trap_left_slope;  \n"
+	    "    }  \n"
+	    "    \n"
+	    "    if(trap_right_vertical == 1) {  \n"
+	    "        x_up_cut_right = trap_right_x;  \n"
+	    "        x_bottom_cut_right = trap_right_x;  \n"
+	    "    } else {  \n"
+	    "        x_up_cut_right = trap_right_x  \n"
+	    "            + (source_texture.y - y_per_pix/2.0 - trap_right_y)  \n"
+	    "              / trap_right_slope;  \n"
+	    "        x_bottom_cut_right = trap_right_x  \n"
+	    "            + (source_texture.y + y_per_pix/2.0 - trap_right_y)  \n"
+	    "              / trap_right_slope;  \n"
+	    "    }  \n"
+	    "    \n"
+	    "    if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
+	    "          (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) &&  \n"
+	    "          (x_up_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
+	    "          (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) &&  \n"
+	    "          (trap_top <= source_texture.y - y_per_pix/2.0) &&  \n"
+	    "          (trap_bottom >= source_texture.y + y_per_pix/2.0)) {  \n"
+	    //       The complete inside case.
+	    "        return 1.0;  \n"
+	    "    } else if((trap_top > source_texture.y + y_per_pix/2.0) ||  \n"
+	    "                (trap_bottom < source_texture.y - y_per_pix/2.0)) {  \n"
+	    //       The complete outside. Above the top or Below the bottom.
+	    "        return 0.0;  \n"
+	    "    } else {  \n"
+	    "        if((x_up_cut_right < source_texture.x - x_per_pix/2.0 &&  \n"
+	    "                   x_bottom_cut_right < source_texture.x - x_per_pix/2.0)  \n"
+	    "            || (x_up_cut_left > source_texture.x + x_per_pix/2.0  &&  \n"
+	    "                   x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) {  \n"
+	    //            The complete outside. At Left or Right of the trapezoide.
+	    "             return 0.0;  \n"
+	    "        }  \n"
+	    "    }  \n"
+	    //   Get here, the pix is partly inside the trapezoid.
+	    "    {  \n"
+	    "        float percent = 0.0;  \n"
+	    "        float up = (source_texture.y - y_per_pix/2.0) >= trap_top ?  \n"
+	    "                       (source_texture.y - y_per_pix/2.0) : trap_top;  \n"
+	    "        float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ?  \n"
+	    "                       (source_texture.y + y_per_pix/2.0) : trap_bottom;  \n"
+	    "        float left = source_texture.x - x_per_pix/2.0;  \n"
+	    "        float right = source_texture.x + x_per_pix/2.0;  \n"
+	    "        \n"
+	    "        percent = (bottom - up) / y_per_pix;  \n"
+	    "        \n"
+	    "	     if(trap_left_vertical == 1) {  \n"
+	    "            if(trap_left_x > source_texture.x - x_per_pix/2.0 &&  \n"
+	    "                     trap_left_x < source_texture.x + x_per_pix/2.0)  \n"
+	    "                left = trap_left_x;  \n"
+	    "        }  \n"
+	    "	     if(trap_right_vertical == 1) {  \n"
+	    "            if(trap_right_x > source_texture.x - x_per_pix/2.0 &&  \n"
+	    "                     trap_right_x < source_texture.x + x_per_pix/2.0)  \n"
+	    "                right = trap_right_x;  \n"
+	    "        }  \n"
+	    "        if((up >= bottom) || (left >= right))  \n"
+	    "            return 0.0;  \n"
+	    "        \n"
+	    "        percent = percent * ((right - left)/x_per_pix);  \n"
+	    "        if(trap_left_vertical == 1 && trap_right_vertical == 1)  \n"
+	    "            return percent;  \n"
+	    "        \n"
+	    "        if(trap_left_vertical != 1) {  \n"
+	    "            float area;  \n"
+	    //           the slope should never be 0.0 here
+	    "            float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope;  \n"
+	    "            float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope;  \n"
+	    "            if(trap_left_slope < 0.0 && up_x > left) {  \n"
+	    /*   case 1
+	         |
+	     ----+------------------------------------->
+	         |                 /
+	         |                /
+	         |           +---/--------+
+	         |           |  /.........|
+	         |           | /..........|
+	         |           |/...........|
+	         |           /............|
+	         |          /|............|
+	         |           +------------+
+	         |
+	        \|/
+	    */
+	    "                float left_y = trap_left_y + trap_left_slope*(left - trap_left_x);  \n"
+	    "                if((up_x > left) && (left_y > up)) {  \n"
+	    "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
+	    "                    if(up_x > right) {  \n"
+	    "                        float right_y = trap_left_y  \n"
+	    "                                  + trap_left_slope*(right - trap_left_x);  \n"
+	    "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
+	    "                    }  \n"
+	    "                    if(left_y > bottom) {  \n"
+	    "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
+	    "                    }  \n"
+	    "                } else {  \n"
+	    "                    area = 0.0;  \n"
+	    "                }  \n"
+	    "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
+	    "            } else if(trap_left_slope > 0.0 && bottom_x > left) {  \n"
+	    /*   case 2
+	         |
+	     ----+------------------------------------->
+	         |          \
+	         |           \
+	         |           +\-----------+
+	         |           | \..........|
+	         |           |  \.........|
+	         |           |   \........|
+	         |           |    \.......|
+	         |           |     \......|
+	         |           +------\-----+
+	         |                   \
+	         |                    \
+	        \|/
+	    */
+	    "                float right_y = trap_left_y + trap_left_slope*(right - trap_left_x);  \n"
+	    "                if((up_x < right) && (right_y > up)) {  \n"
+	    "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
+	    "                    if(up_x < left) {  \n"
+	    "                        float left_y = trap_left_y  \n"
+	    "                                  + trap_left_slope*(left - trap_left_x);  \n"
+	    "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
+	    "                    }  \n"
+	    "                    if(right_y > bottom) {  \n"
+	    "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
+	    "                    }  \n"
+	    "                } else {  \n"
+	    "                    area = 0.0;  \n"
+	    "                }  \n"
+	    "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
+	    "            }  \n"
+	    "        }  \n"
+	    "        \n"
+	    "        if(trap_right_vertical != 1) {  \n"
+	    "            float area;  \n"
+	    //           the slope should never be 0.0 here
+	    "            float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope;  \n"
+	    "            float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope;  \n"
+	    "            if(trap_right_slope < 0.0 && bottom_x < right) {  \n"
+	    /*   case 3
+	         |
+	     ----+------------------------------------->
+	         |                     /
+	         |           +--------/---+
+	         |           |......./    |
+	         |           |....../     |
+	         |           |...../      |
+	         |           |..../       |
+	         |           |.../        |
+	         |           +--/---------+
+	         |             /
+	         |
+	        \|/
+	    */
+	    "                float left_y = trap_right_y + trap_right_slope*(left - trap_right_x);  \n"
+	    "                if((up_x > left) && (left_y > up)) {  \n"
+	    "                    area = 0.5 * (up_x - left) * (left_y - up);  \n"
+	    "                    if(up_x > right) {  \n"
+	    "                        float right_y = trap_right_y  \n"
+	    "                                  + trap_right_slope*(right - trap_right_x);  \n"
+	    "                        area = area - 0.5 * (up_x - right) * (right_y - up);  \n"
+	    "                    }  \n"
+	    "                    if(left_y > bottom) {  \n"
+	    "                        area = area - 0.5 * (bottom_x - left) * (left_y - bottom);  \n"
+	    "                    }  \n"
+	    "                } else {  \n"
+	    "                    area = 0.0;  \n"
+	    "                }  \n"
+	    "                percent = percent * (area/((right-left)*(bottom-up)));  \n"
+	    "            } else if(trap_right_slope > 0.0 && up_x < right) {  \n"
+	    /*   case 4
+	         |
+	     ----+------------------------------------->
+	         |                   \
+	         |           +--------\---+
+	         |           |.........\  |
+	         |           |..........\ |
+	         |           |...........\|
+	         |           |............\
+	         |           |............|\
+	         |           +------------+ \
+	         |                           \
+	         |
+	        \|/
+	    */
+	    "                float right_y = trap_right_y + trap_right_slope*(right - trap_right_x);  \n"
+	    "                if((up_x < right) && (right_y > up)) {  \n"
+	    "                    area = 0.5 * (right - up_x) * (right_y - up);  \n"
+	    "                    if(up_x < left) {  \n"
+	    "                        float left_y = trap_right_y  \n"
+	    "                                  + trap_right_slope*(left - trap_right_x);  \n"
+	    "                        area = area - 0.5 * (left - up_x) * (left_y - up);  \n"
+	    "                    }  \n"
+	    "                    if(right_y > bottom) {  \n"
+	    "                        area = area - 0.5 * (right - bottom_x) * (right_y - bottom);  \n"
+	    "                    }  \n"
+	    "                } else {  \n"
+	    "                    area = 0.0;  \n"
+	    "                }  \n"
+	    "                percent = percent * (1.0 - (area/((right-left)*(bottom-up))));  \n"
+	    "            }  \n"
+	    "        }  \n"
+	    "        \n"
+	    "        return percent;  \n"
+	    "    }  \n"
+	    "}  \n"
+	    "\n"
+	    "void main()  \n"
+	    "{  \n"
+	    "    float alpha_val = get_alpha_val();  \n"
+	    "    gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val);  \n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	glamor_priv->trapezoid_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch,
+	                  GL_VERTEX_SHADER, trapezoid_vs);
+	fs_prog = glamor_compile_glsl_prog(dispatch,
+	                  GL_FRAGMENT_SHADER, trapezoid_fs);
+
+	dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
+	dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
+
+	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+	                               GLAMOR_VERTEX_POS, "v_positionsition");
+	dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog,
+	                               GLAMOR_VERTEX_SOURCE, "v_texcoord");
+
+	glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog);
+
+	dispatch->glUseProgram(0);
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+void
+glamor_fini_trapezoid_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+	dispatch->glDeleteProgram(glamor_priv->trapezoid_prog);
+	glamor_put_dispatch(glamor_priv);
+}
+
+static Bool
+_glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
+        xTrapezoid * traps, int ntrap, BoxRec *bounds)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_private *pixmap_priv;
+	PixmapPtr pixmap = NULL;
+	GLint x_per_pix_uniform_location;
+	GLint y_per_pix_uniform_location;
+	GLint trap_top_uniform_location;
+	GLint trap_bottom_uniform_location;
+	GLint trap_left_x_uniform_location;
+	GLint trap_left_y_uniform_location;
+	GLint trap_left_slope_uniform_location;
+	GLint trap_right_x_uniform_location;
+	GLint trap_right_y_uniform_location;
+	GLint trap_right_slope_uniform_location;
+	GLint trap_left_vertical_uniform_location;
+	GLint trap_right_vertical_uniform_location;
+	GLint trapezoid_prog;
+	float width, height;
+	xFixed width_fix, height_fix;
+	GLfloat xscale, yscale;
+	float left_slope, right_slope;
+	xTrapezoid *ptrap;
+	BoxRec one_trap_bound;
+	float vertices[8];
+	float tex_vertices[8];
+	float tmp;
+	int i;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	trapezoid_prog = glamor_priv->trapezoid_prog;
+
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
+		DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n");
+		return FALSE;
+	}
+
+	/* First, clear all to zero */
+	if (!glamor_solid(pixmap, 0, 0, pixmap_priv->container->drawable.width,
+	                  pixmap_priv->container->drawable.height,
+	                  GXclear, 0xFFFFFFFF, 0)) {
+		DEBUGF("glamor_solid failed, fallback\n");
+		return FALSE;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	/* Bind all the uniform vars .*/
+	x_per_pix_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "x_per_pix");
+	y_per_pix_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "y_per_pix");
+	trap_top_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_top");
+	trap_bottom_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_bottom");
+	trap_left_x_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_x");
+	trap_left_y_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_y");
+	trap_left_slope_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_slope");
+	trap_left_vertical_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_vertical");
+	trap_right_x_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_x");
+	trap_right_y_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_y");
+	trap_right_slope_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_slope");
+	trap_right_vertical_uniform_location =
+	    dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_vertical");
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+	pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
+
+	width = (float)(bounds->x2 - bounds->x1);
+	height = (float)(bounds->y2 - bounds->y1);
+	width_fix = IntToxFixed((bounds->x2 - bounds->x1));
+	height_fix = IntToxFixed((bounds->y2 - bounds->y1));
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	/* Now draw the Trapezoid mask. */
+	dispatch->glUseProgram(trapezoid_prog);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+	        GL_FALSE, 0, vertices);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+	        GL_FALSE, 0, tex_vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	dispatch->glEnable(GL_BLEND);
+	dispatch->glBlendFunc(GL_ONE, GL_ONE);
+
+	for (i = 0; i < ntrap; i++) {
+		ptrap = traps + i;
+
+		DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d  0x%x\tbottom: %d  0x%x\n"
+		       "left:  p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n"
+		       "right: p1 (%d   0x%x, %d   0x%x)\tp2 (%d   0x%x, %d   0x%x)\n",
+		       xFixedToInt(ptrap->top), ptrap->top,
+		       xFixedToInt(ptrap->bottom), ptrap->bottom,
+		       xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x,
+		       xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y,
+		       xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x,
+		       xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y,
+		       xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x,
+		       xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y,
+		       xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x,
+		       xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y);
+
+		miTrapezoidBounds(1, ptrap, &one_trap_bound);
+		glamor_set_tcoords((pixmap_priv->container->drawable.width),
+		                   (pixmap_priv->container->drawable.height),
+		                   (one_trap_bound.x1),
+		                   (one_trap_bound.y1),
+		                   (one_trap_bound.x2),
+		                   (one_trap_bound.y2),
+		                   glamor_priv->yInverted, tex_vertices);
+
+		/* Need to rebase. */
+		one_trap_bound.x1 -= bounds->x1;
+		one_trap_bound.x2 -= bounds->x1;
+		one_trap_bound.y1 -= bounds->y1;
+		one_trap_bound.y2 -= bounds->y1;
+		glamor_set_normalize_vcoords(xscale, yscale,
+		        one_trap_bound.x1, one_trap_bound.y1,
+		        one_trap_bound.x2, one_trap_bound.y2,
+		        glamor_priv->yInverted, vertices);
+
+		/* Swap the vtx for triangle render. */
+		tmp = vertices[4];
+		vertices[4] = vertices[6];
+		vertices[6] = tmp;
+		tmp = vertices[5];
+		vertices[5] = vertices[7];
+		vertices[7] = tmp;
+
+		tmp = tex_vertices[4];
+		tex_vertices[4] = tex_vertices[6];
+		tex_vertices[6] = tmp;
+		tmp = tex_vertices[5];
+		tex_vertices[5] = tex_vertices[7];
+		tex_vertices[7] = tmp;
+
+		DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+		       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+		       vertices[0], vertices[1], vertices[2], vertices[3],
+		       vertices[4], vertices[5], vertices[6], vertices[7]);
+		DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+		       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+		       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
+		       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+
+		if (ptrap->left.p1.x == ptrap->left.p2.x) {
+			left_slope = 0.0;
+			dispatch->glUniform1i(trap_left_vertical_uniform_location, 1);
+		} else {
+			left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y))
+			             / ((float)(ptrap->left.p1.x - ptrap->left.p2.x));
+			dispatch->glUniform1i(trap_left_vertical_uniform_location, 0);
+		}
+		dispatch->glUniform1f(trap_left_slope_uniform_location, left_slope);
+
+		if (ptrap->right.p1.x == ptrap->right.p2.x) {
+			right_slope = 0.0;
+			dispatch->glUniform1i(trap_right_vertical_uniform_location, 1);
+		} else {
+			right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y))
+			              / ((float)(ptrap->right.p1.x - ptrap->right.p2.x));
+			dispatch->glUniform1i(trap_right_vertical_uniform_location, 0);
+		}
+		dispatch->glUniform1f(trap_right_slope_uniform_location, right_slope);
+
+		dispatch->glUniform1f(x_per_pix_uniform_location,
+		        ((float)width_fix) / (65536 * width));
+		dispatch->glUniform1f(y_per_pix_uniform_location,
+		        ((float)height_fix) / (65536 * height));
+
+		dispatch->glUniform1f(trap_top_uniform_location,
+		        ((float)ptrap->top) / 65536);
+		dispatch->glUniform1f(trap_bottom_uniform_location,
+		        ((float)ptrap->bottom) / 65536);
+
+		dispatch->glUniform1f(trap_left_x_uniform_location,
+		        ((float)ptrap->left.p1.x) / 65536);
+		dispatch->glUniform1f(trap_left_y_uniform_location,
+		        ((float)ptrap->left.p1.y) / 65536);
+		dispatch->glUniform1f(trap_right_x_uniform_location,
+		        ((float)ptrap->right.p1.x) / 65536);
+		dispatch->glUniform1f(trap_right_y_uniform_location,
+		        ((float)ptrap->right.p1.y) / 65536);
+
+		DEBUGF("x_per_pix = %f, y_per_pix = %f, trap_top = %f, trap_bottom = %f, "
+		       "trap_left_x = %f, trap_left_y = %f, left_slope = %f, "
+		       "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n",
+		       ((float)width_fix) / (65536*width), ((float)height_fix) / (65536*height),
+		       ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536,
+		       ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536,
+		       left_slope,
+		       ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536,
+		       right_slope);
+
+		/* Now rendering. */
+		dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	dispatch->glBlendFunc(GL_ONE, GL_ZERO);
+	dispatch->glDisable(GL_BLEND);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+	return TRUE;
+}
+
+#endif                           /*GLAMOR_TRAPEZOID_SHADER */
+
 /**
- * Creates an appropriate picture to upload our alpha mask into (which
- * we calculated in system memory)
+ * Creates an appropriate picture for temp mask use.
  */
 static PicturePtr
 glamor_create_mask_picture(ScreenPtr screen,
-			   PicturePtr dst,
-			   PictFormatPtr pict_format,
-			   CARD16 width, CARD16 height)
+        PicturePtr dst,
+        PictFormatPtr pict_format,
+        CARD16 width, CARD16 height, int gpu)
 {
 	PixmapPtr pixmap;
 	PicturePtr picture;
@@ -61,26 +622,33 @@ glamor_create_mask_picture(ScreenPtr screen,
 			return 0;
 	}
 
-	pixmap = glamor_create_pixmap(screen, 0, 0,
-				      pict_format->depth,
-				      GLAMOR_CREATE_PIXMAP_CPU);
+	if (gpu) {
+		pixmap = glamor_create_pixmap(screen, width, height,
+		         pict_format->depth, 0);
+	} else {
+		pixmap = glamor_create_pixmap(screen, 0, 0,
+		         pict_format->depth,
+		         GLAMOR_CREATE_PIXMAP_CPU);
+	}
+
 	if (!pixmap)
 		return 0;
 	picture = CreatePicture(0, &pixmap->drawable, pict_format,
-				0, 0, serverClient, &error);
-	screen->DestroyPixmap(pixmap);
+	                        0, 0, serverClient, &error);
+	glamor_destroy_pixmap(pixmap);
 	return picture;
 }
 
 /**
- * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
- * accumulation in system memory.
+ * glamor_trapezoids will first try to create a trapezoid mask using shader,
+ * if failed, miTrapezoids will generate trapezoid mask accumulating in
+ * system memory.
  */
 static Bool
 _glamor_trapezoids(CARD8 op,
-		  PicturePtr src, PicturePtr dst,
-		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid * traps, Bool fallback)
+                   PicturePtr src, PicturePtr dst,
+                   PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+                   int ntrap, xTrapezoid * traps, Bool fallback)
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
 	BoxRec bounds;
@@ -89,7 +657,8 @@ _glamor_trapezoids(CARD8 op,
 	INT16 x_rel, y_rel;
 	int width, height, stride;
 	PixmapPtr pixmap;
-	pixman_image_t *image;
+	pixman_image_t *image = NULL;
+	int ret = 0;
 
 	/* If a mask format wasn't provided, we get to choose, but behavior should
 	 * be as if there was no temporary mask the traps were accumulated into.
@@ -103,11 +672,14 @@ _glamor_trapezoids(CARD8 op,
 			    PictureMatchFormat(screen, 8, PICT_a8);
 		for (; ntrap; ntrap--, traps++)
 			glamor_trapezoids(op, src, dst, mask_format, x_src,
-					  y_src, 1, traps);
+			                  y_src, 1, traps);
 		return TRUE;
 	}
 
 	miTrapezoidBounds(ntrap, traps, &bounds);
+	DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
+	       "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2,
+	       bounds.y1, bounds.y2);
 
 	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
 		return TRUE;
@@ -118,41 +690,63 @@ _glamor_trapezoids(CARD8 op,
 	width = bounds.x2 - bounds.x1;
 	height = bounds.y2 - bounds.y1;
 	stride = PixmapBytePad(width, mask_format->depth);
+
+#ifdef GLAMOR_TRAPEZOID_SHADER
 	picture = glamor_create_mask_picture(screen, dst, mask_format,
-					     width, height);
+	          width, height, 1);
 	if (!picture)
 		return TRUE;
 
-	image = pixman_image_create_bits(picture->format,
-					 width, height, NULL, stride);
-	if (!image) {
+	ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds);
+
+	if (!ret)
 		FreePicture(picture, 0);
-		return TRUE;
-	}
+#endif
 
-	for (; ntrap; ntrap--, traps++)
-		pixman_rasterize_trapezoid(image,
-					   (pixman_trapezoid_t *) traps,
-					   -bounds.x1, -bounds.y1);
+	if (!ret) {
+		DEBUGF("Fallback to sw rasterize of trapezoid\n");
 
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+		picture = glamor_create_mask_picture(screen, dst, mask_format,
+		          width, height, 0);
+		if (!picture)
+			return TRUE;
+
+		image = pixman_image_create_bits(picture->format,
+		        width, height, NULL, stride);
+		if (!image) {
+			FreePicture(picture, 0);
+			return TRUE;
+		}
 
-	screen->ModifyPixmapHeader(pixmap, width, height,
-				   mask_format->depth,
-				   BitsPerPixel(mask_format->depth),
-				   PixmapBytePad(width,
-						 mask_format->depth),
-				   pixman_image_get_data(image));
+		for (; ntrap; ntrap--, traps++)
+			pixman_rasterize_trapezoid(image,
+			        (pixman_trapezoid_t *) traps,
+			        -bounds.x1, -bounds.y1);
+
+		pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+
+		screen->ModifyPixmapHeader(pixmap, width, height,
+		        mask_format->depth,
+		        BitsPerPixel(mask_format->depth),
+		        PixmapBytePad(width,
+		                      mask_format->depth),
+		        pixman_image_get_data(image));
+	}
 
 	x_rel = bounds.x1 + x_src - x_dst;
 	y_rel = bounds.y1 + y_src - y_dst;
+	DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, "
+	       "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst,
+	       y_dst, x_rel, y_rel);
+
 	CompositePicture(op, src, picture, dst,
-			 x_rel, y_rel,
-			 0, 0,
-			 bounds.x1, bounds.y1,
-			 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+	                 x_rel, y_rel,
+	                 0, 0,
+	                 bounds.x1, bounds.y1,
+	                 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
 
-	pixman_image_unref(image);
+	if (image)
+		pixman_image_unref(image);
 
 	FreePicture(picture, 0);
 	return TRUE;
@@ -160,22 +754,26 @@ _glamor_trapezoids(CARD8 op,
 
 void
 glamor_trapezoids(CARD8 op,
-		  PicturePtr src, PicturePtr dst,
-		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid * traps)
+                  PicturePtr src, PicturePtr dst,
+                  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+                  int ntrap, xTrapezoid * traps)
 {
+	DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
+
 	_glamor_trapezoids(op, src, dst, mask_format, x_src,
-			   y_src, ntrap, traps, TRUE);
+	                   y_src, ntrap, traps, TRUE);
 }
 
 Bool
 glamor_trapezoids_nf(CARD8 op,
-		     PicturePtr src, PicturePtr dst,
-		     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		     int ntrap, xTrapezoid * traps)
+        PicturePtr src, PicturePtr dst,
+        PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+        int ntrap, xTrapezoid * traps)
 {
+	DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
+
 	return _glamor_trapezoids(op, src, dst, mask_format, x_src,
-				  y_src, ntrap, traps, FALSE);
+	        y_src, ntrap, traps, FALSE);
 }
 
 #endif				/* RENDER */
commit 6dd81c5939197eb51bc31ffbc3e6f359f2aad191
Author: RobinHe <robinhe at robinhe-desktop.lan>
Date:   Sat Jun 2 21:52:25 2012 +0800

    Create the file glamor_triangles.c
    
     Create the file glamor_trapezoid.c, extract the logic
     relating to trapezoid from glamor_render.c to this file.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 421846c..e29f918 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -34,6 +34,7 @@ libglamor_la_SOURCES = \
 	glamor_setspans.c \
 	glamor_render.c \
 	glamor_gradient.c \
+	glamor_trapezoid.c \
 	glamor_tile.c \
 	glamor_triangles.c\
 	glamor_addtraps.c\
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a791e04..92aa3a3 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -688,10 +688,6 @@ void glamor_composite(CARD8 op,
 		      INT16 yMask,
 		      INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
 
-void glamor_trapezoids(CARD8 op,
-		       PicturePtr src, PicturePtr dst,
-		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		       int ntrap, xTrapezoid * traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
 void glamor_fini_composite_shaders(ScreenPtr screen);
 void glamor_composite_glyph_rects(CARD8 op,
@@ -704,6 +700,11 @@ void glamor_composite_rects (CARD8         op,
 			     int           nRect,
 			     xRectangle    *rects);
 
+/* glamor_trapezoid.c */
+void glamor_trapezoids(CARD8 op,
+		       PicturePtr src, PicturePtr dst,
+		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		       int ntrap, xTrapezoid * traps);
 
 /* glamor_tile.c */
 Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
@@ -935,7 +936,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_GRADIENT_SHADER
 #endif
 #define GLAMOR_TEXTURED_LARGE_PIXMAP 1
-#if 0
+#if 1
 #define MAX_FBO_SIZE 32 /* For test purpose only. */
 #endif
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e5210cf..da9d847 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1881,150 +1881,6 @@ glamor_composite_nf(CARD8 op,
 				 FALSE);
 }
 
-/**
- * Creates an appropriate picture to upload our alpha mask into (which
- * we calculated in system memory)
- */
-static PicturePtr
-glamor_create_mask_picture(ScreenPtr screen,
-			   PicturePtr dst,
-			   PictFormatPtr pict_format,
-			   CARD16 width, CARD16 height)
-{
-	PixmapPtr pixmap;
-	PicturePtr picture;
-	int error;
-
-	if (!pict_format) {
-		if (dst->polyEdge == PolyEdgeSharp)
-			pict_format =
-			    PictureMatchFormat(screen, 1, PICT_a1);
-		else
-			pict_format =
-			    PictureMatchFormat(screen, 8, PICT_a8);
-		if (!pict_format)
-			return 0;
-	}
-
-	pixmap = glamor_create_pixmap(screen, 0, 0,
-				      pict_format->depth,
-				      GLAMOR_CREATE_PIXMAP_CPU);
-	if (!pixmap)
-		return 0;
-	picture = CreatePicture(0, &pixmap->drawable, pict_format,
-				0, 0, serverClient, &error);
-	screen->DestroyPixmap(pixmap);
-	return picture;
-}
-
-/**
- * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
- * accumulation in system memory.
- */
-static Bool
-_glamor_trapezoids(CARD8 op,
-		  PicturePtr src, PicturePtr dst,
-		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid * traps, Bool fallback)
-{
-	ScreenPtr screen = dst->pDrawable->pScreen;
-	BoxRec bounds;
-	PicturePtr picture;
-	INT16 x_dst, y_dst;
-	INT16 x_rel, y_rel;
-	int width, height, stride;
-	PixmapPtr pixmap;
-	pixman_image_t *image;
-
-	/* If a mask format wasn't provided, we get to choose, but behavior should
-	 * be as if there was no temporary mask the traps were accumulated into.
-	 */
-	if (!mask_format) {
-		if (dst->polyEdge == PolyEdgeSharp)
-			mask_format =
-			    PictureMatchFormat(screen, 1, PICT_a1);
-		else
-			mask_format =
-			    PictureMatchFormat(screen, 8, PICT_a8);
-		for (; ntrap; ntrap--, traps++)
-			glamor_trapezoids(op, src, dst, mask_format, x_src,
-					  y_src, 1, traps);
-		return TRUE;
-	}
-
-	miTrapezoidBounds(ntrap, traps, &bounds);
-
-	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-		return TRUE;
-
-	x_dst = traps[0].left.p1.x >> 16;
-	y_dst = traps[0].left.p1.y >> 16;
-
-	width = bounds.x2 - bounds.x1;
-	height = bounds.y2 - bounds.y1;
-	stride = PixmapBytePad(width, mask_format->depth);
-	picture = glamor_create_mask_picture(screen, dst, mask_format,
-					     width, height);
-	if (!picture)
-		return TRUE;
-
-	image = pixman_image_create_bits(picture->format,
-					 width, height, NULL, stride);
-	if (!image) {
-		FreePicture(picture, 0);
-		return TRUE;
-	}
-
-	for (; ntrap; ntrap--, traps++)
-		pixman_rasterize_trapezoid(image,
-					   (pixman_trapezoid_t *) traps,
-					   -bounds.x1, -bounds.y1);
-
-	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-
-	screen->ModifyPixmapHeader(pixmap, width, height,
-				   mask_format->depth,
-				   BitsPerPixel(mask_format->depth),
-				   PixmapBytePad(width,
-						 mask_format->depth),
-				   pixman_image_get_data(image));
-
-	x_rel = bounds.x1 + x_src - x_dst;
-	y_rel = bounds.y1 + y_src - y_dst;
-	CompositePicture(op, src, picture, dst,
-			 x_rel, y_rel,
-			 0, 0,
-			 bounds.x1, bounds.y1,
-			 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
-
-	pixman_image_unref(image);
-
-	FreePicture(picture, 0);
-	return TRUE;
-}
-
-void
-glamor_trapezoids(CARD8 op,
-		  PicturePtr src, PicturePtr dst,
-		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid * traps)
-{
-	_glamor_trapezoids(op, src, dst, mask_format, x_src,
-			   y_src, ntrap, traps, TRUE);
-}
-
-Bool
-glamor_trapezoids_nf(CARD8 op,
-		     PicturePtr src, PicturePtr dst,
-		     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		     int ntrap, xTrapezoid * traps)
-{
-	return _glamor_trapezoids(op, src, dst, mask_format, x_src,
-				  y_src, ntrap, traps, FALSE);
-}
-
-
-
 void
 glamor_composite_glyph_rects(CARD8 op,
 			     PicturePtr src, PicturePtr mask, PicturePtr dst,
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
new file mode 100644
index 0000000..08ee2d6
--- /dev/null
+++ b/glamor/glamor_trapezoid.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Junyan He <junyan.he at linux.intel.com>
+ *
+ */
+
+/** @file glamor_trapezoid.c
+ *
+ * Trapezoid acceleration implementation
+ */
+
+#include "glamor_priv.h"
+
+#ifdef RENDER
+#include "mipict.h"
+#include "fbpict.h"
+
+/**
+ * Creates an appropriate picture to upload our alpha mask into (which
+ * we calculated in system memory)
+ */
+static PicturePtr
+glamor_create_mask_picture(ScreenPtr screen,
+			   PicturePtr dst,
+			   PictFormatPtr pict_format,
+			   CARD16 width, CARD16 height)
+{
+	PixmapPtr pixmap;
+	PicturePtr picture;
+	int error;
+
+	if (!pict_format) {
+		if (dst->polyEdge == PolyEdgeSharp)
+			pict_format =
+			    PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			pict_format =
+			    PictureMatchFormat(screen, 8, PICT_a8);
+		if (!pict_format)
+			return 0;
+	}
+
+	pixmap = glamor_create_pixmap(screen, 0, 0,
+				      pict_format->depth,
+				      GLAMOR_CREATE_PIXMAP_CPU);
+	if (!pixmap)
+		return 0;
+	picture = CreatePicture(0, &pixmap->drawable, pict_format,
+				0, 0, serverClient, &error);
+	screen->DestroyPixmap(pixmap);
+	return picture;
+}
+
+/**
+ * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
+ * accumulation in system memory.
+ */
+static Bool
+_glamor_trapezoids(CARD8 op,
+		  PicturePtr src, PicturePtr dst,
+		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		  int ntrap, xTrapezoid * traps, Bool fallback)
+{
+	ScreenPtr screen = dst->pDrawable->pScreen;
+	BoxRec bounds;
+	PicturePtr picture;
+	INT16 x_dst, y_dst;
+	INT16 x_rel, y_rel;
+	int width, height, stride;
+	PixmapPtr pixmap;
+	pixman_image_t *image;
+
+	/* If a mask format wasn't provided, we get to choose, but behavior should
+	 * be as if there was no temporary mask the traps were accumulated into.
+	 */
+	if (!mask_format) {
+		if (dst->polyEdge == PolyEdgeSharp)
+			mask_format =
+			    PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			mask_format =
+			    PictureMatchFormat(screen, 8, PICT_a8);
+		for (; ntrap; ntrap--, traps++)
+			glamor_trapezoids(op, src, dst, mask_format, x_src,
+					  y_src, 1, traps);
+		return TRUE;
+	}
+
+	miTrapezoidBounds(ntrap, traps, &bounds);
+
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		return TRUE;
+
+	x_dst = traps[0].left.p1.x >> 16;
+	y_dst = traps[0].left.p1.y >> 16;
+
+	width = bounds.x2 - bounds.x1;
+	height = bounds.y2 - bounds.y1;
+	stride = PixmapBytePad(width, mask_format->depth);
+	picture = glamor_create_mask_picture(screen, dst, mask_format,
+					     width, height);
+	if (!picture)
+		return TRUE;
+
+	image = pixman_image_create_bits(picture->format,
+					 width, height, NULL, stride);
+	if (!image) {
+		FreePicture(picture, 0);
+		return TRUE;
+	}
+
+	for (; ntrap; ntrap--, traps++)
+		pixman_rasterize_trapezoid(image,
+					   (pixman_trapezoid_t *) traps,
+					   -bounds.x1, -bounds.y1);
+
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+
+	screen->ModifyPixmapHeader(pixmap, width, height,
+				   mask_format->depth,
+				   BitsPerPixel(mask_format->depth),
+				   PixmapBytePad(width,
+						 mask_format->depth),
+				   pixman_image_get_data(image));
+
+	x_rel = bounds.x1 + x_src - x_dst;
+	y_rel = bounds.y1 + y_src - y_dst;
+	CompositePicture(op, src, picture, dst,
+			 x_rel, y_rel,
+			 0, 0,
+			 bounds.x1, bounds.y1,
+			 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+
+	pixman_image_unref(image);
+
+	FreePicture(picture, 0);
+	return TRUE;
+}
+
+void
+glamor_trapezoids(CARD8 op,
+		  PicturePtr src, PicturePtr dst,
+		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		  int ntrap, xTrapezoid * traps)
+{
+	_glamor_trapezoids(op, src, dst, mask_format, x_src,
+			   y_src, ntrap, traps, TRUE);
+}
+
+Bool
+glamor_trapezoids_nf(CARD8 op,
+		     PicturePtr src, PicturePtr dst,
+		     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		     int ntrap, xTrapezoid * traps)
+{
+	return _glamor_trapezoids(op, src, dst, mask_format, x_src,
+				  y_src, ntrap, traps, FALSE);
+}
+
+#endif				/* RENDER */
+
commit bf38ee407ba1038a25efa58b8475bcf084a21042
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 14:02:59 2012 +0800

    Enable large pixmap by default.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2af17f0..a791e04 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -934,9 +934,9 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
 #endif
-#define GLAMOR_TEXTURED_LARGE_PIXMAP 0
+#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 #if 0
-#define MAX_FBO_SIZE 512 /* For test purpose only. */
+#define MAX_FBO_SIZE 32 /* For test purpose only. */
 #endif
 
 #endif				/* GLAMOR_PRIV_H */
commit 8ca16754f7e95e47423183bbd5f72966b937f6c8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 13:05:48 2012 +0800

    largepixmap: Fix the selfcopy issue.
    
    If the source and destination are the same pixmap/fbo, and we
    need to split the copy to small pieces. Then we do need to
    consider the sequence of the small pieces when the copy area
    has overlaps. This commit take the reverse/upsidedown into
    the clipping function, thus it can generate correct sequence
    and avoid corruption self copying.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 4d68dbe..bfd957a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -458,17 +458,18 @@ _glamor_copy_n_to_n(DrawablePtr src,
 			int n_dst_region, i, j;
 			PixmapPtr temp_source_pixmap;
 			glamor_pixmap_private *temp_source_priv = NULL;
-			int temp_dx = 0, temp_dy = 0;
 
 			RegionTranslate(&region, dst_x_off, dst_y_off);
 			if (!force_clip)
 				clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
-										     &region, &n_dst_region, 0);
+										     &region, &n_dst_region, 0,
+										     reverse, upsidedown);
 			else
 				clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
 										         &region, &n_dst_region,
 											 glamor_priv->max_fbo_size,
-											 glamor_priv->max_fbo_size);
+											 glamor_priv->max_fbo_size,
+											 reverse, upsidedown);
 			for(i = 0; i < n_dst_region; i++)
 			{
 				int n_src_region;
@@ -484,7 +485,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
 							-dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy);
 					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
 											     clipped_dst_regions[i].region,
-											     &n_src_region, 0);
+											     &n_src_region, 0,
+											     reverse, upsidedown);
 					DEBUGF("Source is large pixmap.\n");
 					for (j = 0; j < n_src_region; j++)
 					{
@@ -507,9 +509,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 							*temp_source_priv = *src_pixmap_priv;
 							temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx];
 							temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx];
-							/* XXX need revisit here. */
-							temp_dx = dx/* - src_x_off*/;
-							temp_dy = dy/* - src_y_off*/;
+							temp_source_priv->base.pixmap = temp_source_pixmap;
 						}
 						assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv
 							&& (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx)));
@@ -531,8 +531,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
 										  n_current_boxes, dx, dy, reverse,
 										  upsidedown, bitplane, closure);
 						else {
-							ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, dst, gc, current_boxes,
-										  n_current_boxes, temp_dx, temp_dy, reverse,
+							ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
+										  dst, gc, current_boxes,
+										  n_current_boxes, dx, dy, reverse,
 										  upsidedown, bitplane, closure);
 							temp_source_priv->type = GLAMOR_MEMORY;
 							temp_source_priv->base.fbo = NULL;
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 5b84dd6..e371148 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -273,7 +273,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		box.x2 = x + width;
 		box.y2 = y + height;
 		RegionInitBoxes(&region, &box, 1);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
 		for(i = 0; i < n_region; i++)
 		{
 			BoxPtr boxes;
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 80cd6ad..f07095a 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -22,14 +22,19 @@ __glamor_compute_clipped_regions(int block_w,
 			       int x, int y,
 			       int w, int h,
                                RegionPtr region,
-                               int *n_region)
+                               int *n_region,
+			       int reverse,
+			       int upsidedown)
 {
 	glamor_pixmap_clipped_regions * clipped_regions;
 	BoxPtr extent;
 	int start_x, start_y, end_x, end_y;
 	int start_block_x, start_block_y;
 	int end_block_x, end_block_y;
-	int i, j;
+	int loop_start_block_x, loop_start_block_y;
+	int loop_end_block_x, loop_end_block_y;
+	int loop_block_stride;
+	int i, j, delta_i, delta_j;
 	int width, height;
 	RegionRec temp_region;
 	RegionPtr current_region;
@@ -66,19 +71,41 @@ __glamor_compute_clipped_regions(int block_w,
 				 * (end_block_y - start_block_y + 1),
 				 sizeof(*clipped_regions));
 
-	block_idx = (start_block_y - 1) * block_stride;
 
 	DEBUGF("startx %d starty %d endx %d endy %d \n",
 		start_x, start_y, end_x, end_y);
 	DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x);
 	DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y);
 
-	for(j = start_block_y; j <= end_block_y; j++)
+	if (!reverse) {
+		loop_start_block_x = start_block_x;
+		loop_end_block_x = end_block_x + 1;
+		delta_i = 1;
+	} else {
+		loop_start_block_x = end_block_x;
+		loop_end_block_x = start_block_x - 1;
+		delta_i = -1;
+	}
+
+	if (!upsidedown) {
+		loop_start_block_y = start_block_y;
+		loop_end_block_y = end_block_y + 1;
+		delta_j = 1;
+	} else {
+		loop_start_block_y = end_block_y;
+		loop_end_block_y = start_block_y - 1;
+		delta_j = -1;
+	}
+
+	loop_block_stride = delta_j * block_stride;
+	block_idx = (loop_start_block_y - delta_j) * block_stride;
+
+	for(j = loop_start_block_y; j != loop_end_block_y; j += delta_j)
 	{
-		block_idx += block_stride;
-		temp_block_idx = block_idx + start_block_x;
-		for(i = start_block_x;
-		    i <= end_block_x; i++, temp_block_idx++)
+		block_idx += loop_block_stride;
+		temp_block_idx = block_idx + loop_start_block_x;
+		for(i = loop_start_block_x;
+		    i != loop_end_block_x; i += delta_i, temp_block_idx += delta_i)
 		{
 			BoxRec temp_box;
 			temp_box.x1 = x + i * block_w;
@@ -123,7 +150,8 @@ glamor_pixmap_clipped_regions *
 glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 				   RegionPtr region,
 				   int *n_region,
-				   int inner_block_w, int inner_block_h)
+				   int inner_block_w, int inner_block_h,
+				   int reverse, int upsidedown)
 {
 	glamor_pixmap_clipped_regions * clipped_regions, *inner_regions, *result_regions;
 	int i, j, x, y, k, inner_n_regions;
@@ -156,7 +184,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 					0, 0,
 					priv->base.pixmap->drawable.width,
 					priv->base.pixmap->drawable.height,
-					region, n_region
+					region, n_region, reverse, upsidedown
 					);
 
 		if (clipped_regions == NULL) {
@@ -184,7 +212,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 					width,
 					height,
 					clipped_regions[i].region,
-					&inner_n_regions);
+					&inner_n_regions, reverse, upsidedown);
 		for(j = 0; j < inner_n_regions; j++)
 		{
 			result_regions[k].region = inner_regions[j].region;
@@ -293,7 +321,8 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
 static glamor_pixmap_clipped_regions *
 _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 				RegionPtr region, int *n_region,
-				int repeat_type, int is_transform)
+				int repeat_type, int is_transform,
+				int reverse, int upsidedown)
 {
 	glamor_pixmap_clipped_regions * clipped_regions;
 	BoxPtr extent;
@@ -338,7 +367,7 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 							0, 0,
 							priv->base.pixmap->drawable.width,
 							priv->base.pixmap->drawable.height,
-							region, n_region
+							region, n_region, reverse, upsidedown
 							);
 		if (saved_region)
 			RegionDestroy(region);
@@ -592,9 +621,11 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 }
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *n_region, int repeat_type)
+glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
+			       int *n_region, int repeat_type,
+			       int reverse, int upsidedown)
 {
-	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
+	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0, reverse, upsidedown);
 }
 
 /* XXX overflow still exist. maybe we need to change to use region32.
@@ -602,7 +633,8 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, in
  **/
 glamor_pixmap_clipped_regions *
 glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
-					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type)
+					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type,
+					 int reverse, int upsidedown)
 {
 	BoxPtr temp_extent;
 	struct pixman_box32 temp_box;
@@ -642,7 +674,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pix
 					      temp_region,
 					      n_region,
 					      repeat_type,
-					      1);
+					      1, reverse,
+					      upsidedown);
 	DEBUGF("n_regions = %d \n", *n_region);
 	RegionDestroy(temp_region);
 
@@ -1036,12 +1069,13 @@ glamor_composite_largepixmap_region(CARD8 op,
 									  region,
 									  &n_dest_regions,
 									  fixed_block_width,
-									  fixed_block_height);
+									  fixed_block_height,
+									  0, 0);
 	else
 		clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
 								      region,
 								      &n_dest_regions,
-								      0);
+								      0, 0, 0);
 	DEBUGF("dest clipped result %d region: \n", n_dest_regions);
 	if (source_pixmap_priv
 	    && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv)
@@ -1066,7 +1100,8 @@ glamor_composite_largepixmap_region(CARD8 op,
 						y_source - y_dest);
 				clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
 										        clipped_dest_regions[i].region,
-										        &n_source_regions, source_repeat_type);
+										        &n_source_regions, source_repeat_type,
+											0, 0);
 				is_normal_source_fbo = 1;
 			}
 			else {
@@ -1075,7 +1110,7 @@ glamor_composite_largepixmap_region(CARD8 op,
 									clipped_dest_regions[i].region,
 									&n_source_regions,
 									x_source - x_dest, y_source - y_dest,
-									source_repeat_type);
+									source_repeat_type, 0, 0);
 				is_normal_source_fbo = 0;
 				if (n_source_regions == 0) {
 					/* Pad the out-of-box region to (0,0,0,0). */
@@ -1104,7 +1139,8 @@ glamor_composite_largepixmap_region(CARD8 op,
 							- y_source + y_mask);
 						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
 											     clipped_source_regions[j].region,
-											     &n_mask_regions, mask_repeat_type);
+											     &n_mask_regions, mask_repeat_type,
+											     0, 0);
 						is_normal_mask_fbo = 1;
 					} else if (is_normal_mask_fbo && !is_normal_source_fbo) {
 						assert(n_source_regions == 1);
@@ -1116,7 +1152,8 @@ glamor_composite_largepixmap_region(CARD8 op,
 								- y_dest + y_mask);
 						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
 											     clipped_dest_regions[i].region,
-											     &n_mask_regions, mask_repeat_type);
+											     &n_mask_regions, mask_repeat_type,
+											     0, 0);
 						is_normal_mask_fbo = 1;
 					} else {
 						/* This mask region has transform or repeatpad, we need clip it agains the previous
@@ -1128,14 +1165,14 @@ glamor_composite_largepixmap_region(CARD8 op,
 												&n_mask_regions,
 												x_mask - x_dest,
 												y_mask - y_dest,
-												mask_repeat_type);
+												mask_repeat_type, 0, 0);
 						else
 							clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
 												mask->transform,
 												clipped_source_regions[j].region,
 												&n_mask_regions,
 												x_mask - x_source, y_mask - y_source,
-												mask_repeat_type);
+												mask_repeat_type, 0, 0);
 						is_normal_mask_fbo = 0;
 						if (n_mask_regions == 0) {
 						/* Pad the out-of-box region to (0,0,0,0). */
@@ -1234,7 +1271,7 @@ glamor_composite_largepixmap_region(CARD8 op,
 							y_mask - y_dest);
 					clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
 								        clipped_dest_regions[i].region,
-								        &n_mask_regions, mask_repeat_type);
+								        &n_mask_regions, mask_repeat_type, 0, 0);
 					is_normal_mask_fbo = 1;
 				}
 				else {
@@ -1243,7 +1280,7 @@ glamor_composite_largepixmap_region(CARD8 op,
 										clipped_dest_regions[i].region,
 										&n_mask_regions,
 										x_mask - x_dest, y_mask - y_dest,
-										mask_repeat_type);
+										mask_repeat_type, 0, 0);
 					is_normal_mask_fbo = 0;
 					if (n_mask_regions == 0) {
 						/* Pad the out-of-box region to (0,0,0,0). */
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index ca38a2b..10d6df3 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -715,7 +715,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 		box.x2 = x + w;
 		box.y2 = y + h;
 		RegionInitBoxes(&region, &box, 1);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
 		DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
 		for(i = 0; i < n_region; i++)
 		{
@@ -1091,7 +1091,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		box.x2 = x + w;
 		box.y2 = y + h;
 		RegionInitBoxes(&region, &box, 1);
-		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
 		DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
 		for(i = 0; i < n_region; i++)
 		{
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c15f189..2af17f0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -798,17 +798,21 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
 		      int w, int h, glamor_access_t access);
 
 glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *clipped_nbox, int repeat_type);
+glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
+			       int *clipped_nbox, int repeat_type,
+			       int reverse, int upsidedown);
 
 glamor_pixmap_clipped_regions *
 glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 				   RegionPtr region,
 				   int *n_region,
-				   int inner_block_w, int inner_block_h);
+				   int inner_block_w, int inner_block_h,
+			           int reverse, int upsidedown);
 
 glamor_pixmap_clipped_regions *
 glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
-					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type);
+					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type,
+			                 int reverse, int upsidedown);
 
 Bool
 glamor_composite_largepixmap_region(CARD8 op,
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 871479b..206485f 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -242,7 +242,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 			box.y2 = y + height;
 			RegionInitBoxes(&region, &box, 1);
 			clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
-									     &region, &n_dst_region, 0);
+									     &region, &n_dst_region, 0, 0, 0);
 			for(i = 0; i < n_dst_region; i++)
 			{
 				int n_src_region;
@@ -258,7 +258,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 					DEBUGF("tiled a large src pixmap. %dx%d \n", tile->drawable.width, tile->drawable.height);
 					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
 											     clipped_dst_regions[i].region,
-											     &n_src_region, 1);
+											     &n_src_region, 1, 0, 0);
 					DEBUGF("got %d src regions %d \n", n_src_region);
 					for (j = 0; j < n_src_region; j++)
 					{
commit 5325c800f706f46085735d608f57d513da63cddf
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 11:42:46 2012 +0800

    largepixmap: Support self composite for large pixmap.
    
    The simplest way to support large pixmap's self compositing
    is to just clone a pixmap private data structure, and change
    the fbo and box to point to the correct postions. Don't need
    to copy a new box.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index 31af711..80cd6ad 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -22,8 +22,7 @@ __glamor_compute_clipped_regions(int block_w,
 			       int x, int y,
 			       int w, int h,
                                RegionPtr region,
-                               int *n_region,
-                               int repeat)
+                               int *n_region)
 {
 	glamor_pixmap_clipped_regions * clipped_regions;
 	BoxPtr extent;
@@ -157,7 +156,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 					0, 0,
 					priv->base.pixmap->drawable.width,
 					priv->base.pixmap->drawable.height,
-					region, n_region, 0
+					region, n_region
 					);
 
 		if (clipped_regions == NULL) {
@@ -185,7 +184,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 					width,
 					height,
 					clipped_regions[i].region,
-					&inner_n_regions, 0);
+					&inner_n_regions);
 		for(j = 0; j < inner_n_regions; j++)
 		{
 			result_regions[k].region = inner_regions[j].region;
@@ -339,7 +338,7 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 							0, 0,
 							priv->base.pixmap->drawable.width,
 							priv->base.pixmap->drawable.height,
-							region, n_region, 0
+							region, n_region
 							);
 		if (saved_region)
 			RegionDestroy(region);
@@ -1044,14 +1043,17 @@ glamor_composite_largepixmap_region(CARD8 op,
 								      &n_dest_regions,
 								      0);
 	DEBUGF("dest clipped result %d region: \n", n_dest_regions);
-	if (source_pixmap_priv == dest_pixmap_priv
-	    && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+	if (source_pixmap_priv
+	    && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv)
+		&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
 		/* XXX self-copy...*/
 		need_free_source_pixmap_priv = source_pixmap_priv;
 		source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
 		*source_pixmap_priv = *need_free_source_pixmap_priv;
 		need_free_source_pixmap_priv = source_pixmap_priv;
 	}
+	assert(mask_pixmap_priv != dest_pixmap_priv);
+
 	for(i = 0; i < n_dest_regions; i++)
 	{
 		DEBUGF("dest region %d  idx %d\n", i, clipped_dest_regions[i].block_idx);
@@ -1149,7 +1151,10 @@ glamor_composite_largepixmap_region(CARD8 op,
 #define COMPOSITE_REGION(region) do {				\
 	if (!glamor_composite_clipped_region(op,		\
 			 null_source ? NULL : source,		\
-			 null_mask ? NULL : mask, dest, region,	\
+			 null_mask ? NULL : mask, dest,		\
+			 null_source ? NULL : source_pixmap_priv, \
+			 null_mask ? NULL : mask_pixmap_priv, 	\
+			 dest_pixmap_priv, region,		\
 			 x_source, y_source, x_mask, y_mask,	\
 			 x_dest, y_dest)) {			\
 		assert(0);					\
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d9f6438..c15f189 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -667,6 +667,9 @@ glamor_composite_clipped_region(CARD8 op,
 				PicturePtr source,
 				PicturePtr mask,
 				PicturePtr dest,
+				glamor_pixmap_private *soruce_pixmap_priv,
+				glamor_pixmap_private *mask_pixmap_priv,
+				glamor_pixmap_private *dest_pixmap_priv,
 				RegionPtr region,
 				int x_source,
 				int y_source,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 40a8794..e5210cf 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -968,22 +968,19 @@ glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
 			     PicturePtr mask,
 			     PicturePtr dest,
+			     glamor_pixmap_private *source_pixmap_priv,
+			     glamor_pixmap_private *mask_pixmap_priv,
+			     glamor_pixmap_private *dest_pixmap_priv,
 			     int nrect,
 			     glamor_composite_rect_t * rects)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
+	glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
 	glamor_gl_dispatch *dispatch;
-	PixmapPtr dest_pixmap =
-	    glamor_get_drawable_pixmap(dest->pDrawable);
+	PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
 	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-	glamor_pixmap_private *source_pixmap_priv = NULL;
-	glamor_pixmap_private *mask_pixmap_priv = NULL;
-	glamor_pixmap_private *dest_pixmap_priv = NULL;
 	GLfloat dst_xscale, dst_yscale;
-	GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale =
-	    1, src_yscale = 1;
+	GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
 	struct shader_key key;
 	glamor_composite_shader *shader;
 	float vertices[8], source_texcoords[8], mask_texcoords[8];
@@ -1000,7 +997,6 @@ glamor_composite_with_shader(CARD8 op,
 	int nrect_max;
 	Bool ret = FALSE;
 
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
@@ -1075,10 +1071,7 @@ glamor_composite_with_shader(CARD8 op,
 	}
 	if (key.source == SHADER_SOURCE_TEXTURE ||
 	    key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
-		source_pixmap =
-		    glamor_get_drawable_pixmap(source->pDrawable);
-		source_pixmap_priv =
-		    glamor_get_pixmap_private(source_pixmap);
+		source_pixmap = source_pixmap_priv->base.pixmap;
 		if (source_pixmap == dest_pixmap) {
 			/* XXX source and the dest share the same texture.
 			 * Does it need special handle? */
@@ -1099,8 +1092,7 @@ glamor_composite_with_shader(CARD8 op,
 	}
 	if (key.mask == SHADER_MASK_TEXTURE ||
 	    key.mask == SHADER_MASK_TEXTURE_ALPHA) {
-		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		mask_pixmap = mask_pixmap_priv->base.pixmap;
 		if (mask_pixmap == dest_pixmap) {
 			glamor_fallback("mask == dest\n");
 			goto fail;
@@ -1432,6 +1424,9 @@ glamor_composite_clipped_region(CARD8 op,
 				PicturePtr source,
 				PicturePtr mask,
 				PicturePtr dest,
+				glamor_pixmap_private *source_pixmap_priv,
+				glamor_pixmap_private *mask_pixmap_priv,
+				glamor_pixmap_private *dest_pixmap_priv,
 				RegionPtr region,
 				int x_source,
 				int y_source,
@@ -1441,13 +1436,10 @@ glamor_composite_clipped_region(CARD8 op,
 				int y_dest)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_pixmap_private *dest_pixmap_priv;
-	glamor_pixmap_private *source_pixmap_priv =
-	    NULL, *mask_pixmap_priv = NULL;
-	PixmapPtr dest_pixmap =
-	    glamor_get_drawable_pixmap(dest->pDrawable);
 	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
 	PicturePtr temp_src = source, temp_mask = mask;
+	glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
+	glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
 	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
 
 	BoxPtr extent;
@@ -1472,20 +1464,12 @@ glamor_composite_clipped_region(CARD8 op,
 	y_temp_mask = y_mask;
 	DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
 		x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
-	DEBUGF("dest pixmap %p ", dest_pixmap);
-
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-	/* Currently. Always fallback to cpu if destination is in CPU memory. */
 
-	if (source && source->pDrawable) {
-		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-	}
+	if (source_pixmap_priv)
+		source_pixmap = source_pixmap_priv->base.pixmap;
 
-	if (mask && mask->pDrawable) {
-		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-	}
+	if (mask_pixmap_priv)
+		mask_pixmap = mask_pixmap_priv->base.pixmap;
 
 	/* XXX is it possible source mask have non-zero drawable.x/y? */
 	if (source
@@ -1504,6 +1488,7 @@ glamor_composite_clipped_region(CARD8 op,
 			temp_src = source;
 			goto out;
 		}
+		temp_src_priv = glamor_get_pixmap_private((PixmapPtr)(temp_src->pDrawable));
 		x_temp_src = - extent->x1 + x_dest;
 		y_temp_src = - extent->y1 + y_dest;
 	}
@@ -1527,6 +1512,7 @@ glamor_composite_clipped_region(CARD8 op,
 			temp_mask = mask;
 			goto out;
 		}
+		temp_mask_priv = glamor_get_pixmap_private((PixmapPtr)(temp_mask->pDrawable));
 		x_temp_mask = - extent->x1 + x_dest;
 		y_temp_mask = - extent->y1 + y_dest;
 	}
@@ -1538,6 +1524,7 @@ glamor_composite_clipped_region(CARD8 op,
 		if (op == PictOpOver) {
 			glamor_composite_clipped_region(PictOpOutReverse,
 							temp_src, temp_mask, dest,
+							temp_src_priv, temp_mask_priv, dest_pixmap_priv,
 							region,
 							x_temp_src, y_temp_src,
 							x_temp_mask, y_temp_mask,
@@ -1545,6 +1532,7 @@ glamor_composite_clipped_region(CARD8 op,
 
 			glamor_composite_clipped_region(PictOpAdd,
 							temp_src, temp_mask, dest,
+							temp_src_priv, temp_mask_priv, dest_pixmap_priv,
 							region,
 							x_temp_src, y_temp_src,
 							x_temp_mask, y_temp_mask,
@@ -1598,8 +1586,10 @@ glamor_composite_clipped_region(CARD8 op,
 			prect[i].width = box[i].x2 - box[i].x1;
 			prect[i].height = box[i].y2 - box[i].y1;
 		}
-		ok = glamor_composite_with_shader(op, temp_src, temp_mask,
-						  dest, box_cnt, prect);
+		ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
+						  temp_src_priv, temp_mask_priv,
+						  dest_pixmap_priv,
+						  box_cnt, prect);
 		if (!ok)
 			break;
 		nbox -= box_cnt;
@@ -1749,7 +1739,11 @@ _glamor_composite(CARD8 op,
 						   width, height);
 	else
 		ok = glamor_composite_clipped_region(op, source,
-						     mask, dest, &region,
+						     mask, dest,
+						     source_pixmap_priv,
+						     mask_pixmap_priv,
+						     dest_pixmap_priv,
+						     &region,
 						     x_source, y_source,
 						     x_mask, y_mask,
 						     x_dest, y_dest);
@@ -2045,7 +2039,17 @@ glamor_composite_glyph_rects(CARD8 op,
 	if (!(glamor_is_large_picture(src)
 	    || (mask && glamor_is_large_picture(mask))
 	    || glamor_is_large_picture(dst))) {
-		if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
+		glamor_pixmap_private *src_pixmap_priv = NULL;
+		glamor_pixmap_private *mask_pixmap_priv = NULL;
+		glamor_pixmap_private *dst_pixmap_priv;
+
+		dst_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(dst->pDrawable));
+		if (mask && mask->pDrawable)
+			mask_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(mask->pDrawable));
+		if (src->pDrawable)
+			src_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(src->pDrawable));
+		if (glamor_composite_with_shader(op, src, mask, dst, src_pixmap_priv,
+						 mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
 			return;
 	}
 
commit 1d2d858b8daacdd349084433a8af60d559fb6a9d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 09:36:56 2012 +0800

    largepixmap: Add transform/repeat/reflect/pad support.
    
    This commit implement almost all the needed functions for
    the large pixmap support. It's almost complete.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index a1a73a4..31af711 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -199,6 +199,89 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
 	return result_regions;
 }
 
+/*
+ *
+ * For the repeat pad mode, we can simply convert the region and
+ * let the out-of-box region can cover the needed edge of the source/mask
+ * Then apply a normal clip we can get what we want.
+ */
+static RegionPtr
+_glamor_convert_pad_region(RegionPtr region, int w, int h)
+{
+	RegionPtr pad_region;
+	int nrect;
+	BoxPtr box;
+	int overlap;
+
+	nrect = RegionNumRects(region);
+	box = RegionRects(region);
+	pad_region = RegionCreate(NULL, 4);
+	if (pad_region == NULL)
+		return NULL;
+	while(nrect--) {
+		BoxRec pad_box;
+		RegionRec temp_region;
+		pad_box = *box;
+		if (pad_box.x1 < 0 && pad_box.x2 <= 0)
+			pad_box.x2 = 1;
+		else if (pad_box.x1 >= w && pad_box.x2 > w)
+			pad_box.x1 = w - 1;
+		if (pad_box.y1 < 0 && pad_box.y2 <=0)
+			pad_box.y2 = 1;
+		else if (pad_box.y1 >= h && pad_box.y2 > h)
+			pad_box.y1 = h - 1;
+		RegionInitBoxes(&temp_region, &pad_box, 1);
+		RegionAppend(pad_region, &temp_region);
+		RegionUninit(&temp_region);
+		box++;
+	}
+	RegionValidate(pad_region, &overlap);
+	return pad_region;
+}
+
+/*
+ * For one type of large pixmap, its one direction is not exceed the
+ * size limitation, and in another word, on one direction it has only
+ * one block.
+ *
+ * This case of reflect repeating, we can optimize it and avoid repeat
+ * clip on that direction. We can just enlarge the repeat box and can
+ * cover all the dest region on that direction. But latter, we need to
+ * fixup the clipped result to get a correct coords for the subsequent
+ * processing. This function is to do the coords correction.
+ *
+ * */
+static void
+_glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
+{
+	int odd1, odd2;
+	int c1, c2;
+
+	if (*xy2 - *xy1 > wh) {
+		*xy1 = 0;
+		*xy2 = wh;
+		return;
+	}
+	modulus(*xy1, wh, c1);
+	odd1 = ((*xy1 - c1) / wh) & 0x1;
+	modulus(*xy2, wh, c2);
+	odd2 = ((*xy2 - c2) / wh) & 0x1;
+
+	if (odd1 && odd2) {
+		*xy1 = wh - c2;
+		*xy2 = wh - c1;
+	} else if (odd1 && !odd2) {
+		*xy1 = 0;
+		*xy2 = MAX(c2, wh - c1);
+	} else if (!odd1 && odd2) {
+		*xy2 = wh;
+		*xy1 = MIN(c1, wh - c2);
+	} else {
+		*xy1 = c1;
+		*xy2 = c2;
+	}
+}
+
 /**
  * Clip the boxes regards to each pixmap's block array.
  *
@@ -207,9 +290,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
  *
  * @is_transform: if it is set, it has a transform matrix.
  *
- * XXX Not support repeatPad currently.
  */
-
 static glamor_pixmap_clipped_regions *
 _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 				RegionPtr region, int *n_region,
@@ -242,7 +323,16 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 
 	pixmap_width = priv->base.pixmap->drawable.width;
 	pixmap_height = priv->base.pixmap->drawable.height;
-	if (repeat_type == 0) {
+	if (repeat_type == 0 || repeat_type == RepeatPad) {
+		RegionPtr saved_region = NULL;
+		if (repeat_type == RepeatPad) {
+			saved_region = region;
+			region = _glamor_convert_pad_region(saved_region, pixmap_width, pixmap_height);
+			if (region == NULL) {
+				*n_region = 0;
+				return NULL;
+			}
+		}
 		clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
 							priv->block_h,
 							priv->block_wcnt,
@@ -251,10 +341,9 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 							priv->base.pixmap->drawable.height,
 							region, n_region, 0
 							);
+		if (saved_region)
+			RegionDestroy(region);
 		return clipped_regions;
-	} else if (repeat_type != RepeatNormal) {
-		*n_region = 0;
-		return NULL;
 	}
 	extent = RegionExtents(region);
 
@@ -329,8 +418,10 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 			int shift_x;
 			int shift_y;
 			int saved_y1, saved_y2;
-			int x_idx = 0, y_idx = 0;
+			int x_idx = 0, y_idx = 0, saved_y_idx = 0;
 			RegionRec temp_region;
+			BoxRec reflect_repeat_box;
+			BoxPtr valid_repeat_box;
 
 			shift_x = (extent->x1 / pixmap_width) * pixmap_width;
 			shift_y = (extent->y1 / pixmap_height) * pixmap_height;
@@ -380,12 +471,108 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
 						RegionUninit(&repeat_region);
 					}
 				}
+			} else if (repeat_type == RepeatReflect) {
+				saved_y1 = repeat_box.y1;
+				saved_y2 = repeat_box.y2;
+				saved_y_idx = y_idx;
+				for(; ; repeat_box.x1 += dx, repeat_box.x2 += dx)
+				{
+					repeat_box.y1 = saved_y1;
+					repeat_box.y2 = saved_y2;
+					y_idx = saved_y_idx;
+					reflect_repeat_box.x1 = (x_idx & 1) ?
+								((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1;
+					reflect_repeat_box.x2 = (x_idx & 1) ?
+								((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2;
+					valid_repeat_box = &reflect_repeat_box;
+
+					if (valid_repeat_box->x1 >= extent->x2)
+						break;
+					for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
+					     ;
+					     repeat_box.y1 += dy, repeat_box.y2 += dy)
+					{
+
+						DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, dx, dy);
+						DEBUGF("repeat box %d %d %d %d \n",
+							repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
+
+						if (priv->block_hcnt > 1) {
+						reflect_repeat_box.y1 = (y_idx & 1) ?
+							((2 * y_idx + 1) * dy - repeat_box.y2) : repeat_box.y1;
+						reflect_repeat_box.y2 = (y_idx & 1) ?
+							((2 * y_idx + 1) * dy - repeat_box.y1) : repeat_box.y2;
+						} else {
+						reflect_repeat_box.y1 = repeat_box.y1;
+						reflect_repeat_box.y2 = repeat_box.y2;
+						}
+
+						DEBUGF("valid_repeat_box x1 %d y1 %d \n",
+							valid_repeat_box->x1, valid_repeat_box->y1);
+						if (valid_repeat_box->y1 >= extent->y2)
+							break;
+						RegionInitBoxes(&repeat_region, valid_repeat_box, 1);
+						DEBUGF("start to clip repeat[reflect] region: \n");
+						DEBUGRegionPrint(&repeat_region);
+						RegionIntersect(&temp_region, &repeat_region, region);
+						DEBUGF("result:\n");
+						DEBUGRegionPrint(&temp_region);
+						if (is_transform && RegionNumRects(&temp_region)) {
+							BoxRec temp_box;
+							BoxPtr temp_extent;
+							temp_extent = RegionExtents(&temp_region);
+							if (priv->block_wcnt > 1) {
+								if (x_idx & 1) {
+									temp_box.x1 = ((2 * x_idx + 1)*dx - temp_extent->x2);
+									temp_box.x2 = ((2 * x_idx + 1)*dx - temp_extent->x1);
+								} else {
+									temp_box.x1 = temp_extent->x1;
+									temp_box.x2 = temp_extent->x2;
+								}
+								modulus(temp_box.x1, pixmap_width, temp_box.x1);
+								modulus(temp_box.x2, pixmap_width, temp_box.x2);
+								if (temp_box.x2 == 0) temp_box.x2 = pixmap_width;
+							} else {
+								temp_box.x1 = temp_extent->x1;
+								temp_box.x2 = temp_extent->x2;
+								_glamor_largepixmap_reflect_fixup(&temp_box.x1, &temp_box.x2, pixmap_width);
+							}
+
+							if (priv->block_hcnt > 1) {
+								if (y_idx & 1) {
+									temp_box.y1 = ((2 * y_idx + 1)*dy - temp_extent->y2);
+									temp_box.y2 = ((2 * y_idx + 1)*dy - temp_extent->y1);
+								} else {
+									temp_box.y1 = temp_extent->y1;
+									temp_box.y2 = temp_extent->y2;
+								}
+
+								modulus(temp_box.y1, pixmap_height, temp_box.y1);
+								modulus(temp_box.y2, pixmap_height, temp_box.y2);
+								if (temp_box.y2 == 0) temp_box.y2 = pixmap_height;
+							} else {
+								temp_box.y1 = temp_extent->y1;
+								temp_box.y2 = temp_extent->y2;
+								_glamor_largepixmap_reflect_fixup(&temp_box.y1, &temp_box.y2, pixmap_height);
+							}
+
+							RegionInitBoxes(&temp_region, &temp_box, 1);
+							RegionTranslate(&temp_region, x_center_shift * pixmap_width, y_center_shift * pixmap_height);
+							DEBUGF("for transform result:\n");
+							DEBUGRegionPrint(&temp_region);
+						}
+						RegionAppend(current_region, &temp_region);
+						RegionUninit(&repeat_region);
+						y_idx++;
+					}
+					x_idx++;
+				}
 			}
 			DEBUGF("dx %d dy %d \n", dx, dy);
 
 			if (RegionNumRects(current_region)) {
 
-				if ((right_shift != 0 || down_shift != 0))
+				if ((right_shift != 0 || down_shift != 0) && !(is_transform && repeat_type == RepeatReflect))
 					RegionTranslate(current_region,
 							-right_shift * pixmap_width,
 							-down_shift * pixmap_height);
@@ -411,6 +598,323 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, in
 	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
 }
 
+/* XXX overflow still exist. maybe we need to change to use region32.
+ * by default. Or just use region32 for repeat cases?
+ **/
+glamor_pixmap_clipped_regions *
+glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
+					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type)
+{
+	BoxPtr temp_extent;
+	struct pixman_box32 temp_box;
+	struct pixman_box16 short_box;
+	RegionPtr temp_region;
+	glamor_pixmap_clipped_regions *ret;
+
+	temp_region = RegionCreate(NULL, 4);
+	temp_extent = RegionExtents(region);
+	DEBUGF("dest region \n");
+	DEBUGRegionPrint(region);
+	/* dx/dy may exceed MAX SHORT. we have to use
+	 * a box32 to represent it.*/
+	temp_box.x1 = temp_extent->x1 + dx;
+	temp_box.x2 = temp_extent->x2 + dx;
+	temp_box.y1 = temp_extent->y1 + dy;
+	temp_box.y2 = temp_extent->y2 + dy;
+
+	DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
+	if (transform)
+		glamor_get_transform_extent_from_box(&temp_box, transform);
+	if (repeat_type == RepeatNone) {
+		if (temp_box.x1 < 0) temp_box.x1 = 0;
+		if (temp_box.y1 < 0) temp_box.y1 = 0;
+		temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
+		temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
+	}
+	/* Now copy back the box32 to a box16 box. */
+	short_box.x1 = temp_box.x1;
+	short_box.y1 = temp_box.y1;
+	short_box.x2 = temp_box.x2;
+	short_box.y2 = temp_box.y2;
+	RegionInitBoxes(temp_region, &short_box, 1);
+	DEBUGF("copy to temp source region \n");
+	DEBUGRegionPrint(temp_region);
+	ret = _glamor_compute_clipped_regions(priv,
+					      temp_region,
+					      n_region,
+					      repeat_type,
+					      1);
+	DEBUGF("n_regions = %d \n", *n_region);
+	RegionDestroy(temp_region);
+
+	return ret;
+}
+/*
+ * As transform and repeatpad mode.
+ * We may get a clipped result which in multipe regions.
+ * It's not easy to do a 2nd round clipping just as we do
+ * without transform/repeatPad. As it's not easy to reverse
+ * the 2nd round clipping result with a transform/repeatPad mode,
+ * or even impossible for some transformation.
+ *
+ * So we have to merge the fragmental region into one region
+ * if the clipped result cross the region boundary.
+ */
+static void
+glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type,
+			     glamor_pixmap_clipped_regions *clipped_regions,
+			     int *n_regions, int *need_clean_fbo)
+{
+	BoxPtr temp_extent;
+	BoxRec temp_box, copy_box;
+	RegionPtr temp_region;
+	glamor_pixmap_private *temp_priv;
+	PixmapPtr temp_pixmap;
+	int overlap;
+	int i;
+	int pixmap_width, pixmap_height;
+	glamor_pixmap_private_large_t *priv;
+
+	priv = &pixmap_priv->large;
+	pixmap_width = priv->base.pixmap->drawable.width;
+	pixmap_height = priv->base.pixmap->drawable.height;
+
+	temp_region = RegionCreate(NULL, 4);
+	for(i = 0; i < *n_regions; i++)
+	{
+		DEBUGF("Region %d:\n", i);
+		DEBUGRegionPrint(clipped_regions[i].region);
+		RegionAppend(temp_region, clipped_regions[i].region);
+	}
+
+	RegionValidate(temp_region, &overlap);
+	DEBUGF("temp region: \n");
+	DEBUGRegionPrint(temp_region);
+	temp_extent = RegionExtents(temp_region);
+
+	temp_box = *temp_extent;
+
+	DEBUGF("need copy region: \n");
+	DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
+	temp_pixmap = glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
+					  temp_box.x2 - temp_box.x1,
+					  temp_box.y2 - temp_box.y1,
+					  priv->base.pixmap->drawable.depth,
+					  GLAMOR_CREATE_PIXMAP_FIXUP);
+	if (temp_pixmap == NULL) {
+		assert(0);
+		return;
+	}
+
+	temp_priv = glamor_get_pixmap_private(temp_pixmap);
+	assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
+
+	priv->box = temp_box;
+	if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
+	    && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) {
+		int dx, dy;
+		copy_box.x1 = 0;
+		copy_box.y1 = 0;
+		copy_box.x2 = temp_extent->x2 - temp_extent->x1;
+		copy_box.y2 = temp_extent->y2 - temp_extent->y1;
+		dx = temp_extent->x1;
+		dy = temp_extent->y1;
+		glamor_copy_n_to_n(&priv->base.pixmap->drawable,
+				   &temp_pixmap->drawable,
+				   NULL, &copy_box, 1, dx,
+				   dy, 0, 0, 0, NULL);
+//		glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
+//			       temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
+	} else {
+		for (i = 0; i < *n_regions; i++)
+		{
+			BoxPtr box;
+			int nbox;
+			box = REGION_RECTS(clipped_regions[i].region);
+			nbox = REGION_NUM_RECTS(clipped_regions[i].region);
+			while(nbox--) {
+				int dx, dy, c, d;
+				DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n",
+					box->x1, box->y1, box->x2, box->y2);
+				modulus(box->x1, pixmap_width, c);
+				dx = c - (box->x1 - temp_box.x1);
+				copy_box.x1 = box->x1 - temp_box.x1;
+				copy_box.x2 = box->x2 - temp_box.x1;
+
+				modulus(box->y1, pixmap_height, d);
+				dy = d - (box->y1 - temp_box.y1);
+				copy_box.y1 = box->y1 - temp_box.y1;
+				copy_box.y2 = box->y2 - temp_box.y1;
+
+				DEBUGF("copying box %d %d %d %d, dx %d dy %d\n",
+					copy_box.x1, copy_box.y1, copy_box.x2,
+					copy_box.y2, dx, dy);
+
+				glamor_copy_n_to_n(&priv->base.pixmap->drawable,
+						   &temp_pixmap->drawable,
+						   NULL, &copy_box, 1, dx,
+						   dy, 0, 0, 0, NULL);
+				box++;
+			}
+		}
+		//glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
+		//	       temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff);
+	}
+	/* The first region will be released at caller side. */
+	for(i = 1; i < *n_regions; i++)
+		RegionDestroy(clipped_regions[i].region);
+	RegionDestroy(temp_region);
+	priv->box = temp_box;
+	priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
+	DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
+		priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
+	glamor_destroy_pixmap(temp_pixmap);
+	*need_clean_fbo = 1;
+	*n_regions = 1;
+}
+
+
+
+/**
+ * Given an expected transformed block width and block height,
+ *
+ * This function calculate a new block width and height which
+ * guarantee the transform result will not exceed the given
+ * block width and height.
+ *
+ * For large block width and height (> 2048), we choose a
+ * smaller new width and height and to reduce the cross region
+ * boundary and can avoid some overhead.
+ *
+ **/
+Bool
+glamor_get_transform_block_size(struct pixman_transform *transform,
+			   int block_w, int block_h,
+			   int *transformed_block_w,
+			   int *transformed_block_h)
+{
+	double a,b,c,d,e,f,g,h;
+	double scale;
+	int width, height;
+	a = pixman_fixed_to_double(transform->matrix[0][0]);
+	b = pixman_fixed_to_double(transform->matrix[0][1]);
+	c = pixman_fixed_to_double(transform->matrix[1][0]);
+	d = pixman_fixed_to_double(transform->matrix[1][1]);
+	scale = pixman_fixed_to_double(transform->matrix[2][2]);
+	if (block_w > 2048) {
+	/* For large block size, we shrink it to smaller box,
+	 * thus latter we may get less cross boundary regions and
+	 * thus can avoid some extra copy.
+	 *
+	 **/
+		width = block_w  / 4;
+		height = block_h / 4;
+	} else {
+		width = block_w - 2;
+		height = block_h - 2;
+	}
+	e = a + b;
+	f = c + d;
+
+	g = a - b;
+	h = c - d;
+
+	e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g)));
+	f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h)));
+	*transformed_block_w = MIN(e, f) - 1;
+	*transformed_block_h = *transformed_block_w;
+	if (*transformed_block_w <= 0 || *transformed_block_h <= 0)
+		return FALSE;
+	DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h,
+		*transformed_block_w, *transformed_block_h);
+	return TRUE;
+}
+
+#define VECTOR_FROM_POINT(p, x, y)	\
+	p.v[0] = x;  \
+	p.v[1] = y;  \
+	p.v[2] = 1.0;
+void
+glamor_get_transform_extent_from_box(struct pixman_box32 *box,
+		struct pixman_transform *transform)
+{
+	struct pixman_f_vector p0, p1, p2, p3;
+	float min_x, min_y, max_x, max_y;
+
+	struct pixman_f_transform ftransform;
+
+	VECTOR_FROM_POINT(p0, box->x1, box->y1)
+	VECTOR_FROM_POINT(p1, box->x2, box->y1)
+	VECTOR_FROM_POINT(p2, box->x2, box->y2)
+	VECTOR_FROM_POINT(p3, box->x1, box->y2)
+
+	pixman_f_transform_from_pixman_transform(&ftransform, transform);
+	pixman_f_transform_point(&ftransform, &p0);
+	pixman_f_transform_point(&ftransform, &p1);
+	pixman_f_transform_point(&ftransform, &p2);
+	pixman_f_transform_point(&ftransform, &p3);
+
+	min_x = MIN(p0.v[0], p1.v[0]);
+	min_x = MIN(min_x, p2.v[0]);
+	min_x = MIN(min_x, p3.v[0]);
+
+	min_y = MIN(p0.v[1], p1.v[1]);
+	min_y = MIN(min_y, p2.v[1]);
+	min_y = MIN(min_y, p3.v[1]);
+
+	max_x = MAX(p0.v[0], p1.v[0]);
+	max_x = MAX(max_x, p2.v[0]);
+	max_x = MAX(max_x, p3.v[0]);
+
+	max_y = MAX(p0.v[1], p1.v[1]);
+	max_y = MAX(max_y, p2.v[1]);
+	max_y = MAX(max_y, p3.v[1]);
+	box->x1 = floor(min_x) - 1;
+	box->y1 = floor(min_y) - 1;
+	box->x2 = ceil(max_x) + 1;
+	box->y2 = ceil(max_y) + 1;
+}
+
+static void
+_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
+					int repeat_type,
+					glamor_pixmap_clipped_regions *clipped_regions,
+					int *n_regions, int *need_clean_fbo)
+{
+	int shift_x, shift_y;
+	if (*n_regions != 1) {
+	/* Merge all source regions into one region. */
+		glamor_merge_clipped_regions(priv, repeat_type,
+					     clipped_regions, n_regions,
+					     need_clean_fbo);
+	} else {
+		SET_PIXMAP_FBO_CURRENT(priv,
+				       clipped_regions[0].block_idx);
+		if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) {
+			/* The required source areas are in one region,
+			 * we need to shift the corresponding box's coords to proper position,
+			 * thus we can calculate the relative coords correctly.*/
+			BoxPtr temp_box;
+			int rem;
+			temp_box = RegionExtents(clipped_regions[0].region);
+			modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
+			shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
+			modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
+			shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
+
+			if (shift_x != 0) {
+				priv->large.box.x1 += shift_x * priv->base.pixmap->drawable.width;
+				priv->large.box.x2 += shift_x * priv->base.pixmap->drawable.width;
+			}
+			if (shift_y != 0) {
+				priv->large.box.y1 += shift_y * priv->base.pixmap->drawable.height;
+				priv->large.box.y2 += shift_y * priv->base.pixmap->drawable.height;
+			}
+		}
+	}
+}
+
+
 Bool
 glamor_composite_largepixmap_region(CARD8 op,
 			  PicturePtr source,
@@ -448,21 +952,11 @@ glamor_composite_largepixmap_region(CARD8 op,
 	PixmapPtr mask_pixmap = NULL;
 	int ok = TRUE;
 
-	if (source_pixmap_priv) {
+	if (source_pixmap_priv)
 		source_pixmap = source_pixmap_priv->base.pixmap;
-		if (source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-		    && (source->transform
-			|| source->repeatType != RepeatNone))
-			return FALSE;
-	}
 
-	if (mask_pixmap_priv) {
+	if (mask_pixmap_priv)
 		mask_pixmap = mask_pixmap_priv->base.pixmap;
-		if (mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
-		    && (mask->transform
-		         || mask->repeatType != RepeatNone))
-			return FALSE;
-	}
 
 	if (source->repeat)
 		source_repeat_type = source->repeatType;
@@ -477,10 +971,68 @@ glamor_composite_largepixmap_region(CARD8 op,
 	glamor_priv = dest_pixmap_priv->base.glamor_priv;
 	fixed_block_width = glamor_priv->max_fbo_size;
 	fixed_block_height = glamor_priv->max_fbo_size;
+	/* If we got an totally out-of-box region for a source or mask
+	 * region without repeat, we need to set it as null_source and
+	 * give it a solid color (0,0,0,0). */
+	null_source = 0;
+	null_mask = 0;
 	RegionTranslate(region, -dest->pDrawable->x,
 			-dest->pDrawable->y);
 
-	if (force_clip)
+	/* need to transform the dest region to the correct sourcei/mask region.
+	 * it's a little complex, as one single edge of the
+	 * target region may be transformed to cross a block boundary of the
+	 * source or mask. Then it's impossible to handle it as usual way.
+	 * We may have to split the original dest region to smaller region, and
+	 * make sure each region's transformed region can fit into one texture,
+	 * and then continue this loop again, and each time when a transformed region
+	 * cross the bound, we need to copy it to a single pixmap and do the composition
+	 * with the new pixmap. If the transformed region doesn't cross a source/mask's
+	 * boundary then we don't need to copy.
+	 *
+	 */
+	if (source_pixmap_priv
+	    && source->transform
+	    && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		int source_transformed_block_width, source_transformed_block_height;
+		if (!glamor_get_transform_block_size(source->transform,
+					  source_pixmap_priv->large.block_w,
+					  source_pixmap_priv->large.block_h,
+					  &source_transformed_block_width,
+					  &source_transformed_block_height)) {
+			DEBUGF("source block size less than 1, fallback.\n");
+			RegionTranslate(region, dest->pDrawable->x,
+					dest->pDrawable->y);
+			return FALSE;
+		}
+		fixed_block_width = min(fixed_block_width , source_transformed_block_width);
+		fixed_block_height = min(fixed_block_height , source_transformed_block_height);
+		DEBUGF("new source block size %d x %d \n", fixed_block_width, fixed_block_height);
+	}
+
+	if (mask_pixmap_priv
+	    && mask->transform
+	    && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		int mask_transformed_block_width, mask_transformed_block_height;
+		if (!glamor_get_transform_block_size(mask->transform,
+					  mask_pixmap_priv->large.block_w,
+					  mask_pixmap_priv->large.block_h,
+					  &mask_transformed_block_width,
+					  &mask_transformed_block_height)) {
+			DEBUGF("mask block size less than 1, fallback.\n");
+			RegionTranslate(region, dest->pDrawable->x,
+					dest->pDrawable->y);
+			return FALSE;
+		}
+		fixed_block_width = min(fixed_block_width , mask_transformed_block_width);
+		fixed_block_height = min(fixed_block_height , mask_transformed_block_height);
+		DEBUGF("new mask block size %d x %d \n", fixed_block_width, fixed_block_height);
+	}
+
+	/*compute the correct block width and height whose transformed source/mask
+	 *region can fit into one texture.*/
+	if (force_clip || fixed_block_width < glamor_priv->max_fbo_size
+	    || fixed_block_height < glamor_priv->max_fbo_size)
 		clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv,
 									  region,
 									  &n_dest_regions,
@@ -492,93 +1044,238 @@ glamor_composite_largepixmap_region(CARD8 op,
 								      &n_dest_regions,
 								      0);
 	DEBUGF("dest clipped result %d region: \n", n_dest_regions);
+	if (source_pixmap_priv == dest_pixmap_priv
+	    && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		/* XXX self-copy...*/
+		need_free_source_pixmap_priv = source_pixmap_priv;
+		source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
+		*source_pixmap_priv = *need_free_source_pixmap_priv;
+		need_free_source_pixmap_priv = source_pixmap_priv;
+	}
 	for(i = 0; i < n_dest_regions; i++)
 	{
 		DEBUGF("dest region %d  idx %d\n", i, clipped_dest_regions[i].block_idx);
 		DEBUGRegionPrint(clipped_dest_regions[i].region);
 		SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx);
 		if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+			if (!source->transform && source_repeat_type != RepeatPad) {
 				RegionTranslate(clipped_dest_regions[i].region,
 						x_source - x_dest,
 						y_source - y_dest);
 				clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
 										        clipped_dest_regions[i].region,
 										        &n_source_regions, source_repeat_type);
+				is_normal_source_fbo = 1;
+			}
+			else {
+				clipped_source_regions = glamor_compute_transform_clipped_regions(source_pixmap_priv,
+									source->transform,
+									clipped_dest_regions[i].region,
+									&n_source_regions,
+									x_source - x_dest, y_source - y_dest,
+									source_repeat_type);
+				is_normal_source_fbo = 0;
+				if (n_source_regions == 0) {
+					/* Pad the out-of-box region to (0,0,0,0). */
+					null_source = 1;
+					n_source_regions = 1;
+				} else
+					_glamor_process_transformed_clipped_region(source_pixmap_priv,
+						source_repeat_type, clipped_source_regions, &n_source_regions,
+						&need_clean_source_fbo);
+			}
 			DEBUGF("source clipped result %d region: \n", n_source_regions);
 			for(j = 0; j < n_source_regions; j++)
 			{
-				SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
-						       clipped_source_regions[j].block_idx);
+				if (is_normal_source_fbo)
+					SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
+							       clipped_source_regions[j].block_idx);
 
 				if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-					DEBUGF("source region %d  idx %d\n", j, clipped_source_regions[j].block_idx);
-					DEBUGRegionPrint(clipped_source_regions[j].region);
-					RegionTranslate(clipped_source_regions[j].region,
-							- x_source + x_mask,
+					if (is_normal_mask_fbo && is_normal_source_fbo) {
+						/* both mask and source are normal fbo box without transform or repeatpad.
+						 * The region is clipped against source and then we clip it against mask here.*/
+						DEBUGF("source region %d  idx %d\n", j, clipped_source_regions[j].block_idx);
+						DEBUGRegionPrint(clipped_source_regions[j].region);
+						RegionTranslate(clipped_source_regions[j].region,
+								- x_source + x_mask,
 							- y_source + y_mask);
-					clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
-										     clipped_source_regions[j].region,
-										     &n_mask_regions, mask_repeat_type);
+						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
+											     clipped_source_regions[j].region,
+											     &n_mask_regions, mask_repeat_type);
+						is_normal_mask_fbo = 1;
+					} else if (is_normal_mask_fbo && !is_normal_source_fbo) {
+						assert(n_source_regions == 1);
+						/* The source fbo is not a normal fbo box, it has transform or repeatpad.
+						 * the valid clip region should be the clip dest region rather than the
+						 * clip source region.*/
+						RegionTranslate(clipped_dest_regions[i].region,
+								- x_dest + x_mask,
+								- y_dest + y_mask);
+						clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
+											     clipped_dest_regions[i].region,
+											     &n_mask_regions, mask_repeat_type);
+						is_normal_mask_fbo = 1;
+					} else {
+						/* This mask region has transform or repeatpad, we need clip it agains the previous
+						 * valid region rather than the mask region. */
+						if (!is_normal_source_fbo)
+							clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
+												mask->transform,
+												clipped_dest_regions[i].region,
+												&n_mask_regions,
+												x_mask - x_dest,
+												y_mask - y_dest,
+												mask_repeat_type);
+						else
+							clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
+												mask->transform,
+												clipped_source_regions[j].region,
+												&n_mask_regions,
+												x_mask - x_source, y_mask - y_source,
+												mask_repeat_type);
+						is_normal_mask_fbo = 0;
+						if (n_mask_regions == 0) {
+						/* Pad the out-of-box region to (0,0,0,0). */
+							null_mask = 1;
+							n_mask_regions = 1;
+						} else
+							_glamor_process_transformed_clipped_region(mask_pixmap_priv,
+								mask_repeat_type, clipped_mask_regions, &n_mask_regions,
+								&need_clean_mask_fbo);
+					}
 					DEBUGF("mask clipped result %d region: \n", n_mask_regions);
 
 #define COMPOSITE_REGION(region) do {				\
 	if (!glamor_composite_clipped_region(op,		\
-			 source,				\
-			 mask, dest, region,			\
+			 null_source ? NULL : source,		\
+			 null_mask ? NULL : mask, dest, region,	\
 			 x_source, y_source, x_mask, y_mask,	\
 			 x_dest, y_dest)) {			\
 		assert(0);					\
 	}							\
    } while(0)
+
 					for(k = 0; k < n_mask_regions; k++)
 					{
 						DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
 						DEBUGRegionPrint(clipped_mask_regions[k].region);
-						SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
-							       clipped_mask_regions[k].block_idx);
-						DEBUGF("mask fbo off %d %d \n",
-							mask_pixmap_priv->large.box.x1,
-							mask_pixmap_priv->large.box.y1);
-						DEBUGF("start composite mask hasn't transform.\n");
-						RegionTranslate(clipped_mask_regions[k].region,
-								x_dest - x_mask + dest->pDrawable->x,
-								y_dest - y_mask + dest->pDrawable->y);
-						COMPOSITE_REGION(clipped_mask_regions[k].region);
+						if (is_normal_mask_fbo) {
+							SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+								       clipped_mask_regions[k].block_idx);
+							DEBUGF("mask fbo off %d %d \n",
+								mask_pixmap_priv->large.box.x1,
+								mask_pixmap_priv->large.box.y1);
+							DEBUGF("start composite mask hasn't transform.\n");
+							RegionTranslate(clipped_mask_regions[k].region,
+									x_dest - x_mask + dest->pDrawable->x,
+									y_dest - y_mask + dest->pDrawable->y);
+							COMPOSITE_REGION(clipped_mask_regions[k].region);
+						} else if (!is_normal_mask_fbo && !is_normal_source_fbo) {
+							DEBUGF("start composite both mask and source have transform.\n");
+							RegionTranslate(clipped_dest_regions[i].region,
+									dest->pDrawable->x,
+									dest->pDrawable->y);
+							COMPOSITE_REGION(clipped_dest_regions[i].region);
+						} else {
+							DEBUGF("start composite only mask has transform.\n");
+							RegionTranslate(clipped_source_regions[j].region,
+									x_dest - x_source + dest->pDrawable->x,
+									y_dest - y_source + dest->pDrawable->y);
+							COMPOSITE_REGION(clipped_source_regions[j].region);
+						}
 						RegionDestroy(clipped_mask_regions[k].region);
 					}
 					free(clipped_mask_regions);
+					if (null_mask) null_mask = 0;
+					if (need_clean_mask_fbo) {
+						assert(is_normal_mask_fbo == 0);
+						glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+						mask_pixmap_priv->base.fbo = NULL;
+						need_clean_mask_fbo = 0;
+					}
 				} else {
-					RegionTranslate(clipped_source_regions[j].region,
-							-x_source + x_dest + dest->pDrawable->x,
-							-y_source + y_dest + dest->pDrawable->y);
-					COMPOSITE_REGION(clipped_source_regions[j].region);
+					if (is_normal_source_fbo) {
+						RegionTranslate(clipped_source_regions[j].region,
+								-x_source + x_dest + dest->pDrawable->x,
+								-y_source + y_dest + dest->pDrawable->y);
+						COMPOSITE_REGION(clipped_source_regions[j].region);
+					} else {
+						/* Source has transform or repeatPad. dest regions is the right
+						 * region to do the composite. */
+						RegionTranslate(clipped_dest_regions[i].region,
+								dest->pDrawable->x,
+								dest->pDrawable->y);
+						COMPOSITE_REGION(clipped_dest_regions[i].region);
+					}
 				}
 				if (clipped_source_regions && clipped_source_regions[j].region)
 					RegionDestroy(clipped_source_regions[j].region);
 			}
 			free(clipped_source_regions);
+			if (null_source) null_source = 0;
+			if (need_clean_source_fbo) {
+				assert(is_normal_source_fbo == 0);
+				glamor_destroy_fbo(source_pixmap_priv->base.fbo);
+				source_pixmap_priv->base.fbo = NULL;
+				need_clean_source_fbo = 0;
+			}
 		}
 		else {
 			if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-				RegionTranslate(clipped_dest_regions[i].region,
-						x_mask - x_dest,
-						y_mask - y_dest);
-				clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
-							        clipped_dest_regions[i].region,
-							        &n_mask_regions, mask_repeat_type);
+				if (!mask->transform && mask_repeat_type != RepeatPad) {
+					RegionTranslate(clipped_dest_regions[i].region,
+							x_mask - x_dest,
+							y_mask - y_dest);
+					clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
+								        clipped_dest_regions[i].region,
+								        &n_mask_regions, mask_repeat_type);
+					is_normal_mask_fbo = 1;
+				}
+				else {
+					clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
+										mask->transform,
+										clipped_dest_regions[i].region,
+										&n_mask_regions,
+										x_mask - x_dest, y_mask - y_dest,
+										mask_repeat_type);
+					is_normal_mask_fbo = 0;
+					if (n_mask_regions == 0) {
+						/* Pad the out-of-box region to (0,0,0,0). */
+						null_mask = 1;
+						n_mask_regions = 1;
+					} else
+						_glamor_process_transformed_clipped_region(mask_pixmap_priv,
+							mask_repeat_type, clipped_mask_regions, &n_mask_regions,
+							&need_clean_mask_fbo);
+				}
+
 				for(k = 0; k < n_mask_regions; k++)
 				{
 					DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
 					DEBUGRegionPrint(clipped_mask_regions[k].region);
-					SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
-							       clipped_mask_regions[k].block_idx);
-					RegionTranslate(clipped_mask_regions[k].region,
-							x_dest - x_mask + dest->pDrawable->x,
-							y_dest - y_mask + dest->pDrawable->y);
-					COMPOSITE_REGION(clipped_mask_regions[k].region);
+					if (is_normal_mask_fbo) {
+						SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+								       clipped_mask_regions[k].block_idx);
+						RegionTranslate(clipped_mask_regions[k].region,
+								x_dest - x_mask + dest->pDrawable->x,
+								y_dest - y_mask + dest->pDrawable->y);
+						COMPOSITE_REGION(clipped_mask_regions[k].region);
+					} else {
+						RegionTranslate(clipped_dest_regions[i].region,
+								dest->pDrawable->x,
+								dest->pDrawable->y);
+						COMPOSITE_REGION(clipped_dest_regions[i].region);
+					}
 					RegionDestroy(clipped_mask_regions[k].region);
 				}
 				free(clipped_mask_regions);
+				if (null_mask) null_mask = 0;
+				if (need_clean_mask_fbo) {
+					glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
+					mask_pixmap_priv->base.fbo = NULL;
+					need_clean_mask_fbo = 0;
+				}
 			}
 			else {
 				RegionTranslate(clipped_dest_regions[i].region,
@@ -590,6 +1287,8 @@ glamor_composite_largepixmap_region(CARD8 op,
 		RegionDestroy(clipped_dest_regions[i].region);
 	}
 	free(clipped_dest_regions);
+	free(need_free_source_pixmap_priv);
+	free(need_free_mask_pixmap_priv);
 	ok = TRUE;
 	return ok;
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b19d66c..40a8794 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -955,7 +955,12 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
 						    yInverted,
 						    texcoords);
 	else if (matrix && repeat_type != RepeatNone)
-		assert(0);
+		glamor_set_repeat_transformed_normalize_tcoords(priv, repeat_type,
+								matrix, xscale, yscale,
+								x1, y1,
+								x2, y2,
+								yInverted,
+								texcoords);
 }
 
 static Bool
@@ -1718,9 +1723,9 @@ _glamor_composite(CARD8 op,
 		extent->x2 - extent->x1, extent->y2 - extent->y1)
 	   && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
            && ((source_pixmap_priv
-	        && source_pixmap_priv->type == GLAMOR_MEMORY)
+	        && (source_pixmap_priv->type == GLAMOR_MEMORY || source->repeatType == RepeatPad))
 	     || (mask_pixmap_priv
-		&& mask_pixmap_priv->type == GLAMOR_MEMORY)
+		&& (mask_pixmap_priv->type == GLAMOR_MEMORY || mask->repeatType == RepeatPad))
 	     || (!source_pixmap_priv
 		   && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	     || (!mask_pixmap_priv && mask
@@ -1742,7 +1747,6 @@ _glamor_composite(CARD8 op,
 						   x_mask, y_mask,
 						   x_dest, y_dest,
 						   width, height);
-
 	else
 		ok = glamor_composite_clipped_region(op, source,
 						     mask, dest, &region,
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 44c8175..18f7f3b 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -39,13 +39,13 @@
 #define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
-#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
-   do {									\
-    int w,h;								\
-    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h);			\
-    *(_pxscale_) = 1.0 / w;						\
-    *(_pyscale_) = 1.0 / h;						\
-  } while(0)
+#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)\
+  do {                                                                 \
+    int w,h;                                                           \
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h);                  \
+    *(_pxscale_) = 1.0 / w;                                            \
+    *(_pyscale_) = 1.0 / h;                                            \
+   } while(0)
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
@@ -108,24 +108,175 @@
       }									\
   }  while(0)
 
+#define fmod(x, w)		(x - w * floor((float)x/w))
+
+#define fmodulus(x, w, c)	do {c = fmod(x, w);		\
+				    c = c >= 0 ? c : c + w;}	\
+				while(0)
+/* @x: is current coord
+ * @x2: is the right/bottom edge
+ * @w: is current width or height
+ * @odd: is output value, 0 means we are in an even region, 1 means we are in a
+ * odd region.
+ * @c: is output value, equal to x mod w. */
+#define fodd_repeat_mod(x, x2, w, odd, c)	\
+  do {						\
+	float shift;				\
+	fmodulus((x), w, c); 			\
+	shift = fabs((x) - (c));		\
+	shift = floor(fabs(round(shift)) / w);	\
+	odd = (int)shift & 1;			\
+	if (odd && (((x2 % w) == 0) &&		\
+	    round(fabs(x)) == x2))		\
+		odd = 0;			\
+  } while(0)
+
+/* @txy: output value, is the corrected coords.
+ * @xy: input coords to be fixed up.
+ * @cd: xy mod wh, is a input value.
+ * @wh: current width or height.
+ * @bxy1,bxy2: current box edge's x1/x2 or y1/y2
+ *
+ * case 1:
+ *  ----------
+ *  |  *     |
+ *  |        |
+ *  ----------
+ *  tx = (c - x1) mod w
+ *
+ *  case 2:
+ *     ---------
+ *  *  |       |
+ *     |       |
+ *     ---------
+ *   tx = - (c - (x1 mod w))
+ *
+ *   case 3:
+ *
+ *   ----------
+ *   |        |  *
+ *   |        |
+ *   ----------
+ *   tx = ((x2 mod x) - c) + (x2 - x1)
+ **/
+#define __glamor_repeat_reflect_fixup(txy, xy,		\
+				cd, wh, bxy1, bxy2)	\
+  do {							\
+	cd = wh - cd;					\
+	if ( xy >= bxy1 && xy < bxy2) {			\
+		cd = cd - bxy1;				\
+		fmodulus(cd, wh, txy);			\
+	} else	if (xy < bxy1) {			\
+		float bxy1_mod;				\
+		fmodulus(bxy1, wh, bxy1_mod);		\
+		txy = -(cd - bxy1_mod);			\
+	}						\
+	else if (xy >= bxy2)	{			\
+		float bxy2_mod;				\
+		fmodulus(bxy2, wh, bxy2_mod);		\
+		if (bxy2_mod == 0)			\
+			bxy2_mod = wh;			\
+		txy = (bxy2_mod - cd) + bxy2 - bxy1;	\
+	} else {assert(0); txy = 0;}			\
+  } while(0)
+
+#define _glamor_repeat_reflect_fixup(txy, xy, cd, odd,	\
+				     wh, bxy1, bxy2)	\
+  do {							\
+	if (odd) {					\
+		__glamor_repeat_reflect_fixup(txy, xy, 	\
+			cd, wh, bxy1, bxy2);		\
+	} else						\
+		txy = xy - bxy1;			\
+  } while(0)
+
+#define _glamor_get_reflect_transform_coords(priv, repeat_type,	\
+					    tx1, ty1, 		\
+				            _x1_, _y1_)		\
+  do {								\
+	int odd_x, odd_y;					\
+	float c, d;						\
+	fodd_repeat_mod(_x1_,priv->box.x2,			\
+		    priv->base.pixmap->drawable.width,		\
+		    odd_x, c);					\
+	fodd_repeat_mod(_y1_,	priv->box.y2,			\
+		    priv->base.pixmap->drawable.height,		\
+		    odd_y, d);					\
+	DEBUGF("c %f d %f oddx %d oddy %d \n",			\
+		c, d, odd_x, odd_y);				\
+	DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2,	\
+		priv->box.x1, priv->base.fbo->width);		\
+	DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, 	\
+		priv->box.y1, priv->base.fbo->height);		\
+	_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x,	\
+		priv->base.pixmap->drawable.width,		\
+		priv->box.x1, priv->box.x2);			\
+	_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y,	\
+		priv->base.pixmap->drawable.height,		\
+		priv->box.y1, priv->box.y2);			\
+   } while(0)
+
 #define _glamor_get_repeat_coords(priv, repeat_type, tx1,	\
 				  ty1, tx2, ty2,		\
 				  _x1_, _y1_, _x2_,		\
 				  _y2_, c, d, odd_x, odd_y)	\
   do {								\
 	if (repeat_type == RepeatReflect) {			\
-		assert(0);					\
+		DEBUGF("x1 y1 %d %d\n",				\
+			_x1_, _y1_ );				\
+		DEBUGF("width %d box.x1 %d \n",			\
+		       (priv)->base.pixmap->drawable.width,	\
+		       priv->box.x1);				\
+		if (odd_x) {					\
+			c = (priv)->base.pixmap->drawable.width	\
+				- c;				\
+			tx1 = c - priv->box.x1;			\
+			tx2 = tx1 - ((_x2_) - (_x1_));		\
+		} else {					\
+			tx1 = c - priv->box.x1;			\
+			tx2 = tx1 + ((_x2_) - (_x1_));		\
+		}						\
+		if (odd_y){					\
+			d = (priv)->base.pixmap->drawable.height\
+			    - d;				\
+			ty1 = d - priv->box.y1;			\
+			ty2 = ty1 - ((_y2_) - (_y1_));		\
+		} else {					\
+			ty1 = d - priv->box.y1;			\
+			ty2 = ty1 + ((_y2_) - (_y1_));		\
+		}						\
 	} else if (repeat_type == RepeatNormal) {		\
 		tx1 = (c - priv->box.x1);  			\
 		ty1 = (d - priv->box.y1);			\
 		tx2 = tx1 + ((_x2_) - (_x1_));			\
 		ty2 = ty1 + ((_y2_) - (_y1_));			\
 	} else {						\
-		assert(0);					\
+		tx1 = _x1_ - priv->box.x1;			\
+		ty1 = _y1_ - priv->box.y1;			\
+		tx2 = tx1 + ((_x2_) - (_x1_));			\
+		ty2 = ty1 + ((_y2_) - (_y1_));			\
 	}							\
    } while(0)
 
 
+/* _x1_ ... _y2_ may has fractional. */
+#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1,	\
+					   ty1, _x1_, _y1_)		\
+  do {									\
+	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
+		(priv)->base.pixmap->drawable.width,			\
+		priv->box.x1, priv->box.x2, priv->box.y1,		\
+		priv->box.y2);						\
+	DEBUGF("x1 %f y1 %f \n", _x1_, _y1_);				\
+	if (repeat_type != RepeatReflect) {				\
+		tx1 = _x1_ - priv->box.x1;				\
+		ty1 = _y1_ - priv->box.y1;				\
+	} else			\
+		_glamor_get_reflect_transform_coords(priv, repeat_type, \
+				  tx1, ty1, 				\
+				  _x1_, _y1_);				\
+	DEBUGF("tx1 %f ty1 %f \n", tx1, ty1);				\
+   } while(0)
 
 /* _x1_ ... _y2_ must be integer. */
 #define glamor_get_repeat_coords(priv, repeat_type, tx1,		\
@@ -152,8 +303,6 @@
 				  odd_x, odd_y);			\
    } while(0)
 
-
-
 #define glamor_transform_point(matrix, tx, ty, x, y)			\
   do {									\
     int i;								\
@@ -221,6 +370,58 @@
 				 yInverted);				\
   } while (0)
 
+#define glamor_set_repeat_transformed_normalize_tcoords( priv,		\
+							 repeat_type,	\
+							 matrix,	\
+							 xscale,	\
+							 yscale,	\
+							 _x1_, _y1_,	\
+							 _x2_, _y2_,   	\
+							 yInverted,	\
+							 texcoords)	\
+  do {									\
+    if (priv->type != GLAMOR_TEXTURE_LARGE) {				\
+	glamor_set_transformed_normalize_tcoords(priv, matrix, xscale,	\
+						 yscale, _x1_, _y1_,	\
+						 _x2_, _y2_, yInverted,	\
+						 texcoords);		\
+    } else {								\
+	/* For a large pixmap, if both transform and repeat are set,
+	 * the transform must only has x and y scale factor.*/		\
+    float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;			\
+    float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4;		\
+    DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_);	\
+    glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_);		\
+    glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_);		\
+    glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_);		\
+    glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_);		\
+    DEBUGF("transformed %f %f %f %f %f %f %f %f\n",			\
+	   tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);			\
+    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+				       ttx1, tty1, 			\
+				       tx1, ty1);			\
+    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+				       ttx2, tty2, 			\
+				       tx2, ty2);			\
+    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+				       ttx3, tty3, 			\
+				       tx3, ty3);			\
+    glamor_get_repeat_transform_coords((&priv->large), repeat_type, 	\
+				       ttx4, tty4, 			\
+				       tx4, ty4);			\
+    DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, 	\
+	    ttx2, tty2,	ttx3, tty3, ttx4, tty4);			\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1,		\
+				 texcoords, yInverted);			\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2,		\
+				 texcoords + 2, yInverted);		\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3,		\
+				 texcoords + 4, yInverted);		\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4,		\
+				 texcoords + 6, yInverted);		\
+   }									\
+  } while (0)
+
 #define _glamor_set_normalize_tcoords(xscale, yscale, tx1,		\
 				      ty1, tx2, ty2,			\
 				      yInverted, vertices)		\
@@ -261,6 +462,8 @@
 				   tx2, ty2, yInverted, vertices);	\
  } while(0)
 
+
+
 #define glamor_set_repeat_normalize_tcoords(priv, repeat_type,		\
 					    xscale, yscale,		\
 					    _x1_, _y1_, _x2_, _y2_,	\
@@ -480,7 +683,7 @@ format_for_pixmap(PixmapPtr pixmap)
 
 /*
  * Map picture's format to the correct gl texture format and type.
- * no_alpha is used to indicate whehter we need to wire alpha to 1. 
+ * no_alpha is used to indicate whehter we need to wire alpha to 1.
  *
  * Although opengl support A1/GL_BITMAP, we still don't use it
  * here, it seems that mesa has bugs when uploading a A1 bitmap.
@@ -899,7 +1102,7 @@ inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-	return (!pixmap_priv 
+	return (!pixmap_priv
 		|| (pixmap_priv->type == GLAMOR_TEXTURE_DRM
 		    || pixmap_priv->type == GLAMOR_MEMORY
 		    || pixmap_priv->type == GLAMOR_DRM_ONLY));
commit 48916a23a92366128f5a1eeb08949d8d32383c32
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 02:27:00 2012 +0800

    glamor_getimage: should call miGetimage if failed to get sub-image.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 655ed94..f446c83 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -45,6 +45,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	if (format != ZPixmap)
 		goto fall_back;
+	pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
 	if (!glamor_set_planemask(pixmap, planeMask)) {
 		glamor_fallback
@@ -78,7 +80,7 @@ fall_back:
 				      y + y_off + drawable->y,
 				      w, h, GLAMOR_ACCESS_RO);
 	} else
-		fbGetImage(drawable, x, y, w, h, format, planeMask, d);
+		miGetImage(drawable, x, y, w, h, format, planeMask, d);
 
 	return TRUE;
 }
commit 56d6e7a85fbe8e50c38efda0f59f09aac52b769a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 02:24:41 2012 +0800

    glamor_putimage: Correct the wrong stride value.
    
    We should not use the destination pixmap's devkind as the input
    image data's stride.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 6d62bd7..34e86a1 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -307,7 +307,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		glamor_destroy_pixmap(temp_pixmap);
 	} else
 		glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off,
-						    w, h, pixmap->devKind, bits, 0);
+						    w, h, PixmapBytePad(w, depth), bits, 0);
 	ret = TRUE;
 	goto done;
 
commit eb6f981ba4d3a4aff1b3651bdad3cd7a52233b41
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 02:15:53 2012 +0800

    largepixmap: Enable glamor_composite.
    
    Now we start to enable glamor_composite on large pixmap.
    We need to do a three layer clipping to split the dest/source/mask
    to small pieces. This commit only support non-transformation and
    repeat normal case.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index fe7d9de..dd3b4c6 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -62,7 +62,7 @@
  */
 #define GLYPH_BUFFER_SIZE 1024
 
-#define CACHE_PICTURE_SIZE  1024
+#define CACHE_PICTURE_SIZE 1024
 #define GLYPH_MIN_SIZE 8
 #define GLYPH_MAX_SIZE 64
 #define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index e8c1030..a1a73a4 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -410,3 +410,186 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, in
 {
 	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
 }
+
+Bool
+glamor_composite_largepixmap_region(CARD8 op,
+			  PicturePtr source,
+			  PicturePtr mask,
+			  PicturePtr dest,
+			  glamor_pixmap_private * source_pixmap_priv,
+			  glamor_pixmap_private * mask_pixmap_priv,
+			  glamor_pixmap_private * dest_pixmap_priv,
+			  RegionPtr region, Bool force_clip,
+			  INT16 x_source,
+			  INT16 y_source,
+			  INT16 x_mask,
+			  INT16 y_mask,
+			  INT16 x_dest, INT16 y_dest,
+			  CARD16 width, CARD16 height)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_pixmap_clipped_regions *clipped_dest_regions;
+	glamor_pixmap_clipped_regions *clipped_source_regions;
+	glamor_pixmap_clipped_regions *clipped_mask_regions;
+	int n_dest_regions;
+	int n_mask_regions;
+	int n_source_regions;
+	int i,j,k;
+	int need_clean_source_fbo = 0;
+	int need_clean_mask_fbo = 0;
+	int is_normal_source_fbo = 0;
+	int is_normal_mask_fbo = 0;
+	int fixed_block_width, fixed_block_height;
+	int null_source, null_mask;
+	glamor_pixmap_private * need_free_source_pixmap_priv = NULL;
+	glamor_pixmap_private * need_free_mask_pixmap_priv = NULL;
+	int source_repeat_type = 0, mask_repeat_type = 0;
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr mask_pixmap = NULL;
+	int ok = TRUE;
+
+	if (source_pixmap_priv) {
+		source_pixmap = source_pixmap_priv->base.pixmap;
+		if (source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+		    && (source->transform
+			|| source->repeatType != RepeatNone))
+			return FALSE;
+	}
+
+	if (mask_pixmap_priv) {
+		mask_pixmap = mask_pixmap_priv->base.pixmap;
+		if (mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+		    && (mask->transform
+		         || mask->repeatType != RepeatNone))
+			return FALSE;
+	}
+
+	if (source->repeat)
+		source_repeat_type = source->repeatType;
+	else
+		source_repeat_type = RepeatNone;
+
+	if (mask && mask->repeat)
+		mask_repeat_type = mask->repeatType;
+	else
+		mask_repeat_type = RepeatNone;
+
+	glamor_priv = dest_pixmap_priv->base.glamor_priv;
+	fixed_block_width = glamor_priv->max_fbo_size;
+	fixed_block_height = glamor_priv->max_fbo_size;
+	RegionTranslate(region, -dest->pDrawable->x,
+			-dest->pDrawable->y);
+
+	if (force_clip)
+		clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv,
+									  region,
+									  &n_dest_regions,
+									  fixed_block_width,
+									  fixed_block_height);
+	else
+		clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
+								      region,
+								      &n_dest_regions,
+								      0);
+	DEBUGF("dest clipped result %d region: \n", n_dest_regions);
+	for(i = 0; i < n_dest_regions; i++)
+	{
+		DEBUGF("dest region %d  idx %d\n", i, clipped_dest_regions[i].block_idx);
+		DEBUGRegionPrint(clipped_dest_regions[i].region);
+		SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx);
+		if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+				RegionTranslate(clipped_dest_regions[i].region,
+						x_source - x_dest,
+						y_source - y_dest);
+				clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
+										        clipped_dest_regions[i].region,
+										        &n_source_regions, source_repeat_type);
+			DEBUGF("source clipped result %d region: \n", n_source_regions);
+			for(j = 0; j < n_source_regions; j++)
+			{
+				SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
+						       clipped_source_regions[j].block_idx);
+
+				if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+					DEBUGF("source region %d  idx %d\n", j, clipped_source_regions[j].block_idx);
+					DEBUGRegionPrint(clipped_source_regions[j].region);
+					RegionTranslate(clipped_source_regions[j].region,
+							- x_source + x_mask,
+							- y_source + y_mask);
+					clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
+										     clipped_source_regions[j].region,
+										     &n_mask_regions, mask_repeat_type);
+					DEBUGF("mask clipped result %d region: \n", n_mask_regions);
+
+#define COMPOSITE_REGION(region) do {				\
+	if (!glamor_composite_clipped_region(op,		\
+			 source,				\
+			 mask, dest, region,			\
+			 x_source, y_source, x_mask, y_mask,	\
+			 x_dest, y_dest)) {			\
+		assert(0);					\
+	}							\
+   } while(0)
+					for(k = 0; k < n_mask_regions; k++)
+					{
+						DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
+						DEBUGRegionPrint(clipped_mask_regions[k].region);
+						SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+							       clipped_mask_regions[k].block_idx);
+						DEBUGF("mask fbo off %d %d \n",
+							mask_pixmap_priv->large.box.x1,
+							mask_pixmap_priv->large.box.y1);
+						DEBUGF("start composite mask hasn't transform.\n");
+						RegionTranslate(clipped_mask_regions[k].region,
+								x_dest - x_mask + dest->pDrawable->x,
+								y_dest - y_mask + dest->pDrawable->y);
+						COMPOSITE_REGION(clipped_mask_regions[k].region);
+						RegionDestroy(clipped_mask_regions[k].region);
+					}
+					free(clipped_mask_regions);
+				} else {
+					RegionTranslate(clipped_source_regions[j].region,
+							-x_source + x_dest + dest->pDrawable->x,
+							-y_source + y_dest + dest->pDrawable->y);
+					COMPOSITE_REGION(clipped_source_regions[j].region);
+				}
+				if (clipped_source_regions && clipped_source_regions[j].region)
+					RegionDestroy(clipped_source_regions[j].region);
+			}
+			free(clipped_source_regions);
+		}
+		else {
+			if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+				RegionTranslate(clipped_dest_regions[i].region,
+						x_mask - x_dest,
+						y_mask - y_dest);
+				clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
+							        clipped_dest_regions[i].region,
+							        &n_mask_regions, mask_repeat_type);
+				for(k = 0; k < n_mask_regions; k++)
+				{
+					DEBUGF("mask region %d  idx %d\n", k, clipped_mask_regions[k].block_idx);
+					DEBUGRegionPrint(clipped_mask_regions[k].region);
+					SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
+							       clipped_mask_regions[k].block_idx);
+					RegionTranslate(clipped_mask_regions[k].region,
+							x_dest - x_mask + dest->pDrawable->x,
+							y_dest - y_mask + dest->pDrawable->y);
+					COMPOSITE_REGION(clipped_mask_regions[k].region);
+					RegionDestroy(clipped_mask_regions[k].region);
+				}
+				free(clipped_mask_regions);
+			}
+			else {
+				RegionTranslate(clipped_dest_regions[i].region,
+						dest->pDrawable->x,
+						dest->pDrawable->y);
+				COMPOSITE_REGION(clipped_dest_regions[i].region);
+			}
+		}
+		RegionDestroy(clipped_dest_regions[i].region);
+	}
+	free(clipped_dest_regions);
+	ok = TRUE;
+	return ok;
+}
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 48a5bb3..b19d66c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1732,7 +1732,17 @@ _glamor_composite(CARD8 op,
 		&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
 	    || (mask_pixmap_priv
 		&& mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
-		goto fail;
+		ok = glamor_composite_largepixmap_region(op,
+						   source, mask, dest,
+						   source_pixmap_priv,
+						   mask_pixmap_priv,
+						   dest_pixmap_priv,
+						   &region, force_clip,
+						   x_source, y_source,
+						   x_mask, y_mask,
+						   x_dest, y_dest,
+						   width, height);
+
 	else
 		ok = glamor_composite_clipped_region(op, source,
 						     mask, dest, &region,
commit e96ea02010874a3a46f212f42134083bd29fefe3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 01:52:14 2012 +0800

    largepixmap: Implement infrastructure for large pixmap.
    
    Added infrastructure for largepixmap, this commit implemented:
    1. Create/Destroy large pixmap.
    2. Upload/Download large pixmap.
    3. Implement basic repeat normal support.
    3. tile/fill/copyarea large pixmap get supported.
    
    The most complicated part glamor_composite still not implemented.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2e94ffd..421846c 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -42,6 +42,7 @@ libglamor_la_SOURCES = \
 	glamor_glyphblt.c\
 	glamor_polyops.c\
 	glamor_pixmap.c\
+	glamor_largepixmap.c\
 	glamor_picture.c\
 	glamor_window.c\
 	glamor_gl_dispatch.c\
diff --git a/glamor/glamor.c b/glamor/glamor.c
index a22f445..74b22d3 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -141,9 +141,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
-	if (usage == GLAMOR_CREATE_PIXMAP_CPU
-	    || (w == 0 && h == 0)
-	    || !glamor_check_pixmap_fbo_depth(depth))
+	if ((usage == GLAMOR_CREATE_PIXMAP_CPU
+		|| (w == 0 && h == 0)
+		|| !glamor_check_pixmap_fbo_depth(depth))
+	    || (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
+		!glamor_check_fbo_size(glamor_priv, w, h)))
 		return fbCreatePixmap(screen, w, h, depth, usage);
 	else
 		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
@@ -161,10 +163,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 	pixmap_priv->base.pixmap = pixmap;
 	pixmap_priv->base.glamor_priv = glamor_priv;
-	pixmap_priv->type = type;
 
 	gl_iformat_for_depth(depth, &format);
-	fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
+
+	pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
+	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+
+	if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) {
+		pixmap_priv->type = type;
+		fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
+	}
+	else {
+		DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h);
+		pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
+		fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
+					      glamor_priv->max_fbo_size,
+					      glamor_priv->max_fbo_size,
+					      pixmap_priv);
+	}
 
 	if (fbo == NULL) {
 		fbDestroyPixmap(pixmap);
@@ -174,8 +190,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 	glamor_pixmap_attach_fbo(pixmap, fbo);
 
-	pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
-	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
 	return pixmap;
 }
 
@@ -186,13 +200,8 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 		glamor_pixmap_private *pixmap_priv;
 
 		pixmap_priv = glamor_get_pixmap_private(pixmap);
-		if (pixmap_priv != NULL) {
-			glamor_pixmap_fbo *fbo;
-			fbo = glamor_pixmap_detach_fbo(pixmap_priv);
-			if (fbo)
-				glamor_destroy_fbo(fbo);
-			free(pixmap_priv);
-		}
+		if (pixmap_priv != NULL)
+			glamor_pixmap_destroy_fbo(pixmap_priv);
 	}
 }
 
@@ -315,6 +324,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	    glamor_gl_has_extension("GL_EXT_framebuffer_blit");
 	glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
 					     &glamor_priv->max_fbo_size);
+#ifdef MAX_FBO_SIZE
+	glamor_priv->max_fbo_size = MAX_FBO_SIZE;
+#endif
 
 	glamor_set_debug_level(&glamor_debug_level);
 
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 84a449c..4d68dbe 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -40,11 +40,13 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	ScreenPtr screen = dst->pScreen;
 	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
 	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-	glamor_pixmap_private *src_pixmap_priv;
+	glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 	int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
+	int fbo_x_off, fbo_y_off;
+	int src_fbo_x_off, src_fbo_y_off;
 
 	if (!glamor_priv->has_fbo_blit) {
 		glamor_delayed_fallback(screen,
@@ -52,17 +54,13 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 		return FALSE;
 	}
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
 	if (gc) {
 		if (gc->alu != GXcopy) {
 			glamor_delayed_fallback(screen, "non-copy ALU\n");
 			return FALSE;
 		}
-		if (!glamor_pm_is_solid(dst, gc->planemask)) {
-			glamor_delayed_fallback(screen,
-						"non-solid planemask\n");
-			return FALSE;
-		}
 	}
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
@@ -73,6 +71,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	if (glamor_set_destination_pixmap(dst_pixmap))
 		return FALSE;
 
+	pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
+	pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
 				    src_pixmap_priv->base.fbo->fb);
@@ -80,7 +81,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 				   &dst_y_off);
 	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
 				   &src_y_off);
-	src_y_off += dy;
+	dst_x_off += fbo_x_off;
+	dst_y_off += fbo_y_off;
+	src_y_off += dy + src_fbo_y_off;
+	src_x_off += src_fbo_x_off;
 
 	for (i = 0; i < nbox; i++) {
 		if (glamor_priv->yInverted) {
@@ -154,17 +158,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
 	enum glamor_pixmap_status src_status = GLAMOR_NONE;
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-	int alu = GXcopy;
 
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
-		glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
-		return FALSE;
-	}
-
-	if (!src_pixmap_priv || !src_pixmap_priv->base.gl_fbo) {
+	if (!src_pixmap_priv->base.gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
 		return FALSE;
@@ -177,11 +175,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 #endif
 	}
 
-	if (gc) {
-		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-			return FALSE;
-		alu = gc->alu;
-	}
 
 	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
@@ -191,10 +184,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 
-	if (!glamor_set_alu(dispatch, alu)) {
-		glamor_put_dispatch(glamor_priv);
-		return FALSE;
-	}
 
 	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -239,8 +228,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 	for (i = 0; i < nbox; i++) {
 
-		glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
-					     dst_yscale,
+		glamor_set_normalize_vcoords(dst_pixmap_priv,
+					     dst_xscale, dst_yscale,
 					     box[i].x1 + dst_x_off,
 					     box[i].y1 + dst_y_off,
 					     box[i].x2 + dst_x_off,
@@ -248,7 +237,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 					     glamor_priv->yInverted,
 					     vertices);
 
-		glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
+		glamor_set_normalize_tcoords(src_pixmap_priv,
+					     src_xscale,
 					     src_yscale,
 					     box[i].x1 + dx,
 					     box[i].y1 + dy,
@@ -270,19 +260,18 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	return TRUE;
 }
 
-static Bool 
-_glamor_copy_n_to_n(DrawablePtr src,
-		    DrawablePtr dst,
-		    GCPtr gc,
-		    BoxPtr box,
-		    int nbox,
-		    int dx,
-		    int dy,
-		    Bool reverse,
-		    Bool upsidedown, Pixel bitplane, 
-		    void *closure, Bool fallback)
+static Bool
+__glamor_copy_n_to_n(DrawablePtr src,
+		     DrawablePtr dst,
+		     GCPtr gc,
+		     BoxPtr box,
+		     int nbox,
+		     int dx,
+		     int dy,
+		     Bool reverse,
+		     Bool upsidedown, Pixel bitplane,
+		     void *closure)
 {
-	glamor_access_t dst_access;
 	PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
 	DrawablePtr temp_src = src;
 	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
@@ -296,32 +285,20 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	int overlaped = 0;
 	Bool ret = FALSE;
 
-	if (nbox == 0)
-		return TRUE;
 	dst_pixmap = glamor_get_drawable_pixmap(dst);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 	src_pixmap = glamor_get_drawable_pixmap(src);
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
 	glamor_priv = glamor_get_screen_private(dst->pScreen);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
-		glamor_fallback("dest pixmap %p has no fbo. \n",
-				dst_pixmap);
-		goto fail;
-	}
-
-	if (!src_pixmap_priv) {
-		glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
-		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-	}
-
 	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
 				   &src_y_off);
+
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 
-	if (src_pixmap_priv->base.fbo && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
+	if (src_pixmap_priv->base.fbo
+		&& src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
 		int x_shift = abs(src_x_off - dx - dst_x_off);
 		int y_shift = abs(src_y_off - dy - dst_y_off);
 		for (i = 0; i < nbox; i++) {
@@ -332,6 +309,11 @@ _glamor_copy_n_to_n(DrawablePtr src,
 			}
 		}
 	}
+	DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
+		box[0].x1, box[0].y1,
+		box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
+		dx, dy,
+		src_pixmap, dst_pixmap);
 #ifndef GLAMOR_GLES2
 	if ((overlaped
 	     || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
@@ -345,10 +327,13 @@ _glamor_copy_n_to_n(DrawablePtr src,
 
 	/*  Overlaped indicate the src and dst are the same pixmap. */
 	if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
-			  && ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
+			  && (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
 			      * 4 >
 			      src_pixmap->drawable.width *
-			      src_pixmap->drawable.height))) {
+			      src_pixmap->drawable.height)
+		             || !(glamor_check_fbo_size(glamor_priv,
+					src_pixmap->drawable.width,
+					src_pixmap->drawable.height))))) {
 
 		temp_pixmap = glamor_create_pixmap(screen,
 						   bound.x2 - bound.x1,
@@ -357,9 +342,11 @@ _glamor_copy_n_to_n(DrawablePtr src,
 						   drawable.depth,
 						   overlaped ? 0 :
 						   GLAMOR_CREATE_PIXMAP_CPU);
+		assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
+		assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
 		if (!temp_pixmap)
-			goto fail;
-		glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
+			goto done;
+		glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
 		temp_src = &temp_pixmap->drawable;
 
 		if (overlaped)
@@ -371,7 +358,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 			fbCopyNtoN(src, temp_src, gc, box, nbox,
 				   temp_dx + bound.x1, temp_dy + bound.y1,
 				   reverse, upsidedown, bitplane, closure);
-		glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
+		glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
 		temp_dx = -bound.x1;
 		temp_dy = -bound.y1;
 	} else {
@@ -383,13 +370,221 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	if (glamor_copy_n_to_n_textured
 	    (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
 		ret = TRUE;
-		goto done;
+	}
+done:
+	if (temp_src != src)
+		glamor_destroy_pixmap(temp_pixmap);
+	return ret;
+}
+
+static Bool
+_glamor_copy_n_to_n(DrawablePtr src,
+		    DrawablePtr dst,
+		    GCPtr gc,
+		    BoxPtr box,
+		    int nbox,
+		    int dx,
+		    int dy,
+		    Bool reverse,
+		    Bool upsidedown, Pixel bitplane,
+		    void *closure, Bool fallback)
+{
+	glamor_access_t dst_access;
+	PixmapPtr dst_pixmap, src_pixmap;
+	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	BoxPtr extent;
+	RegionRec region;
+	ScreenPtr screen;
+	int src_x_off, src_y_off, dst_x_off, dst_y_off;
+	Bool ret = FALSE;
+	int ok = TRUE;
+	int force_clip = 0;
+
+	if (nbox == 0)
+		return TRUE;
+	dst_pixmap = glamor_get_drawable_pixmap(dst);
+	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+	src_pixmap = glamor_get_drawable_pixmap(src);
+	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	screen = dst_pixmap->drawable.pScreen;
+
+	glamor_priv = glamor_get_screen_private(dst->pScreen);
+
+	DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
+		box[0].x1, box[0].y1,
+		box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
+		dx, dy,
+		src_pixmap, dst_pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
+		goto fall_back;
+
+	if (gc) {
+		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+			goto fail;
+		dispatch = glamor_get_dispatch(glamor_priv);
+		if (!glamor_set_alu(dispatch, gc->alu)) {
+			glamor_put_dispatch(glamor_priv);
+			goto fail;
+		}
+		glamor_put_dispatch(glamor_priv);
+	}
+
+	if (!src_pixmap_priv) {
+		glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
+		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	}
+
+	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+				   &src_y_off);
+	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
+				   &dst_y_off);
+
+	RegionInitBoxes(&region, box, nbox);
+	extent = RegionExtents(&region);
+
+	if (!glamor_check_fbo_size(glamor_priv,
+		extent->x2 - extent->x1, extent->y2 - extent->y1)
+	   && (src_pixmap_priv->type == GLAMOR_MEMORY
+		|| (src_pixmap_priv == dst_pixmap_priv))) {
+		force_clip = 1;
 	}
 
+	if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+	    || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+			glamor_pixmap_clipped_regions *clipped_dst_regions;
+			int n_dst_region, i, j;
+			PixmapPtr temp_source_pixmap;
+			glamor_pixmap_private *temp_source_priv = NULL;
+			int temp_dx = 0, temp_dy = 0;
+
+			RegionTranslate(&region, dst_x_off, dst_y_off);
+			if (!force_clip)
+				clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
+										     &region, &n_dst_region, 0);
+			else
+				clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
+										         &region, &n_dst_region,
+											 glamor_priv->max_fbo_size,
+											 glamor_priv->max_fbo_size);
+			for(i = 0; i < n_dst_region; i++)
+			{
+				int n_src_region;
+				glamor_pixmap_clipped_regions *clipped_src_regions;
+				BoxPtr current_boxes;
+				int n_current_boxes;
+
+				SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
+
+				temp_source_pixmap = NULL;
+				if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+					RegionTranslate(clipped_dst_regions[i].region,
+							-dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy);
+					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
+											     clipped_dst_regions[i].region,
+											     &n_src_region, 0);
+					DEBUGF("Source is large pixmap.\n");
+					for (j = 0; j < n_src_region; j++)
+					{
+						if (src_pixmap_priv != dst_pixmap_priv)
+							SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
+						else if (src_pixmap_priv == dst_pixmap_priv &&
+						    clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) {
+							/* source and the dest are the same, but need different block_idx.
+							 * we create a empty pixmap and fill the required source fbo and box to
+							 * it. It's a little hacky, but avoid extra copy. */
+							temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0,
+												  src->depth, 0);
+							if (!temp_source_pixmap)
+								goto fail;
+							src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
+										      src_pixmap->drawable.width,
+										      src_pixmap->drawable.height,
+										      0, 0, src_pixmap->devKind, NULL);
+							temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap);
+							*temp_source_priv = *src_pixmap_priv;
+							temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx];
+							temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx];
+							/* XXX need revisit here. */
+							temp_dx = dx/* - src_x_off*/;
+							temp_dy = dy/* - src_y_off*/;
+						}
+						assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv
+							&& (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx)));
+
+						RegionTranslate(clipped_src_regions[j].region,
+								-src_x_off - dx,
+								-src_y_off - dy);
+						current_boxes = RegionRects(clipped_src_regions[j].region);
+						n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
+						DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
+							clipped_dst_regions[i].block_idx,
+							clipped_src_regions[j].block_idx);
+						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
+							current_boxes[0].x1, current_boxes[0].y1,
+							current_boxes[0].x2, current_boxes[0].y2,
+							dx, dy, src_pixmap, dst_pixmap);
+						if (!temp_source_pixmap)
+							ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
+										  n_current_boxes, dx, dy, reverse,
+										  upsidedown, bitplane, closure);
+						else {
+							ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, dst, gc, current_boxes,
+										  n_current_boxes, temp_dx, temp_dy, reverse,
+										  upsidedown, bitplane, closure);
+							temp_source_priv->type = GLAMOR_MEMORY;
+							temp_source_priv->base.fbo = NULL;
+							glamor_destroy_pixmap(temp_source_pixmap);
+							temp_source_pixmap = NULL;
+						}
+
+						RegionDestroy(clipped_src_regions[j].region);
+						if (!ok) {
+							assert(0);
+							goto fail;
+						}
+					}
+					free(clipped_src_regions);
+				} else {
+					RegionTranslate(clipped_dst_regions[i].region,
+							- dst_x_off,
+							- dst_y_off);
+					current_boxes = RegionRects(clipped_dst_regions[i].region);
+					n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
+
+						DEBUGF("dest pixmap fbo idx %d \n",
+							clipped_dst_regions[i].block_idx);
+						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
+							current_boxes[0].x1, current_boxes[0].y1,
+							current_boxes[0].x2, current_boxes[0].y2,
+							dx, dy, src_pixmap, dst_pixmap);
+
+					ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
+								  n_current_boxes, dx, dy, reverse,
+								  upsidedown, bitplane, closure);
+
+				}
+				RegionDestroy(clipped_dst_regions[i].region);
+			}
+		free(clipped_dst_regions);
+		RegionUninit(&region);
+	} else {
+		ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
+					  reverse, upsidedown, bitplane,
+					  closure);
+	}
 
-      fail:
-	
-	if (!fallback 
+fail:
+	dispatch = glamor_get_dispatch(glamor_priv);
+	glamor_set_alu(dispatch, GXcopy);
+	glamor_put_dispatch(glamor_priv);
+
+	if (ok)
+		return TRUE;
+fall_back:
+	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(src)
 	    && glamor_ddx_fallback_check_pixmap(dst))
 		goto done;
@@ -428,8 +623,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
       done:
 	glamor_clear_delayed_fallbacks(src->pScreen);
 	glamor_clear_delayed_fallbacks(dst->pScreen);
-	if (temp_src != src)
-		glamor_destroy_pixmap(temp_pixmap);
 	return ret;
 }
 
@@ -455,10 +648,10 @@ glamor_copy_n_to_n(DrawablePtr src,
 		   int dx,
 		   int dy,
 		   Bool reverse,
-		   Bool upsidedown, Pixel bitplane, 
+		   Bool upsidedown, Pixel bitplane,
 		   void *closure)
 {
-	_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, 
+	_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
 			    dy, reverse, upsidedown, bitplane, closure, TRUE);
 }
 
@@ -471,10 +664,10 @@ glamor_copy_n_to_n_nf(DrawablePtr src,
 		   int dx,
 		   int dy,
 		   Bool reverse,
-		   Bool upsidedown, Pixel bitplane, 
+		   Bool upsidedown, Pixel bitplane,
 		   void *closure)
 {
-	return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, 
+	return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
 				    dy, reverse, upsidedown, bitplane, closure, FALSE);
 }
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 5337149..1ab7686 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -175,7 +175,8 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 
 	if (fbo->fb == 0 || n_format == -1
 	   || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
-		fbo->glamor_priv->tick ++;
+		fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
+		glamor_fbo_expire(fbo->glamor_priv);
 		glamor_purge_fbo(fbo);
 		return;
 	}
@@ -404,6 +405,92 @@ no_tex:
 	return fbo;
 }
 
+static glamor_pixmap_fbo *
+_glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+			 int w, int h, GLenum format, int flag,
+			 int block_w, int block_h,
+			 glamor_pixmap_private *pixmap_priv,
+			 int has_fbo)
+{
+	int block_wcnt;
+	int block_hcnt;
+	glamor_pixmap_fbo **fbo_array;
+	BoxPtr box_array;
+	int i,j;
+	glamor_pixmap_private_large_t *priv;
+
+	priv = &pixmap_priv->large;
+
+	block_wcnt = (w + block_w - 1) / block_w;
+	block_hcnt = (h + block_h - 1) / block_h;
+
+	box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0]));
+	if (box_array == NULL)
+		return NULL;
+
+	fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo*));
+	if (fbo_array == NULL) {
+		free(box_array);
+		return FALSE;
+	}
+	for(i = 0; i < block_hcnt; i++)
+	{
+		int block_y1, block_y2;
+		int fbo_w, fbo_h;
+
+		block_y1 = i * block_h;
+		block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h);
+		fbo_h = block_y2 - block_y1;
+
+		for (j = 0; j < block_wcnt; j++)
+		{
+			box_array[i * block_wcnt + j].x1 = j * block_w;
+			box_array[i * block_wcnt + j].y1 = block_y1;
+			box_array[i * block_wcnt + j].x2 = (j + 1) * block_w > w ? w : (j + 1) * block_w;
+			box_array[i * block_wcnt + j].y2 = block_y2;
+			fbo_w = box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + j].x1;
+			if (!has_fbo)
+				fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
+										  fbo_w, fbo_h, format,
+										  GLAMOR_CREATE_PIXMAP_FIXUP);
+			else
+				fbo_array[i * block_wcnt + j] = priv->base.fbo;
+			if (fbo_array[i * block_wcnt + j] == NULL)
+				goto cleanup;
+		}
+	}
+
+	priv->box = box_array[0];
+	priv->box_array = box_array;
+	priv->fbo_array = fbo_array;
+	priv->block_wcnt = block_wcnt;
+	priv->block_hcnt = block_hcnt;
+	return fbo_array[0];
+
+cleanup:
+	for(i = 0; i < block_wcnt * block_hcnt; i++)
+		if ((fbo_array)[i])
+			glamor_destroy_fbo((fbo_array)[i]);
+	free(box_array);
+	free(fbo_array);
+	return NULL;
+}
+
+
+/* Create a fbo array to cover the w*h region, by using block_w*block_h
+ * block.*/
+glamor_pixmap_fbo *
+glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+			int w, int h, GLenum format, int flag,
+			int block_w, int block_h,
+			glamor_pixmap_private *pixmap_priv)
+{
+	pixmap_priv->large.block_w = block_w;
+	pixmap_priv->large.block_h = block_h;
+	return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
+					block_w, block_h, pixmap_priv, 0);
+}
+
 glamor_pixmap_fbo *
 glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
 {
@@ -428,23 +515,13 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (pixmap_priv == NULL) {
-		glamor_screen_private *glamor_priv;
-		glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-		pixmap_priv = calloc(1, sizeof(*pixmap_priv));
-		dixSetPrivate(&pixmap->devPrivates,
-			      glamor_pixmap_private_key, pixmap_priv);
-		pixmap_priv->base.pixmap = pixmap;
-		pixmap_priv->base.glamor_priv = glamor_priv;
-		pixmap_priv->type = GLAMOR_MEMORY;
-	}
-
 	if (pixmap_priv->base.fbo)
 		return;
 
 	pixmap_priv->base.fbo = fbo;
 
 	switch (pixmap_priv->type) {
+	case GLAMOR_TEXTURE_LARGE:
 	case GLAMOR_TEXTURE_ONLY:
 	case GLAMOR_TEXTURE_DRM:
 		pixmap_priv->base.gl_fbo = 1;
@@ -462,6 +539,23 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 	}
 }
 
+void
+glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
+{
+	glamor_pixmap_fbo *fbo;
+	if (priv->type == GLAMOR_TEXTURE_LARGE) {
+		int i;
+		glamor_pixmap_private_large_t *large = &priv->large;
+		for(i = 0; i < large->block_wcnt * large->block_hcnt; i++)
+			glamor_destroy_fbo(large->fbo_array[i]);
+		free(large->fbo_array);
+	} else {
+		fbo = glamor_pixmap_detach_fbo(priv);
+		if (fbo)
+			glamor_destroy_fbo(fbo);
+		free(priv);
+	}
+}
 
 Bool
 glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
@@ -472,7 +566,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
+	if (pixmap_priv->base.fbo == NULL) {
 
 		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 					pixmap->drawable.height,
@@ -492,7 +586,6 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 			glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
 	}
 
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index b63756d..5b84dd6 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -180,10 +180,9 @@ glamor_fini_solid_shader(ScreenPtr screen)
 	glamor_put_dispatch(glamor_priv);
 }
 
-Bool
-glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	     unsigned char alu, unsigned long planemask,
-	     unsigned long fg_pixel)
+static void
+_glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+	      float *color)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	glamor_screen_private *glamor_priv =
@@ -195,14 +194,49 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	int x2 = x + width;
 	int y1 = y;
 	int y2 = y + height;
-	GLfloat color[4];
 	float vertices[8];
 	GLfloat xscale, yscale;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-		glamor_fallback("dest %p has no fbo.\n", pixmap);
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	dispatch->glUseProgram(glamor_priv->solid_prog);
+
+	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
+			       1, color);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+
+	glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
+				     x1, y1,
+				     x2, y2,
+				     glamor_priv->yInverted, vertices);
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+}
+
+Bool
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+	     unsigned char alu, unsigned long planemask,
+	     unsigned long fg_pixel)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_pixmap_private *pixmap_priv;
+	glamor_gl_dispatch *dispatch;
+	GLfloat color[4];
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return FALSE;
-	}
 
 	if (!glamor_set_planemask(pixmap, planemask)) {
 		glamor_fallback
@@ -216,8 +250,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 				   &color[2],
 				   &color[3], format_for_pixmap(pixmap));
 
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (!glamor_set_alu(dispatch, alu)) {
 		if (alu == GXclear)
@@ -228,23 +260,47 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 			return FALSE;
 		}
 	}
-	dispatch->glUseProgram(glamor_priv->solid_prog);
 
-	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
-			       1, color);
+	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		RegionRec region;
+		BoxRec box;
+		int n_region;
+		glamor_pixmap_clipped_regions *clipped_regions;
+		int i,j;
 
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+		box.x1 = x;
+		box.y1 = y;
+		box.x2 = x + width;
+		box.y2 = y + height;
+		RegionInitBoxes(&region, &box, 1);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		for(i = 0; i < n_region; i++)
+		{
+			BoxPtr boxes;
+			int nbox;
+			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+			boxes = RegionRects(clipped_regions[i].region);
+			nbox = RegionNumRects(clipped_regions[i].region);
+			for(j = 0; j < nbox; j++)
+			{
+				_glamor_solid(pixmap, boxes[j].x1, boxes[j].y1,
+					      boxes[j].x2 - boxes[j].x1,
+					      boxes[j].y2 - boxes[j].y1, color);
+			}
+			RegionDestroy(clipped_regions[i].region);
+		}
+		free(clipped_regions);
+		RegionUninit(&region);
+	} else
+		_glamor_solid(pixmap,
+			      x,
+			      y,
+			      width, height,
+			      color);
 
-	glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, x1, y1, x2, y2,
-				     glamor_priv->yInverted, vertices);
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_put_dispatch(glamor_priv);
+
 	return TRUE;
 }
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
new file mode 100644
index 0000000..e8c1030
--- /dev/null
+++ b/glamor/glamor_largepixmap.c
@@ -0,0 +1,412 @@
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+
+/**
+ * Clip the boxes regards to each pixmap's block array.
+ *
+ * Should translate the region to relative coords to the pixmap,
+ * start at (0,0).
+ */
+#if 0
+//#define DEBUGF(str, ...)  do {} while(0)
+#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
+//#define DEBUGRegionPrint(x) do {} while (0)
+#define DEBUGRegionPrint RegionPrint
+#endif
+
+static glamor_pixmap_clipped_regions *
+__glamor_compute_clipped_regions(int block_w,
+			       int block_h,
+			       int block_stride,
+			       int x, int y,
+			       int w, int h,
+                               RegionPtr region,
+                               int *n_region,
+                               int repeat)
+{
+	glamor_pixmap_clipped_regions * clipped_regions;
+	BoxPtr extent;
+	int start_x, start_y, end_x, end_y;
+	int start_block_x, start_block_y;
+	int end_block_x, end_block_y;
+	int i, j;
+	int width, height;
+	RegionRec temp_region;
+	RegionPtr current_region;
+	int block_idx;
+	int k = 0;
+	int temp_block_idx;
+
+	extent = RegionExtents(region);
+	start_x = MAX(x, extent->x1);
+	start_y = MAX(y, extent->y1);
+	end_x = MIN(x + w, extent->x2);
+	end_y = MIN(y + h, extent->y2);
+
+	DEBUGF("start compute clipped regions:\n");
+	DEBUGF("block w %d h %d  x %d y %d w %d h %d, block_stride %d \n",
+		block_w, block_h, x, y, w, h, block_stride);
+	DEBUGRegionPrint(region);
+
+	DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, end_x, end_y);
+
+	if (start_x >= end_x || start_y >= end_y) {
+		*n_region = 0;
+		return NULL;
+	}
+
+	width = end_x - start_x;
+	height = end_y - start_y;
+	start_block_x = (start_x  - x)/ block_w;
+	start_block_y = (start_y - y)/ block_h;
+	end_block_x = (end_x - x)/ block_w;
+	end_block_y = (end_y - y)/ block_h;
+
+	clipped_regions = calloc((end_block_x - start_block_x + 1)
+				 * (end_block_y - start_block_y + 1),
+				 sizeof(*clipped_regions));
+
+	block_idx = (start_block_y - 1) * block_stride;
+
+	DEBUGF("startx %d starty %d endx %d endy %d \n",
+		start_x, start_y, end_x, end_y);
+	DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x);
+	DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y);
+
+	for(j = start_block_y; j <= end_block_y; j++)
+	{
+		block_idx += block_stride;
+		temp_block_idx = block_idx + start_block_x;
+		for(i = start_block_x;
+		    i <= end_block_x; i++, temp_block_idx++)
+		{
+			BoxRec temp_box;
+			temp_box.x1 = x + i * block_w;
+			temp_box.y1 = y + j * block_h;
+			temp_box.x2 = MIN(temp_box.x1 + block_w, end_x);
+			temp_box.y2 = MIN(temp_box.y1 + block_h, end_y);
+			RegionInitBoxes(&temp_region, &temp_box, 1);
+			DEBUGF("block idx %d \n",temp_block_idx);
+			DEBUGRegionPrint(&temp_region);
+			current_region = RegionCreate(NULL, 4);
+			RegionIntersect(current_region, &temp_region, region);
+			DEBUGF("i %d j %d  region: \n",i ,j);
+			DEBUGRegionPrint(current_region);
+			if (RegionNumRects(current_region)) {
+				clipped_regions[k].region = current_region;
+				clipped_regions[k].block_idx = temp_block_idx;
+				k++;
+			} else
+				RegionDestroy(current_region);
+			RegionUninit(&temp_region);
+		}
+	}
+
+	*n_region = k;
+	return clipped_regions;
+}
+
+/**
+ * Do a two round clipping,
+ * first is to clip the region regard to current pixmap's
+ * block array. Then for each clipped region, do a inner
+ * block clipping. This is to make sure the final result
+ * will be shapped by inner_block_w and inner_block_h, and
+ * the final region also will not cross the pixmap's block
+ * boundary.
+ *
+ * This is mainly used by transformation support when do
+ * compositing.
+ */
+
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+				   RegionPtr region,
+				   int *n_region,
+				   int inner_block_w, int inner_block_h)
+{
+	glamor_pixmap_clipped_regions * clipped_regions, *inner_regions, *result_regions;
+	int i, j, x, y, k, inner_n_regions;
+	int width, height;
+	glamor_pixmap_private_large_t *priv;
+	priv = &pixmap_priv->large;
+
+	DEBUGF("ext called \n");
+
+	if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+		clipped_regions = calloc(1, sizeof(*clipped_regions));
+		if (clipped_regions == NULL) {
+			*n_region = 0;
+			return NULL;
+		}
+		clipped_regions[0].region = RegionCreate(NULL, 1);
+		clipped_regions[0].block_idx = 0;
+		RegionCopy(clipped_regions[0].region, region);
+		*n_region = 1;
+		priv->block_w = priv->base.pixmap->drawable.width;
+		priv->block_h = priv->base.pixmap->drawable.height;
+		priv->box_array = &priv->box;
+		priv->box.x1 = priv->box.y1 = 0;
+		priv->box.x2 = priv->block_w;
+		priv->box.y2 = priv->block_h;
+	} else {
+		clipped_regions =  __glamor_compute_clipped_regions(priv->block_w,
+					priv->block_h,
+					priv->block_wcnt,
+					0, 0,
+					priv->base.pixmap->drawable.width,
+					priv->base.pixmap->drawable.height,
+					region, n_region, 0
+					);
+
+		if (clipped_regions == NULL) {
+			*n_region = 0;
+			return NULL;
+		}
+	}
+	if (inner_block_w >= priv->block_w
+	    && inner_block_h >= priv->block_h)
+		return clipped_regions;
+	result_regions = calloc(*n_region
+				* ((priv->block_w + inner_block_w - 1)/inner_block_w)
+				* ((priv->block_h + inner_block_h - 1)/ inner_block_h),
+				sizeof(*result_regions));
+	k = 0;
+	for(i = 0; i < *n_region; i++)
+	{
+		x = priv->box_array[clipped_regions[i].block_idx].x1;
+		y = priv->box_array[clipped_regions[i].block_idx].y1;
+		width = priv->box_array[clipped_regions[i].block_idx].x2 - x;
+		height = priv->box_array[clipped_regions[i].block_idx].y2 - y;
+		inner_regions = __glamor_compute_clipped_regions(inner_block_w,
+					inner_block_h,
+					0, x, y,
+					width,
+					height,
+					clipped_regions[i].region,
+					&inner_n_regions, 0);
+		for(j = 0; j < inner_n_regions; j++)
+		{
+			result_regions[k].region = inner_regions[j].region;
+			result_regions[k].block_idx = clipped_regions[i].block_idx;
+			k++;
+		}
+		free(inner_regions);
+	}
+	*n_region = k;
+	free(clipped_regions);
+	return result_regions;
+}
+
+/**
+ * Clip the boxes regards to each pixmap's block array.
+ *
+ * Should translate the region to relative coords to the pixmap,
+ * start at (0,0).
+ *
+ * @is_transform: if it is set, it has a transform matrix.
+ *
+ * XXX Not support repeatPad currently.
+ */
+
+static glamor_pixmap_clipped_regions *
+_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
+				RegionPtr region, int *n_region,
+				int repeat_type, int is_transform)
+{
+	glamor_pixmap_clipped_regions * clipped_regions;
+	BoxPtr extent;
+	int i, j;
+	int width, height;
+	RegionPtr current_region;
+	int pixmap_width, pixmap_height;
+	int m;
+	BoxRec repeat_box;
+	RegionRec repeat_region;
+	int right_shift = 0;
+	int down_shift = 0;
+	int x_center_shift = 0, y_center_shift = 0;
+	glamor_pixmap_private_large_t *priv;
+	priv = &pixmap_priv->large;
+
+	DEBUGRegionPrint(region);
+	if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+		clipped_regions = calloc(1, sizeof(*clipped_regions));
+		clipped_regions[0].region = RegionCreate(NULL, 1);
+		clipped_regions[0].block_idx = 0;
+		RegionCopy(clipped_regions[0].region, region);
+		*n_region = 1;
+		return clipped_regions;
+	}
+
+	pixmap_width = priv->base.pixmap->drawable.width;
+	pixmap_height = priv->base.pixmap->drawable.height;
+	if (repeat_type == 0) {
+		clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
+							priv->block_h,
+							priv->block_wcnt,
+							0, 0,
+							priv->base.pixmap->drawable.width,
+							priv->base.pixmap->drawable.height,
+							region, n_region, 0
+							);
+		return clipped_regions;
+	} else if (repeat_type != RepeatNormal) {
+		*n_region = 0;
+		return NULL;
+	}
+	extent = RegionExtents(region);
+
+	x_center_shift = extent->x1 / pixmap_width;
+	if (x_center_shift < 0)
+		x_center_shift--;
+	if (abs(x_center_shift) & 1)
+		x_center_shift++;
+	y_center_shift = extent->y1 / pixmap_height;
+	if (y_center_shift < 0)
+		y_center_shift--;
+	if (abs(y_center_shift) & 1)
+		y_center_shift++;
+
+	if (extent->x1 < 0)
+		right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width );
+	if (extent->y1 < 0)
+		down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height );
+
+	if (right_shift != 0 || down_shift != 0) {
+		if (repeat_type == RepeatReflect) {
+			right_shift = (right_shift + 1)&~1;
+			down_shift = (down_shift + 1)&~1;
+		}
+		RegionTranslate(region, right_shift * pixmap_width, down_shift * pixmap_height);
+	}
+
+	extent = RegionExtents(region);
+	width = extent->x2 - extent->x1;
+	height = extent->y2 - extent->y1;
+	/* Tile a large pixmap to another large pixmap.
+	 * We can't use the target large pixmap as the
+	 * loop variable, instead we need to loop for all
+	 * the blocks in the tile pixmap.
+	 *
+	 * simulate repeat each single block to cover the
+	 * target's blocks. Two special case:
+	 * a block_wcnt == 1 or block_hcnt ==1, then we
+	 * only need to loop one direction as the other
+	 * direction is fully included in the first block.
+	 *
+	 * For the other cases, just need to start
+	 * from a proper shiftx/shifty, and then increase
+	 * y by tile_height each time to walk trhough the
+	 * target block and then walk trhough the target
+	 * at x direction by increate tile_width each time.
+	 *
+	 * This way, we can consolidate all the sub blocks
+	 * of the target boxes into one tile source's block.
+	 *
+	 * */
+	m = 0;
+	clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt,
+				 sizeof(*clipped_regions));
+	if (clipped_regions == NULL) {
+		*n_region = 0;
+		return NULL;
+	}
+	if (right_shift != 0 || down_shift != 0) {
+		DEBUGF("region to be repeated shifted \n");
+		DEBUGRegionPrint(region);
+	}
+	DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height);
+	DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, extent->x2, extent->y2);
+	for(j = 0; j < priv->block_hcnt; j++)
+	{
+		for(i = 0; i < priv->block_wcnt; i++)
+		{
+			int dx = pixmap_width;
+			int dy = pixmap_height;
+			int idx;
+			int shift_x;
+			int shift_y;
+			int saved_y1, saved_y2;
+			int x_idx = 0, y_idx = 0;
+			RegionRec temp_region;
+
+			shift_x = (extent->x1 / pixmap_width) * pixmap_width;
+			shift_y = (extent->y1 / pixmap_height) * pixmap_height;
+			idx = j * priv->block_wcnt + i;
+			if (repeat_type == RepeatReflect) {
+				x_idx = (extent->x1 / pixmap_width);
+				y_idx = (extent->y1 / pixmap_height);
+			}
+
+			/* Construct a rect to clip the target region. */
+			repeat_box.x1 = shift_x + priv->box_array[idx].x1;
+			repeat_box.y1 = shift_y + priv->box_array[idx].y1;
+			if (priv->block_wcnt == 1)
+				repeat_box.x2 = extent->x2;
+			else
+				repeat_box.x2 = shift_x + priv->box_array[idx].x2;
+			if (priv->block_hcnt == 1)
+				repeat_box.y2 = extent->y2;
+			else
+				repeat_box.y2 = shift_y + priv->box_array[idx].y2;
+
+			current_region = RegionCreate(NULL, 4);
+			RegionInit(&temp_region, NULL, 4);
+			DEBUGF("init repeat box %d %d %d %d \n",
+				repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
+
+			if (repeat_type == RepeatNormal) {
+				saved_y1 = repeat_box.y1;
+				saved_y2 = repeat_box.y2;
+				for(; repeat_box.x1 < extent->x2;
+				      repeat_box.x1 += dx, repeat_box.x2 += dx)
+				{
+					repeat_box.y1 = saved_y1;
+					repeat_box.y2 = saved_y2;
+					for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
+					     repeat_box.y1 < extent->y2;
+					     repeat_box.y1 += dy, repeat_box.y2 += dy)
+					{
+
+						RegionInitBoxes(&repeat_region, &repeat_box, 1);
+						DEBUGF("Start to clip repeat region: \n");
+						DEBUGRegionPrint(&repeat_region);
+						RegionIntersect(&temp_region, &repeat_region, region);
+						DEBUGF("clip result:\n");
+						DEBUGRegionPrint(&temp_region);
+						RegionAppend(current_region, &temp_region);
+						RegionUninit(&repeat_region);
+					}
+				}
+			}
+			DEBUGF("dx %d dy %d \n", dx, dy);
+
+			if (RegionNumRects(current_region)) {
+
+				if ((right_shift != 0 || down_shift != 0))
+					RegionTranslate(current_region,
+							-right_shift * pixmap_width,
+							-down_shift * pixmap_height);
+				clipped_regions[m].region = current_region;
+				clipped_regions[m].block_idx = idx;
+				m++;
+			} else
+				RegionDestroy(current_region);
+			RegionUninit(&temp_region);
+		}
+	}
+
+	if (right_shift != 0 || down_shift != 0)
+		RegionTranslate(region, -right_shift * pixmap_width, -down_shift * pixmap_height);
+	*n_region = m;
+
+	return clipped_regions;
+}
+
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *n_region, int repeat_type)
+{
+	return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
+}
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index fa05bed..ca38a2b 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -83,9 +83,11 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int w
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
+	int w,h;
+
+	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
 	glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
-					  pixmap_priv->base.pixmap->drawable.width,
-					  pixmap_priv->base.pixmap->drawable.height);
+					  w, h);
 }
 
 int
@@ -489,16 +491,23 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum ty
 	}
 
 ready_to_upload:
+
 	/* Try fast path firstly, upload the pixmap to the texture attached
 	 * to the fbo directly. */
 	if (no_alpha == 0
 	    && revert == REVERT_NONE
 	    && swap_rb == SWAP_NONE_UPLOADING
 	    && !need_flip) {
+		int fbo_x_off, fbo_y_off;
 		assert(pixmap_priv->base.fbo->tex);
+		pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
+		assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
+		assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
+		assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
 		__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
 						  format, type,
-						  x, y, w, h,
+						  x + fbo_x_off, y + fbo_y_off, w, h,
 						  bits, pbo);
 		return TRUE;
 	}
@@ -515,7 +524,6 @@ ready_to_upload:
 				     x + w, y + h,
 				     glamor_priv->yInverted,
 				     vertices);
-
 	/* Slow path, we need to flip y or wire alpha to 1. */
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -586,6 +594,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
+	if (pixmap_priv->base.gl_fbo)
+		return 0;
+
 	if (pixmap_priv->base.fbo
 	     && (pixmap_priv->base.fbo->width < pixmap->drawable.width
            || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
@@ -605,8 +616,10 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 		flag = GLAMOR_CREATE_FBO_NO_FBO;
 	}
 
-	if ((flag == 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
-	    || (flag != 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
+	if ((flag == GLAMOR_CREATE_FBO_NO_FBO
+		&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
+	    || (flag == 0
+		&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
 		return 0;
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -614,35 +627,63 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	else
 		iformat = format;
 
-	if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
-
-		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
-					pixmap->drawable.height,
-					iformat,
-					flag);
-		if (fbo == NULL) {
-			glamor_fallback
-			    ("upload failed, depth %d x %d @depth %d \n",
-			     pixmap->drawable.width, pixmap->drawable.height,
-			     pixmap->drawable.depth);
-			return -1;
-		}
+	if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
+		return -1;
 
-		glamor_pixmap_attach_fbo(pixmap, fbo);
-	} else {
-		/* We do have a fbo, but it may lack of fb or tex. */
-		glamor_pixmap_ensure_fbo(pixmap, iformat, flag);
+	return 0;
+}
+
+/*
+ * upload sub region to a large region.
+ * */
+static void
+glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
+		int src_stride, int bpp,
+		int x, int y, int w, int h)
+{
+	int j;
+	int byte_per_pixel;
+
+	byte_per_pixel = bpp / 8;
+	src_bits += y * src_stride + (x * byte_per_pixel);
+
+	for(j = y; j < y + h; j++)
+	{
+		memcpy(dst_bits, src_bits, w * byte_per_pixel);
+		src_bits += src_stride;
+		dst_bits += dst_stride;
 	}
+}
+/*
+ * download sub region from a large region.
+ */
+static void
+glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits,
+		int src_stride, int bpp,
+		int x, int y, int w, int h)
+{
+	int j;
+	int byte_per_pixel;
 
-	return 0;
+	byte_per_pixel = bpp / 8;
+	dst_bits += y * dst_stride + x * byte_per_pixel;
+
+	for(j = y; j < y + h; j++)
+	{
+		memcpy(dst_bits, src_bits, w * byte_per_pixel);
+		src_bits += src_stride;
+		dst_bits += dst_stride;
+	}
 }
 
+
 Bool
 glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
 				    int stride, void *bits, int pbo)
 {
 	GLenum format, type;
 	int no_alpha, revert, swap_rb;
+	glamor_pixmap_private *pixmap_priv;
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
@@ -657,7 +698,77 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
 		return FALSE;
 
-	return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+		RegionRec region;
+		BoxRec box;
+		int n_region;
+		glamor_pixmap_clipped_regions *clipped_regions;
+		void *sub_bits;
+		int i,j;
+
+		sub_bits = malloc(h * stride);
+		if (sub_bits == NULL)
+			return FALSE;
+		box.x1 = x;
+		box.y1 = y;
+		box.x2 = x + w;
+		box.y2 = y + h;
+		RegionInitBoxes(&region, &box, 1);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
+		for(i = 0; i < n_region; i++)
+		{
+			BoxPtr boxes;
+			int nbox;
+			int temp_stride;
+			void *temp_bits;
+
+			assert(pbo == 0);
+
+			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+			boxes = RegionRects(clipped_regions[i].region);
+			nbox = RegionNumRects(clipped_regions[i].region);
+			DEBUGF("split to %d boxes\n", nbox);
+			for(j = 0; j < nbox; j++)
+			{
+				temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
+							    pixmap->drawable.depth);
+
+				if (boxes[j].x1 == x && temp_stride == stride) {
+					temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
+				} else {
+					temp_bits = sub_bits;
+					glamor_put_bits(temp_bits, temp_stride, bits, stride,
+							pixmap->drawable.bitsPerPixel,
+							boxes[j].x1 - x, boxes[j].y1 - y,
+							boxes[j].x2 - boxes[j].x1,
+							boxes[j].y2 - boxes[j].y1);
+				}
+				DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
+					boxes[j].x1 - x, boxes[j].y1 - y,
+					boxes[j].x2 - boxes[j].x1,
+					boxes[j].y2 - boxes[j].y1, temp_stride);
+				if (_glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha,
+									  revert, swap_rb, boxes[j].x1, boxes[j].y1,
+									  boxes[j].x2 - boxes[j].x1,
+									  boxes[j].y2 - boxes[j].y1,
+									  temp_stride, temp_bits, pbo) == FALSE) {
+					RegionUninit(&region);
+					free(sub_bits);
+					assert(0);
+					return FALSE;
+				}
+			}
+			RegionDestroy(clipped_regions[i].region);
+		}
+		free(sub_bits);
+		free(clipped_regions);
+		RegionUninit(&region);
+		return TRUE;
+	} else
+		return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
 						     x, y, w, h, stride, bits, pbo);
 }
 
@@ -671,8 +782,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (pixmap_priv
-	    && (pixmap_priv->base.fbo)
+	if ((pixmap_priv->base.fbo)
 	    && (pixmap_priv->base.fbo->pbo_valid)) {
 		data = NULL;
 		pbo = pixmap_priv->base.fbo->pbo;
@@ -737,7 +847,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 	temp_xscale = 1.0 / w;
 	temp_yscale = 1.0 / h;
 
-	glamor_set_normalize_vcoords((glamor_pixmap_private *)NULL, temp_xscale,
+	glamor_set_normalize_vcoords((struct glamor_pixmap_private*)NULL,temp_xscale,
 				     temp_yscale,
 				     0, 0,
 				     w, h,
@@ -793,13 +903,15 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
  * The pixmap must have a valid FBO, otherwise return a NULL.
  * */
 
-void *
-glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
-				  int stride, void *bits, int pbo, glamor_access_t access)
+static void *
+_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
+				   GLenum type, int no_alpha,
+				   int revert, int swap_rb,
+				   int x, int y, int w, int h,
+				   int stride, void *bits, int pbo, glamor_access_t access)
 {
 	glamor_pixmap_private *pixmap_priv;
-	GLenum format, type, gl_access = 0, gl_usage = 0;
-	int no_alpha, revert, swap_rb;
+	GLenum gl_access = 0, gl_usage = 0;
 	void *data, *read;
 	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
@@ -808,6 +920,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	glamor_pixmap_fbo *temp_fbo = NULL;
 	int need_post_conversion = 0;
 	int need_free_data = 0;
+	int fbo_x_off, fbo_y_off;
 
 	data = bits;
 	screen = pixmap->drawable.pScreen;
@@ -831,18 +944,6 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		assert(0);
 	}
 
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type,
-						   &no_alpha,
-						   &revert,
-						   &swap_rb, 0)) {
-		ErrorF("Unknown pixmap depth %d.\n",
-		       pixmap->drawable.depth);
-		assert(0);	// Should never happen.
-		return NULL;
-	}
-
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
 	need_post_conversion = (revert > REVERT_NORMAL);
@@ -857,6 +958,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		}
 	}
 
+	pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
 	    && !need_post_conversion
 	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
@@ -868,6 +971,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		}
 		x = 0;
 		y = 0;
+		fbo_x_off = 0;
+		fbo_y_off = 0;
 	}
 
 	dispatch = glamor_get_dispatch(glamor_priv);
@@ -890,7 +995,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 					       NULL, gl_usage);
 		}
 
-		dispatch->glReadPixels(x, y, w, h, format, type, data);
+		dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
 
 		if (!glamor_priv->yInverted) {
 			assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
@@ -913,7 +1018,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 				       stride *
 				       h,
 				       NULL, GL_STREAM_READ);
-		dispatch->glReadPixels(0, 0, w, h,
+		dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
 				       format, type, 0);
 		read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
 					     GL_READ_ONLY);
@@ -946,6 +1051,107 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	return bits;
 }
 
+void *
+glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
+				  int stride, void *bits, int pbo, glamor_access_t access)
+{
+	GLenum format, type;
+	int no_alpha, revert, swap_rb;
+	glamor_pixmap_private *pixmap_priv;
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type,
+						   &no_alpha,
+						   &revert,
+						   &swap_rb, 1)) {
+		glamor_fallback("Unknown pixmap depth %d.\n",
+				pixmap->drawable.depth);
+		return NULL;
+	}
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return NULL;
+
+	if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+
+		RegionRec region;
+		BoxRec box;
+		int n_region;
+		glamor_pixmap_clipped_regions *clipped_regions;
+		void *sub_bits;
+		int i,j;
+
+		sub_bits = malloc(h * stride);
+		if (sub_bits == NULL)
+			return FALSE;
+		box.x1 = x;
+		box.y1 = y;
+		box.x2 = x + w;
+		box.y2 = y + h;
+		RegionInitBoxes(&region, &box, 1);
+		clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0);
+		DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
+		for(i = 0; i < n_region; i++)
+		{
+			BoxPtr boxes;
+			int nbox;
+			int temp_stride;
+			void *temp_bits;
+
+			assert(pbo == 0);
+			SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
+
+			boxes = RegionRects(clipped_regions[i].region);
+			nbox = RegionNumRects(clipped_regions[i].region);
+			for(j = 0; j < nbox; j++)
+			{
+				temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
+							    pixmap->drawable.depth);
+
+				if (boxes[j].x1 == x && temp_stride == stride) {
+					temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
+				} else {
+					temp_bits = sub_bits;
+				}
+				DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
+					boxes[j].x1, boxes[j].y1,
+					boxes[j].x2 - boxes[j].x1,
+					boxes[j].y2 - boxes[j].y1, temp_stride);
+
+				/* For large pixmap, we don't support pbo currently.*/
+				assert(pbo == 0);
+				if (_glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha,
+								       revert, swap_rb, boxes[j].x1, boxes[j].y1,
+								       boxes[j].x2 - boxes[j].x1,
+								       boxes[j].y2 - boxes[j].y1,
+								       temp_stride, temp_bits, pbo, access) == FALSE) {
+					RegionUninit(&region);
+					free(sub_bits);
+					assert(0);
+					return NULL;
+				}
+				if (boxes[j].x1 != x || temp_stride != stride)
+					glamor_get_bits(bits, stride, temp_bits, temp_stride,
+							pixmap->drawable.bitsPerPixel,
+							boxes[j].x1 - x , boxes[j].y1 - y,
+							boxes[j].x2 - boxes[j].x1,
+							boxes[j].y2 - boxes[j].y1);
+			}
+
+			RegionDestroy(clipped_regions[i].region);
+		}
+		free(sub_bits);
+		free(clipped_regions);
+		RegionUninit(&region);
+		return bits;
+	} else
+	return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha, revert, swap_rb,
+						  x, y, w, h, stride,
+						  bits, pbo, access);
+}
+
 
 /**
  * Move a pixmap to CPU memory.
@@ -984,7 +1190,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	if (access == GLAMOR_ACCESS_WO
 	    || glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)) {
+	    || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
+	    || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
 		data = malloc(stride * pixmap->drawable.height);
 	} else {
 		dispatch = glamor_get_dispatch(glamor_priv);
@@ -1024,6 +1231,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 }
 
 /* fixup a fbo to the exact size as the pixmap. */
+/* XXX LARGE pixmap? */
 Bool
 glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 {
@@ -1038,8 +1246,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 
 	drawable = &pixmap_priv->base.pixmap->drawable;
 
-	if (pixmap_priv->base.pixmap->drawable.width == pixmap_priv->base.fbo->width
-	    && pixmap_priv->base.pixmap->drawable.height == pixmap_priv->base.fbo->height)
+	if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
 		return	TRUE;
 
 	old_fbo = pixmap_priv->base.fbo;
@@ -1058,7 +1265,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 
 	scratch_priv = glamor_get_pixmap_private(scratch);
 
-	if (!scratch_priv || !scratch_priv->base.fbo)
+	if (!scratch_priv->base.fbo)
 		goto fail;
 
 	ValidateGC(&scratch->drawable, gc);
@@ -1111,14 +1318,13 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	void *data;
 	int pbo;
 	int flag;
-
-	assert(x >= 0 && y >= 0);
+	if (x < 0 || y < 0)
+		return NULL;
 	w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
 	h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
 	if (access == GLAMOR_ACCESS_WO) {
 		sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
 						  pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
-		ErrorF("WO\n");
 		return sub_pixmap;
 	}
 
@@ -1127,7 +1333,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return NULL;
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
 		flag = GLAMOR_CREATE_PIXMAP_CPU;
 	else
 		flag = GLAMOR_CREATE_PIXMAP_MAP;
@@ -1141,17 +1347,16 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
 	pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
 
-	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
+	if (pixmap_priv->base.is_picture) {
 		sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
 		sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
 	}
 
 	if (pbo)
 		data = NULL;
-	else {
+	else
 		data = sub_pixmap->devPrivate.ptr;
-		assert(flag != GLAMOR_CREATE_PIXMAP_MAP);
-	}
+
 	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
 						 data, pbo, access);
 	if (pbo) {
@@ -1173,7 +1378,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 
 	new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
 					      pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
-	glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
+	glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
 	glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
 #endif
 
@@ -1188,8 +1393,7 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
 	glamor_pixmap_private *sub_pixmap_priv;
 	if (access != GLAMOR_ACCESS_RO) {
 		sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
-		if (sub_pixmap_priv
-		    && sub_pixmap_priv->base.fbo
+		if (sub_pixmap_priv->base.fbo
 		    && sub_pixmap_priv->base.fbo->pbo_valid) {
 			bits = NULL;
 			pbo = sub_pixmap_priv->base.fbo->pbo;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2172d17..d9f6438 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -927,6 +927,9 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
 #endif
-#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
+#define GLAMOR_TEXTURED_LARGE_PIXMAP 0
+#if 0
+#define MAX_FBO_SIZE 512 /* For test purpose only. */
+#endif
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6a584ba..48a5bb3 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -37,7 +37,12 @@
 #ifdef RENDER
 #include "mipict.h"
 #include "fbpict.h"
-
+#if 0
+//#define DEBUGF(str, ...)  do {} while(0)
+#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
+//#define DEBUGRegionPrint(x) do {} while (0)
+#define DEBUGRegionPrint RegionPrint
+#endif
 struct shader_key {
 	enum shader_source source;
 	enum shader_mask mask;
@@ -606,18 +611,20 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #endif
 	/* XXX may be we can eaxctly check whether we need to touch
 	 * the out-of-box area then determine whether we need to fix.
-	 * */
-	if (repeat_type != RepeatNone)
-		repeat_type += RepeatFix;
-	else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		if (picture->transform
-		   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
+	 **/
+	/*if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE)*/ {
+		if (repeat_type != RepeatNone)
 			repeat_type += RepeatFix;
-	}
-
-	if (repeat_type >= RepeatFix) {
-		glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
-		dispatch->glUniform2fv(wh_location, 1, wh);
+		else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+			 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+			if (picture->transform
+			   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
+				repeat_type += RepeatFix;
+		}
+		if (repeat_type >= RepeatFix) {
+			glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
+			dispatch->glUniform2fv(wh_location, 1, wh);
+		}
 	}
 	dispatch->glUniform1i(repeat_location, repeat_type);
 	glamor_put_dispatch(glamor_priv);
@@ -687,53 +694,44 @@ glamor_composite_with_copy(CARD8 op,
 			   INT16 x_source,
 			   INT16 y_source,
 			   INT16 x_dest,
-			   INT16 y_dest, CARD16 width, CARD16 height)
+			   INT16 y_dest,
+			   RegionPtr region)
 {
-	RegionRec region;
 	int ret = FALSE;
-
 	if (!source->pDrawable)
 		return FALSE;
 
 	if (!compatible_formats(op, dest, source))
 		return FALSE;
 
-	if (source->repeat || source->transform)
+	if (source->repeat || source->transform) {
 		return FALSE;
+	}
 
 	x_dest += dest->pDrawable->x;
 	y_dest += dest->pDrawable->y;
 	x_source += source->pDrawable->x;
 	y_source += source->pDrawable->y;
-	if (!miComputeCompositeRegion(&region,
-				      source, NULL, dest,
-				      x_source, y_source,
-				      0, 0, x_dest, y_dest, width, height))
-		return TRUE;
-
 	if (PICT_FORMAT_A(source->format) == 0) {
 		/* Fallback if we sample outside the source so that we
 		 * swizzle the correct clear color for out-of-bounds texels.
 		 */
-		if (region.extents.x1 + x_source - x_dest < 0)
+		if (region->extents.x1 + x_source - x_dest < 0)
 			goto cleanup_region;
-		if (region.extents.x2 + x_source - x_dest > source->pDrawable->width)
+		if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
 			goto cleanup_region;
 
-		if (region.extents.y1 + y_source - y_dest < 0)
+		if (region->extents.y1 + y_source - y_dest < 0)
 			goto cleanup_region;
-		if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
+		if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
 			goto cleanup_region;
 	}
-
 	ret = glamor_copy_n_to_n_nf(source->pDrawable,
 				    dest->pDrawable, NULL,
-				    REGION_RECTS(&region),
-				    REGION_NUM_RECTS(&region),
+				    RegionRects(region), RegionNumRects(region),
 				    x_source - x_dest, y_source - y_dest,
 				    FALSE, FALSE, 0, NULL);
 cleanup_region:
-	REGION_UNINIT(dest->pDrawable->pScreen, &region);
 	return ret;
 }
 
@@ -929,12 +927,44 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
 	return FALSE;
 }
 
+static void
+glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
+				     int repeat_type,
+				     float *matrix,
+				     float xscale, float yscale,
+				     int x1, int y1, int x2, int y2,
+				     int yInverted, float *texcoords)
+{
+	if (!matrix && repeat_type == RepeatNone)
+		glamor_set_normalize_tcoords(priv, xscale, yscale,
+					     x1, y1,
+					     x2, y2,
+					     yInverted,
+					     texcoords);
+	else if (matrix && repeat_type == RepeatNone)
+		glamor_set_transformed_normalize_tcoords(priv, matrix, xscale,
+							 yscale, x1, y1,
+							 x2, y2,
+							 yInverted,
+							 texcoords);
+	else if (!matrix && repeat_type != RepeatNone)
+		glamor_set_repeat_normalize_tcoords(priv, repeat_type,
+						    xscale, yscale,
+						    x1, y1,
+						    x2, y2,
+						    yInverted,
+						    texcoords);
+	else if (matrix && repeat_type != RepeatNone)
+		assert(0);
+}
+
 static Bool
 glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
 			     PicturePtr mask,
 			     PicturePtr dest,
-			     int nrect, glamor_composite_rect_t * rects)
+			     int nrect,
+			     glamor_composite_rect_t * rects)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_screen_private *glamor_priv =
@@ -959,6 +989,7 @@ glamor_composite_with_shader(CARD8 op,
 	enum glamor_pixmap_status mask_status = GLAMOR_NONE;
 	PictFormatShort saved_source_format = 0;
 	float src_matrix[9], mask_matrix[9];
+	float *psrc_matrix = NULL, *pmask_matrix = NULL;
 	GLfloat source_solid_color[4], mask_solid_color[4];
 	int vert_stride = 4;
 	int nrect_max;
@@ -970,20 +1001,23 @@ glamor_composite_with_shader(CARD8 op,
 		goto fail;
 	}
 	memset(&key, 0, sizeof(key));
-	if (!source->pDrawable) {
-		if (source->pSourcePict->type == SourcePictTypeSolidFill) {
-			key.source = SHADER_SOURCE_SOLID;
-			glamor_get_rgba_from_pixel(source->
-						   pSourcePict->solidFill.
-						   color,
-						   &source_solid_color[0],
-						   &source_solid_color[1],
-						   &source_solid_color[2],
-						   &source_solid_color[3],
-						   PICT_a8r8g8b8);
-		} else {
-			glamor_fallback("gradient source\n");
-			goto fail;
+	if (!source) {
+		key.source = SHADER_SOURCE_SOLID;
+		source_solid_color[0] = 0.0;
+		source_solid_color[1] = 0.0;
+		source_solid_color[2] = 0.0;
+		source_solid_color[3] = 0.0;
+	} else if (!source->pDrawable) {
+			if (source->pSourcePict->type == SourcePictTypeSolidFill) {
+				key.source = SHADER_SOURCE_SOLID;
+				glamor_get_rgba_from_pixel(source->
+							   pSourcePict->solidFill.
+							   color,
+							   &source_solid_color[0],
+							   &source_solid_color[1],
+							   &source_solid_color[2],
+							   &source_solid_color[3],
+							   PICT_a8r8g8b8);
 		}
 	} else {
 		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
@@ -999,9 +1033,6 @@ glamor_composite_with_shader(CARD8 op,
 				     &mask_solid_color[1],
 				     &mask_solid_color[2],
 				     &mask_solid_color[3], PICT_a8r8g8b8);
-			} else {
-				glamor_fallback("gradient mask\n");
-				goto fail;
 			}
 		} else {
 			key.mask = SHADER_MASK_TEXTURE_ALPHA;
@@ -1029,7 +1060,7 @@ glamor_composite_with_shader(CARD8 op,
 		key.in = SHADER_IN_SOURCE_ONLY;
 	}
 
-	if (source->alphaMap) {
+	if (source && source->alphaMap) {
 		glamor_fallback("source alphaMap\n");
 		goto fail;
 	}
@@ -1044,13 +1075,14 @@ glamor_composite_with_shader(CARD8 op,
 		source_pixmap_priv =
 		    glamor_get_pixmap_private(source_pixmap);
 		if (source_pixmap == dest_pixmap) {
+			/* XXX source and the dest share the same texture.
+			 * Does it need special handle? */
 			glamor_fallback("source == dest\n");
-			goto fail;
 		}
-		if (!source_pixmap_priv || source_pixmap_priv->base.gl_fbo == 0) {
-			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
+		if (source_pixmap_priv->base.gl_fbo == 0) {
+			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
 			 * equal to zero when the pixmap is screen pixmap. Then we may
-			 * refer the tex zero directly latter in the composition. 
+			 * refer the tex zero directly latter in the composition.
 			 * It seems that it works fine, but it may have potential problem*/
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 			source_status = GLAMOR_UPLOAD_PENDING;
@@ -1068,7 +1100,7 @@ glamor_composite_with_shader(CARD8 op,
 			glamor_fallback("mask == dest\n");
 			goto fail;
 		}
-		if (!mask_pixmap_priv || mask_pixmap_priv->base.gl_fbo == 0) {
+		if (mask_pixmap_priv->base.gl_fbo == 0) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 			mask_status = GLAMOR_UPLOAD_PENDING;
 #else
@@ -1095,20 +1127,20 @@ glamor_composite_with_shader(CARD8 op,
 			}
 
 			if (source->format != saved_source_format) {
-				glamor_picture_format_fixup(source,
-							    source_pixmap_priv);
+				//glamor_picture_format_fixup(source,
+				//			    source_pixmap_priv);
 			}
-			/* XXX  
+			/* XXX
 			 * By default, glamor_upload_picture_to_texture will wire alpha to 1
-			 * if one picture doesn't have alpha. So we don't do that again in 
+			 * if one picture doesn't have alpha. So we don't do that again in
 			 * rendering function. But here is a special case, as source and
-			 * mask share the same texture but may have different formats. For 
+			 * mask share the same texture but may have different formats. For
 			 * example, source doesn't have alpha, but mask has alpha. Then the
 			 * texture will have the alpha value for the mask. And will not wire
 			 * to 1 for the source. In this case, we have to use different shader
 			 * to wire the source's alpha to 1.
 			 *
-			 * But this may cause a potential problem if the source's repeat mode 
+			 * But this may cause a potential problem if the source's repeat mode
 			 * is REPEAT_NONE, and if the source is smaller than the dest, then
 			 * for the region not covered by the source may be painted incorrectly.
 			 * because we wire the alpha to 1.
@@ -1156,13 +1188,15 @@ glamor_composite_with_shader(CARD8 op,
 	 * transformed source and mask, if the transform is not int translate. */
 	if (key.source != SHADER_SOURCE_SOLID
 	    && source->transform
-	    && !pixman_transform_is_int_translate(source->transform)) {
+	    && !pixman_transform_is_int_translate(source->transform)
+	    && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
 		if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
 			goto fail;
 	}
 	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
 	    && mask->transform
-	    && !pixman_transform_is_int_translate(mask->transform)) {
+	    && !pixman_transform_is_int_translate(mask->transform)
+	    && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
 		if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
 			goto fail;
 	}
@@ -1217,7 +1251,10 @@ glamor_composite_with_shader(CARD8 op,
 					   &source_y_off);
 		pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
 				      &src_yscale);
-		glamor_picture_get_matrixf(source, src_matrix);
+		if (source->transform) {
+			psrc_matrix = src_matrix;
+			glamor_picture_get_matrixf(source, psrc_matrix);
+		}
 		vert_stride += 4;
 	}
 
@@ -1226,7 +1263,10 @@ glamor_composite_with_shader(CARD8 op,
 					   &mask_x_off, &mask_y_off);
 		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
 				      &mask_yscale);
-		glamor_picture_get_matrixf(mask, mask_matrix);
+		if (mask->transform) {
+			pmask_matrix = mask_matrix;
+			glamor_picture_get_matrixf(mask, pmask_matrix);
+		}
 		vert_stride += 4;
 	}
 
@@ -1252,13 +1292,16 @@ glamor_composite_with_shader(CARD8 op,
 
 			x_dest = rects->x_dst + dest_x_off;
 			y_dest = rects->y_dst + dest_y_off;
-			x_source = rects->x_src + source_x_off;;
+			x_source = rects->x_src + source_x_off;
 			y_source = rects->y_src + source_y_off;
 			x_mask = rects->x_mask + mask_x_off;
 			y_mask = rects->y_mask + mask_y_off;
 			width = rects->width;
 			height = rects->height;
 
+			DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
+				x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height);
+
 			glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
 						     dst_yscale,
 						     x_dest, y_dest,
@@ -1266,41 +1309,21 @@ glamor_composite_with_shader(CARD8 op,
 						     glamor_priv->yInverted,
 						     vertices);
 
-			if (key.source != SHADER_SOURCE_SOLID) {
-				if (source->transform)
-					glamor_set_transformed_normalize_tcoords
-						(source_pixmap_priv, src_matrix, src_xscale,
-						 src_yscale, x_source, y_source,
-						 x_source + width, y_source + height,
-						 glamor_priv->yInverted,
-						 source_texcoords);
-				else
-					glamor_set_normalize_tcoords
-						(source_pixmap_priv, src_xscale, src_yscale,
-						 x_source, y_source,
-						 x_source + width, y_source + height,
-						 glamor_priv->yInverted,
-						 source_texcoords);
-			}
+			if (key.source != SHADER_SOURCE_SOLID)
+				glamor_set_normalize_tcoords_generic(
+					source_pixmap_priv, source->repeatType, psrc_matrix,
+					src_xscale, src_yscale, x_source, y_source,
+					x_source + width, y_source + height,
+					glamor_priv->yInverted, source_texcoords);
 
 			if (key.mask != SHADER_MASK_NONE
-			    && key.mask != SHADER_MASK_SOLID) {
-				if (mask->transform)
-					glamor_set_transformed_normalize_tcoords
-						(mask_pixmap_priv, mask_matrix,
-						 mask_xscale,
-						 mask_yscale, x_mask, y_mask,
-						 x_mask + width, y_mask + height,
-						 glamor_priv->yInverted,
-						 mask_texcoords);
-				else
-					glamor_set_normalize_tcoords
-						(mask_pixmap_priv, mask_xscale,
-						 mask_yscale, x_mask, y_mask,
-						 x_mask + width, y_mask + height,
-						 glamor_priv->yInverted,
-						 mask_texcoords);
-			}
+			    && key.mask != SHADER_MASK_SOLID)
+				glamor_set_normalize_tcoords_generic(
+					mask_pixmap_priv, mask->repeatType, pmask_matrix,
+					mask_xscale, mask_yscale, x_mask, y_mask,
+					x_mask + width, y_mask + height,
+					glamor_priv->yInverted, mask_texcoords);
+
 			glamor_emit_composite_rect(screen,
 						   source_texcoords,
 						   mask_texcoords,
@@ -1323,6 +1346,7 @@ glamor_composite_with_shader(CARD8 op,
 	dispatch->glActiveTexture(GL_TEXTURE1);
 	dispatch->glDisable(GL_TEXTURE_2D);
 #endif
+	DEBUGF("finish rendering.\n");
 	dispatch->glUseProgram(0);
 	if (saved_source_format)
 		source->format = saved_source_format;
@@ -1398,17 +1422,18 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	return dst;
 }
 
-static Bool
-_glamor_composite(CARD8 op,
-		  PicturePtr source,
-		  PicturePtr mask,
-		  PicturePtr dest,
-		  INT16 x_source,
-		  INT16 y_source,
-		  INT16 x_mask,
-		  INT16 y_mask,
-		  INT16 x_dest, INT16 y_dest, 
-		  CARD16 width, CARD16 height, Bool fallback)
+Bool
+glamor_composite_clipped_region(CARD8 op,
+				PicturePtr source,
+				PicturePtr mask,
+				PicturePtr dest,
+				RegionPtr region,
+				int x_source,
+				int y_source,
+				int x_mask,
+				int y_mask,
+				int x_dest,
+				int y_dest)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_pixmap_private *dest_pixmap_priv;
@@ -1419,80 +1444,63 @@ _glamor_composite(CARD8 op,
 	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
 	PicturePtr temp_src = source, temp_mask = mask;
 	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
+
+	BoxPtr extent;
 	glamor_composite_rect_t rect[10];
 	glamor_composite_rect_t *prect = rect;
 	int prect_size = ARRAY_SIZE(rect);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	Bool ret = TRUE;
-	RegionRec region;
+	int ok = FALSE;
+	int i;
+	int width;
+	int height;
 	BoxPtr box;
-	int nbox, i, ok = FALSE;
-	PixmapPtr sub_dest_pixmap = NULL;
-	PixmapPtr sub_source_pixmap = NULL;
-	PixmapPtr sub_mask_pixmap = NULL;
-	int dest_x_off, dest_y_off, saved_dest_x = 0, saved_dest_y = 0;
-	int source_x_off, source_y_off, saved_source_x = 0, saved_source_y = 0;
-	int mask_x_off, mask_y_off, saved_mask_x = 0, saved_mask_y = 0;
-	DrawablePtr saved_dest_drawable = NULL;
-	DrawablePtr saved_source_drawable = NULL;
-	DrawablePtr saved_mask_drawable = NULL;
+	int nbox;
+	extent = RegionExtents(region);
+	box = RegionRects(region);
+	nbox = RegionNumRects(region);
+	width = extent->x2 - extent->x1;
+	height = extent->y2 - extent->y1;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
 	x_temp_mask = x_mask;
 	y_temp_mask = y_mask;
-
-	DEBUGF("Composite Src: (%d, %d)\n"
-	       "         Mask: (%d, %d)\n"
-	       "       to dst: (%d, %d), size: %d X %d \n",
-	       x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+	DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
+		x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+	DEBUGF("dest pixmap %p ", dest_pixmap);
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
 
-	if (source->pDrawable) {
+	if (source && source->pDrawable) {
 		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
-			goto fail;
 	}
 
 	if (mask && mask->pDrawable) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
-			goto fail;
-	}
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-		goto fail;
 	}
 
-	if (op >= ARRAY_SIZE(composite_op_info))
-		goto fail;
-
-	if ((!source->pDrawable
+	/* XXX is it possible source mask have non-zero drawable.x/y? */
+	if (source
+	    && ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	    || (source->pDrawable
 		&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
-		&&
-		((width * height * 4 <
-		  (source_pixmap->drawable.width *
-		   source_pixmap->drawable.height))
-		 ||
-		 !(glamor_check_fbo_size
-		   (glamor_priv, source_pixmap->drawable.width,
-		    source_pixmap->drawable.height))))) {
+		&& (source_pixmap->drawable.width != width
+		    || source_pixmap->drawable.height != height)))) {
 		temp_src =
 		    glamor_convert_gradient_picture(screen, source,
-						    x_source, y_source,
+						    extent->x1 + x_source - x_dest,
+						    extent->y1 + y_source - y_dest,
 						    width, height);
 		if (!temp_src) {
 			temp_src = source;
-			goto fail;
+			goto out;
 		}
-		x_temp_src = y_temp_src = 0;
+		x_temp_src = - extent->x1 + x_dest;
+		y_temp_src = - extent->y1 + y_dest;
 	}
 
 	if (mask
@@ -1500,26 +1508,22 @@ _glamor_composite(CARD8 op,
 	    ((!mask->pDrawable
 	      && (mask->pSourcePict->type != SourcePictTypeSolidFill))
 	     || (mask->pDrawable
-		 && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
-		 &&
-		 ((width * height * 4 <
-		   (mask_pixmap->drawable.width *
-		    mask_pixmap->drawable.height))
-		  ||
-		  !(glamor_check_fbo_size
-		    (glamor_priv, mask_pixmap->drawable.width,
-		     mask_pixmap->drawable.height)))))) {
+		 && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)
+		 && (mask_pixmap->drawable.width != width
+		    || mask_pixmap->drawable.height != height)))) {
 		/* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
 		 * to do reduce one convertion. */
 		temp_mask =
 		    glamor_convert_gradient_picture(screen, mask,
-						    x_mask, y_mask,
+						    extent->x1 + x_mask - x_dest,
+						    extent->y1 + y_mask - y_dest,
 						    width, height);
 		if (!temp_mask) {
 			temp_mask = mask;
-			goto fail;
+			goto out;
 		}
-		x_temp_mask = y_temp_mask = 0;
+		x_temp_mask = - extent->x1 + x_dest;
+		y_temp_mask = - extent->y1 + y_dest;
 	}
 	/* Do two-pass PictOpOver componentAlpha, until we enable
 	 * dual source color blending.
@@ -1527,43 +1531,38 @@ _glamor_composite(CARD8 op,
 
 	if (mask && mask->componentAlpha) {
 		if (op == PictOpOver) {
-			glamor_composite(PictOpOutReverse,
-					 temp_src, temp_mask, dest,
-					 x_temp_src, y_temp_src,
-					 x_temp_mask, y_temp_mask,
-					 x_dest, y_dest, width, height);
-			glamor_composite(PictOpAdd,
-					 temp_src, temp_mask, dest,
-					 x_temp_src, y_temp_src,
-					 x_temp_mask, y_temp_mask,
-					 x_dest, y_dest, width, height);
-			goto done;
-
-		} else if (op == PictOpAtop
-			   || op == PictOpAtopReverse
-			   || op == PictOpXor
-			   || op >= PictOpSaturate) {
-				glamor_fallback
-					("glamor_composite(): component alpha op %x\n", op);
-				goto fail;
+			glamor_composite_clipped_region(PictOpOutReverse,
+							temp_src, temp_mask, dest,
+							region,
+							x_temp_src, y_temp_src,
+							x_temp_mask, y_temp_mask,
+							x_dest, y_dest);
+
+			glamor_composite_clipped_region(PictOpAdd,
+							temp_src, temp_mask, dest,
+							region,
+							x_temp_src, y_temp_src,
+							x_temp_mask, y_temp_mask,
+							x_dest, y_dest);
+			ok = TRUE;
+			goto out;
 		}
 	}
 
-	if (!mask) {
+	if (!mask && temp_src) {
 		if (glamor_composite_with_copy(op, temp_src, dest,
 					       x_temp_src, y_temp_src,
-					       x_dest, y_dest, width,
-					       height))
-			goto done;
+					       x_dest, y_dest, region)) {
+			ok = TRUE;
+			goto out;
+		}
 	}
 
-	/*XXXXX, maybe we can make a copy of dest pixmap.*/
-	if (source_pixmap == dest_pixmap)
-		goto full_fallback;
+	/*XXXXX, self copy?*/
 
 	x_dest += dest->pDrawable->x;
 	y_dest += dest->pDrawable->y;
-	if (temp_src->pDrawable) {
+	if (temp_src && temp_src->pDrawable) {
 		x_temp_src += temp_src->pDrawable->x;
 		y_temp_src += temp_src->pDrawable->y;
 	}
@@ -1571,16 +1570,6 @@ _glamor_composite(CARD8 op,
 		x_temp_mask += temp_mask->pDrawable->x;
 		y_temp_mask += temp_mask->pDrawable->y;
 	}
-	if (!miComputeCompositeRegion(&region,
-				      temp_src, temp_mask, dest,
-				      x_temp_src, y_temp_src,
-				      x_temp_mask, y_temp_mask,
-				      x_dest, y_dest, width,
-				      height))
-		goto done;
-
-	box = REGION_RECTS(&region);
-	nbox = REGION_NUM_RECTS(&region);
 
 	if (nbox > ARRAY_SIZE(rect)) {
 		prect = calloc(nbox, sizeof(*prect));
@@ -1612,15 +1601,153 @@ _glamor_composite(CARD8 op,
 		box += box_cnt;
 	}
 
+	if (prect != rect)
+		free(prect);
+out:
+	if (temp_src != source)
+		FreePicture(temp_src, 0);
+	if (temp_mask != mask)
+		FreePicture(temp_mask, 0);
+
+	return ok;
+}
+
+static Bool
+_glamor_composite(CARD8 op,
+		  PicturePtr source,
+		  PicturePtr mask,
+		  PicturePtr dest,
+		  INT16 x_source,
+		  INT16 y_source,
+		  INT16 x_mask,
+		  INT16 y_mask,
+		  INT16 x_dest, INT16 y_dest,
+		  CARD16 width, CARD16 height, Bool fallback)
+{
+	ScreenPtr screen = dest->pDrawable->pScreen;
+	glamor_pixmap_private *dest_pixmap_priv;
+	glamor_pixmap_private *source_pixmap_priv =
+	    NULL, *mask_pixmap_priv = NULL;
+	PixmapPtr dest_pixmap =
+	    glamor_get_drawable_pixmap(dest->pDrawable);
+	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	Bool ret = TRUE;
+	RegionRec region;
+	BoxPtr box, extent;
+	int nbox, ok = FALSE;
+	PixmapPtr sub_dest_pixmap = NULL;
+	PixmapPtr sub_source_pixmap = NULL;
+	PixmapPtr sub_mask_pixmap = NULL;
+	int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
+	int source_x_off, source_y_off, saved_source_x, saved_source_y;
+	int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
+	DrawablePtr saved_dest_drawable;
+	DrawablePtr saved_source_drawable;
+	DrawablePtr saved_mask_drawable;
+	int force_clip = 0;
+
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+	if (source->pDrawable) {
+		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+			goto fail;
+	}
+
+	if (mask && mask->pDrawable) {
+		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+			goto fail;
+	}
+
+	DEBUGF("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n",
+		source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		goto fail;
+	}
+
+	if (op >= ARRAY_SIZE(composite_op_info))
+		goto fail;
+
+	if (mask && mask->componentAlpha) {
+		if (op == PictOpAtop
+		    || op == PictOpAtopReverse
+		    || op == PictOpXor
+		    || op >= PictOpSaturate) {
+			glamor_fallback
+				("glamor_composite(): component alpha op %x\n", op);
+			goto fail;
+		}
+	}
+
+	if (!miComputeCompositeRegion(&region,
+				      source, mask, dest,
+				      x_source + (source_pixmap ? source->pDrawable->x : 0),
+				      y_source + (source_pixmap ? source->pDrawable->y : 0),
+				      x_mask + (mask_pixmap ? mask->pDrawable->x : 0),
+				      y_mask + (mask_pixmap ? mask->pDrawable->y : 0),
+				      x_dest + dest->pDrawable->x,
+				      y_dest + dest->pDrawable->y,
+				      width,
+				      height)) {
+		ret = TRUE;
+		goto done;
+	}
+
+	box = REGION_RECTS(&region);
+	nbox = REGION_NUM_RECTS(&region);
+	DEBUGF("first clipped when compositing.\n");
+	DEBUGRegionPrint(&region);
+	extent = RegionExtents(&region);
+	if (nbox == 0) {
+		ret = TRUE;
+		goto done;
+	}
+	/* If destination is not a large pixmap, but the region is larger
+	 * than texture size limitation, and source or mask is memory pixmap,
+	 * then there may be need to load a large memory pixmap to a
+	 * texture, and this is not permitted. Then we force to clip the
+	 * destination and make sure latter will not upload a large memory
+	 * pixmap. */
+	if (!glamor_check_fbo_size(glamor_priv,
+		extent->x2 - extent->x1, extent->y2 - extent->y1)
+	   && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
+           && ((source_pixmap_priv
+	        && source_pixmap_priv->type == GLAMOR_MEMORY)
+	     || (mask_pixmap_priv
+		&& mask_pixmap_priv->type == GLAMOR_MEMORY)
+	     || (!source_pixmap_priv
+		   && (source->pSourcePict->type != SourcePictTypeSolidFill))
+	     || (!mask_pixmap_priv && mask
+		  && mask->pSourcePict->type != SourcePictTypeSolidFill)))
+		force_clip = 1;
+
+	if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+	    || (source_pixmap_priv
+		&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
+	    || (mask_pixmap_priv
+		&& mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
+		goto fail;
+	else
+		ok = glamor_composite_clipped_region(op, source,
+						     mask, dest, &region,
+						     x_source, y_source,
+						     x_mask, y_mask,
+						     x_dest, y_dest);
+
 	REGION_UNINIT(dest->pDrawable->pScreen, &region);
 	if (ok)
 		goto done;
-
 fail:
 
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
-	    && (!source_pixmap 
+	    && (!source_pixmap
 		|| glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
 	    && (!mask_pixmap
 		|| glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
@@ -1662,13 +1789,11 @@ fail:
 		x_ ##p = 0;								\
 		y_ ##p = 0;								\
 	} } while(0)
-
 	GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
-	if (source->pDrawable)
+	if (source->pDrawable && !source->transform)
 		GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
-	if (mask && mask->pDrawable)
+	if (mask && mask->pDrawable && !mask->transform)
 		GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
-
 full_fallback:
 	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
 		if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
@@ -1711,12 +1836,6 @@ full_fallback:
 		PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
 	PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
       done:
-	if (temp_src != source)
-		FreePicture(temp_src, 0);
-	if (temp_mask != mask)
-		FreePicture(temp_mask, 0);
-	if (prect != rect)
-		free(prect);
 	return ret;
 }
 
@@ -1754,9 +1873,6 @@ glamor_composite_nf(CARD8 op,
 				 FALSE);
 }
 
-
-
-
 /**
  * Creates an appropriate picture to upload our alpha mask into (which
  * we calculated in system memory)
@@ -1797,7 +1913,7 @@ glamor_create_mask_picture(ScreenPtr screen,
  * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
  * accumulation in system memory.
  */
-static Bool 
+static Bool
 _glamor_trapezoids(CARD8 op,
 		  PicturePtr src, PicturePtr dst,
 		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
@@ -1885,7 +2001,7 @@ glamor_trapezoids(CARD8 op,
 		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		  int ntrap, xTrapezoid * traps)
 {
-	_glamor_trapezoids(op, src, dst, mask_format, x_src, 
+	_glamor_trapezoids(op, src, dst, mask_format, x_src,
 			   y_src, ntrap, traps, TRUE);
 }
 
@@ -1895,7 +2011,7 @@ glamor_trapezoids_nf(CARD8 op,
 		     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		     int ntrap, xTrapezoid * traps)
 {
-	return _glamor_trapezoids(op, src, dst, mask_format, x_src, 
+	return _glamor_trapezoids(op, src, dst, mask_format, x_src,
 				  y_src, ntrap, traps, FALSE);
 }
 
@@ -1912,8 +2028,12 @@ glamor_composite_glyph_rects(CARD8 op,
 	ValidatePicture(src);
 	ValidatePicture(dst);
 
-	if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
-		return;
+	if (!(glamor_is_large_picture(src)
+	    || (mask && glamor_is_large_picture(mask))
+	    || glamor_is_large_picture(dst))) {
+		if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
+			return;
+	}
 
 	n = nrect;
 	r = rects;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index c6b88d2..871479b 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -102,10 +102,9 @@ glamor_fini_tile_shader(ScreenPtr screen)
 	glamor_put_dispatch(glamor_priv);
 }
 
-Bool
-glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+static void
+_glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	    int x, int y, int width, int height,
-	    unsigned char alu, unsigned long planemask,
 	    int tile_x, int tile_y)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -126,48 +125,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	glamor_pixmap_private *src_pixmap_priv;
 	glamor_pixmap_private *dst_pixmap_priv;
 	float wh[2];
-
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
-		goto fail;
-
-	if (glamor_priv->tile_prog == 0) {
-		glamor_fallback("Tiling unsupported\n");
-		goto fail;
-	}
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
-		glamor_fallback("dest has no fbo.\n");
-		goto fail;
-	}
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
-		/* XXX dynamic uploading candidate. */
-		glamor_fallback("Non-texture tile pixmap\n");
-		goto fail;
-	}
-
-	if (!glamor_set_planemask(pixmap, planemask)) {
-		glamor_fallback("unsupported planemask %lx\n", planemask);
-		goto fail;
-	}
-
 	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
 	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, alu)) {
-		glamor_put_dispatch(glamor_priv);
-		goto fail;
-	}
-
 	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
 			      &src_yscale);
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glUseProgram(glamor_priv->tile_prog);
 
 	glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
-
 	dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D,
@@ -185,21 +153,23 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
-				     src_yscale,
-				     tile_x1, tile_y1,
-				     tile_x2, tile_y2,
-				     glamor_priv->yInverted,
-				     source_texcoords);
+	glamor_set_repeat_normalize_tcoords
+			(src_pixmap_priv, RepeatNormal,
+			 src_xscale, src_yscale,
+			 tile_x1, tile_y1,
+			 tile_x2, tile_y2,
+			 glamor_priv->yInverted,
+			 source_texcoords);
+
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
 					GL_FLOAT, GL_FALSE,
 					2 * sizeof(float),
 					source_texcoords);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-	glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
-				     dst_yscale,
-				     x1, y1, x2, y2,
+	glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
+				     x1, y1,
+				     x2, y2,
 				     glamor_priv->yInverted, vertices);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -214,11 +184,139 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 #endif
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+}
+
+Bool
+glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+	    int x, int y, int width, int height,
+	    unsigned char alu, unsigned long planemask,
+	    int tile_x, int tile_y)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_pixmap_private *dst_pixmap_priv;
+	glamor_pixmap_private *src_pixmap_priv;
+	glamor_gl_dispatch *dispatch;
+
+	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+	src_pixmap_priv = glamor_get_pixmap_private(tile);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
+		return FALSE;
+
+	if (glamor_priv->tile_prog == 0) {
+		glamor_fallback("Tiling unsupported\n");
+		goto fail;
+	}
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+		/* XXX dynamic uploading candidate. */
+		glamor_fallback("Non-texture tile pixmap\n");
+		goto fail;
+	}
+
+	if (!glamor_set_planemask(pixmap, planemask)) {
+		glamor_fallback("unsupported planemask %lx\n", planemask);
+		goto fail;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	if (!glamor_set_alu(dispatch, alu)) {
+		glamor_fallback("unsupported alu %x\n", alu);
+		glamor_put_dispatch(glamor_priv);
+		goto fail;
+	}
+
+	if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
+	    || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+			glamor_pixmap_clipped_regions *clipped_dst_regions;
+			int n_dst_region, i, j, k;
+			BoxRec box;
+			RegionRec region;
+
+			box.x1 = x;
+			box.y1 = y;
+			box.x2 = x + width;
+			box.y2 = y + height;
+			RegionInitBoxes(&region, &box, 1);
+			clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
+									     &region, &n_dst_region, 0);
+			for(i = 0; i < n_dst_region; i++)
+			{
+				int n_src_region;
+				glamor_pixmap_clipped_regions *clipped_src_regions;
+				BoxPtr current_boxes;
+				int n_current_boxes;
+
+				SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
+
+				if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+					RegionTranslate(clipped_dst_regions[i].region,
+							tile_x - x, tile_y - y);
+					DEBUGF("tiled a large src pixmap. %dx%d \n", tile->drawable.width, tile->drawable.height);
+					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
+											     clipped_dst_regions[i].region,
+											     &n_src_region, 1);
+					DEBUGF("got %d src regions %d \n", n_src_region);
+					for (j = 0; j < n_src_region; j++)
+					{
+
+						SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
+
+						RegionTranslate(clipped_src_regions[j].region,
+								x - tile_x,
+								y - tile_y);
+						current_boxes = RegionRects(clipped_src_regions[j].region);
+						n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
+						for(k = 0; k < n_current_boxes; k++)
+						{
+							DEBUGF("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
+								     current_boxes[k].x1, current_boxes[k].y1,
+								     current_boxes[k].x2 - current_boxes[k].x1,
+								     current_boxes[k].y2 - current_boxes[k].y1,
+									clipped_dst_regions[i].block_idx,
+									clipped_src_regions[j].block_idx,
+								     (tile_x + (current_boxes[k].x1 - x)),
+								     tile_y + (current_boxes[k].y1 - y));
+
+							_glamor_tile(pixmap, tile,
+								     current_boxes[k].x1, current_boxes[k].y1,
+								     current_boxes[k].x2 - current_boxes[k].x1,
+								     current_boxes[k].y2 - current_boxes[k].y1,
+								     (tile_x + (current_boxes[k].x1 - x)),
+								     (tile_y + (current_boxes[k].y1 - y)));
+						}
+
+						RegionDestroy(clipped_src_regions[j].region);
+					}
+					free(clipped_src_regions);
+				} else {
+					current_boxes = RegionRects(clipped_dst_regions[i].region);
+					n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
+					for(k = 0; k < n_current_boxes; k++)
+					{
+						_glamor_tile(pixmap, tile,
+							     current_boxes[k].x1, current_boxes[k].y1,
+							     current_boxes[k].x2 - current_boxes[k].x1,
+							     current_boxes[k].y2 - current_boxes[k].y1,
+							     (tile_x + (current_boxes[k].x1 - x)),
+							     (tile_y + (current_boxes[k].y1 - y)));
+					}
+				}
+				RegionDestroy(clipped_dst_regions[i].region);
+			}
+			free(clipped_dst_regions);
+			RegionUninit(&region);
+	}
+	else
+		_glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
+
 	glamor_set_alu(dispatch, GXcopy);
-	glamor_set_planemask(pixmap, ~0);
 	glamor_put_dispatch(glamor_priv);
 	return TRUE;
-
-      fail:
+fail:
 	return FALSE;
+
 }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 90a1657..44c8175 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -41,8 +41,10 @@
 
 #define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
-    *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.width;			\
-    *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.height;			\
+    int w,h;								\
+    PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h);			\
+    *(_pxscale_) = 1.0 / w;						\
+    *(_pyscale_) = 1.0 / h;						\
   } while(0)
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
@@ -106,6 +108,52 @@
       }									\
   }  while(0)
 
+#define _glamor_get_repeat_coords(priv, repeat_type, tx1,	\
+				  ty1, tx2, ty2,		\
+				  _x1_, _y1_, _x2_,		\
+				  _y2_, c, d, odd_x, odd_y)	\
+  do {								\
+	if (repeat_type == RepeatReflect) {			\
+		assert(0);					\
+	} else if (repeat_type == RepeatNormal) {		\
+		tx1 = (c - priv->box.x1);  			\
+		ty1 = (d - priv->box.y1);			\
+		tx2 = tx1 + ((_x2_) - (_x1_));			\
+		ty2 = ty1 + ((_y2_) - (_y1_));			\
+	} else {						\
+		assert(0);					\
+	}							\
+   } while(0)
+
+
+
+/* _x1_ ... _y2_ must be integer. */
+#define glamor_get_repeat_coords(priv, repeat_type, tx1,		\
+				 ty1, tx2, ty2, _x1_, _y1_, _x2_,	\
+				 _y2_) 					\
+  do {									\
+	int c, d;							\
+	int odd_x = 0, odd_y = 0;					\
+	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
+		(priv)->base.pixmap->drawable.width,			\
+		priv->box.x1, priv->box.x2,				\
+		priv->box.y1, priv->box.y2);				\
+	modulus((_x1_), (priv)->base.pixmap->drawable.width, c); 	\
+	modulus((_y1_), (priv)->base.pixmap->drawable.height, d);	\
+	DEBUGF("c %d d %d \n", c, d);					\
+	if (repeat_type == RepeatReflect) {				\
+		odd_x = abs((_x1_ - c)					\
+			/ (priv->base.pixmap->drawable.width)) & 1;	\
+		odd_y = abs((_y1_ - d)					\
+			/ (priv->base.pixmap->drawable.height)) & 1;	\
+	}								\
+	_glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\
+				  _x1_, _y1_, _x2_, _y2_, c, d,		\
+				  odd_x, odd_y);			\
+   } while(0)
+
+
+
 #define glamor_transform_point(matrix, tx, ty, x, y)			\
   do {									\
     int i;								\
@@ -213,6 +261,24 @@
 				   tx2, ty2, yInverted, vertices);	\
  } while(0)
 
+#define glamor_set_repeat_normalize_tcoords(priv, repeat_type,		\
+					    xscale, yscale,		\
+					    _x1_, _y1_, _x2_, _y2_,	\
+	                                    yInverted, vertices)	\
+  do {									\
+     float tx1, tx2, ty1, ty2;						\
+     if (priv->type == GLAMOR_TEXTURE_LARGE)				\
+	glamor_get_repeat_coords((&priv->large), repeat_type,		\
+				 tx1, ty1, tx2, ty2,			\
+				 _x1_, _y1_, _x2_, _y2_);		\
+     else {								\
+	tx1 = _x1_; tx2 = _x2_; ty1 = _y1_; ty2 = _y2_;			\
+     }									\
+     _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
+				   tx2, ty2, yInverted, vertices);	\
+ } while(0)
+
+
 #define glamor_set_tcoords(width, height, x1, y1, x2, y2,	\
 			   yInverted, vertices)			\
     do {							\
@@ -303,7 +369,7 @@ glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
 }
 
 inline static void
-glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
+glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 {
 	int i;
 	for (i = 0; i < nbox; i++) {
commit ace35e408cd7a79c5215bbd0f14b624d8d949e34
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jun 11 01:02:30 2012 +0800

    glamor_largepixmap: first commit for large pixmap.
    
    This is the first commit to add support for large pixmap.
    The large here means a pixmap is larger than the texutre's
    size limitation thus can't fit into one single texutre.
    
    The previous implementation will simply fallback to use a
    in memory pixmap to contain the large pixmap which is
    very slow in practice.
    
    The basic idea here is to use an array of texture to hold
    the large pixmap. And when we need to get a specific area
    of the pixmap, we just need to compute/clip the correct
    region and find the corresponding fbo.
    
    We need to implement some auxiliary routines to clip every
    rendering operations into small pieces which can fit into
    one texture.
    
    The complex part is the transformation/repeat/repeatReflect
    and repeat pad and their comination. We will support all of
    them step by step.
    
    This commit just add some necessary data structure to represent
    the large pixmap, and doesn't change any rendering process.
    This commit doesn't add real large pixmap support.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6b6fa0b..a22f445 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -73,8 +73,8 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 	if (pixmap_priv == NULL) {
 		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
 		glamor_set_pixmap_private(pixmap, pixmap_priv);
-		pixmap_priv->container = pixmap;
-		pixmap_priv->glamor_priv = glamor_priv;
+		pixmap_priv->base.pixmap = pixmap;
+		pixmap_priv->base.glamor_priv = glamor_priv;
 	}
 	pixmap_priv->type = type;
 }
@@ -91,7 +91,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 	glamor_priv = glamor_get_screen_private(screen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (pixmap_priv->fbo) {
+	if (pixmap_priv->base.fbo) {
 		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
 		glamor_destroy_fbo(fbo);
 	}
@@ -117,10 +117,10 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
 
 	glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
 	pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
-	glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
+	glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
 
-	pixmap_priv->fbo->width = screen_pixmap->drawable.width;
-	pixmap_priv->fbo->height = screen_pixmap->drawable.height;
+	pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
+	pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
 
 	glamor_priv->back_pixmap = back_pixmap;
 }
@@ -159,8 +159,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (usage == GLAMOR_CREATE_PIXMAP_MAP)
 		type = GLAMOR_MEMORY_MAP;
 
-	pixmap_priv->container = pixmap;
-	pixmap_priv->glamor_priv = glamor_priv;
+	pixmap_priv->base.pixmap = pixmap;
+	pixmap_priv->base.glamor_priv = glamor_priv;
 	pixmap_priv->type = type;
 
 	gl_iformat_for_depth(depth, &format);
diff --git a/glamor/glamor.h b/glamor/glamor.h
index c2db86a..fe3e4f8 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -55,7 +55,9 @@ typedef enum  glamor_pixmap_type {
 	GLAMOR_TEXTURE_DRM,
 	GLAMOR_SEPARATE_TEXTURE,
 	GLAMOR_DRM_ONLY,
-	GLAMOR_TEXTURE_ONLY
+	GLAMOR_TEXTURE_ONLY,
+	GLAMOR_TEXTURE_LARGE,
+	GLAMOR_TEXTURE_PACK
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 356e0f9..84a449c 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -75,7 +75,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
-				    src_pixmap_priv->fbo->fb);
+				    src_pixmap_priv->base.fbo->fb);
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
@@ -164,7 +164,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		return FALSE;
 	}
 
-	if (!src_pixmap_priv || !src_pixmap_priv->gl_fbo) {
+	if (!src_pixmap_priv || !src_pixmap_priv->base.gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
 		return FALSE;
@@ -209,7 +209,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D,
-				src_pixmap_priv->fbo->tex);
+				src_pixmap_priv->base.fbo->tex);
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
@@ -239,7 +239,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 	for (i = 0; i < nbox; i++) {
 
-		glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+		glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
+					     dst_yscale,
 					     box[i].x1 + dst_x_off,
 					     box[i].y1 + dst_y_off,
 					     box[i].x2 + dst_x_off,
@@ -247,7 +248,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 					     glamor_priv->yInverted,
 					     vertices);
 
-		glamor_set_normalize_tcoords(src_xscale,
+		glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
 					     src_yscale,
 					     box[i].x1 + dx,
 					     box[i].y1 + dy,
@@ -320,7 +321,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 
-	if (src_pixmap_priv->fbo && src_pixmap_priv->fbo->fb == dst_pixmap_priv->fbo->fb) {
+	if (src_pixmap_priv->base.fbo && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
 		int x_shift = abs(src_x_off - dx - dst_x_off);
 		int y_shift = abs(src_y_off - dy - dst_y_off);
 		for (i = 0; i < nbox; i++) {
@@ -333,7 +334,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	}
 #ifndef GLAMOR_GLES2
 	if ((overlaped
-	     || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
+	     || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
 	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
 					   dy)) {
 		ret = TRUE;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 009a089..8ba3347 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -43,9 +43,9 @@ glamor_get_drawable_location(const DrawablePtr drawable)
 	    glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
-	if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
+	if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0)
 		return 'm';
-	if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
+	if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
 		return 's';
 	else
 		return 'f';
@@ -327,7 +327,7 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 		glamor_restore_pixmap_to_texture(pixmap);
 	}
 
-	if (pixmap_priv->fbo->pbo != 0 && pixmap_priv->fbo->pbo_valid) {
+	if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
 		glamor_gl_dispatch *dispatch;
 
 		assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
@@ -335,20 +335,20 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 		dispatch = glamor_get_dispatch(glamor_priv);
 		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-		dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
+		dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
 		glamor_put_dispatch(glamor_priv);
 
-		pixmap_priv->fbo->pbo_valid = FALSE;
-		pixmap_priv->fbo->pbo = 0;
+		pixmap_priv->base.fbo->pbo_valid = FALSE;
+		pixmap_priv->base.fbo->pbo = 0;
 	} else {
 		free(pixmap->devPrivate.ptr);
 	}
 
 	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
-		pixmap->devKind = pixmap_priv->drm_stride;
+		pixmap->devKind = pixmap_priv->base.drm_stride;
 
-	if (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED)
-		pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
+	if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
+		pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
 
 	pixmap->devPrivate.ptr = NULL;
 }
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index 99dce04..f0c969b 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -107,8 +107,10 @@ AbortServer(void)
 		     _glamor_priv_->delayed_fallback_string);		\
       _glamor_priv_->delayed_fallback_pending = 0;  } } while(0)
 
-#define DEBUGF(str, ...)
+#define DEBUGF(str, ...)  do {} while(0)
 //#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
+#define DEBUGRegionPrint(x) do {} while (0)
+//#define DEBUGRegionPrint RegionPrint
 
 
 #endif
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index f4e02b2..5337149 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -412,11 +412,11 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
 	if (pixmap_priv == NULL)
 		return NULL;
 
-	fbo = pixmap_priv->fbo;
+	fbo = pixmap_priv->base.fbo;
 	if (fbo == NULL)
 		return NULL;
 
-	pixmap_priv->fbo = NULL;
+	pixmap_priv->base.fbo = NULL;
 	return fbo;
 }
 
@@ -434,25 +434,25 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 		pixmap_priv = calloc(1, sizeof(*pixmap_priv));
 		dixSetPrivate(&pixmap->devPrivates,
 			      glamor_pixmap_private_key, pixmap_priv);
-		pixmap_priv->container = pixmap;
-		pixmap_priv->glamor_priv = glamor_priv;
+		pixmap_priv->base.pixmap = pixmap;
+		pixmap_priv->base.glamor_priv = glamor_priv;
 		pixmap_priv->type = GLAMOR_MEMORY;
 	}
 
-	if (pixmap_priv->fbo)
+	if (pixmap_priv->base.fbo)
 		return;
 
-	pixmap_priv->fbo = fbo;
+	pixmap_priv->base.fbo = fbo;
 
 	switch (pixmap_priv->type) {
 	case GLAMOR_TEXTURE_ONLY:
 	case GLAMOR_TEXTURE_DRM:
-		pixmap_priv->gl_fbo = 1;
+		pixmap_priv->base.gl_fbo = 1;
 		if (fbo->tex != 0)
-			pixmap_priv->gl_tex = 1;
+			pixmap_priv->base.gl_tex = 1;
 		else {
 			/* XXX For the Xephyr only, may be broken now.*/
-			pixmap_priv->gl_tex = 0;
+			pixmap_priv->base.gl_tex = 0;
 		}
 	case GLAMOR_MEMORY_MAP:
 		pixmap->devPrivate.ptr = NULL;
@@ -472,7 +472,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
+	if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
 
 		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 					pixmap->drawable.height,
@@ -484,12 +484,12 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 		glamor_pixmap_attach_fbo(pixmap, fbo);
 	} else {
 		/* We do have a fbo, but it may lack of fb or tex. */
-		if (!pixmap_priv->fbo->tex)
-			pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
+		if (!pixmap_priv->base.fbo->tex)
+			pixmap_priv->base.fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
 								   pixmap->drawable.height, format);
 
-		if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
-			glamor_pixmap_ensure_fb(pixmap_priv->fbo);
+		if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
+			glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
 	}
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -504,7 +504,7 @@ glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
 
 	front_priv = glamor_get_pixmap_private(front);
 	back_priv = glamor_get_pixmap_private(back);
-	temp_fbo = front_priv->fbo;
-	front_priv->fbo = back_priv->fbo;
-	back_priv->fbo = temp_fbo;
+	temp_fbo = front_priv->base.fbo;
+	front_priv->base.fbo = back_priv->base.fbo;
+	back_priv->base.fbo = temp_fbo;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 57dd698..b63756d 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -239,7 +239,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
 
-	glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
+	glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, x1, y1, x2, y2,
 				     glamor_priv->yInverted, vertices);
 	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index ab2c2ed..09e33d7 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -806,14 +806,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	       *xscale, *yscale, x_source, y_source,
 	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
 
-	glamor_set_normalize_vcoords(*xscale, *yscale,
+	glamor_set_normalize_vcoords(pixmap_priv, *xscale, *yscale,
 	                             0, 0,
 	                             (INT16)(dst_picture->pDrawable->width),
 	                             (INT16)(dst_picture->pDrawable->height),
 	                             glamor_priv->yInverted, vertices);
 
 	if (tex_normalize) {
-		glamor_set_normalize_tcoords(*xscale, *yscale,
+		glamor_set_normalize_tcoords(pixmap_priv, *xscale, *yscale,
 		                             x_source, y_source,
 		                             (INT16)(dst_picture->pDrawable->width + x_source),
 		                             (INT16)(dst_picture->pDrawable->height + y_source),
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index a6d21f1..44e1e40 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -101,8 +101,8 @@ glamor_create_picture(PicturePtr picture)
 		}
 	}
 
-	pixmap_priv->is_picture = 1;
-	pixmap_priv->pict_format = picture->format;
+	pixmap_priv->base.is_picture = 1;
+	pixmap_priv->base.picture = picture;
 
 	return miCreatePicture(picture);
 }
@@ -123,8 +123,8 @@ glamor_destroy_picture(PicturePtr picture)
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 	if (pixmap_priv) {
-		pixmap_priv->is_picture = 0;
-		pixmap_priv->pict_format = 0;
+		pixmap_priv->base.is_picture = 0;
+		pixmap_priv->base.picture = NULL;
 	}
 	miDestroyPicture(picture);
 }
@@ -133,5 +133,5 @@ void
 glamor_picture_format_fixup(PicturePtr picture,
 			    glamor_pixmap_private * pixmap_priv)
 {
-	pixmap_priv->pict_format = picture->format;
+	pixmap_priv->base.picture = picture;
 }
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f0c1586..fa05bed 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -83,9 +83,9 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int w
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
-	glamor_set_destination_pixmap_fbo(pixmap_priv->fbo, 0, 0,
-					  pixmap_priv->container->drawable.width,
-					  pixmap_priv->container->drawable.height);
+	glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
+					  pixmap_priv->base.pixmap->drawable.width,
+					  pixmap_priv->base.pixmap->drawable.height);
 }
 
 int
@@ -495,8 +495,8 @@ ready_to_upload:
 	    && revert == REVERT_NONE
 	    && swap_rb == SWAP_NONE_UPLOADING
 	    && !need_flip) {
-		assert(pixmap_priv->fbo->tex);
-		__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
+		assert(pixmap_priv->base.fbo->tex);
+		__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
 						  format, type,
 						  x, y, w, h,
 						  bits, pbo);
@@ -509,7 +509,7 @@ ready_to_upload:
 		ptexcoords = texcoords_inv;
 
 	pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
-	glamor_set_normalize_vcoords(dst_xscale,
+	glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
 				     dst_yscale,
 				     x, y,
 				     x + w, y + h,
@@ -586,14 +586,14 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-	if (pixmap_priv->fbo
-	     && (pixmap_priv->fbo->width < pixmap->drawable.width
-           || pixmap_priv->fbo->height < pixmap->drawable.height)) {
+	if (pixmap_priv->base.fbo
+	     && (pixmap_priv->base.fbo->width < pixmap->drawable.width
+           || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
 		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
 		glamor_destroy_fbo(fbo);
         }
 
-	if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
+	if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
 		return 0;
 
 	if (!(no_alpha
@@ -605,8 +605,8 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 		flag = GLAMOR_CREATE_FBO_NO_FBO;
 	}
 
-	if ((flag == 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->tex)
-	    || (flag != 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->fb))
+	if ((flag == 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
+	    || (flag != 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
 		return 0;
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -614,7 +614,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	else
 		iformat = format;
 
-	if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
+	if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
 
 		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 					pixmap->drawable.height,
@@ -672,10 +672,10 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 	if (pixmap_priv
-	    && (pixmap_priv->fbo)
-	    && (pixmap_priv->fbo->pbo_valid)) {
+	    && (pixmap_priv->base.fbo)
+	    && (pixmap_priv->base.fbo->pbo_valid)) {
 		data = NULL;
-		pbo = pixmap_priv->fbo->pbo;
+		pbo = pixmap_priv->base.fbo->pbo;
 	} else {
 		data = pixmap->devPrivate.ptr;
 		pbo = 0;
@@ -737,7 +737,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 	temp_xscale = 1.0 / w;
 	temp_yscale = 1.0 / h;
 
-	glamor_set_normalize_vcoords(temp_xscale,
+	glamor_set_normalize_vcoords((glamor_pixmap_private *)NULL, temp_xscale,
 				     temp_yscale,
 				     0, 0,
 				     w, h,
@@ -750,7 +750,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
 	pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
-	glamor_set_normalize_tcoords(source_xscale,
+	glamor_set_normalize_tcoords(source_priv, source_xscale,
 				     source_yscale,
 				     x, y,
 				     x + w, y + h,
@@ -763,7 +763,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
 	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
 				  GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
@@ -988,16 +988,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		data = malloc(stride * pixmap->drawable.height);
 	} else {
 		dispatch = glamor_get_dispatch(glamor_priv);
-		if (pixmap_priv->fbo->pbo == 0)
+		if (pixmap_priv->base.fbo->pbo == 0)
 			dispatch->glGenBuffers(1,
-					       &pixmap_priv->fbo->pbo);
+					       &pixmap_priv->base.fbo->pbo);
 		glamor_put_dispatch(glamor_priv);
-		pbo = pixmap_priv->fbo->pbo;
+		pbo = pixmap_priv->base.fbo->pbo;
 	}
 
 	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
 		stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
-		pixmap_priv->drm_stride = pixmap->devKind;
+		pixmap_priv->base.drm_stride = pixmap->devKind;
 		pixmap->devKind = stride;
 	}
 
@@ -1014,9 +1014,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	}
 
 	if (pbo != 0)
-		pixmap_priv->fbo->pbo_valid = 1;
+		pixmap_priv->base.fbo->pbo_valid = 1;
 
-	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
+	pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
 
 	pixmap->devPrivate.ptr = dst;
 
@@ -1036,14 +1036,14 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 	GCPtr gc = NULL;
 	int ret = FALSE;
 
-	drawable = &pixmap_priv->container->drawable;
+	drawable = &pixmap_priv->base.pixmap->drawable;
 
-	if (pixmap_priv->container->drawable.width == pixmap_priv->fbo->width
-	    && pixmap_priv->container->drawable.height == pixmap_priv->fbo->height)
+	if (pixmap_priv->base.pixmap->drawable.width == pixmap_priv->base.fbo->width
+	    && pixmap_priv->base.pixmap->drawable.height == pixmap_priv->base.fbo->height)
 		return	TRUE;
 
-	old_fbo = pixmap_priv->fbo;
-	glamor_priv = pixmap_priv->glamor_priv;
+	old_fbo = pixmap_priv->base.fbo;
+	glamor_priv = pixmap_priv->base.glamor_priv;
 
 	if (!old_fbo)
 		return FALSE;
@@ -1058,7 +1058,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 
 	scratch_priv = glamor_get_pixmap_private(scratch);
 
-	if (!scratch_priv || !scratch_priv->fbo)
+	if (!scratch_priv || !scratch_priv->base.fbo)
 		goto fail;
 
 	ValidateGC(&scratch->drawable, gc);
@@ -1069,7 +1069,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
 			 0, 0);
 	old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
 	new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
-	glamor_pixmap_attach_fbo(pixmap_priv->container, new_fbo);
+	glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
 	glamor_pixmap_attach_fbo(scratch, old_fbo);
 
 	DEBUGF("old %dx%d type %d\n",
@@ -1139,11 +1139,11 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 		return NULL;
 
 	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
-	pbo = sub_pixmap_priv ? (sub_pixmap_priv->fbo ? sub_pixmap_priv->fbo->pbo : 0): 0;
+	pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
 
-	if (pixmap_priv->is_picture) {
-		sub_pixmap_priv->pict_format = pixmap_priv->pict_format;
-		sub_pixmap_priv->is_picture = pixmap_priv->is_picture;
+	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
+		sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
+		sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
 	}
 
 	if (pbo)
@@ -1157,7 +1157,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	if (pbo) {
 		assert(sub_pixmap->devPrivate.ptr == NULL);
 		sub_pixmap->devPrivate.ptr = data;
-		sub_pixmap_priv->fbo->pbo_valid = 1;
+		sub_pixmap_priv->base.fbo->pbo_valid = 1;
 	}
 #if 0
 	struct pixman_box16 box;
@@ -1189,10 +1189,10 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
 	if (access != GLAMOR_ACCESS_RO) {
 		sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
 		if (sub_pixmap_priv
-		    && sub_pixmap_priv->fbo
-		    && sub_pixmap_priv->fbo->pbo_valid) {
+		    && sub_pixmap_priv->base.fbo
+		    && sub_pixmap_priv->base.fbo->pbo_valid) {
 			bits = NULL;
-			pbo = sub_pixmap_priv->fbo->pbo;
+			pbo = sub_pixmap_priv->base.fbo->pbo;
 		} else {
 			bits = sub_pixmap->devPrivate.ptr;
 			pbo = 0;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a817f78..2172d17 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -309,19 +309,132 @@ typedef struct glamor_pixmap_fbo {
  * @gl_tex:  The pixmap is in a gl texture originally.
  * @is_picture: The drawable is attached to a picture.
  * @pict_format: the corresponding picture's format.
- * @container: The corresponding pixmap's pointer.
+ * @pixmap: The corresponding pixmap's pointer.
+ *
+ * For GLAMOR_TEXTURE_LARGE, nbox should larger than 1.
+ * And the box and fbo will both have nbox elements.
+ * and box[i] store the relatively coords in this pixmap
+ * of the fbo[i]. The reason why use boxes not region to
+ * represent this structure is we may need to use overlapped
+ * boxes for one pixmap for some special reason.
+ *
+ * pixmap
+ * ******************
+ * *  fbo0 * fbo1   *
+ * *       *        *
+ * ******************
+ * *  fbo2 * fbo3   *
+ * *       *        *
+ * ******************
+ *
+ * Let's assume the texture has size of 1024x1024
+ * box[0] = {0,0,1024,1024}
+ * box[1] = {1024,0,2048,2048}
+ * ...
+ *
+ * For GLAMOR_TEXTURE_ATLAS nbox should be 1. And box
+ * and fbo both has one elements, and the box store
+ * the relatively coords in the fbo of this pixmap:
+ *
+ * fbo
+ * ******************
+ * *   pixmap       *
+ * *   *********    *
+ * *   *       *    *
+ * *   *********    *
+ * *                *
+ * ******************
+ *
+ * Assume the pixmap is at the (100,100) relatively to
+ * the fbo's origin.
+ * box[0]={100, 100, 1124, 1124};
+ *
+ * Considering large pixmap is not a normal case, to keep
+ * it simple, I designe it as the following way.
+ * When deal with a large pixmap, it split the working
+ * rectangle into serval boxes, and each box fit into a
+ * corresponding fbo. And then the rendering function will
+ * loop from the left-top box to the right-bottom box,
+ * each time, we will set current box and current fbo
+ * to the box and fbo elements. Thus the inner routines
+ * can handle it as normal, only the coords calculation need
+ * to aware of it's large pixmap.
+ *
+ * Currently, we haven't implemented the atlas pixmap.
+ *
  **/
-typedef struct glamor_pixmap_private {
+
+typedef struct glamor_pixmap_clipped_regions{
+	int block_idx;
+	RegionPtr region;
+} glamor_pixmap_clipped_regions;
+
+#define SET_PIXMAP_FBO_CURRENT(priv, idx) 				\
+  do {									\
+	if (priv->type == GLAMOR_TEXTURE_LARGE) {			\
+		(priv)->large.base.fbo = priv->large.fbo_array[idx]; 	\
+		(priv)->large.box = priv->large.box_array[idx]; 	\
+	}								\
+  } while(0)
+
+typedef struct glamor_pixmap_private_base {
+	glamor_pixmap_type_t type;
 	unsigned char gl_fbo:2;
 	unsigned char is_picture:1;
 	unsigned char gl_tex:1;
-	glamor_pixmap_type_t type;
 	glamor_pixmap_fbo *fbo;
-	PictFormatShort pict_format;
-	PixmapPtr container;
+	PixmapPtr pixmap;
 	int drm_stride;
 	glamor_screen_private *glamor_priv;
-} glamor_pixmap_private;
+	PicturePtr picture;
+}glamor_pixmap_private_base_t;
+
+/*
+ * @base.fbo: current fbo.
+ * @box: current fbo's coords in the whole pixmap.
+ * @block_w: block width of this large pixmap.
+ * @block_h: block height of this large pixmap.
+ * @block_wcnt: block count in one block row.
+ * @block_hcnt: block count in one block column.
+ * @nbox: total block count.
+ * @box_array: contains each block's corresponding box.
+ * @fbo_array: contains each block's fbo pointer.
+ *
+ **/
+typedef struct glamor_pixmap_private_large {
+	union {
+		glamor_pixmap_type_t type;
+		glamor_pixmap_private_base_t base;
+	};
+	BoxRec box;
+	int block_w;
+	int block_h;
+	int block_wcnt;
+	int block_hcnt;
+	int nbox;
+	BoxPtr box_array;
+	glamor_pixmap_fbo **fbo_array;
+}glamor_pixmap_private_large_t;
+
+/*
+ * @box: the relative coords in the corresponding fbo.
+ */
+typedef struct glamor_pixmap_private_atlas {
+	union {
+		glamor_pixmap_type_t type;
+		glamor_pixmap_private_base_t base;
+	};
+	BoxRec box;
+}glamor_pixmap_private_atlas_t;
+
+typedef struct glamor_pixmap_private {
+	union {
+		glamor_pixmap_type_t type;
+		glamor_pixmap_private_base_t base;
+		glamor_pixmap_private_large_t large;
+		glamor_pixmap_private_atlas_t atlas;
+	};
+}glamor_pixmap_private;
 
 /* 
  * Pixmap dynamic status, used by dynamic upload feature.
@@ -404,6 +517,7 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_pri
 glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
 				      int w, int h, GLenum format, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
+void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
 void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
@@ -413,6 +527,11 @@ void glamor_fbo_expire(glamor_screen_private *glamor_priv);
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
 
+glamor_pixmap_fbo *
+glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+			int w, int h, GLenum format, int flag,
+			int block_w, int block_h, glamor_pixmap_private *);
+
 Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
 
 /* glamor_copyarea.c */
@@ -543,6 +662,19 @@ void glamor_init_putimage_shaders(ScreenPtr screen);
 void glamor_fini_putimage_shaders(ScreenPtr screen);
 
 /* glamor_render.c */
+Bool
+glamor_composite_clipped_region(CARD8 op,
+				PicturePtr source,
+				PicturePtr mask,
+				PicturePtr dest,
+				RegionPtr region,
+				int x_source,
+				int y_source,
+				int x_mask,
+				int y_mask,
+				int x_dest,
+				int y_dest);
+
 void glamor_composite(CARD8 op,
 		      PicturePtr pSrc,
 		      PicturePtr pMask,
@@ -552,6 +684,7 @@ void glamor_composite(CARD8 op,
 		      INT16 xMask,
 		      INT16 yMask,
 		      INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+
 void glamor_trapezoids(CARD8 op,
 		       PicturePtr src, PicturePtr dst,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
@@ -654,7 +787,6 @@ Bool
 glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
 				    int stride, void *bits, int pbo);
 
-
 PixmapPtr
 glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
 		      int w, int h, glamor_access_t access);
@@ -662,6 +794,44 @@ void
 glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
 		      int w, int h, glamor_access_t access);
 
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *clipped_nbox, int repeat_type);
+
+glamor_pixmap_clipped_regions *
+glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+				   RegionPtr region,
+				   int *n_region,
+				   int inner_block_w, int inner_block_h);
+
+glamor_pixmap_clipped_regions *
+glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
+					 RegionPtr region, int *n_region, int dx, int dy, int repeat_type);
+
+Bool
+glamor_composite_largepixmap_region(CARD8 op,
+			  PicturePtr source,
+			  PicturePtr mask,
+			  PicturePtr dest,
+			  glamor_pixmap_private * source_pixmap_priv,
+			  glamor_pixmap_private * mask_pixmap_priv,
+			  glamor_pixmap_private * dest_pixmap_priv,
+			  RegionPtr region, Bool force_clip,
+			  INT16 x_source,
+			  INT16 y_source,
+			  INT16 x_mask,
+			  INT16 y_mask,
+			  INT16 x_dest, INT16 y_dest,
+			  CARD16 width, CARD16 height);
+
+Bool
+glamor_get_transform_block_size(struct pixman_transform *transform,
+			   int block_w, int block_h,
+			   int *transformed_block_w,
+			   int *transformed_block_h);
+
+void
+glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
+		struct pixman_transform *transform);
 
 /**
  * Upload a picture to gl texture. Similar to the
@@ -757,5 +927,6 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
 #endif
+#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index d1e3a83..6d62bd7 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -295,9 +295,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
-		if (pixmap_priv->is_picture) {
-			temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
-			temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
+		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
+			temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
+			temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
 		}
 
 		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 907d65b..6a584ba 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -545,7 +545,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
-	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
 	repeat_type = picture->repeatType;
 	switch (picture->repeatType) {
 	case RepeatNone:
@@ -1047,7 +1047,7 @@ glamor_composite_with_shader(CARD8 op,
 			glamor_fallback("source == dest\n");
 			goto fail;
 		}
-		if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
+		if (!source_pixmap_priv || source_pixmap_priv->base.gl_fbo == 0) {
 			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
 			 * equal to zero when the pixmap is screen pixmap. Then we may
 			 * refer the tex zero directly latter in the composition. 
@@ -1068,7 +1068,7 @@ glamor_composite_with_shader(CARD8 op,
 			glamor_fallback("mask == dest\n");
 			goto fail;
 		}
-		if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) {
+		if (!mask_pixmap_priv || mask_pixmap_priv->base.gl_fbo == 0) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 			mask_status = GLAMOR_UPLOAD_PENDING;
 #else
@@ -1259,7 +1259,7 @@ glamor_composite_with_shader(CARD8 op,
 			width = rects->width;
 			height = rects->height;
 
-			glamor_set_normalize_vcoords(dst_xscale,
+			glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
 						     dst_yscale,
 						     x_dest, y_dest,
 						     x_dest + width, y_dest + height,
@@ -1269,14 +1269,14 @@ glamor_composite_with_shader(CARD8 op,
 			if (key.source != SHADER_SOURCE_SOLID) {
 				if (source->transform)
 					glamor_set_transformed_normalize_tcoords
-						(src_matrix, src_xscale,
+						(source_pixmap_priv, src_matrix, src_xscale,
 						 src_yscale, x_source, y_source,
 						 x_source + width, y_source + height,
 						 glamor_priv->yInverted,
 						 source_texcoords);
 				else
 					glamor_set_normalize_tcoords
-						(src_xscale, src_yscale,
+						(source_pixmap_priv, src_xscale, src_yscale,
 						 x_source, y_source,
 						 x_source + width, y_source + height,
 						 glamor_priv->yInverted,
@@ -1287,7 +1287,7 @@ glamor_composite_with_shader(CARD8 op,
 			    && key.mask != SHADER_MASK_SOLID) {
 				if (mask->transform)
 					glamor_set_transformed_normalize_tcoords
-						(mask_matrix,
+						(mask_pixmap_priv, mask_matrix,
 						 mask_xscale,
 						 mask_yscale, x_mask, y_mask,
 						 x_mask + width, y_mask + height,
@@ -1295,7 +1295,7 @@ glamor_composite_with_shader(CARD8 op,
 						 mask_texcoords);
 				else
 					glamor_set_normalize_tcoords
-						(mask_xscale,
+						(mask_pixmap_priv, mask_xscale,
 						 mask_yscale, x_mask, y_mask,
 						 x_mask + width, y_mask + height,
 						 glamor_priv->yInverted,
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 6790550..c6b88d2 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -166,13 +166,12 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 			      &src_yscale);
 	dispatch->glUseProgram(glamor_priv->tile_prog);
 
-	wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
-	wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
+	glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
 
 	dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D,
-				src_pixmap_priv->fbo->tex);
+				src_pixmap_priv->base.fbo->tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
 				  GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
@@ -186,7 +185,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	glamor_set_normalize_tcoords(src_xscale, src_yscale,
+	glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
+				     src_yscale,
 				     tile_x1, tile_y1,
 				     tile_x2, tile_y2,
 				     glamor_priv->yInverted,
@@ -197,7 +197,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 					source_texcoords);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-	glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+	glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
+				     dst_yscale,
 				     x1, y1, x2, y2,
 				     glamor_priv->yInverted, vertices);
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 4af6739..90a1657 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -41,26 +41,50 @@
 
 #define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
-    *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width;	\
-    *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height;	\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.width;			\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.height;			\
   } while(0)
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
-    *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
-    *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width;			\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height;			\
   } while(0)
 
-#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv)				\
-	(priv->fbo->width != priv->container->drawable.width 	\
-	 || priv->fbo->height != priv->container->drawable.height)
+#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv)			\
+   (priv->base.fbo->width != priv->base.pixmap->drawable.width 	\
+      || priv->base.fbo->height != priv->base.pixmap->drawable.height)	\
+
+#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h)			\
+  do {								\
+	if (priv->type == GLAMOR_TEXTURE_LARGE) {		\
+		w = priv->large.box.x2 - priv->large.box.x1;	\
+		h = priv->large.box.y2 - priv->large.box.y1;	\
+	} else {						\
+		w = priv->base.pixmap->drawable.width;		\
+		h = priv->base.pixmap->drawable.height;		\
+	}							\
+  } while(0)
+
+#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv)  		\
+  do {								\
+	int actual_w, actual_h;					\
+	PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h);	\
+	wh[0] = (float)priv->base.fbo->width / actual_w;	\
+	wh[1] = (float)priv->base.fbo->height / actual_h;	\
+  } while(0)
 
-#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv)  do {			\
-	wh[0] = (float)priv->fbo->width					\
-		/ priv->container->drawable.width;			\
-	wh[1] = (float)priv->fbo->height				\
-		/ priv->container->drawable.height;			\
-	} while(0)
+#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
+   do {								\
+	if (_priv_ && (_priv_)->type				\
+		== GLAMOR_TEXTURE_LARGE) {			\
+		*(_xoff_) = - (_priv_)->large.box.x1;	\
+		*(_yoff_) = - (_priv_)->large.box.y1;	\
+	} else {						\
+		*(_xoff_) = 0;					\
+		*(_yoff_) = 0;					\
+	}							\
+   } while(0)
 
 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
 			      + ((float)xFixedFrac(_val_) / 65536.0))
@@ -82,67 +106,113 @@
       }									\
   }  while(0)
 
-#define glamor_set_transformed_point(matrix, xscale, yscale, texcoord,	\
-                                     x, y, yInverted)			\
+#define glamor_transform_point(matrix, tx, ty, x, y)			\
   do {									\
-    float result[4];							\
     int i;								\
-    float tx, ty;							\
-									\
+    float result[4];							\
     for (i = 0; i < 3; i++) {						\
       result[i] = (matrix)[i * 3] * (x) + (matrix)[i * 3 + 1] * (y)	\
 	+ (matrix)[i * 3 + 2];						\
     }									\
     tx = result[0] / result[2];						\
     ty = result[1] / result[2];						\
+  } while(0)
+
+#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_,	\
+				     texcoord, yInverted)		\
+  do {									\
+	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
+	if (yInverted)							\
+		(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
+	else								\
+		(texcoord)[1] = t_from_x_coord_y(yscale, _ty_);		\
+        DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0],	\
+		(texcoord)[1]);						\
+  } while(0)
+
+#define glamor_set_transformed_point(priv, matrix, xscale,		\
+				     yscale, texcoord,			\
+                                     x, y, 				\
+				     yInverted)				\
+  do {									\
+    float tx, ty;							\
+    int fbo_x_off, fbo_y_off;						\
+    pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
+    glamor_transform_point(matrix, tx, ty, x, y);			\
+    DEBUGF("tx %f ty %f fbooff %d %d \n",				\
+	    tx, ty, fbo_x_off, fbo_y_off);				\
 									\
+    tx += fbo_x_off;							\
+    ty += fbo_y_off;							\
     (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
     if (yInverted)							\
       (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty);		\
     else								\
       (texcoord)[1] = t_from_x_coord_y(yscale, ty);			\
+    DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]);	\
   } while(0)
 
-
-#define glamor_set_transformed_normalize_tcoords( matrix,		\
+#define glamor_set_transformed_normalize_tcoords( priv,			\
+						  matrix,		\
 						  xscale,		\
 						  yscale,		\
                                                   tx1, ty1, tx2, ty2,   \
                                                   yInverted, texcoords)	\
   do {									\
-    glamor_set_transformed_point(matrix, xscale, yscale,		\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
 				 texcoords, tx1, ty1,			\
 				 yInverted);				\
-    glamor_set_transformed_point(matrix, xscale, yscale,		\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
 				 texcoords + 2, tx2, ty1,		\
 				 yInverted);				\
-    glamor_set_transformed_point(matrix, xscale, yscale,		\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
 				 texcoords + 4, tx2, ty2,		\
 				 yInverted);				\
-    glamor_set_transformed_point(matrix, xscale, yscale,		\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
 				 texcoords + 6, tx1, ty2,		\
 				 yInverted);				\
   } while (0)
 
-#define glamor_set_normalize_tcoords(xscale, yscale, x1, y1, x2, y2,	\
-                                     yInverted, vertices)		\
+#define _glamor_set_normalize_tcoords(xscale, yscale, tx1,		\
+				      ty1, tx2, ty2,			\
+				      yInverted, vertices)		\
   do {									\
-    (vertices)[0] = t_from_x_coord_x(xscale, x1);			\
-    (vertices)[2] = t_from_x_coord_x(xscale, x2);			\
+    (vertices)[0] = t_from_x_coord_x(xscale, tx1);			\
+    (vertices)[2] = t_from_x_coord_x(xscale, tx2);			\
     (vertices)[4] = (vertices)[2];					\
     (vertices)[6] = (vertices)[0];					\
     if (yInverted) {							\
-      (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);		\
-      (vertices)[5] = t_from_x_coord_y_inverted(yscale, y2);		\
+      (vertices)[1] = t_from_x_coord_y_inverted(yscale, ty1);		\
+      (vertices)[5] = t_from_x_coord_y_inverted(yscale, ty2);		\
     }									\
     else {								\
-      (vertices)[1] = t_from_x_coord_y(yscale, y1);			\
-      (vertices)[5] = t_from_x_coord_y(yscale, y2);			\
+      (vertices)[1] = t_from_x_coord_y(yscale, ty1);			\
+      (vertices)[5] = t_from_x_coord_y(yscale, ty2);			\
     }									\
     (vertices)[3] = (vertices)[1];					\
     (vertices)[7] = (vertices)[5];					\
+    DEBUGF("texture %f %f %f %f\n", tx1, ty1, tx2, ty2);		\
+    DEBUGF("texture %f %f %f %f\n", (vertices)[0], (vertices)[1],	\
+	(vertices)[2], (vertices)[3]);					\
+    DEBUGF("texture %f %f %f %f\n", (vertices)[4], (vertices)[5],	\
+	(vertices)[6], (vertices)[7]);					\
   } while(0)
 
+#define glamor_set_normalize_tcoords(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     yInverted, vertices)		\
+  do {									\
+     float tx1, tx2, ty1, ty2;						\
+     int fbo_x_off, fbo_y_off;						\
+     pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
+     tx1 = x1 + fbo_x_off; 						\
+     tx2 = x2 + fbo_x_off;						\
+     ty1 = y1 + fbo_y_off;						\
+     ty2 = y2 + fbo_y_off;						\
+     _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
+				   tx2, ty2, yInverted, vertices);	\
+ } while(0)
+
 #define glamor_set_tcoords(width, height, x1, y1, x2, y2,	\
 			   yInverted, vertices)			\
     do {							\
@@ -163,24 +233,27 @@
     } while(0)
 
 
-#define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,	\
+#define glamor_set_normalize_vcoords(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
                                      yInverted, vertices)		\
-    do {								\
-	(vertices)[0] = v_from_x_coord_x(xscale, x1);			\
-	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
-	(vertices)[4] = (vertices)[2];					\
-	(vertices)[6] = (vertices)[0];					\
-	if (yInverted) {						\
-	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);	\
-	    (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2);	\
-	}								\
-	else {								\
-	    (vertices)[1] = v_from_x_coord_y(yscale, y1);		\
-	    (vertices)[5] = v_from_x_coord_y(yscale, y2);		\
-	}								\
-	(vertices)[3] = (vertices)[1];					\
-	(vertices)[7] = (vertices)[5];					\
-    } while(0)
+  do {									\
+    int fbo_x_off, fbo_y_off;						\
+    pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
+    (vertices)[0] = v_from_x_coord_x(xscale, x1 + fbo_x_off);		\
+    (vertices)[2] = v_from_x_coord_x(xscale, x2 + fbo_x_off);		\
+    (vertices)[4] = (vertices)[2];					\
+    (vertices)[6] = (vertices)[0];					\
+    if (yInverted) {							\
+      (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1 + fbo_y_off);\
+      (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2 + fbo_y_off);\
+    }									\
+    else {								\
+      (vertices)[1] = v_from_x_coord_y(yscale, y1 + fbo_y_off);		\
+      (vertices)[5] = v_from_x_coord_y(yscale, y2 + fbo_y_off);		\
+    }									\
+    (vertices)[3] = (vertices)[1];					\
+    (vertices)[7] = (vertices)[5];					\
+  } while(0)
 
 #define glamor_set_normalize_pt(xscale, yscale, x, y,		\
                                 yInverted, pt)			\
@@ -244,10 +317,11 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
+#define MAX(a,b)	((a) > (b) ? (a) : (b))
 
 #define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
-                                                    && (_w_) < _glamor_->max_fbo_size  \
-                                                    && (_h_) < _glamor_->max_fbo_size)
+                                                    && (_w_) <= _glamor_->max_fbo_size  \
+                                                    && (_h_) <= _glamor_->max_fbo_size)
 
 /* For 1bpp pixmap, we don't store it as texture. */
 #define glamor_check_pixmap_fbo_depth(_depth_) (			\
@@ -258,9 +332,9 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 						|| _depth_ == 30	\
 						|| _depth_ == 32)
 
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED))
 
 /**
  * Borrow from uxa.
@@ -315,7 +389,7 @@ format_for_pixmap(PixmapPtr pixmap)
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-		pict_format = pixmap_priv->pict_format;
+		pict_format = pixmap_priv->base.picture->format;
 	else
 		pict_format = format_for_depth(pixmap->drawable.depth);
 
@@ -659,7 +733,7 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-		pict_format = pixmap_priv->pict_format;
+		pict_format = pixmap_priv->base.picture->format;
 	else
 		pict_format = format_for_depth(pixmap->drawable.depth);
 
@@ -783,6 +857,24 @@ inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc)
         }
 	return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
 }
+inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap)
+{
+	glamor_pixmap_private *priv;
+
+	priv = glamor_get_pixmap_private(pixmap);
+	return (priv->type == GLAMOR_TEXTURE_LARGE);
+}
+
+inline static Bool glamor_is_large_picture(PicturePtr picture)
+{
+	PixmapPtr pixmap;
+
+	if (picture->pDrawable) {
+		pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+		return glamor_is_large_pixmap(pixmap);
+	}
+	return FALSE;
+}
 
 inline static Bool glamor_tex_format_is_readable(GLenum format)
 {
commit 4c174f4c9ce1514ef226e9de97e5c87a46a75524
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue May 15 10:08:03 2012 +0800

    Fix the problem of x_source and y_source causing radial error
    
     The x_source and y_source cause some problem in
     gradient. The old way to handle it by recaulate P1 P2
     to minus the x_source and y_source, but this causes
     problem in radial shader. Now we modify the manner to
     set the texture coordinates: (x_source, y_source) -->
     (x_source + width, y_source + height) to handle all the
     cases.
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 8e1d06a..ab2c2ed 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -814,14 +814,16 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 
 	if (tex_normalize) {
 		glamor_set_normalize_tcoords(*xscale, *yscale,
-		                             0, 0,
-		                             (INT16)(dst_picture->pDrawable->width),
-		                             (INT16)(dst_picture->pDrawable->height),
+		                             x_source, y_source,
+		                             (INT16)(dst_picture->pDrawable->width + x_source),
+		                             (INT16)(dst_picture->pDrawable->height + y_source),
 		                             glamor_priv->yInverted, tex_vertices);
 	} else {
-		glamor_set_tcoords(0, 0,
-		                   (INT16)(dst_picture->pDrawable->width),
+		glamor_set_tcoords((INT16)(dst_picture->pDrawable->width),
 		                   (INT16)(dst_picture->pDrawable->height),
+		                   x_source, y_source,
+		                   (INT16)(dst_picture->pDrawable->width) + x_source,
+		                   (INT16)(dst_picture->pDrawable->height) + y_source,
 		                   glamor_priv->yInverted, tex_vertices);
 	}
 
@@ -1201,14 +1203,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius);
 	r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius);
 
-
-	cxy[0] = c1x;
-	cxy[1] = c1y;
+	glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted, cxy);
 	dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
 	dispatch->glUniform1f(r1_uniform_location, r1);
 
-	cxy[0] = c2x;
-	cxy[1] = c2y;
+	glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted, cxy);
 	dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
 	dispatch->glUniform1f(r2_uniform_location, r2);
 
@@ -1282,7 +1281,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	int count = 0;
 	float slope;
 	GLfloat xscale, yscale;
-	GLfloat pt1[4], pt2[4];
+	GLfloat pt1[2], pt2[2];
 	float vertices[8];
 	float transform_mat[3][3];
 	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
@@ -1292,8 +1291,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	GLfloat n_stops_st[LINEAR_SMALL_STOPS];
 
 	GLint transform_mat_uniform_location = 0;
-	GLint pt1_uniform_location = 0;
-	GLint pt2_uniform_location = 0;
 	GLint n_stop_uniform_location = 0;
 	GLint stops_uniform_location = 0;
 	GLint stop0_uniform_location = 0;
@@ -1441,24 +1438,20 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
 	/* Normalize the PTs. */
 	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.x),
-	                        x_source,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.y),
-	                        y_source,
+	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
+	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
 	                        glamor_priv->yInverted,
 	                        pt1);
-	dispatch->glUniform4fv(pt1_uniform_location, 1, pt1);
-	DEBUGF("pt1:(%f %f)\n", pt1[0], pt1[1]);
+	DEBUGF("pt1:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
+	       pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y), pt1[0], pt1[1]);
 
 	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.x),
-	                        x_source,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.y),
-	                        y_source,
+	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
+	                        pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
 	                        glamor_priv->yInverted,
 	                        pt2);
-	dispatch->glUniform4fv(pt2_uniform_location, 1, pt2);
-	DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
+	DEBUGF("pt2:(%f, %f) ---> (%f %f)\n", pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
+	       pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y), pt2[0], pt2[1]);
 
 	/* Set all the stops and colors to shader. */
 	if (stops_count > LINEAR_SMALL_STOPS) {
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 8dad2df..4af6739 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -143,54 +143,65 @@
     (vertices)[7] = (vertices)[5];					\
   } while(0)
 
-#define glamor_set_tcoords(x1, y1, x2, y2, yInverted, vertices)	    \
-    do {                                                            \
-      (vertices)[0] = (x1);                                         \
-      (vertices)[2] = (x2);                                         \
-      (vertices)[4] = (vertices)[2];                                \
-      (vertices)[6] = (vertices)[0];                                \
-      if (yInverted) {                                              \
-          (vertices)[1] = (y1);                                     \
-          (vertices)[5] = (y2);                                     \
-      }                                                             \
-      else {                                                        \
-          (vertices)[1] = (y2);                                     \
-          (vertices)[5] = (y1);                                     \
-      }                                                             \
-      (vertices)[3] = (vertices)[1];                \
-      (vertices)[7] = (vertices)[5];                \
+#define glamor_set_tcoords(width, height, x1, y1, x2, y2,	\
+			   yInverted, vertices)			\
+    do {							\
+	(vertices)[0] = (x1);					\
+	(vertices)[2] = (x2);					\
+	(vertices)[4] = (vertices)[2];				\
+	(vertices)[6] = (vertices)[0];				\
+	if (yInverted) {					\
+	    (vertices)[1] = (y1);				\
+	    (vertices)[5] = (y2);				\
+	}							\
+	else {							\
+	    (vertices)[1] = height - (y2);			\
+	    (vertices)[5] = height - (y1);			\
+	}							\
+	(vertices)[3] = (vertices)[1];				\
+	(vertices)[7] = (vertices)[5];				\
     } while(0)
 
 
 #define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,	\
                                      yInverted, vertices)		\
-  do {									\
-    (vertices)[0] = v_from_x_coord_x(xscale, x1);			\
-    (vertices)[2] = v_from_x_coord_x(xscale, x2);			\
-    (vertices)[4] = (vertices)[2];					\
-    (vertices)[6] = (vertices)[0];					\
-    if (yInverted) {							\
-      (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);		\
-      (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2);		\
-    }									\
-    else {								\
-      (vertices)[1] = v_from_x_coord_y(yscale, y1);			\
-      (vertices)[5] = v_from_x_coord_y(yscale, y2);			\
-    }									\
-    (vertices)[3] = (vertices)[1];					\
-    (vertices)[7] = (vertices)[5];					\
-  } while(0)
+    do {								\
+	(vertices)[0] = v_from_x_coord_x(xscale, x1);			\
+	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
+	(vertices)[4] = (vertices)[2];					\
+	(vertices)[6] = (vertices)[0];					\
+	if (yInverted) {						\
+	    (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);	\
+	    (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2);	\
+	}								\
+	else {								\
+	    (vertices)[1] = v_from_x_coord_y(yscale, y1);		\
+	    (vertices)[5] = v_from_x_coord_y(yscale, y2);		\
+	}								\
+	(vertices)[3] = (vertices)[1];					\
+	(vertices)[7] = (vertices)[5];					\
+    } while(0)
+
+#define glamor_set_normalize_pt(xscale, yscale, x, y,		\
+                                yInverted, pt)			\
+    do {							\
+        (pt)[0] = t_from_x_coord_x(xscale, x);			\
+        if (yInverted) {					\
+            (pt)[1] = t_from_x_coord_y_inverted(yscale, y);	\
+        } else {						\
+            (pt)[1] = t_from_x_coord_y(yscale, y);		\
+        }							\
+    } while(0)
 
-#define glamor_set_normalize_pt(xscale, yscale, x, x_start, y, y_start,     \
-                                yInverted, pt)                              \
-    do {                                                                    \
-        (pt)[0] = t_from_x_coord_x(xscale, x - x_start);                    \
-        if (yInverted) {                                                    \
-            (pt)[1] = t_from_x_coord_y_inverted(yscale, y - y_start);       \
-        } else {                                                            \
-            (pt)[1] = t_from_x_coord_y(yscale, y - y_start);                \
-        }                                                                   \
-        (pt)[2] = (pt)[3] = 0.0;                                            \
+#define glamor_set_circle_centre(width, height, x, y,	\
+				 yInverted, c)		\
+    do {						\
+        (c)[0] = (float)x;				\
+        if (yInverted) {				\
+            (c)[1] = (float)y;				\
+        } else {					\
+            (c)[1] = (float)height - (float)y;		\
+        }						\
     } while(0)
 
 inline static void
commit 553910d08b93ef80cc25fcbfd7876726778bc655
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue May 15 10:07:55 2012 +0800

    Fix the problem of vertical and horizontal case error in linear gradient.
    
     1. The vertical and horizontal judgement in linear
     gradient have problem when p1 point and p2 point
     distance is very small but the gradient pict have a
     transform matrix which will convert the X Y coordinates
     to small values. So the judgement is not suitable.
     Because this judgement's purpose is to assure the
     divisor not to be zero, so we simply it to enter
     horizontal judgement when p1 and p2's Y is same.
     Vertical case is deleted. 2. Delete the unused p1 p2
     uniform variable.
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index b24dc9f..8e1d06a 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -491,8 +491,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 	    "uniform mat3 transform_mat;\n"
 	    "uniform int repeat_type;\n"
 	    "uniform int hor_ver;\n"
-	    "uniform vec4 pt1;\n"
-	    "uniform vec4 pt2;\n"
 	    "uniform float pt_slope;\n"
 	    "uniform float cos_val;\n"
 	    "uniform float p1_distance;\n"
@@ -529,10 +527,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 	    "        distance = source_texture_trans.x;\n"
 	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
 	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } else if (hor_ver == 2) {\n"//vertical case.
-	    "        distance = source_texture_trans.y;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
 	    "    } \n"
 	    "    \n"
 	    "    distance = distance - _p1_distance; \n"
@@ -1366,10 +1360,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	}
 
 	/* Bind all the uniform vars .*/
-	pt1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt1");
-	pt2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt2");
 	n_stop_uniform_location =
 	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
 	pt_slope_uniform_location =
@@ -1542,22 +1532,16 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 		dispatch->glUniform1i(n_stop_uniform_location, count);
 	}
 
-	if (abs((pt2[1] - pt1[1]) / yscale) < 1.0) { // The horizontal case.
+	if (src_picture->pSourcePict->linear.p2.y ==
+	              src_picture->pSourcePict->linear.p1.y) { // The horizontal case.
 		dispatch->glUniform1i(hor_ver_uniform_location, 1);
-		DEBUGF("p1.x: %f, p2.x: %f, enter the horizontal case\n", pt1[1], pt2[1]);
+		DEBUGF("p1.y: %f, p2.y: %f, enter the horizontal case\n",
+		       pt1[1], pt2[1]);
 
 		p1_distance = pt1[0];
 		pt_distance = (pt2[0] - p1_distance);
 		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
 		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	} else if (abs((pt2[0] - pt1[0]) / xscale) < 1.0) { //The vertical case.
-		dispatch->glUniform1i(hor_ver_uniform_location, 2);
-		DEBUGF("p1.y: %f, p2.y: %f, enter the vertical case\n", pt1[0], pt2[0]);
-
-		p1_distance = pt1[1];
-		pt_distance = (pt2[1] - p1_distance);
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
 	} else {
 		/* The slope need to compute here. In shader, the viewport set will change
 		   the orginal slope and the slope which is vertical to it will not be correct.*/
commit 41aa93c393c8760aae357725db63fa4a8f798557
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue May 15 10:07:46 2012 +0800

    Fix the problem of set the same stop several times.
    
     Some gradient set the stops at the same position, for
     example: firstly 0.5 to red color and then set 0.5 to
     blue. This kind of setting will cause the shader work
     not correctly because the percentage caculating need to
     use the stop[i] - stop[i-1] as dividend. The previous
     patch we just kill some stop if the distance between
     them is 0. But this cause the problem that the color
     for next stop is wrong. We now modify to handle it in
     the shader to avoid the 0 as dividend.
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 165d211..b24dc9f 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -67,9 +67,12 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	    "            break; \n"
 	    "    }\n"
 	    "    \n"
-	    "    percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
 	    "    if(stops[i] - stops[i-1] > 2.0)\n"
 	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+	    "    else if(stops[i] - stops[i-1] < 0.000001)\n"
+	    "        percentage = 0.0;\n"
+	    "    else \n"
+	    "        percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
 	    "    new_alpha = percentage * stop_colors[i].a + \n"
 	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
 	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
@@ -116,58 +119,53 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	    "        stop_color_after = stop_color0;\n"
 	    "        stop_after = stop0;\n"
 	    "        stop_before = stop0;\n"
-	    "        percentage = 0.0;\n"
 	    "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
 	    "        stop_color_before = stop_color0;\n"
 	    "        stop_color_after = stop_color1;\n"
 	    "        stop_after = stop1;\n"
 	    "        stop_before = stop0;\n"
-	    "        percentage = (stop_len - stop0)/(stop1 - stop0);\n"
 	    "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
 	    "        stop_color_before = stop_color1;\n"
 	    "        stop_color_after = stop_color2;\n"
 	    "        stop_after = stop2;\n"
 	    "        stop_before = stop1;\n"
-	    "        percentage = (stop_len - stop1)/(stop2 - stop1);\n"
 	    "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
 	    "        stop_color_before = stop_color2;\n"
 	    "        stop_color_after = stop_color3;\n"
 	    "        stop_after = stop3;\n"
 	    "        stop_before = stop2;\n"
-	    "        percentage = (stop_len - stop2)/(stop3 - stop2);\n"
 	    "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
 	    "        stop_color_before = stop_color3;\n"
 	    "        stop_color_after = stop_color4;\n"
 	    "        stop_after = stop4;\n"
 	    "        stop_before = stop3;\n"
-	    "        percentage = (stop_len - stop3)/(stop4 - stop3);\n"
 	    "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
 	    "        stop_color_before = stop_color4;\n"
 	    "        stop_color_after = stop_color5;\n"
 	    "        stop_after = stop5;\n"
 	    "        stop_before = stop4;\n"
-	    "        percentage = (stop_len - stop4)/(stop5 - stop4);\n"
 	    "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
 	    "        stop_color_before = stop_color5;\n"
 	    "        stop_color_after = stop_color6;\n"
 	    "        stop_after = stop6;\n"
 	    "        stop_before = stop5;\n"
-	    "        percentage = (stop_len - stop5)/(stop6 - stop5);\n"
 	    "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
 	    "        stop_color_before = stop_color6;\n"
 	    "        stop_color_after = stop_color7;\n"
 	    "        stop_after = stop7;\n"
 	    "        stop_before = stop6;\n"
-	    "        percentage = (stop_len - stop6)/(stop7 - stop6);\n"
 	    "    } else {\n"
 	    "        stop_color_before = stop_color7;\n"
 	    "        stop_color_after = stop_color7;\n"
 	    "        stop_after = stop7;\n"
 	    "        stop_before = stop7;\n"
-	    "        percentage = 0.0;\n"
 	    "    }\n"
 	    "    if(stop_after - stop_before > 2.0)\n"
 	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
+	    "    else if(stop_after - stop_before < 0.000001)\n"
+	    "        percentage = 0.0;\n"
+	    "    else \n"
+	    "        percentage = (stop_len - stop_before)/(stop_after - stop_before);\n"
 	    "    new_alpha = percentage * stop_color_after.a + \n"
 	    "                       (1.0-percentage) * stop_color_before.a; \n"
 	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
@@ -880,13 +878,6 @@ _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
 	int count = 1;
 
 	for (i = 0; i < pgradient->nstops; i++) {
-		/* We find some gradient picture set the stops at the same percentage, which
-		   will cause the shader problem because the (stops[i] - stops[i-1]) will
-		   be used as divisor. We just keep the later one if stops[i] == stops[i-1] */
-		if (i < pgradient->nstops - 1
-		         && pgradient->stops[i].x == pgradient->stops[i+1].x)
-			continue;
-
 		stop_colors[count*4] = pixman_fixed_to_double(
 		                                pgradient->stops[i].color.red);
 		stop_colors[count*4+1] = pixman_fixed_to_double(
commit 09de37ec1c0543c8073f934274c84b3b7d5f31ae
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue May 15 10:07:35 2012 +0800

    Fix a bugy macro definition.
    
     The macro like "#define LINEAR_SMALL_STOPS 6 + 2" causes
     the problem. When use it to define like "GLfloat
     stop_colors_st[LINEAR_SMALL_STOPS*4];" The array is
     small than what we supposed it to be. Cause memory
     corruption problem and cause the bug of render wrong
     result. Fix it.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index f1c36af..165d211 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -34,11 +34,11 @@
 
 #ifdef RENDER
 
-#define LINEAR_SMALL_STOPS 6 + 2
-#define LINEAR_LARGE_STOPS 16 + 2
+#define LINEAR_SMALL_STOPS (6 + 2)
+#define LINEAR_LARGE_STOPS (16 + 2)
 
-#define RADIAL_SMALL_STOPS 6 + 2
-#define RADIAL_LARGE_STOPS 16 + 2
+#define RADIAL_SMALL_STOPS (6 + 2)
+#define RADIAL_LARGE_STOPS (16 + 2)
 
 #ifdef GLAMOR_GRADIENT_SHADER
 
commit d900f553c2bb8d6e01529524fb7125918291c406
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Tue May 15 10:07:24 2012 +0800

    Extract the gradient related code out.
    
     1. Extract the logic of gradient from the glamor_render.c
     to the file glamor_gradient.c.
     2. Modify the logic of gradient pixmap gl draw. Use the
     logic like composite before, but the gradient always just
     have one rect to render, so no need to set the VB and EB,
     replace it with just call glDrawArrays. 3.Kill all the
     warning in glamor_render.c
    
    Reviewed-by: Zhigang Gong<zhigang.gong at linux.intel.com>
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 8e334b1..2e94ffd 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -33,6 +33,7 @@ libglamor_la_SOURCES = \
 	glamor_putimage.c \
 	glamor_setspans.c \
 	glamor_render.c \
+	glamor_gradient.c \
 	glamor_tile.c \
 	glamor_triangles.c\
 	glamor_addtraps.c\
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
new file mode 100644
index 0000000..f1c36af
--- /dev/null
+++ b/glamor/glamor_gradient.c
@@ -0,0 +1,1633 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Junyan He <junyan.he at linux.intel.com>
+ *
+ */
+
+/** @file glamor_gradient.c
+ *
+ * Gradient acceleration implementation
+ */
+
+#include "glamor_priv.h"
+
+#ifdef RENDER
+
+#define LINEAR_SMALL_STOPS 6 + 2
+#define LINEAR_LARGE_STOPS 16 + 2
+
+#define RADIAL_SMALL_STOPS 6 + 2
+#define RADIAL_LARGE_STOPS 16 + 2
+
+#ifdef GLAMOR_GRADIENT_SHADER
+
+static GLint
+_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	char *gradient_fs = NULL;
+	GLint fs_getcolor_prog;
+
+	const char *gradient_fs_getcolor =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform int n_stop;\n"
+	    "uniform float stops[%d];\n"
+	    "uniform vec4 stop_colors[%d];\n"
+	    "vec4 get_color(float stop_len)\n"
+	    "{\n"
+	    "    int i = 0;\n"
+	    "    float new_alpha; \n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    for(i = 0; i < n_stop - 1; i++) {\n"
+	    "        if(stop_len < stops[i])\n"
+	    "            break; \n"
+	    "    }\n"
+	    "    \n"
+	    "    percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
+	    "    if(stops[i] - stops[i-1] > 2.0)\n"
+	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_colors[i].a + \n"
+	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
+	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
+	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n";
+
+	/* Because the array access for shader is very slow, the performance is very low
+	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
+	const char *gradient_fs_getcolor_no_array =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform int n_stop;\n"
+	    "uniform float stop0;\n"
+	    "uniform float stop1;\n"
+	    "uniform float stop2;\n"
+	    "uniform float stop3;\n"
+	    "uniform float stop4;\n"
+	    "uniform float stop5;\n"
+	    "uniform float stop6;\n"
+	    "uniform float stop7;\n"
+	    "uniform vec4 stop_color0;\n"
+	    "uniform vec4 stop_color1;\n"
+	    "uniform vec4 stop_color2;\n"
+	    "uniform vec4 stop_color3;\n"
+	    "uniform vec4 stop_color4;\n"
+	    "uniform vec4 stop_color5;\n"
+	    "uniform vec4 stop_color6;\n"
+	    "uniform vec4 stop_color7;\n"
+	    "\n"
+	    "vec4 get_color(float stop_len)\n"
+	    "{\n"
+	    "    float stop_after;\n"
+	    "    float stop_before;\n"
+	    "    vec4 stop_color_before;\n"
+	    "    vec4 stop_color_after;\n"
+	    "    float new_alpha; \n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    \n"
+	    "    if((stop_len < stop0) && (n_stop >= 1)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color0;\n"
+	    "        stop_after = stop0;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = 0.0;\n"
+	    "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color1;\n"
+	    "        stop_after = stop1;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = (stop_len - stop0)/(stop1 - stop0);\n"
+	    "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
+	    "        stop_color_before = stop_color1;\n"
+	    "        stop_color_after = stop_color2;\n"
+	    "        stop_after = stop2;\n"
+	    "        stop_before = stop1;\n"
+	    "        percentage = (stop_len - stop1)/(stop2 - stop1);\n"
+	    "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
+	    "        stop_color_before = stop_color2;\n"
+	    "        stop_color_after = stop_color3;\n"
+	    "        stop_after = stop3;\n"
+	    "        stop_before = stop2;\n"
+	    "        percentage = (stop_len - stop2)/(stop3 - stop2);\n"
+	    "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
+	    "        stop_color_before = stop_color3;\n"
+	    "        stop_color_after = stop_color4;\n"
+	    "        stop_after = stop4;\n"
+	    "        stop_before = stop3;\n"
+	    "        percentage = (stop_len - stop3)/(stop4 - stop3);\n"
+	    "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
+	    "        stop_color_before = stop_color4;\n"
+	    "        stop_color_after = stop_color5;\n"
+	    "        stop_after = stop5;\n"
+	    "        stop_before = stop4;\n"
+	    "        percentage = (stop_len - stop4)/(stop5 - stop4);\n"
+	    "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
+	    "        stop_color_before = stop_color5;\n"
+	    "        stop_color_after = stop_color6;\n"
+	    "        stop_after = stop6;\n"
+	    "        stop_before = stop5;\n"
+	    "        percentage = (stop_len - stop5)/(stop6 - stop5);\n"
+	    "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
+	    "        stop_color_before = stop_color6;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop6;\n"
+	    "        percentage = (stop_len - stop6)/(stop7 - stop6);\n"
+	    "    } else {\n"
+	    "        stop_color_before = stop_color7;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop7;\n"
+	    "        percentage = 0.0;\n"
+	    "    }\n"
+	    "    if(stop_after - stop_before > 2.0)\n"
+	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_color_after.a + \n"
+	    "                       (1.0-percentage) * stop_color_before.a; \n"
+	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
+	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	if(use_array) {
+		XNFasprintf(&gradient_fs,
+		    gradient_fs_getcolor, stops_count, stops_count);
+		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+		                                            gradient_fs);
+		free(gradient_fs);
+	} else {
+		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+		                                            gradient_fs_getcolor_no_array);
+	}
+
+	return fs_getcolor_prog;
+}
+
+static void
+_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	int index;
+
+	GLint gradient_prog = 0;
+	char *gradient_fs = NULL;
+	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+
+	const char *gradient_vs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_Position = v_position;\n"
+	    "    source_texture = v_texcoord.xy;\n"
+	    "}\n";
+
+	/*
+	 *     Refer to pixman radial gradient.
+	 *
+	 *     The problem is given the two circles of c1 and c2 with the radius of r1 and
+	 *     r1, we need to caculate the t, which is used to do interpolate with stops,
+	 *     using the fomula:
+	 *     length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2
+	 *     expand the fomula with xy coond, get the following:
+	 *     sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y))
+	 *           = (1-t)r1 + t*r2
+	 *     <====> At*t- 2Bt + C = 0
+	 *     where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1)
+	 *           B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1)
+	 *           C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1
+	 *
+	 *     solve the fomula and we get the result of
+	 *     t = (B + sqrt(B*B - A*C)) / A  or
+	 *     t = (B - sqrt(B*B - A*C)) / A  (quadratic equation have two solutions)
+	 *
+	 *     The solution we are going to prefer is the bigger one, unless the
+	 *     radius associated to it is negative (or it falls outside the valid t range)
+	 */
+
+	const char *gradient_fs_template =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform mat3 transform_mat;\n"
+	    "uniform int repeat_type;\n"
+	    "uniform float A_value;\n"
+	    "uniform vec2 c1;\n"
+	    "uniform float r1;\n"
+	    "uniform vec2 c2;\n"
+	    "uniform float r2;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "vec4 get_color(float stop_len);\n"
+	    "\n"
+	    "int t_invalid;\n"
+	    "\n"
+	    "float get_stop_len()\n"
+	    "{\n"
+	    "    float t = 0.0;\n"
+	    "    float sqrt_value;\n"
+	    "    int revserse = 0;\n"
+	    "    t_invalid = 0;\n"
+	    "    \n"
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
+	    "    source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"
+	    "    float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"
+	    "                     + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"
+	    "                     + r1 * (r2 - r1);\n"
+	    "    float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"
+	    "                     + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"
+	    "                     - r1*r1;\n"
+	    "    if(abs(A_value) < 0.00001) {\n"
+	    "        if(B_value == 0.0) {\n"
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "        t = 0.5 * C_value / B_value;"
+	    "    } else {\n"
+	    "        sqrt_value = B_value * B_value - A_value * C_value;\n"
+	    "        if(sqrt_value < 0.0) {\n"
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "        sqrt_value = sqrt(sqrt_value);\n"
+	    "        t = (B_value + sqrt_value) / A_value;\n"
+	    "    }\n"
+	    "    if(repeat_type == %d) {\n" // RepeatNone case.
+	    "        if((t <= 0.0) || (t > 1.0))\n"
+	    //           try another if first one invalid
+	    "            t = (B_value - sqrt_value) / A_value;\n"
+	    "        \n"
+	    "        if((t <= 0.0) || (t > 1.0)) {\n" //still invalid, return.
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "    } else {\n"
+	    "        if(t * (r2 - r1) <= -1.0 * r1)\n"
+	    //           try another if first one invalid
+	    "            t = (B_value - sqrt_value) / A_value;\n"
+	    "        \n"
+	    "        if(t * (r2 -r1) <= -1.0 * r1) {\n" //still invalid, return.
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d){\n" // repeat normal
+	    "        while(t > 1.0) \n"
+	    "            t = t - 1.0; \n"
+	    "        while(t < 0.0) \n"
+	    "            t = t + 1.0; \n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d) {\n" // repeat reflect
+	    "        while(t > 1.0) {\n"
+	    "            t = t - 1.0; \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        while(t < 0.0) {\n"
+	    "            t = t + 1.0; \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        if(revserse == 1) {\n"
+	    "            t = 1.0 - t; \n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    return t;\n"
+	    "}\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    float stop_len = get_stop_len();\n"
+	    "    if(t_invalid == 1) {\n"
+	    "        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
+	    "    } else {\n"
+	    "        gl_FragColor = get_color(stop_len);\n"
+	    "    }\n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+
+	if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
+		/* Very Good, not to generate again. */
+		return;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
+		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
+	}
+
+	gradient_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch,
+	                                   GL_VERTEX_SHADER, gradient_vs);
+
+	XNFasprintf(&gradient_fs,
+	            gradient_fs_template,
+	            PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+
+	fs_main_prog = glamor_compile_glsl_prog(dispatch,
+	                                        GL_FRAGMENT_SHADER, gradient_fs);
+
+	free(gradient_fs);
+
+	fs_getcolor_prog =
+	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
+
+	dispatch->glAttachShader(gradient_prog, vs_prog);
+	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+	dispatch->glAttachShader(gradient_prog, fs_main_prog);
+
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
+
+	glamor_link_glsl_prog(dispatch, gradient_prog);
+
+	dispatch->glUseProgram(0);
+
+	if (dyn_gen) {
+		index = 2;
+		glamor_priv->radial_max_nstops = stops_count;
+	} else if (stops_count) {
+		index = 1;
+	} else {
+		index = 0;
+	}
+
+	glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+static void
+_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	int index = 0;
+	GLint gradient_prog = 0;
+	char *gradient_fs = NULL;
+	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+
+	const char *gradient_vs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_Position = v_position;\n"
+	    "    source_texture = v_texcoord.xy;\n"
+	    "}\n";
+
+	/*
+	 *                                      |
+	 *                                      |\
+	 *                                      | \
+	 *                                      |  \
+	 *                                      |   \
+	 *                                      |\   \
+	 *                                      | \   \
+	 *     cos_val =                        |\ p1d \   /
+	 *      sqrt(1/(slope*slope+1.0))  ------>\ \   \ /
+	 *                                      |  \ \   \
+	 *                                      |   \ \ / \
+	 *                                      |    \ *Pt1\
+	 *         *p1                          |     \     \     *P
+	 *          \                           |    / \     \   /
+	 *           \                          |   /   \     \ /
+	 *            \                         |       pd     \
+	 *             \                        |         \   / \
+	 *            p2*                       |          \ /   \       /
+	 *        slope = (p2.y - p1.y) /       |           /     p2d   /
+	 *                    (p2.x - p1.x)     |          /       \   /
+	 *                                      |         /         \ /
+	 *                                      |        /           /
+	 *                                      |       /           /
+	 *                                      |      /           *Pt2
+	 *                                      |                 /
+	 *                                      |                /
+	 *                                      |               /
+	 *                                      |              /
+	 *                                      |             /
+	 *                               -------+---------------------------------
+	 *                                     O|
+	 *                                      |
+	 *                                      |
+	 *
+	 *	step 1: compute the distance of p, pt1 and pt2 in the slope direction.
+	 *		Caculate the distance on Y axis first and multiply cos_val to
+	 *		get the value on slope direction(pd, p1d and p2d represent the
+	 *		distance of p, pt1, and pt2 respectively).
+	 *
+	 *	step 2: caculate the percentage of (pd - p1d)/(p2d - p1d).
+	 *		If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d)
+	 *		to make it in the range of [0, (p2d - p1d)].
+	 *
+	 *	step 3: compare the percentage to every stop and find the stpos just
+	 *		before and after it. Use the interpolation fomula to compute RGBA.
+	 */
+
+	const char *gradient_fs_template =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform mat3 transform_mat;\n"
+	    "uniform int repeat_type;\n"
+	    "uniform int hor_ver;\n"
+	    "uniform vec4 pt1;\n"
+	    "uniform vec4 pt2;\n"
+	    "uniform float pt_slope;\n"
+	    "uniform float cos_val;\n"
+	    "uniform float p1_distance;\n"
+	    "uniform float pt_distance;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "vec4 get_color(float stop_len);\n"
+	    "\n"
+	    "float get_stop_len()\n"
+	    "{\n"
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
+	    "    float len_percentage;\n"
+	    "    float distance;\n"
+	    "    float _p1_distance;\n"
+	    "    float _pt_distance;\n"
+	    "    float y_dist;\n"
+	    "    float stop_after;\n"
+	    "    float stop_before;\n"
+	    "    vec4 stop_color_before;\n"
+	    "    vec4 stop_color_after;\n"
+	    "    float new_alpha; \n"
+	    "    int revserse = 0;\n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
+	    "    \n"
+	    "    if(hor_ver == 0) { \n" //Normal case.
+	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
+	    "        distance = y_dist * cos_val;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "        \n"
+	    "    } else if (hor_ver == 1) {\n"//horizontal case.
+	    "        distance = source_texture_trans.x;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } else if (hor_ver == 2) {\n"//vertical case.
+	    "        distance = source_texture_trans.y;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } \n"
+	    "    \n"
+	    "    distance = distance - _p1_distance; \n"
+	    "    \n"
+	    "    if(repeat_type == %d){\n" // repeat normal
+	    "        while(distance > _pt_distance) \n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "        while(distance < 0.0) \n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d) {\n" // repeat reflect
+	    "        while(distance > _pt_distance) {\n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        while(distance < 0.0) {\n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        if(revserse == 1) {\n"
+	    "            distance = (_pt_distance) - distance; \n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    len_percentage = distance/(_pt_distance);\n"
+	    "    \n"
+	    "    return len_percentage;\n"
+	    "}\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    float stop_len = get_stop_len();\n"
+	    "    gl_FragColor = get_color(stop_len);\n"
+	    "}\n";
+
+
+	glamor_priv = glamor_get_screen_private(screen);
+
+	if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
+		/* Very Good, not to generate again. */
+		return;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
+		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
+	}
+
+	gradient_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch,
+	                                   GL_VERTEX_SHADER, gradient_vs);
+
+	XNFasprintf(&gradient_fs,
+	            gradient_fs_template,
+	            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+
+	fs_main_prog = glamor_compile_glsl_prog(dispatch,
+	                                        GL_FRAGMENT_SHADER, gradient_fs);
+	free(gradient_fs);
+
+	fs_getcolor_prog =
+	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
+
+	dispatch->glAttachShader(gradient_prog, vs_prog);
+	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+	dispatch->glAttachShader(gradient_prog, fs_main_prog);
+
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
+
+	glamor_link_glsl_prog(dispatch, gradient_prog);
+
+	dispatch->glUseProgram(0);
+
+	if (dyn_gen) {
+		index = 2;
+		glamor_priv->linear_max_nstops = stops_count;
+	} else if (stops_count) {
+		index = 1;
+	} else {
+		index = 0;
+	}
+
+	glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+void
+glamor_init_gradient_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	int i;
+
+	glamor_priv = glamor_get_screen_private(screen);
+
+	for (i = 0; i < 3; i++) {
+		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+
+		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+	}
+	glamor_priv->linear_max_nstops = 0;
+	glamor_priv->radial_max_nstops = 0;
+
+	_glamor_create_linear_gradient_program(screen, 0, 0);
+	_glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
+
+	_glamor_create_radial_gradient_program(screen, 0, 0);
+	_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
+}
+
+void
+glamor_fini_gradient_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	int i = 0;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	for (i = 0; i < 3; i++) {
+		/* Linear Gradient */
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+		if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
+			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]);
+
+		/* Radial Gradient */
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+		if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
+			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]);
+	}
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+static void
+_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
+				      int width, int height, int normalize)
+{
+	/*
+	 * Because in the shader program, we normalize all the pixel cood to [0, 1],
+	 * so with the transform matrix, the correct logic should be:
+	 * v_s = A*T*v
+	 * v_s: point vector in shader after normalized.
+	 * A: The transition matrix from   width X height --> 1.0 X 1.0
+	 * T: The transform matrix.
+	 * v: point vector in width X height space.
+	 *
+	 * result is OK if we use this fomula. But for every point in width X height space,
+	 * we can just use their normalized point vector in shader, namely we can just
+	 * use the result of A*v in shader. So we have no chance to insert T in A*v.
+	 * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the
+	 * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v)
+	 * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and
+	 * we name this matrix T_s.
+	 *
+	 * Firstly, because A is for the scale convertion, we find
+	 *      --         --
+	 *      |1/w  0   0 |
+	 * A =  | 0  1/h  0 |
+	 *      | 0   0  1.0|
+	 *      --         --
+	 * so T_s = A*T*inv(a) and result
+	 *
+	 *       --                      --
+	 *       | t11      h*t12/w  t13/w|
+	 * T_s = | w*t21/h  t22      t23/h|
+	 *       | w*t31    h*t32    t33  |
+	 *       --                      --
+	 */
+
+	to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]);
+	to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1])
+	                        * (normalize ? (((float)height) / ((float)width)) : 1.0);
+	to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2])
+	                        / (normalize ? ((float)width) : 1.0);
+
+	to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0])
+	                        * (normalize ? (((float)width) / ((float)height)) : 1.0);
+	to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]);
+	to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2])
+	                        / (normalize ? ((float)height) : 1.0);
+
+	to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0])
+	                        * (normalize ? ((float)width) : 1.0);
+	to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1])
+	                        * (normalize ? ((float)height) : 1.0);
+	to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]);
+
+	DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
+	       to[0][0], to[0][1], to[0][2],
+	       to[1][0], to[1][1], to[1][2],
+	       to[2][0], to[2][1], to[2][2]);
+}
+
+static int
+_glamor_gradient_set_pixmap_destination(ScreenPtr screen,
+                                        glamor_screen_private *glamor_priv,
+                                        PicturePtr dst_picture,
+                                        GLfloat *xscale, GLfloat *yscale,
+                                        int x_source, int y_source,
+                                        float vertices[8],
+                                        float tex_vertices[8],
+					int tex_normalize)
+{
+	glamor_pixmap_private *pixmap_priv;
+	PixmapPtr pixmap = NULL;
+	glamor_gl_dispatch *dispatch = NULL;
+	float tmp;
+
+	pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
+		return 0;
+	}
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+	pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+
+	DEBUGF("xscale = %f, yscale = %f,"
+	       " x_source = %d, y_source = %d, width = %d, height = %d\n",
+	       *xscale, *yscale, x_source, y_source,
+	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
+
+	glamor_set_normalize_vcoords(*xscale, *yscale,
+	                             0, 0,
+	                             (INT16)(dst_picture->pDrawable->width),
+	                             (INT16)(dst_picture->pDrawable->height),
+	                             glamor_priv->yInverted, vertices);
+
+	if (tex_normalize) {
+		glamor_set_normalize_tcoords(*xscale, *yscale,
+		                             0, 0,
+		                             (INT16)(dst_picture->pDrawable->width),
+		                             (INT16)(dst_picture->pDrawable->height),
+		                             glamor_priv->yInverted, tex_vertices);
+	} else {
+		glamor_set_tcoords(0, 0,
+		                   (INT16)(dst_picture->pDrawable->width),
+		                   (INT16)(dst_picture->pDrawable->height),
+		                   glamor_priv->yInverted, tex_vertices);
+	}
+
+	DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+	       vertices[0], vertices[1], vertices[2], vertices[3],
+	       vertices[4], vertices[5], vertices[6], vertices[7]);
+	DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+	       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
+	       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+
+	/* Swap the vtx for triangle render. */
+	tmp = vertices[4];
+	vertices[4] = vertices[6];
+	vertices[6] = tmp;
+	tmp = vertices[5];
+	vertices[5] = vertices[7];
+	vertices[7] = tmp;
+
+	tmp = tex_vertices[4];
+	tex_vertices[4] = tex_vertices[6];
+	tex_vertices[6] = tmp;
+	tmp = tex_vertices[5];
+	tex_vertices[5] = tex_vertices[7];
+	tex_vertices[7] = tmp;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 0, vertices);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 0, tex_vertices);
+
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	glamor_put_dispatch(glamor_priv);
+
+	return 1;
+}
+
+static int
+_glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
+        GLfloat *stop_colors, GLfloat *n_stops)
+{
+	int i;
+	int count = 1;
+
+	for (i = 0; i < pgradient->nstops; i++) {
+		/* We find some gradient picture set the stops at the same percentage, which
+		   will cause the shader problem because the (stops[i] - stops[i-1]) will
+		   be used as divisor. We just keep the later one if stops[i] == stops[i-1] */
+		if (i < pgradient->nstops - 1
+		         && pgradient->stops[i].x == pgradient->stops[i+1].x)
+			continue;
+
+		stop_colors[count*4] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.red);
+		stop_colors[count*4+1] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.green);
+		stop_colors[count*4+2] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.blue);
+		stop_colors[count*4+3] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.alpha);
+
+		n_stops[count] = (GLfloat)pixman_fixed_to_double(
+		                                pgradient->stops[i].x);
+		count++;
+	}
+
+	/* for the end stop. */
+	count++;
+
+	switch (src_picture->repeatType) {
+#define REPEAT_FILL_STOPS(m, n) \
+			stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \
+			stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \
+			stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \
+			stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3];
+
+		default:
+		case PIXMAN_REPEAT_NONE:
+			stop_colors[0] = 0.0;	   //R
+			stop_colors[1] = 0.0;	   //G
+			stop_colors[2] = 0.0;	   //B
+			stop_colors[3] = 0.0;	   //Alpha
+			n_stops[0] = -(float)INT_MAX;  //should be small enough.
+
+			stop_colors[0 + (count-1)*4] = 0.0;	 //R
+			stop_colors[1 + (count-1)*4] = 0.0;	 //G
+			stop_colors[2 + (count-1)*4] = 0.0;	 //B
+			stop_colors[3 + (count-1)*4] = 0.0;	 //Alpha
+			n_stops[count-1] = (float)INT_MAX;  //should be large enough.
+			break;
+		case PIXMAN_REPEAT_NORMAL:
+			REPEAT_FILL_STOPS(0, count - 2);
+			n_stops[0] = n_stops[count-2] - 1.0;
+
+			REPEAT_FILL_STOPS(count - 1, 1);
+			n_stops[count-1] = n_stops[1] + 1.0;
+			break;
+		case PIXMAN_REPEAT_REFLECT:
+			REPEAT_FILL_STOPS(0, 1);
+			n_stops[0] = -n_stops[1];
+
+			REPEAT_FILL_STOPS(count - 1, count - 2);
+			n_stops[count-1] = 1.0 + 1.0 - n_stops[count-2];
+			break;
+		case PIXMAN_REPEAT_PAD:
+			REPEAT_FILL_STOPS(0, 1);
+			n_stops[0] = -(float)INT_MAX;
+
+			REPEAT_FILL_STOPS(count - 1, count - 2);
+			n_stops[count-1] = (float)INT_MAX;
+			break;
+#undef REPEAT_FILL_STOPS
+	}
+
+	for (i = 0; i < count; i++) {
+		DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n",
+		       i, n_stops[i],
+		       stop_colors[i*4], stop_colors[i*4+1],
+		       stop_colors[i*4+2], stop_colors[i*4+3]);
+	}
+
+	return count;
+}
+
+PicturePtr
+glamor_generate_radial_gradient_picture(ScreenPtr screen,
+                                         PicturePtr src_picture,
+                                         int x_source, int y_source,
+                                         int width, int height,
+                                         PictFormatShort format)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	PicturePtr dst_picture = NULL;
+	PixmapPtr pixmap = NULL;
+	GLint gradient_prog = 0;
+	int error;
+	float tex_vertices[8];
+	int stops_count = 0;
+	int count = 0;
+	GLfloat *stop_colors = NULL;
+	GLfloat *n_stops = NULL;
+	GLfloat xscale, yscale;
+	float vertices[8];
+	float transform_mat[3][3];
+	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
+	                                         {0.0, 1.0, 0.0},
+	                                         {0.0, 0.0, 1.0}};
+	GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4];
+	GLfloat n_stops_st[RADIAL_SMALL_STOPS];
+	GLfloat A_value;
+	GLfloat cxy[4];
+	float c1x, c1y, c2x, c2y, r1, r2;
+
+	GLint transform_mat_uniform_location = 0;
+	GLint repeat_type_uniform_location = 0;
+	GLint n_stop_uniform_location = 0;
+	GLint stops_uniform_location = 0;
+	GLint stop_colors_uniform_location = 0;
+	GLint stop0_uniform_location = 0;
+	GLint stop1_uniform_location = 0;
+	GLint stop2_uniform_location = 0;
+	GLint stop3_uniform_location = 0;
+	GLint stop4_uniform_location = 0;
+	GLint stop5_uniform_location = 0;
+	GLint stop6_uniform_location = 0;
+	GLint stop7_uniform_location = 0;
+	GLint stop_color0_uniform_location = 0;
+	GLint stop_color1_uniform_location = 0;
+	GLint stop_color2_uniform_location = 0;
+	GLint stop_color3_uniform_location = 0;
+	GLint stop_color4_uniform_location = 0;
+	GLint stop_color5_uniform_location = 0;
+	GLint stop_color6_uniform_location = 0;
+	GLint stop_color7_uniform_location = 0;
+	GLint A_value_uniform_location = 0;
+	GLint c1_uniform_location = 0;
+	GLint r1_uniform_location = 0;
+	GLint c2_uniform_location = 0;
+	GLint r2_uniform_location = 0;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	/* Create a pixmap with VBO. */
+	pixmap = glamor_create_pixmap(screen,
+	                              width, height,
+	                              PIXMAN_FORMAT_DEPTH(format),
+	                              0);
+	if (!pixmap)
+		goto GRADIENT_FAIL;
+
+	dst_picture = CreatePicture(0, &pixmap->drawable,
+	                            PictureMatchFormat(screen,
+	                                 PIXMAN_FORMAT_DEPTH(format), format),
+	                            0, 0, serverClient, &error);
+
+	/* Release the reference, picture will hold the last one. */
+	glamor_destroy_pixmap(pixmap);
+
+	if (!dst_picture)
+		goto GRADIENT_FAIL;
+
+	ValidatePicture(dst_picture);
+
+	stops_count = src_picture->pSourcePict->radial.nstops + 2;
+
+	/* Because the max value of nstops is unkown, so create a program
+	   when nstops > LINEAR_LARGE_STOPS.*/
+	if (stops_count <= RADIAL_SMALL_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
+	} else if (stops_count <= RADIAL_LARGE_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
+	} else {
+		_glamor_create_radial_gradient_program(screen,
+						       src_picture->pSourcePict->linear.nstops + 2,
+						       1);
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
+	}
+
+	/* Bind all the uniform vars .*/
+	transform_mat_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	n_stop_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+	A_value_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "A_value");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	c1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "c1");
+	r1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "r1");
+	c2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "c2");
+	r2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "r2");
+
+	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
+		stop0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
+		stop1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
+		stop2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
+		stop3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
+		stop4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
+		stop5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
+		stop6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
+		stop7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+		stop_color0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+		stop_color1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+		stop_color2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+		stop_color3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+		stop_color4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+		stop_color5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+		stop_color6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+		stop_color7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+	} else {
+		stops_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stops");
+		stop_colors_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+	}
+
+	dispatch->glUseProgram(gradient_prog);
+
+	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
+
+
+	if (src_picture->transform) {
+		_glamor_gradient_convert_trans_matrix(src_picture->transform,
+		                                      transform_mat,
+		                                      width, height, 0);
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &transform_mat[0][0]);
+	} else {
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &identity_mat[0][0]);
+	}
+
+	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
+	                                             &xscale, &yscale, x_source, y_source,
+	                                             vertices, tex_vertices, 0))
+		goto GRADIENT_FAIL;
+
+	/* Set all the stops and colors to shader. */
+	if (stops_count > RADIAL_SMALL_STOPS) {
+		stop_colors = malloc(4 * stops_count * sizeof(float));
+		if (stop_colors == NULL) {
+			ErrorF("Failed to allocate stop_colors memory.\n");
+			goto GRADIENT_FAIL;
+		}
+
+		n_stops = malloc(stops_count * sizeof(float));
+		if (n_stops == NULL) {
+			ErrorF("Failed to allocate n_stops memory.\n");
+			goto GRADIENT_FAIL;
+		}
+	} else {
+		stop_colors = stop_colors_st;
+		n_stops = n_stops_st;
+	}
+
+	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
+	                                   stop_colors, n_stops);
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
+		int j = 0;
+		dispatch->glUniform4f(stop_color0_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color1_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color2_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color3_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color4_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color5_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color6_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color7_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+
+		j = 0;
+		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	} else {
+		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	}
+
+	c1x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
+	c1y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y);
+	c2x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x);
+	c2y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y);
+
+	r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius);
+	r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius);
+
+
+	cxy[0] = c1x;
+	cxy[1] = c1y;
+	dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
+	dispatch->glUniform1f(r1_uniform_location, r1);
+
+	cxy[0] = c2x;
+	cxy[1] = c2y;
+	dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
+	dispatch->glUniform1f(r2_uniform_location, r2);
+
+	A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1);
+	dispatch->glUniform1f(A_value_uniform_location, A_value);
+
+	DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
+	       c1x, c1y, r1, c2x, c2y, r2, A_value);
+
+	/* Now rendering. */
+	dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	/* Do the clear logic.*/
+	if (stops_count > RADIAL_SMALL_STOPS) {
+		free(n_stops);
+		free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+
+	glamor_put_dispatch(glamor_priv);
+	return dst_picture;
+
+GRADIENT_FAIL:
+	if (dst_picture) {
+		FreePicture(dst_picture, 0);
+	}
+
+	if (stops_count > RADIAL_SMALL_STOPS) {
+		if (n_stops)
+			free(n_stops);
+		if (stop_colors)
+			free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+	return NULL;
+}
+
+PicturePtr
+glamor_generate_linear_gradient_picture(ScreenPtr screen,
+                                         PicturePtr src_picture,
+                                         int x_source, int y_source,
+                                         int width, int height,
+                                         PictFormatShort format)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	PicturePtr dst_picture = NULL;
+	PixmapPtr pixmap = NULL;
+	GLint gradient_prog = 0;
+	int error;
+	float pt_distance;
+	float p1_distance;
+	GLfloat cos_val;
+	float tex_vertices[8];
+	int stops_count = 0;
+	GLfloat *stop_colors = NULL;
+	GLfloat *n_stops = NULL;
+	int count = 0;
+	float slope;
+	GLfloat xscale, yscale;
+	GLfloat pt1[4], pt2[4];
+	float vertices[8];
+	float transform_mat[3][3];
+	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
+	                                         {0.0, 1.0, 0.0},
+	                                         {0.0, 0.0, 1.0}};
+	GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4];
+	GLfloat n_stops_st[LINEAR_SMALL_STOPS];
+
+	GLint transform_mat_uniform_location = 0;
+	GLint pt1_uniform_location = 0;
+	GLint pt2_uniform_location = 0;
+	GLint n_stop_uniform_location = 0;
+	GLint stops_uniform_location = 0;
+	GLint stop0_uniform_location = 0;
+	GLint stop1_uniform_location = 0;
+	GLint stop2_uniform_location = 0;
+	GLint stop3_uniform_location = 0;
+	GLint stop4_uniform_location = 0;
+	GLint stop5_uniform_location = 0;
+	GLint stop6_uniform_location = 0;
+	GLint stop7_uniform_location = 0;
+	GLint stop_colors_uniform_location = 0;
+	GLint stop_color0_uniform_location = 0;
+	GLint stop_color1_uniform_location = 0;
+	GLint stop_color2_uniform_location = 0;
+	GLint stop_color3_uniform_location = 0;
+	GLint stop_color4_uniform_location = 0;
+	GLint stop_color5_uniform_location = 0;
+	GLint stop_color6_uniform_location = 0;
+	GLint stop_color7_uniform_location = 0;
+	GLint pt_slope_uniform_location = 0;
+	GLint repeat_type_uniform_location = 0;
+	GLint hor_ver_uniform_location = 0;
+	GLint cos_val_uniform_location = 0;
+	GLint p1_distance_uniform_location = 0;
+	GLint pt_distance_uniform_location = 0;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	/* Create a pixmap with VBO. */
+	pixmap = glamor_create_pixmap(screen,
+	                              width, height,
+	                              PIXMAN_FORMAT_DEPTH(format),
+	                              0);
+
+	if (!pixmap)
+		goto GRADIENT_FAIL;
+
+	dst_picture = CreatePicture(0, &pixmap->drawable,
+	                            PictureMatchFormat(screen,
+	                                    PIXMAN_FORMAT_DEPTH(format), format),
+	                            0, 0, serverClient, &error);
+
+	/* Release the reference, picture will hold the last one. */
+	glamor_destroy_pixmap(pixmap);
+
+	if (!dst_picture)
+		goto GRADIENT_FAIL;
+
+	ValidatePicture(dst_picture);
+
+	stops_count = src_picture->pSourcePict->linear.nstops + 2;
+
+	/* Because the max value of nstops is unkown, so create a program
+	   when nstops > LINEAR_LARGE_STOPS.*/
+	if (stops_count <= LINEAR_SMALL_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
+	} else if (stops_count <= LINEAR_LARGE_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
+	} else {
+		_glamor_create_linear_gradient_program(screen,
+		        src_picture->pSourcePict->linear.nstops + 2, 1);
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
+	}
+
+	/* Bind all the uniform vars .*/
+	pt1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt1");
+	pt2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt2");
+	n_stop_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+	pt_slope_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	hor_ver_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
+	transform_mat_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+	cos_val_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "cos_val");
+	p1_distance_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
+	pt_distance_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
+		stop0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
+		stop1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
+		stop2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
+		stop3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
+		stop4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
+		stop5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
+		stop6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
+		stop7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+		stop_color0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+		stop_color1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+		stop_color2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+		stop_color3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+		stop_color4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+		stop_color5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+		stop_color6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+		stop_color7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+	} else {
+		stops_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stops");
+		stop_colors_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+	}
+
+	dispatch->glUseProgram(gradient_prog);
+
+	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
+
+	/* set the transform matrix. */
+	if (src_picture->transform) {
+		_glamor_gradient_convert_trans_matrix(src_picture->transform,
+		                                      transform_mat,
+		                                      width, height, 1);
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &transform_mat[0][0]);
+	} else {
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &identity_mat[0][0]);
+	}
+
+	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
+	                                             &xscale, &yscale, x_source, y_source,
+	                                             vertices, tex_vertices, 1))
+		goto GRADIENT_FAIL;
+
+	/* Normalize the PTs. */
+	glamor_set_normalize_pt(xscale, yscale,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.x),
+	                        x_source,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.y),
+	                        y_source,
+	                        glamor_priv->yInverted,
+	                        pt1);
+	dispatch->glUniform4fv(pt1_uniform_location, 1, pt1);
+	DEBUGF("pt1:(%f %f)\n", pt1[0], pt1[1]);
+
+	glamor_set_normalize_pt(xscale, yscale,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.x),
+	                        x_source,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.y),
+	                        y_source,
+	                        glamor_priv->yInverted,
+	                        pt2);
+	dispatch->glUniform4fv(pt2_uniform_location, 1, pt2);
+	DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
+
+	/* Set all the stops and colors to shader. */
+	if (stops_count > LINEAR_SMALL_STOPS) {
+		stop_colors = malloc(4 * stops_count * sizeof(float));
+		if (stop_colors == NULL) {
+			ErrorF("Failed to allocate stop_colors memory.\n");
+			goto GRADIENT_FAIL;
+		}
+
+		n_stops = malloc(stops_count * sizeof(float));
+		if (n_stops == NULL) {
+			ErrorF("Failed to allocate n_stops memory.\n");
+			goto GRADIENT_FAIL;
+		}
+	} else {
+		stop_colors = stop_colors_st;
+		n_stops = n_stops_st;
+	}
+
+	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
+	                                   stop_colors, n_stops);
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
+		int j = 0;
+		dispatch->glUniform4f(stop_color0_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color1_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color2_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color3_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color4_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color5_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color6_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color7_uniform_location,
+		                      stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+
+		j = 0;
+		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	} else {
+		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	}
+
+	if (abs((pt2[1] - pt1[1]) / yscale) < 1.0) { // The horizontal case.
+		dispatch->glUniform1i(hor_ver_uniform_location, 1);
+		DEBUGF("p1.x: %f, p2.x: %f, enter the horizontal case\n", pt1[1], pt2[1]);
+
+		p1_distance = pt1[0];
+		pt_distance = (pt2[0] - p1_distance);
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	} else if (abs((pt2[0] - pt1[0]) / xscale) < 1.0) { //The vertical case.
+		dispatch->glUniform1i(hor_ver_uniform_location, 2);
+		DEBUGF("p1.y: %f, p2.y: %f, enter the vertical case\n", pt1[0], pt2[0]);
+
+		p1_distance = pt1[1];
+		pt_distance = (pt2[1] - p1_distance);
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	} else {
+		/* The slope need to compute here. In shader, the viewport set will change
+		   the orginal slope and the slope which is vertical to it will not be correct.*/
+		slope = - (float)(src_picture->pSourcePict->linear.p2.x
+				  - src_picture->pSourcePict->linear.p1.x) /
+		          (float)(src_picture->pSourcePict->linear.p2.y
+				  - src_picture->pSourcePict->linear.p1.y);
+		slope = slope * yscale / xscale;
+		dispatch->glUniform1f(pt_slope_uniform_location, slope);
+		dispatch->glUniform1i(hor_ver_uniform_location, 0);
+
+		cos_val = sqrt(1.0 / (slope * slope + 1.0));
+		dispatch->glUniform1f(cos_val_uniform_location, cos_val);
+
+		p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
+		pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	}
+
+	/* Now rendering. */
+	dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	/* Do the clear logic.*/
+	if (stops_count > LINEAR_SMALL_STOPS) {
+		free(n_stops);
+		free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+
+	glamor_put_dispatch(glamor_priv);
+	return dst_picture;
+
+GRADIENT_FAIL:
+	if (dst_picture) {
+		FreePicture(dst_picture, 0);
+	}
+
+	if (stops_count > LINEAR_SMALL_STOPS) {
+		if (n_stops)
+			free(n_stops);
+		if (stop_colors)
+			free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
+	return NULL;
+}
+
+#endif /* End of GLAMOR_GRADIENT_SHADER */
+
+#endif /* End of RENDER */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8f1d428..a817f78 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -577,8 +577,19 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 void glamor_init_tile_shader(ScreenPtr screen);
 void glamor_fini_tile_shader(ScreenPtr screen);
 
+/* glamor_gradient.c */
 void glamor_init_gradient_shader(ScreenPtr screen);
 void glamor_fini_gradient_shader(ScreenPtr screen);
+PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen,
+                                                   PicturePtr src_picture,
+                                                   int x_source, int y_source,
+                                                   int width, int height,
+                                                   PictFormatShort format);
+PicturePtr glamor_generate_radial_gradient_picture(ScreenPtr screen,
+                                                   PicturePtr src_picture,
+                                                   int x_source, int y_source,
+                                                   int width, int height,
+                                                   PictFormatShort format);
 
 /* glamor_triangles.c */
 void
@@ -744,7 +755,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #ifndef GLAMOR_GLES2
-//#define GLAMOR_GRADIENT_SHADER
+#define GLAMOR_GRADIENT_SHADER
 #endif
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 94f7dc5..907d65b 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -745,7 +745,6 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	glamor_gl_dispatch *dispatch;
 
 	glamor_priv->vbo_offset = 0;
-	glamor_priv->vbo_offset = 0;
 	glamor_priv->render_nr_verts = 0;
 	glamor_priv->vbo_size = n_verts * sizeof(float) * 2;
 
@@ -1339,1583 +1338,6 @@ done:
 	return ret;
 }
 
-#ifdef GLAMOR_GRADIENT_SHADER
-static GLint
-_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-
-	char *gradient_fs = NULL;
-	GLint fs_getcolor_prog;
-
-	const char *gradient_fs_getcolor =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform int n_stop;\n"
-	    "uniform float stops[%d];\n"
-	    "uniform vec4 stop_colors[%d];\n"
-	    "vec4 get_color(float stop_len)\n"
-	    "{\n"
-	    "    int i = 0;\n"
-	    "    float new_alpha; \n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    for(i = 0; i < n_stop - 1; i++) {\n"
-	    "        if(stop_len < stops[i])\n"
-	    "            break; \n"
-	    "    }\n"
-	    "    \n"
-	    "    percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
-	    "    if(stops[i] - stops[i-1] > 2.0)\n"
-	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
-	    "    new_alpha = percentage * stop_colors[i].a + \n"
-	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
-	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
-	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
-	    "    \n"
-	    "    return gradient_color;\n"
-	    "}\n";
-
-	/* Because the array access for shader is very slow, the performance is very low
-	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
-	const char *gradient_fs_getcolor_no_array =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform int n_stop;\n"
-	    "uniform float stop0;\n"
-	    "uniform float stop1;\n"
-	    "uniform float stop2;\n"
-	    "uniform float stop3;\n"
-	    "uniform float stop4;\n"
-	    "uniform float stop5;\n"
-	    "uniform float stop6;\n"
-	    "uniform float stop7;\n"
-	    "uniform vec4 stop_color0;\n"
-	    "uniform vec4 stop_color1;\n"
-	    "uniform vec4 stop_color2;\n"
-	    "uniform vec4 stop_color3;\n"
-	    "uniform vec4 stop_color4;\n"
-	    "uniform vec4 stop_color5;\n"
-	    "uniform vec4 stop_color6;\n"
-	    "uniform vec4 stop_color7;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len)\n"
-	    "{\n"
-	    "    float stop_after;\n"
-	    "    float stop_before;\n"
-	    "    vec4 stop_color_before;\n"
-	    "    vec4 stop_color_after;\n"
-	    "    float new_alpha; \n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    \n"
-	    "    if((stop_len < stop0) && (n_stop >= 1)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color0;\n"
-	    "        stop_after = stop0;\n"
-	    "        stop_before = stop0;\n"
-	    "        percentage = 0.0;\n"
-	    "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color1;\n"
-	    "        stop_after = stop1;\n"
-	    "        stop_before = stop0;\n"
-	    "        percentage = (stop_len - stop0)/(stop1 - stop0);\n"
-	    "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
-	    "        stop_color_before = stop_color1;\n"
-	    "        stop_color_after = stop_color2;\n"
-	    "        stop_after = stop2;\n"
-	    "        stop_before = stop1;\n"
-	    "        percentage = (stop_len - stop1)/(stop2 - stop1);\n"
-	    "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
-	    "        stop_color_before = stop_color2;\n"
-	    "        stop_color_after = stop_color3;\n"
-	    "        stop_after = stop3;\n"
-	    "        stop_before = stop2;\n"
-	    "        percentage = (stop_len - stop2)/(stop3 - stop2);\n"
-	    "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
-	    "        stop_color_before = stop_color3;\n"
-	    "        stop_color_after = stop_color4;\n"
-	    "        stop_after = stop4;\n"
-	    "        stop_before = stop3;\n"
-	    "        percentage = (stop_len - stop3)/(stop4 - stop3);\n"
-	    "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
-	    "        stop_color_before = stop_color4;\n"
-	    "        stop_color_after = stop_color5;\n"
-	    "        stop_after = stop5;\n"
-	    "        stop_before = stop4;\n"
-	    "        percentage = (stop_len - stop4)/(stop5 - stop4);\n"
-	    "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
-	    "        stop_color_before = stop_color5;\n"
-	    "        stop_color_after = stop_color6;\n"
-	    "        stop_after = stop6;\n"
-	    "        stop_before = stop5;\n"
-	    "        percentage = (stop_len - stop5)/(stop6 - stop5);\n"
-	    "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
-	    "        stop_color_before = stop_color6;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop6;\n"
-	    "        percentage = (stop_len - stop6)/(stop7 - stop6);\n"
-	    "    } else {\n"
-	    "        stop_color_before = stop_color7;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop7;\n"
-	    "        percentage = 0.0;\n"
-	    "    }\n"
-	    "    if(stop_after - stop_before > 2.0)\n"
-	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
-	    "    new_alpha = percentage * stop_color_after.a + \n"
-	    "                       (1.0-percentage) * stop_color_before.a; \n"
-	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
-	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
-	    "    \n"
-	    "    return gradient_color;\n"
-	    "}\n";
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	if(use_array) {
-		XNFasprintf(&gradient_fs,
-		    gradient_fs_getcolor, stops_count, stops_count);
-		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-		                                            gradient_fs);
-		free(gradient_fs);
-	} else {
-		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-		                                            gradient_fs_getcolor_no_array);
-	}
-
-	return fs_getcolor_prog;
-}
-
-static void
-_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	int index;
-
-	GLint gradient_prog = 0;
-	char *gradient_fs = NULL;
-	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
-
-	const char *gradient_vs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_Position = v_position;\n"
-	    "    source_texture = v_texcoord.xy;\n"
-	    "}\n";
-
-	/*
-	 *     Refer to pixman radial gradient.
-	 *
-	 *     The problem is given the two circles of c1 and c2 with the radius of r1 and
-	 *     r1, we need to caculate the t, which is used to do interpolate with stops,
-	 *     using the fomula:
-	 *     length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2
-	 *     expand the fomula with xy coond, get the following:
-	 *     sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y))
-	 *           = (1-t)r1 + t*r2
-	 *     <====> At*t- 2Bt + C = 0
-	 *     where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1)
-	 *           B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1)
-	 *           C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1
-	 *
-	 *     solve the fomula and we get the result of
-	 *     t = (B + sqrt(B*B - A*C)) / A  or
-	 *     t = (B - sqrt(B*B - A*C)) / A  (quadratic equation have two solutions)
-	 *
-	 *     The solution we are going to prefer is the bigger one, unless the
-	 *     radius associated to it is negative (or it falls outside the valid t range)
-	 */
-
-	const char *gradient_fs_template =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform mat3 transform_mat;\n"
-	    "uniform int repeat_type;\n"
-	    "uniform float A_value;\n"
-	    "uniform vec2 c1;\n"
-	    "uniform float r1;\n"
-	    "uniform vec2 c2;\n"
-	    "uniform float r2;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len);\n"
-	    "\n"
-	    "int t_invalid;\n"
-	    "\n"
-	    "float get_stop_len()\n"
-	    "{\n"
-	    "    float t = 0.0;\n"
-	    "    float sqrt_value;\n"
-	    "    int revserse = 0;\n"
-	    "    t_invalid = 0;\n"
-	    "    \n"
-	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
-	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
-	    "    source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"
-	    "    float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"
-	    "                     + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"
-	    "                     + r1 * (r2 - r1);\n"
-	    "    float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"
-	    "                     + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"
-	    "                     - r1*r1;\n"
-	    "    if(abs(A_value) < 0.00001) {\n"
-	    "        if(B_value == 0.0) {\n"
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "        t = 0.5 * C_value / B_value;"
-	    "    } else {\n"
-	    "        sqrt_value = B_value * B_value - A_value * C_value;\n"
-	    "        if(sqrt_value < 0.0) {\n"
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "        sqrt_value = sqrt(sqrt_value);\n"
-	    "        t = (B_value + sqrt_value) / A_value;\n"
-	    "    }\n"
-	    "    if(repeat_type == %d) {\n" // RepeatNone case.
-	    "        if((t <= 0.0) || (t > 1.0))\n"
-	    //           try another if first one invalid
-	    "            t = (B_value - sqrt_value) / A_value;\n"
-	    "        \n"
-	    "        if((t <= 0.0) || (t > 1.0)) {\n" //still invalid, return.
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "    } else {\n"
-	    "        if(t * (r2 - r1) <= -1.0 * r1)\n"
-	    //           try another if first one invalid
-	    "            t = (B_value - sqrt_value) / A_value;\n"
-	    "        \n"
-	    "        if(t * (r2 -r1) <= -1.0 * r1) {\n" //still invalid, return.
-	    "            t_invalid = 1;\n"
-	    "            return t;\n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d){\n" // repeat normal
-	    "        while(t > 1.0) \n"
-	    "            t = t - 1.0; \n"
-	    "        while(t < 0.0) \n"
-	    "            t = t + 1.0; \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d) {\n" // repeat reflect
-	    "        while(t > 1.0) {\n"
-	    "            t = t - 1.0; \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        while(t < 0.0) {\n"
-	    "            t = t + 1.0; \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        if(revserse == 1) {\n"
-	    "            t = 1.0 - t; \n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    return t;\n"
-	    "}\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    float stop_len = get_stop_len();\n"
-	    "    if(t_invalid == 1) {\n"
-	    "        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
-	    "    } else {\n"
-	    "        gl_FragColor = get_color(stop_len);\n"
-	    "    }\n"
-	    "}\n";
-
-	glamor_priv = glamor_get_screen_private(screen);
-
-	if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
-		/* Very Good, not to generate again. */
-		return;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
-		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
-		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
-	}
-
-	gradient_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch,
-	                                   GL_VERTEX_SHADER, gradient_vs);
-
-	XNFasprintf(&gradient_fs,
-	            gradient_fs_template,
-	            PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-
-	fs_main_prog = glamor_compile_glsl_prog(dispatch,
-	                                        GL_FRAGMENT_SHADER, gradient_fs);
-
-	free(gradient_fs);
-
-	fs_getcolor_prog =
-	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
-
-	dispatch->glAttachShader(gradient_prog, vs_prog);
-	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-	dispatch->glAttachShader(gradient_prog, fs_main_prog);
-
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
-
-	glamor_link_glsl_prog(dispatch, gradient_prog);
-
-	dispatch->glUseProgram(0);
-
-	if (dyn_gen) {
-		index = 2;
-		glamor_priv->radial_max_nstops = stops_count;
-	} else if (stops_count) {
-		index = 1;
-	} else {
-		index = 0;
-	}
-
-	glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
-	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
-
-	glamor_put_dispatch(glamor_priv);
-}
-
-static void
-_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-
-	int index = 0;
-	GLint gradient_prog = 0;
-	char *gradient_fs = NULL;
-	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
-
-	const char *gradient_vs =
-	    GLAMOR_DEFAULT_PRECISION
-	    "attribute vec4 v_position;\n"
-	    "attribute vec4 v_texcoord;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_Position = v_position;\n"
-	    "    source_texture = v_texcoord.xy;\n"
-	    "}\n";
-
-	/*
-	 *                                      |
-	 *                                      |\
-	 *                                      | \
-	 *                                      |  \
-	 *                                      |   \
-	 *                                      |\   \
-	 *                                      | \   \
-	 *     cos_val =                        |\ p1d \   /
-	 *      sqrt(1/(slope*slope+1.0))  ------>\ \   \ /
-	 *                                      |  \ \   \
-	 *                                      |   \ \ / \
-	 *                                      |    \ *Pt1\
-	 *         *p1                          |     \     \     *P
-	 *          \                           |    / \     \   /
-	 *           \                          |   /   \     \ /
-	 *            \                         |       pd     \
-	 *             \                        |         \   / \
-	 *            p2*                       |          \ /   \       /
-	 *        slope = (p2.y - p1.y) /       |           /     p2d   /
-	 *                    (p2.x - p1.x)     |          /       \   /
-	 *                                      |         /         \ /
-	 *                                      |        /           /
-	 *                                      |       /           /
-	 *                                      |      /           *Pt2
-	 *                                      |                 /
-	 *                                      |                /
-	 *                                      |               /
-	 *                                      |              /
-	 *                                      |             /
-	 *                               -------+---------------------------------
-	 *                                     O|
-	 *                                      |
-	 *                                      |
-	 *
-	 *	step 1: compute the distance of p, pt1 and pt2 in the slope direction.
-	 *		Caculate the distance on Y axis first and multiply cos_val to
-	 *		get the value on slope direction(pd, p1d and p2d represent the
-	 *		distance of p, pt1, and pt2 respectively).
-	 *
-	 *	step 2: caculate the percentage of (pd - p1d)/(p2d - p1d).
-	 *		If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d)
-	 *		to make it in the range of [0, (p2d - p1d)].
-	 *
-	 *	step 3: compare the percentage to every stop and find the stpos just
-	 *		before and after it. Use the interpolation fomula to compute RGBA.
-	 */
-
-	const char *gradient_fs_template =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform mat3 transform_mat;\n"
-	    "uniform int repeat_type;\n"
-	    "uniform int hor_ver;\n"
-	    "uniform vec4 pt1;\n"
-	    "uniform vec4 pt2;\n"
-	    "uniform float pt_slope;\n"
-	    "uniform float cos_val;\n"
-	    "uniform float p1_distance;\n"
-	    "uniform float pt_distance;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "vec4 get_color(float stop_len);\n"
-	    "\n"
-	    "float get_stop_len()\n"
-	    "{\n"
-	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
-	    "    float len_percentage;\n"
-	    "    float distance;\n"
-	    "    float _p1_distance;\n"
-	    "    float _pt_distance;\n"
-	    "    float y_dist;\n"
-	    "    float stop_after;\n"
-	    "    float stop_before;\n"
-	    "    vec4 stop_color_before;\n"
-	    "    vec4 stop_color_after;\n"
-	    "    float new_alpha; \n"
-	    "    int revserse = 0;\n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
-	    "    \n"
-	    "    if(hor_ver == 0) { \n" //Normal case.
-	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
-	    "        distance = y_dist * cos_val;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "        \n"
-	    "    } else if (hor_ver == 1) {\n"//horizontal case.
-	    "        distance = source_texture_trans.x;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } else if (hor_ver == 2) {\n"//vertical case.
-	    "        distance = source_texture_trans.y;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } \n"
-	    "    \n"
-	    "    distance = distance - _p1_distance; \n"
-	    "    \n"
-	    "    if(repeat_type == %d){\n" // repeat normal
-	    "        while(distance > _pt_distance) \n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "        while(distance < 0.0) \n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d) {\n" // repeat reflect
-	    "        while(distance > _pt_distance) {\n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        while(distance < 0.0) {\n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        if(revserse == 1) {\n"
-	    "            distance = (_pt_distance) - distance; \n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    len_percentage = distance/(_pt_distance);\n"
-	    "    \n"
-	    "    return len_percentage;\n"
-	    "}\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    float stop_len = get_stop_len();\n"
-	    "    gl_FragColor = get_color(stop_len);\n"
-	    "}\n";
-
-
-	glamor_priv = glamor_get_screen_private(screen);
-
-	if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
-		/* Very Good, not to generate again. */
-		return;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
-
-		dispatch->glDeleteShader(
-		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
-
-		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
-		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
-	}
-
-	gradient_prog = dispatch->glCreateProgram();
-
-	vs_prog = glamor_compile_glsl_prog(dispatch,
-	                                   GL_VERTEX_SHADER, gradient_vs);
-
-	XNFasprintf(&gradient_fs,
-	            gradient_fs_template,
-	            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-
-	fs_main_prog = glamor_compile_glsl_prog(dispatch,
-	                                        GL_FRAGMENT_SHADER, gradient_fs);
-	free(gradient_fs);
-
-	fs_getcolor_prog =
-	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
-
-	dispatch->glAttachShader(gradient_prog, vs_prog);
-	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
-	dispatch->glAttachShader(gradient_prog, fs_main_prog);
-
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
-	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
-
-	glamor_link_glsl_prog(dispatch, gradient_prog);
-
-	dispatch->glUseProgram(0);
-
-	if (dyn_gen) {
-		index = 2;
-		glamor_priv->linear_max_nstops = stops_count;
-	} else if (stops_count) {
-		index = 1;
-	} else {
-		index = 0;
-	}
-
-	glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
-	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
-
-	glamor_put_dispatch(glamor_priv);
-}
-
-#define LINEAR_SMALL_STOPS 6 + 2
-#define LINEAR_LARGE_STOPS 16 + 2
-
-#define RADIAL_SMALL_STOPS 6 + 2
-#define RADIAL_LARGE_STOPS 16 + 2
-
-void
-glamor_init_gradient_shader(ScreenPtr screen)
-{
-	glamor_screen_private *glamor_priv;
-	int i;
-
-	glamor_priv = glamor_get_screen_private(screen);
-
-	for (i = 0; i < 3; i++) {
-		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
-		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
-
-		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
-		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
-	}
-	glamor_priv->linear_max_nstops = 0;
-	glamor_priv->radial_max_nstops = 0;
-
-	_glamor_create_linear_gradient_program(screen, 0, 0);
-	_glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
-
-	_glamor_create_radial_gradient_program(screen, 0, 0);
-	_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
-}
-
-void
-glamor_fini_gradient_shader(ScreenPtr screen)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	int i = 0;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	for (i = 0; i < 3; i++) {
-		/* Linear Gradient */
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
-
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
-		if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
-			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]);
-
-		/* Radial Gradient */
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
-
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
-
-		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
-			dispatch->glDeleteShader(
-			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
-
-		if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
-			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]);
-	}
-
-	glamor_put_dispatch(glamor_priv);
-}
-
-static void
-_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
-				      int width, int height, int normalize)
-{
-	/*
-	 * Because in the shader program, we normalize all the pixel cood to [0, 1],
-	 * so with the transform matrix, the correct logic should be:
-	 * v_s = A*T*v
-	 * v_s: point vector in shader after normalized.
-	 * A: The transition matrix from   width X height --> 1.0 X 1.0
-	 * T: The transform matrix.
-	 * v: point vector in width X height space.
-	 *
-	 * result is OK if we use this fomula. But for every point in width X height space,
-	 * we can just use their normalized point vector in shader, namely we can just
-	 * use the result of A*v in shader. So we have no chance to insert T in A*v.
-	 * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the
-	 * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v)
-	 * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and
-	 * we name this matrix T_s.
-	 *
-	 * Firstly, because A is for the scale convertion, we find
-	 *      --         --
-	 *      |1/w  0   0 |
-	 * A =  | 0  1/h  0 |
-	 *      | 0   0  1.0|
-	 *      --         --
-	 * so T_s = A*T*inv(a) and result
-	 *
-	 *       --                      --
-	 *       | t11      h*t12/w  t13/w|
-	 * T_s = | w*t21/h  t22      t23/h|
-	 *       | w*t31    h*t32    t33  |
-	 *       --                      --
-	 */
-
-	to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]);
-	to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1])
-	                        * (normalize ? (((float)height) / ((float)width)) : 1.0);
-	to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2])
-	                        / (normalize ? ((float)width) : 1.0);
-
-	to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0])
-	                        * (normalize ? (((float)width) / ((float)height)) : 1.0);
-	to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]);
-	to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2])
-	                        / (normalize ? ((float)height) : 1.0);
-
-	to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0])
-	                        * (normalize ? ((float)width) : 1.0);
-	to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1])
-	                        * (normalize ? ((float)height) : 1.0);
-	to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]);
-
-	DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
-	       to[0][0], to[0][1], to[0][2],
-	       to[1][0], to[1][1], to[1][2],
-	       to[2][0], to[2][1], to[2][2]);
-}
-
-static int
-_glamor_gradient_set_pixmap_destination(ScreenPtr screen,
-                                        glamor_screen_private *glamor_priv,
-                                        PicturePtr dst_picture,
-                                        GLfloat *xscale, GLfloat *yscale,
-                                        int x_source, int y_source,
-                                        float vertices[8],
-                                        float tex_vertices[8],
-					int tex_normalize)
-{
-	glamor_pixmap_private *pixmap_priv;
-	PixmapPtr pixmap = NULL;
-
-	pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
-		return 0;
-	}
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-	pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
-
-	glamor_priv->has_source_coords = 1;
-	glamor_priv->has_mask_coords = 0;
-	glamor_setup_composite_vbo(screen, 4*2);
-
-	DEBUGF("xscale = %f, yscale = %f,"
-	       " x_source = %d, y_source = %d, width = %d, height = %d\n",
-	       *xscale, *yscale, x_source, y_source,
-	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
-
-	glamor_set_normalize_vcoords(*xscale, *yscale,
-	                             0, 0,
-	                             (INT16)(dst_picture->pDrawable->width),
-	                             (INT16)(dst_picture->pDrawable->height),
-	                             glamor_priv->yInverted, vertices);
-
-	if (tex_normalize) {
-		glamor_set_normalize_tcoords(*xscale, *yscale,
-		                             0, 0,
-		                             (INT16)(dst_picture->pDrawable->width),
-		                             (INT16)(dst_picture->pDrawable->height),
-		                             glamor_priv->yInverted, tex_vertices);
-	} else {
-		glamor_set_tcoords(0, 0,
-		                   (INT16)(dst_picture->pDrawable->width),
-		                   (INT16)(dst_picture->pDrawable->height),
-		                   glamor_priv->yInverted, tex_vertices);
-	}
-
-	DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
-	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-	       vertices[0], vertices[1], vertices[2], vertices[3],
-	       vertices[4], vertices[5], vertices[6], vertices[7]);
-	DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
-	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
-	       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
-	       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
-
-	return 1;
-}
-
-static int
-_glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
-        GLfloat *stop_colors, GLfloat *n_stops)
-{
-	int i;
-	int count = 1;
-
-	for (i = 0; i < pgradient->nstops; i++) {
-		/* We find some gradient picture set the stops at the same percentage, which
-		   will cause the shader problem because the (stops[i] - stops[i-1]) will
-		   be used as divisor. We just keep the later one if stops[i] == stops[i-1] */
-		if (i < pgradient->nstops - 1
-		         && pgradient->stops[i].x == pgradient->stops[i+1].x)
-			continue;
-
-		stop_colors[count*4] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.red);
-		stop_colors[count*4+1] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.green);
-		stop_colors[count*4+2] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.blue);
-		stop_colors[count*4+3] = pixman_fixed_to_double(
-		                                pgradient->stops[i].color.alpha);
-
-		n_stops[count] = (GLfloat)pixman_fixed_to_double(
-		                                pgradient->stops[i].x);
-		count++;
-	}
-
-	/* for the end stop. */
-	count++;
-
-	switch (src_picture->repeatType) {
-#define REPEAT_FILL_STOPS(m, n) \
-			stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \
-			stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \
-			stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \
-			stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3];
-
-		default:
-		case PIXMAN_REPEAT_NONE:
-			stop_colors[0] = 0.0;	   //R
-			stop_colors[1] = 0.0;	   //G
-			stop_colors[2] = 0.0;	   //B
-			stop_colors[3] = 0.0;	   //Alpha
-			n_stops[0] = -(float)INT_MAX;  //should be small enough.
-
-			stop_colors[0 + (count-1)*4] = 0.0;	 //R
-			stop_colors[1 + (count-1)*4] = 0.0;	 //G
-			stop_colors[2 + (count-1)*4] = 0.0;	 //B
-			stop_colors[3 + (count-1)*4] = 0.0;	 //Alpha
-			n_stops[count-1] = (float)INT_MAX;  //should be large enough.
-			break;
-		case PIXMAN_REPEAT_NORMAL:
-			REPEAT_FILL_STOPS(0, count - 2);
-			n_stops[0] = n_stops[count-2] - 1.0;
-
-			REPEAT_FILL_STOPS(count - 1, 1);
-			n_stops[count-1] = n_stops[1] + 1.0;
-			break;
-		case PIXMAN_REPEAT_REFLECT:
-			REPEAT_FILL_STOPS(0, 1);
-			n_stops[0] = -n_stops[1];
-
-			REPEAT_FILL_STOPS(count - 1, count - 2);
-			n_stops[count-1] = 1.0 + 1.0 - n_stops[count-2];
-			break;
-		case PIXMAN_REPEAT_PAD:
-			REPEAT_FILL_STOPS(0, 1);
-			n_stops[0] = -(float)INT_MAX;
-
-			REPEAT_FILL_STOPS(count - 1, count - 2);
-			n_stops[count-1] = (float)INT_MAX;
-			break;
-#undef REPEAT_FILL_STOPS
-	}
-
-	for (i = 0; i < count; i++) {
-		DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n",
-		       i, n_stops[i],
-		       stop_colors[i*4], stop_colors[i*4+1],
-		       stop_colors[i*4+2], stop_colors[i*4+3]);
-	}
-
-	return count;
-}
-
-static PicturePtr
-_glamor_generate_radial_gradient_picture(ScreenPtr screen,
-                                         PicturePtr src_picture,
-                                         int x_source, int y_source,
-                                         int width, int height,
-                                         PictFormatShort format)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	PicturePtr dst_picture = NULL;
-	PixmapPtr pixmap = NULL;
-	GLint gradient_prog = 0;
-	int error;
-	float tex_vertices[8];
-	int stops_count;
-	int count = 0;
-	GLfloat *stop_colors = NULL;
-	GLfloat *n_stops = NULL;
-	GLfloat xscale, yscale;
-	float vertices[8];
-	float transform_mat[3][3];
-	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
-	                                         {0.0, 1.0, 0.0},
-	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4];
-	GLfloat n_stops_st[RADIAL_SMALL_STOPS];
-	GLfloat A_value;
-	GLfloat cxy[4];
-	float c1x, c1y, c2x, c2y, r1, r2;
-
-	GLint transform_mat_uniform_location;
-	GLint repeat_type_uniform_location;
-	GLint n_stop_uniform_location;
-	GLint stops_uniform_location;
-	GLint stop_colors_uniform_location;
-	GLint stop0_uniform_location;
-	GLint stop1_uniform_location;
-	GLint stop2_uniform_location;
-	GLint stop3_uniform_location;
-	GLint stop4_uniform_location;
-	GLint stop5_uniform_location;
-	GLint stop6_uniform_location;
-	GLint stop7_uniform_location;
-	GLint stop_color0_uniform_location;
-	GLint stop_color1_uniform_location;
-	GLint stop_color2_uniform_location;
-	GLint stop_color3_uniform_location;
-	GLint stop_color4_uniform_location;
-	GLint stop_color5_uniform_location;
-	GLint stop_color6_uniform_location;
-	GLint stop_color7_uniform_location;
-	GLint A_value_uniform_location;
-	GLint c1_uniform_location;
-	GLint r1_uniform_location;
-	GLint c2_uniform_location;
-	GLint r2_uniform_location;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	/* Create a pixmap with VBO. */
-	pixmap = glamor_create_pixmap(screen,
-	                              width, height,
-	                              PIXMAN_FORMAT_DEPTH(format),
-	                              0);
-	if (!pixmap)
-		goto GRADIENT_FAIL;
-
-	dst_picture = CreatePicture(0, &pixmap->drawable,
-	                            PictureMatchFormat(screen,
-	                                 PIXMAN_FORMAT_DEPTH(format), format),
-	                            0, 0, serverClient, &error);
-
-	/* Release the reference, picture will hold the last one. */
-	glamor_destroy_pixmap(pixmap);
-
-	if (!dst_picture)
-		goto GRADIENT_FAIL;
-
-	ValidatePicture(dst_picture);
-
-	stops_count = src_picture->pSourcePict->radial.nstops + 2;
-
-	/* Because the max value of nstops is unkown, so create a program
-	   when nstops > LINEAR_LARGE_STOPS.*/
-	if (stops_count <= RADIAL_SMALL_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
-	} else if (stops_count <= RADIAL_LARGE_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
-	} else {
-		_glamor_create_radial_gradient_program(screen, src_picture->pSourcePict->linear.nstops + 2, 1);
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
-	}
-
-	/* Bind all the uniform vars .*/
-	transform_mat_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	n_stop_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
-	A_value_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "A_value");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	c1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "c1");
-	r1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "r1");
-	c2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "c2");
-	r2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "r2");
-
-	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
-		stop0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
-		stop1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
-		stop2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
-		stop3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
-		stop4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
-		stop5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
-		stop6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
-		stop7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
-
-		stop_color0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
-		stop_color1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
-		stop_color2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
-		stop_color3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
-		stop_color4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
-		stop_color5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
-		stop_color6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
-		stop_color7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
-	} else {
-		stops_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stops");
-		stop_colors_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
-	}
-
-	dispatch->glUseProgram(gradient_prog);
-
-	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
-
-
-	if (src_picture->transform) {
-		_glamor_gradient_convert_trans_matrix(src_picture->transform,
-		                                      transform_mat,
-		                                      width, height, 0);
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &transform_mat[0][0]);
-	} else {
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &identity_mat[0][0]);
-	}
-
-	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
-	                                             &xscale, &yscale, x_source, y_source,
-	                                             vertices, tex_vertices, 0))
-		goto GRADIENT_FAIL;
-
-	/* Set all the stops and colors to shader. */
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		stop_colors = malloc(4 * stops_count * sizeof(float));
-		if (stop_colors == NULL) {
-			ErrorF("Failed to allocate stop_colors memory.\n");
-			goto GRADIENT_FAIL;
-		}
-
-		n_stops = malloc(stops_count * sizeof(float));
-		if (n_stops == NULL) {
-			ErrorF("Failed to allocate n_stops memory.\n");
-			goto GRADIENT_FAIL;
-		}
-	} else {
-		stop_colors = stop_colors_st;
-		n_stops = n_stops_st;
-	}
-
-	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
-	                                   stop_colors, n_stops);
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
-		int j = 0;
-		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color1_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color2_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color3_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color4_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color5_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color6_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color7_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-
-		j = 0;
-		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	} else {
-		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
-		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	}
-
-	c1x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
-	c1y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y);
-	c2x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x);
-	c2y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y);
-
-	r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius);
-	r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius);
-
-
-	cxy[0] = c1x;
-	cxy[1] = c1y;
-	dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
-	dispatch->glUniform1f(r1_uniform_location, r1);
-
-	cxy[0] = c2x;
-	cxy[1] = c2y;
-	dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
-	dispatch->glUniform1f(r2_uniform_location, r2);
-
-	A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1);
-	dispatch->glUniform1f(A_value_uniform_location, A_value);
-
-	DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
-	       c1x, c1y, r1, c2x, c2y, r2, A_value);
-
-	glamor_emit_composite_rect(screen, tex_vertices, NULL, vertices);
-
-	if (glamor_priv->render_nr_verts) {
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-		else {
-
-			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-			                       glamor_priv->vbo_offset,
-			                       glamor_priv->vb, GL_DYNAMIC_DRAW);
-		}
-
-		dispatch->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL);
-	}
-
-
-	/* Do the clear logic.*/
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		free(n_stops);
-		free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-
-	glamor_put_dispatch(glamor_priv);
-	return dst_picture;
-
-GRADIENT_FAIL:
-	if (dst_picture) {
-		FreePicture(dst_picture, 0);
-	}
-
-	if (stops_count > RADIAL_SMALL_STOPS) {
-		if (n_stops)
-			free(n_stops);
-		if (stop_colors)
-			free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return NULL;
-}
-
-static PicturePtr
-_glamor_generate_linear_gradient_picture(ScreenPtr screen,
-                                         PicturePtr src_picture,
-                                         int x_source, int y_source,
-                                         int width, int height,
-                                         PictFormatShort format)
-{
-	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
-	PicturePtr dst_picture = NULL;
-	PixmapPtr pixmap = NULL;
-	GLint gradient_prog = 0;
-	int error;
-	float pt_distance;
-	float p1_distance;
-	GLfloat cos_val;
-	float tex_vertices[8];
-	int stops_count;
-	GLfloat *stop_colors = NULL;
-	GLfloat *n_stops = NULL;
-	int count = 0;
-	float slope;
-	GLfloat xscale, yscale;
-	GLfloat pt1[4], pt2[4];
-	float vertices[8];
-	float transform_mat[3][3];
-	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
-	                                         {0.0, 1.0, 0.0},
-	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4];
-	GLfloat n_stops_st[LINEAR_SMALL_STOPS];
-
-	GLint transform_mat_uniform_location;
-	GLint pt1_uniform_location;
-	GLint pt2_uniform_location;
-	GLint n_stop_uniform_location;
-	GLint stops_uniform_location;
-	GLint stop0_uniform_location;
-	GLint stop1_uniform_location;
-	GLint stop2_uniform_location;
-	GLint stop3_uniform_location;
-	GLint stop4_uniform_location;
-	GLint stop5_uniform_location;
-	GLint stop6_uniform_location;
-	GLint stop7_uniform_location;
-	GLint stop_colors_uniform_location;
-	GLint stop_color0_uniform_location;
-	GLint stop_color1_uniform_location;
-	GLint stop_color2_uniform_location;
-	GLint stop_color3_uniform_location;
-	GLint stop_color4_uniform_location;
-	GLint stop_color5_uniform_location;
-	GLint stop_color6_uniform_location;
-	GLint stop_color7_uniform_location;
-	GLint pt_slope_uniform_location;
-	GLint repeat_type_uniform_location;
-	GLint hor_ver_uniform_location;
-	GLint cos_val_uniform_location;
-	GLint p1_distance_uniform_location;
-	GLint pt_distance_uniform_location;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = glamor_get_dispatch(glamor_priv);
-
-	/* Create a pixmap with VBO. */
-	pixmap = glamor_create_pixmap(screen,
-	                              width, height,
-	                              PIXMAN_FORMAT_DEPTH(format),
-	                              0);
-
-	if (!pixmap)
-		goto GRADIENT_FAIL;
-
-	dst_picture = CreatePicture(0, &pixmap->drawable,
-	                            PictureMatchFormat(screen,
-	                                    PIXMAN_FORMAT_DEPTH(format), format),
-	                            0, 0, serverClient, &error);
-
-	/* Release the reference, picture will hold the last one. */
-	glamor_destroy_pixmap(pixmap);
-
-	if (!dst_picture)
-		goto GRADIENT_FAIL;
-
-	ValidatePicture(dst_picture);
-
-	stops_count = src_picture->pSourcePict->linear.nstops + 2;
-
-	/* Because the max value of nstops is unkown, so create a program
-	   when nstops > LINEAR_LARGE_STOPS.*/
-	if (stops_count <= LINEAR_SMALL_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
-	} else if (stops_count <= LINEAR_LARGE_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
-	} else {
-		_glamor_create_linear_gradient_program(screen,
-		        src_picture->pSourcePict->linear.nstops + 2, 1);
-		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
-	}
-
-	/* Bind all the uniform vars .*/
-	pt1_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt1");
-	pt2_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt2");
-	n_stop_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
-	pt_slope_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
-	repeat_type_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
-	hor_ver_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
-	transform_mat_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
-	cos_val_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "cos_val");
-	p1_distance_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
-	pt_distance_uniform_location =
-	    dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
-		stop0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
-		stop1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
-		stop2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
-		stop3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
-		stop4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
-		stop5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
-		stop6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
-		stop7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
-
-		stop_color0_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
-		stop_color1_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
-		stop_color2_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
-		stop_color3_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
-		stop_color4_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
-		stop_color5_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
-		stop_color6_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
-		stop_color7_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
-	} else {
-		stops_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stops");
-		stop_colors_uniform_location =
-		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
-	}
-
-	dispatch->glUseProgram(gradient_prog);
-
-	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
-
-	if (src_picture->transform) {
-		_glamor_gradient_convert_trans_matrix(src_picture->transform,
-		                                      transform_mat,
-		                                      width, height, 1);
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &transform_mat[0][0]);
-	} else {
-		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
-		                             1, 1, &identity_mat[0][0]);
-	}
-
-	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
-	                                             &xscale, &yscale, x_source, y_source,
-	                                             vertices, tex_vertices, 1))
-		goto GRADIENT_FAIL;
-
-	/* Normalize the PTs. */
-	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.x),
-	                        x_source,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.y),
-	                        y_source,
-	                        glamor_priv->yInverted,
-	                        pt1);
-	dispatch->glUniform4fv(pt1_uniform_location, 1, pt1);
-	DEBUGF("pt1:(%f %f)\n", pt1[0], pt1[1]);
-
-	glamor_set_normalize_pt(xscale, yscale,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.x),
-	                        x_source,
-	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.y),
-	                        y_source,
-	                        glamor_priv->yInverted,
-	                        pt2);
-	dispatch->glUniform4fv(pt2_uniform_location, 1, pt2);
-	DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
-
-	/* Set all the stops and colors to shader. */
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		stop_colors = malloc(4 * stops_count * sizeof(float));
-		if (stop_colors == NULL) {
-			ErrorF("Failed to allocate stop_colors memory.\n");
-			goto GRADIENT_FAIL;
-		}
-
-		n_stops = malloc(stops_count * sizeof(float));
-		if (n_stops == NULL) {
-			ErrorF("Failed to allocate n_stops memory.\n");
-			goto GRADIENT_FAIL;
-		}
-	} else {
-		stop_colors = stop_colors_st;
-		n_stops = n_stops_st;
-	}
-
-	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
-	                                   stop_colors, n_stops);
-
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
-		int j = 0;
-		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color1_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color2_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color3_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color4_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color5_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color6_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-		j++;
-		dispatch->glUniform4f(stop_color7_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
-		                      stop_colors[4*j+2], stop_colors[4*j+3]);
-
-		j = 0;
-		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
-		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
-
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	} else {
-		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
-		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
-		dispatch->glUniform1i(n_stop_uniform_location, count);
-	}
-
-	if ((pt2[1] - pt1[1]) / yscale < 1.0) { // The horizontal case.
-		dispatch->glUniform1i(hor_ver_uniform_location, 1);
-		DEBUGF("p1.x: %f, p2.x: %f, enter the horizontal case\n", pt1[1], pt2[1]);
-
-		p1_distance = pt1[0];
-		pt_distance = (pt2[0] - p1_distance);
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	} else if ((pt2[0] - pt1[0]) / xscale < 1.0) { //The vertical case.
-		dispatch->glUniform1i(hor_ver_uniform_location, 2);
-		DEBUGF("p1.y: %f, p2.y: %f, enter the vertical case\n", pt1[0], pt2[0]);
-
-		p1_distance = pt1[1];
-		pt_distance = (pt2[1] - p1_distance);
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	} else {
-		/* The slope need to compute here. In shader, the viewport set will change
-		   the orginal slope and the slope which is vertical to it will not be correct.*/
-		slope = - (float)(src_picture->pSourcePict->linear.p2.x - src_picture->pSourcePict->linear.p1.x) /
-		        (float)(src_picture->pSourcePict->linear.p2.y - src_picture->pSourcePict->linear.p1.y);
-		slope = slope * yscale / xscale;
-		dispatch->glUniform1f(pt_slope_uniform_location, slope);
-		dispatch->glUniform1i(hor_ver_uniform_location, 0);
-
-		cos_val = sqrt(1.0 / (slope * slope + 1.0));
-		dispatch->glUniform1f(cos_val_uniform_location, cos_val);
-
-		p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
-		pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
-		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
-		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
-	}
-
-	/* set the transform matrix. */	/* Now rendering. */
-	glamor_emit_composite_rect(screen, tex_vertices, NULL, vertices);
-
-	if (glamor_priv->render_nr_verts) {
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
-		else {
-
-			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-			dispatch->glBufferData(GL_ARRAY_BUFFER,
-			                       glamor_priv->vbo_offset,
-			                       glamor_priv->vb, GL_DYNAMIC_DRAW);
-		}
-
-		dispatch->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL);
-	}
-
-	/* Do the clear logic.*/
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		free(n_stops);
-		free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-
-	glamor_put_dispatch(glamor_priv);
-	return dst_picture;
-
-GRADIENT_FAIL:
-	if (dst_picture) {
-		FreePicture(dst_picture, 0);
-	}
-
-	if (stops_count > LINEAR_SMALL_STOPS) {
-		if (n_stops)
-			free(n_stops);
-		if (stop_colors)
-			free(stop_colors);
-	}
-
-	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	glamor_put_dispatch(glamor_priv);
-	return NULL;
-}
-#undef LINEAR_DEFAULT_STOPS
-#endif
-
 static PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
                                 PicturePtr source,
@@ -2933,10 +1355,10 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 #ifdef GLAMOR_GRADIENT_SHADER
 	if (!source->pDrawable) {
 		if (source->pSourcePict->type == SourcePictTypeLinear) {
-			dst = _glamor_generate_linear_gradient_picture(screen,
+			dst = glamor_generate_linear_gradient_picture(screen,
 				source, x_source, y_source, width, height, format);
 		} else if (source->pSourcePict->type == SourcePictTypeRadial) {
-			dst = _glamor_generate_radial_gradient_picture(screen,
+			dst = glamor_generate_radial_gradient_picture(screen,
 		                  source, x_source, y_source, width, height, format);
 		}
 
@@ -3021,6 +1443,11 @@ _glamor_composite(CARD8 op,
 	x_temp_mask = x_mask;
 	y_temp_mask = y_mask;
 
+	DEBUGF("Composite Src: (%d, %d)\n"
+	       "         Mask: (%d, %d)\n"
+	       "       to dst: (%d, %d), size: %d X %d \n",
+	       x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
+
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
 
commit 81692804645394b43832c8ec586e8e67f3e4f606
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue May 15 15:25:41 2012 +0800

    glamor_set_destination_pixmap_priv_nc: set drawable's width x height.
    
    Previous implementation set the whole fbo's width and height as the
    viewpoint. This may increase the numerical error as we may only has
    a partial region as the valid pixmap. So add a new marco
    pixmap_priv_get_dest_scale to get proper scale factor for the
    destination pixmap. For the source/mask pixmap, we still need to
    consider the whole fbo's size.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 3bb077c..356e0f9 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -183,7 +183,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		alu = gc->alu;
 	}
 
-	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
@@ -206,8 +206,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 				   &src_y_off);
 	dx += src_x_off;
 	dy += src_y_off;
-	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
-			      &src_yscale);
 
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D,
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 072408e..57dd698 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -237,7 +237,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+	pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
 
 	glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
 				     glamor_priv->yInverted, vertices);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 3f268d9..f0c1586 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -64,7 +64,7 @@ glamor_pixmap_fini(ScreenPtr screen)
 }
 
 void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
+glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int width, int height)
 {
 	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
@@ -74,9 +74,8 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
 	dispatch->glMatrixMode(GL_MODELVIEW);
 	dispatch->glLoadIdentity();
 #endif
-	dispatch->glViewport(0, 0,
-			     fbo->width,
-			     fbo->height);
+	dispatch->glViewport(x0, y0,
+			     width, height);
 
 	glamor_put_dispatch(fbo->glamor_priv);
 }
@@ -84,7 +83,9 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
-	glamor_set_destination_pixmap_fbo(pixmap_priv->fbo);
+	glamor_set_destination_pixmap_fbo(pixmap_priv->fbo, 0, 0,
+					  pixmap_priv->container->drawable.width,
+					  pixmap_priv->container->drawable.height);
 }
 
 int
@@ -507,7 +508,7 @@ ready_to_upload:
 	else
 		ptexcoords = texcoords_inv;
 
-	pixmap_priv_get_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
 	glamor_set_normalize_vcoords(dst_xscale,
 				     dst_yscale,
 				     x, y,
@@ -733,8 +734,8 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 		return NULL;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	temp_xscale = 1.0 / temp_fbo->width;
-	temp_yscale = 1.0 / temp_fbo->height;
+	temp_xscale = 1.0 / w;
+	temp_yscale = 1.0 / h;
 
 	glamor_set_normalize_vcoords(temp_xscale,
 				     temp_yscale,
@@ -770,7 +771,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 				  GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
 
-	glamor_set_destination_pixmap_fbo(temp_fbo);
+	glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 	dispatch->glUniform1i(glamor_priv->
 			      finish_access_revert[no_alpha],
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d26f59f..8f1d428 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -456,7 +456,7 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
 int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
 				       pixmap_priv);
-void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *);
+void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a17b6fd..94f7dc5 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1210,7 +1210,7 @@ glamor_composite_with_shader(CARD8 op,
 
 	glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
 				   &dest_x_off, &dest_y_off);
-	pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	if (glamor_priv->has_source_coords) {
 		glamor_get_drawable_deltas(source->pDrawable,
@@ -2109,7 +2109,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
-	pixmap_priv_get_scale(pixmap_priv, xscale, yscale);
+	pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
 
 	glamor_priv->has_source_coords = 1;
 	glamor_priv->has_mask_coords = 0;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index df66d05..6790550 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -154,7 +154,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	}
 
 	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (!glamor_set_alu(dispatch, alu)) {
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 5cd37de..8dad2df 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -39,6 +39,12 @@
 #define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
+#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
+   do {									\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width;	\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height;	\
+  } while(0)
+
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
    do {									\
     *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
commit 7f55e48499ea7bed73cb1adeac00c480263583f8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue May 15 10:52:37 2012 +0800

    Remove the texture cache code.
    
    Caching texture objects is not necessary based on previous testing.
    To keep the code simple, we remove it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 546fe7b..f4e02b2 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -34,7 +34,6 @@
 
 #define GLAMOR_CACHE_DEFAULT    0
 #define GLAMOR_CACHE_EXACT_SIZE 1
-#define GLAMOR_CACHE_TEXTURE	2
 
 //#define NO_FBO_CACHE 1
 #define FBO_CACHE_THRESHOLD  (256*1024*1024)
@@ -105,14 +104,9 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	n_format = cache_format(format);
 	if (n_format == -1)
 		return NULL;
-	if (!(flag & GLAMOR_CACHE_TEXTURE))
-		cache = &glamor_priv->fbo_cache[n_format]
-					       [cache_wbucket(w)]
-					       [cache_hbucket(h)];
-	else
-		cache = &glamor_priv->tex_cache[n_format]
-					       [cache_wbucket(w)]
-					       [cache_hbucket(h)];
+	cache = &glamor_priv->fbo_cache[n_format]
+				       [cache_wbucket(w)]
+				       [cache_hbucket(h)];
 	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
 		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width >= w && fbo_entry->height >= h) {
@@ -186,14 +180,9 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 		return;
 	}
 
-	if (fbo->fb)
-		cache = &fbo->glamor_priv->fbo_cache[n_format]
-						    [cache_wbucket(fbo->width)]
-						    [cache_hbucket(fbo->height)];
-	else
-		cache = &fbo->glamor_priv->tex_cache[n_format]
-						    [cache_wbucket(fbo->width)]
-						    [cache_hbucket(fbo->height)];
+	cache = &fbo->glamor_priv->fbo_cache[n_format]
+					    [cache_wbucket(fbo->width)]
+					    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
 		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
 
@@ -310,19 +299,6 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 						fbo_entry->expire, glamor_priv->tick);
 					glamor_purge_fbo(fbo_entry);
 				}
-#if 0
-				cache = &glamor_priv->tex_cache[i][j][k];
-				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
-						empty_cache = FALSE;
-						break;
-					}
-					xorg_list_del(&fbo_entry->list);
-					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
-						fbo_entry->expire, glamor_priv->tick);
-					glamor_purge_fbo(fbo_entry);
-				}
-#endif
 			}
 
 }
@@ -339,7 +315,6 @@ glamor_init_pixmap_fbo(ScreenPtr screen)
 			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
 			{
 				xorg_list_init(&glamor_priv->fbo_cache[i][j][k]);
-				xorg_list_init(&glamor_priv->tex_cache[i][j][k]);
 			}
 	glamor_priv->fbo_cache_watermark = 0;
 }
@@ -362,13 +337,6 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 					xorg_list_del(&fbo_entry->list);
 					glamor_purge_fbo(fbo_entry);
 				}
-#if 0
-				cache = &glamor_priv->tex_cache[i][j][k];
-				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					xorg_list_del(&fbo_entry->list);
-					glamor_purge_fbo(fbo_entry);
-				}
-#endif
 			}
 }
 
@@ -380,56 +348,6 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 
 }
 
-static glamor_pixmap_fbo *
-glamor_create_tex_obj(glamor_screen_private *glamor_priv,
-		      int w, int h, GLenum format, int flag)
-{
-	glamor_gl_dispatch *dispatch;
-	glamor_pixmap_fbo *fbo;
-	int cache_flag = GLAMOR_CACHE_TEXTURE;
-	GLuint tex;
-
-	if (flag == GLAMOR_CREATE_TEXTURE_EXACT_SIZE)
-		cache_flag |= GLAMOR_CACHE_EXACT_SIZE;
-
-	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
-					  format, cache_flag);
-	if (fbo)
-		return fbo;
-	fbo = calloc(1, sizeof(*fbo));
-	if (fbo == NULL)
-		return NULL;
-
-	xorg_list_init(&fbo->list);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glGenTextures(1, &tex);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
-			       GL_UNSIGNED_BYTE, NULL);
-	glamor_put_dispatch(glamor_priv);
-
-	fbo->tex = tex;
-	fbo->width = w;
-	fbo->height = h;
-	fbo->format = format;
-	fbo->glamor_priv = glamor_priv;
-
-	return fbo;
-}
-
-static void
-glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
-{
-	assert(tex_obj->fb == 0);
-	xorg_list_del(&tex_obj->list);
-	glamor_pixmap_fbo_cache_put(tex_obj);
-}
-
 static int
 _glamor_create_tex(glamor_screen_private *glamor_priv,
 		   int w, int h, GLenum format)
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ca88fb4..d26f59f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -210,7 +210,6 @@ typedef struct glamor_screen_private {
 	int max_fbo_size;
 
 	struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
-	struct xorg_list tex_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
 	unsigned long    fbo_cache_watermark;
 
 	/* glamor_solid */
commit c5b3c2cedc8b2e486b1e3727f288c42869310387
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue May 15 10:42:41 2012 +0800

    Added strict warning flags to CFLAGS.
    
    We miss the strict warning flags for a long time, now add it back.
    This commit also fixed most of the warnings after enable the strict
    flags.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index c7e3000..8e334b1 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -15,7 +15,7 @@ instdir = $(moduledir)
 INCLUDES = \
 	$(XORG_INCS)
 
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
+AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 
 libglamor_la_LDFLAGS = -avoid-version
 
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 691f758..6b6fa0b 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -465,12 +465,11 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	glamor_screen_private *glamor_priv;
 	PixmapPtr screen_pixmap;
 	int flags;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	flags = glamor_priv->flags;
 #ifdef RENDER
 	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
+	glamor_priv = glamor_get_screen_private(screen);
+	flags = glamor_priv->flags;
 	glamor_glyphs_fini(screen);
 	screen->CloseScreen = glamor_priv->saved_procs.close_screen;
 	if (flags & GLAMOR_USE_SCREEN) {
diff --git a/glamor/glamor.h b/glamor/glamor.h
index da45acc..c2db86a 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -157,6 +157,9 @@ extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
  * */
 extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back);
 
+extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
+
+
 #ifdef GLAMOR_FOR_XORG
 
 #define GLAMOR_EGL_MODULE_NAME  "glamoregl"
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 35bcc9e..07acf1a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -91,7 +91,8 @@ struct glamor_egl_screen_private {
 	struct gbm_device *gbm;
 #endif
 	int has_gem;
-	void *gl_context, *old_context;
+	void *glamor_context;
+	void *current_context;
 	int gl_context_depth;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
@@ -121,10 +122,9 @@ glamor_egl_make_current(ScreenPtr screen)
 	if (glamor_egl->gl_context_depth++)
 		return;
 
-	GET_CURRENT_CONTEXT(current);
-	glamor_egl->old_context = current;
+	GET_CURRENT_CONTEXT(glamor_egl->current_context);
 
-	if (glamor_egl->gl_context != current) {
+	if (glamor_egl->glamor_context != glamor_egl->current_context) {
 		eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
 			       EGL_NO_SURFACE, EGL_NO_CONTEXT);
 		if (!eglMakeCurrent(glamor_egl->display,
@@ -145,9 +145,9 @@ glamor_egl_restore_context(ScreenPtr screen)
 	if (--glamor_egl->gl_context_depth)
 		return;
 
-	if (glamor_egl->old_context &&
-	    glamor_egl->gl_context != glamor_egl->old_context)
-		SET_CURRENT_CONTEXT(glamor_egl->old_context);
+	if (glamor_egl->current_context &&
+	    glamor_egl->glamor_context != glamor_egl->current_context)
+		SET_CURRENT_CONTEXT(glamor_egl->current_context);
 }
 #else
 #define glamor_egl_make_current(x)
@@ -255,7 +255,7 @@ glamor_egl_create_textured_screen_ext(ScreenPtr screen,
 	return TRUE;
 }
 
-Bool
+static Bool
 glamor_egl_check_has_gem(int fd)
 {
 	struct drm_gem_flink flink;
@@ -548,8 +548,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 		return FALSE;
 	}
 #ifdef GLX_USE_SHARED_DISPATCH
-	GET_CURRENT_CONTEXT(current);
-	glamor_egl->gl_context = current;
+	GET_CURRENT_CONTEXT(glamor_egl->glamor_context);
 #endif
 	glamor_egl->saved_free_screen = scrn->FreeScreen;
 	scrn->FreeScreen = glamor_egl_free_screen;
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d80771a..546fe7b 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -92,7 +92,7 @@ inline static int cache_hbucket(int size)
 	return order;
 }
 
-glamor_pixmap_fbo *
+static glamor_pixmap_fbo *
 glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 			    int w, int h, GLenum format, int flag)
 {
@@ -380,7 +380,7 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 
 }
 
-glamor_pixmap_fbo *
+static glamor_pixmap_fbo *
 glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 		      int w, int h, GLenum format, int flag)
 {
@@ -422,7 +422,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	return fbo;
 }
 
-void
+static void
 glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
 {
 	assert(tex_obj->fb == 0);
@@ -430,7 +430,7 @@ glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
 	glamor_pixmap_fbo_cache_put(tex_obj);
 }
 
-int
+static int
 _glamor_create_tex(glamor_screen_private *glamor_priv,
 		   int w, int h, GLenum format)
 {
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 9b40b66..3f268d9 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -185,7 +185,7 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 	return TRUE;
 }
 
-void *
+static void *
 _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert)
 {
 	PictFormatShort dst_format, src_format;
@@ -269,7 +269,7 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 			(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
 	}
 
-void *
+static void *
 _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	int x,y;
@@ -306,7 +306,7 @@ _glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, i
 
 }
 
-void *
+static void *
 _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	int x,y;
@@ -360,7 +360,7 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int
  *
  */
 
-void *
+static void *
 glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
@@ -917,8 +917,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
 					     GL_READ_ONLY);
 		for (yy = 0; yy < pixmap->drawable.height; yy++)
-			memcpy(data + yy * stride,
-			       read + (h - yy - 1) * stride, stride);
+			memcpy((char*)data + yy * stride,
+			       (char*)read + (h - yy - 1) * stride, stride);
 		dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
 		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		dispatch->glDeleteBuffers(1, &temp_pbo);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b729e98..a17b6fd 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -961,11 +961,11 @@ glamor_composite_with_shader(CARD8 op,
 	PictFormatShort saved_source_format = 0;
 	float src_matrix[9], mask_matrix[9];
 	GLfloat source_solid_color[4], mask_solid_color[4];
-	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	int vert_stride = 4;
 	int nrect_max;
 	Bool ret = FALSE;
 
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 9d32e6e..5cd37de 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -886,9 +886,9 @@ static inline void _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
 	int little_endian = 0;
 	unsigned char *p_test;
 	int bpp = pixmap1->drawable.depth == 8 ? 1 : 4;
+	int stride = pixmap1->devKind;
 
 	assert(pixmap1->devKind == pixmap2->devKind);
-	int stride = pixmap1->devKind;
 
 	ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h);
 
diff --git a/glamor/glapi.h b/glamor/glapi.h
index da521aa..d510dac 100644
--- a/glamor/glapi.h
+++ b/glamor/glapi.h
@@ -79,7 +79,7 @@ extern const struct _glapi_table *_glapi_Dispatch;
 extern const void *_glapi_Context;
 
 # define GET_DISPATCH() _glapi_tls_Dispatch
-# define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_tls_Context
+# define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_tls_Context
 # define SET_CURRENT_CONTEXT(C)  _glapi_tls_Context = (void*)C
 
 #else
@@ -92,7 +92,7 @@ extern void *_glapi_Context;
 #  define GET_DISPATCH() \
      (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
 
-#  define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) \
+#  define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) \
      (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context())
 
 
@@ -104,7 +104,7 @@ extern void *_glapi_Context;
 # else
 
 #  define GET_DISPATCH() _glapi_Dispatch
-#  define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_Context
+#  define GET_CURRENT_CONTEXT(C)  C = (typeof(C)) _glapi_Context
 # define SET_CURRENT_CONTEXT(C)  _glapi_Context = (void*)C
 
 # endif
commit 6839996b0b0fe5f4e6ef28d1dfe527092d60d28a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 18:23:09 2012 +0800

    We should not call gradient finalization code if we disable it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 87c9839..691f758 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -427,7 +427,9 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_fini_tile_shader(screen);
 	glamor_fini_putimage_shaders(screen);
 	glamor_fini_finish_access_shaders(screen);
+#ifdef GLAMOR_GRADIENT_SHADER
 	glamor_fini_gradient_shader(screen);
+#endif
 	glamor_pixmap_fini(screen);
 	free(glamor_priv);
 
commit 1035fc72b9017eb2466760133ca7bbc9155c8c46
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 14:55:34 2012 +0800

    Fixed all unused variables warnings.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index f924c91..87c9839 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -136,7 +136,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	    glamor_get_screen_private(screen);
 	glamor_pixmap_fbo *fbo;
 	int pitch;
-	int flag;
 	GLenum format;
 
 	if (w > 32767 || h > 32767)
@@ -463,8 +462,6 @@ glamor_close_screen(int idx, ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
 	PixmapPtr screen_pixmap;
-	glamor_pixmap_private *screen_pixmap_priv;
-	glamor_pixmap_fbo *fbo;
 	int flags;
 
 	glamor_priv = glamor_get_screen_private(screen);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index ee9e9f4..3bb077c 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -398,8 +398,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
 	    || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
 		LogMessage(X_WARNING,
-			   "Access a DRM only pixmap is not allowed within glamor.\n",
-			   dst->pScreen->myNum);
+			   "Access a DRM only pixmap is not allowed within glamor.\n");
 		return TRUE;
 	}
 	glamor_report_delayed_fallbacks(src->pScreen);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index c2627b9..35bcc9e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -260,10 +260,9 @@ glamor_egl_check_has_gem(int fd)
 {
 	struct drm_gem_flink flink;
 	flink.handle = 0;
-	int err;
 
 	ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
-	if (errno == ENOENT || err == EINVAL)
+	if (errno == ENOENT || errno == EINVAL)
 		return TRUE;
 	return FALSE;
 }
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 9b8dcdf..d80771a 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -98,7 +98,6 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 {
 	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
-	int size;
 	int n_format;
 #ifdef NO_FBO_CACHE
 	return NULL;
@@ -436,7 +435,7 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
 		   int w, int h, GLenum format)
 {
 	glamor_gl_dispatch *dispatch;
-	int tex;
+	unsigned int tex;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glGenTextures(1, &tex);
@@ -451,15 +450,12 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
 	return tex;
 }
 
-
-
 glamor_pixmap_fbo *
 glamor_create_fbo(glamor_screen_private *glamor_priv,
 		  int w, int h,
 		  GLenum format,
 		  int flag)
 {
-	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *fbo;
 	GLint tex = 0;
 	int cache_flag;
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index def4550..072408e 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -40,7 +40,7 @@ glamor_fill(DrawablePtr drawable,
 	PixmapPtr sub_pixmap = NULL;
 	glamor_access_t sub_pixmap_access;
 	DrawablePtr saved_drawable = NULL;
-	int saved_x, saved_y;
+	int saved_x = x, saved_y = y;
 
 	glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
 
@@ -119,8 +119,6 @@ glamor_fill(DrawablePtr drawable,
 	}
 
 	if (sub_pixmap != NULL) {
-		struct pixman_box16 box;
-		int dx, dy;
 		if (gc->fillStyle != FillSolid) {
 			gc->patOrg.x -= (saved_drawable->x - saved_x);
 			gc->patOrg.y -= (saved_drawable->y - saved_y);
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index b53635c..655ed94 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -37,7 +37,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	PixmapPtr pixmap, sub_pixmap;
 	struct glamor_pixmap_private *pixmap_priv;
 	int x_off, y_off;
-	Bool ret = FALSE;
 	int stride;
 	void *data;
 
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 18ad536..b55327c 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -33,8 +33,6 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
@@ -65,8 +63,6 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 5c46b03..9b40b66 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -188,7 +188,6 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 void *
 _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert)
 {
-	void *bits;
 	PictFormatShort dst_format, src_format;
 	pixman_image_t *dst_image;
 	pixman_image_t *src_image;
@@ -209,7 +208,6 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 					     dst_bits,
 					     stride);
 	if (dst_image == NULL) {
-		free(bits);
 		return NULL;
 	}
 
@@ -220,7 +218,6 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 
 	if (src_image == NULL) {
 		pixman_image_unref(dst_image);
-		free(bits);
 		return NULL;
 	}
 
@@ -384,7 +381,7 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int s
  **/
 int in_restore = 0;
 static void
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, int *tex,
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 				  GLenum format,
 				  GLenum type,
 				  int x, int y, int w, int h,
@@ -394,7 +391,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, int *tex,
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	int non_sub = 0;
-	int iformat;
+	unsigned int iformat = 0;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (*tex == 0) {
@@ -480,7 +477,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum ty
 						    stride,
 						    no_alpha, revert, swap_rb);
 		if (bits == NULL) {
-			ErrorF("Failed to convert pixmap no_alpha %d, revert mode %d, swap mode %d\n", swap_rb);
+			ErrorF("Failed to convert pixmap no_alpha %d,"
+				"revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
 			return FALSE;
 		}
 		no_alpha = 0;
@@ -698,8 +696,7 @@ void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
 	if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
-		LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n",
-			   pixmap->drawable.pScreen->myNum);
+		LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
 }
 
 /*
@@ -800,7 +797,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 				  int stride, void *bits, int pbo, glamor_access_t access)
 {
 	glamor_pixmap_private *pixmap_priv;
-	GLenum format, type, gl_access, gl_usage;
+	GLenum format, type, gl_access = 0, gl_usage = 0;
 	int no_alpha, revert, swap_rb;
 	void *data, *read;
 	ScreenPtr screen;
@@ -904,7 +901,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		}
 	} else {
-		int temp_pbo;
+		unsigned int temp_pbo;
 		int yy;
 
 		dispatch = glamor_get_dispatch(glamor_priv);
@@ -940,8 +937,6 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 						    revert, swap_rb);
 	}
 
-      done:
-
 	if (temp_fbo != NULL)
 		glamor_destroy_fbo(temp_fbo);
 	if (need_free_data)
@@ -965,9 +960,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 {
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	unsigned int stride, y;
-	GLenum format, type, gl_access, gl_usage;
-	int no_alpha, revert, swap_rb;
+	unsigned int stride;
 	void *data = NULL, *dst;
 	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
@@ -1024,8 +1017,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
 
-      done:
-
 	pixmap->devPrivate.ptr = dst;
 
 	return TRUE;
@@ -1188,7 +1179,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	return sub_pixmap;
 }
 
-PixmapPtr
+void
 glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
 {
 	void *bits;
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index bbe10a1..738e8eb 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -44,7 +44,6 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	RegionPtr pClip = fbGetCompositeClip(gc);
 	Bool ret = FALSE;
 	glamor_screen_private *glamor_priv;
-	xRectangle *saved_prect = prect;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 91473c3..ca88fb4 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -648,8 +648,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 PixmapPtr
 glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
 		      int w, int h, glamor_access_t access);
-
-PixmapPtr
+void
 glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
 		      int w, int h, glamor_access_t access);
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index a1119b6..d1e3a83 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -255,7 +255,6 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	    glamor_get_pixmap_private(pixmap);
 	RegionPtr clip;
 	int x_off, y_off;
-	float vertices[8], texcoords[8];
 	Bool ret = FALSE;
 	PixmapPtr temp_pixmap, sub_pixmap;
 	glamor_pixmap_private *temp_pixmap_priv;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d133135..9d32e6e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1018,8 +1018,6 @@ static inline void glamor_compare_pictures( ScreenPtr screen,
 	PixmapPtr fst_pixmap;
 	PixmapPtr snd_pixmap;
 	int fst_generated, snd_generated;
-	glamor_pixmap_private *fst_pixmap_priv;
-	glamor_pixmap_private *snd_pixmap_priv;
 	int error;
 	int fst_type = -1;
 	int snd_type = -1; // -1 represent has drawable.
commit 33e11cd6149294060269ed693de67b135868e094
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 14:54:38 2012 +0800

    Fixed an uninitialized problem at gradient shader functions.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index c6f9c06..b729e98 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1651,6 +1651,8 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy
 		return;
 	}
 
+	dispatch = glamor_get_dispatch(glamor_priv);
+
 	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
 		dispatch->glDeleteShader(
 		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
@@ -1668,8 +1670,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dy
 		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
 	}
 
-	dispatch = glamor_get_dispatch(glamor_priv);
-
 	gradient_prog = dispatch->glCreateProgram();
 
 	vs_prog = glamor_compile_glsl_prog(dispatch,
@@ -1883,6 +1883,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 		return;
 	}
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
 		dispatch->glDeleteShader(
 		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
@@ -1900,8 +1901,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dy
 		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
 	}
 
-	dispatch = glamor_get_dispatch(glamor_priv);
-
 	gradient_prog = dispatch->glCreateProgram();
 
 	vs_prog = glamor_compile_glsl_prog(dispatch,
commit c0f75c657f36642faea4ff8c51f7e4f6971c3d19
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 14:51:27 2012 +0800

    Fixed one typo bug when fixup a mask picture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 0377a8a..c6f9c06 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -403,9 +403,8 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
 	unsigned short *eb;
-	float *vb;
+	float *vb = NULL;
 	int eb_size;
-	int vb_size;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch = glamor_get_dispatch(glamor_priv);
@@ -542,7 +541,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
 	float wh[2];
-	Bool has_repeat;
 	int repeat_type;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
@@ -1163,7 +1161,7 @@ glamor_composite_with_shader(CARD8 op,
 		if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
 			goto fail;
 	}
-	if (key.mask != SHADER_SOURCE_SOLID && key.mask != SHADER_MASK_SOLID
+	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
 	    && mask->transform
 	    && !pixman_transform_is_int_translate(mask->transform)) {
 		if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
@@ -1341,6 +1339,7 @@ done:
 	return ret;
 }
 
+#ifdef GLAMOR_GRADIENT_SHADER
 static GLint
 _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array)
 {
@@ -1348,7 +1347,6 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	glamor_gl_dispatch *dispatch;
 
 	char *gradient_fs = NULL;
-	GLint gradient_prog = 0;
 	GLint fs_getcolor_prog;
 
 	const char *gradient_fs_getcolor =
@@ -2252,7 +2250,6 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	glamor_gl_dispatch *dispatch;
 	PicturePtr dst_picture = NULL;
 	PixmapPtr pixmap = NULL;
-	glamor_pixmap_private *pixmap_priv;
 	GLint gradient_prog = 0;
 	int error;
 	float tex_vertices[8];
@@ -2581,7 +2578,6 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	int stops_count;
 	GLfloat *stop_colors = NULL;
 	GLfloat *n_stops = NULL;
-	int i = 0;
 	int count = 0;
 	float slope;
 	GLfloat xscale, yscale;
@@ -2919,6 +2915,7 @@ GRADIENT_FAIL:
 	return NULL;
 }
 #undef LINEAR_DEFAULT_STOPS
+#endif
 
 static PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
@@ -3009,17 +3006,16 @@ _glamor_composite(CARD8 op,
 	Bool ret = TRUE;
 	RegionRec region;
 	BoxPtr box;
-	int nbox, i, ok;
+	int nbox, i, ok = FALSE;
 	PixmapPtr sub_dest_pixmap = NULL;
 	PixmapPtr sub_source_pixmap = NULL;
 	PixmapPtr sub_mask_pixmap = NULL;
-	int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
-	int source_x_off, source_y_off, saved_source_x, saved_source_y;
-	int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
-	DrawablePtr saved_dest_drawable;
-	DrawablePtr saved_source_drawable;
-	DrawablePtr saved_mask_drawable;
-
+	int dest_x_off, dest_y_off, saved_dest_x = 0, saved_dest_y = 0;
+	int source_x_off, source_y_off, saved_source_x = 0, saved_source_y = 0;
+	int mask_x_off, mask_y_off, saved_mask_x = 0, saved_mask_y = 0;
+	DrawablePtr saved_dest_drawable = NULL;
+	DrawablePtr saved_source_drawable = NULL;
+	DrawablePtr saved_mask_drawable = NULL;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
commit 5c1f15fac26b86b6cb73776db1a644d6af570da7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 14:13:47 2012 +0800

    Added some copyright and author information.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index ea822f3..f924c91 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index e6206d0..da45acc 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index f282067..ee9e9f4 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -19,6 +19,10 @@
  * 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  */
 
 #include "glamor_priv.h"
@@ -329,7 +333,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 			}
 		}
 	}
-	/* XXX need revisit to handle overlapped area copying. */
 #ifndef GLAMOR_GLES2
 	if ((overlaped
 	     || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index ac7e698..99dce04 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
 #ifndef __GLAMOR_DEBUG_H__
 #define __GLAMOR_DEBUG_H__
 
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 0961651..046f4de 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -22,6 +22,9 @@
  * not be used in advertising or otherwise to promote the sale, use or other
  * dealings in this Software without prior written authorization from the
  * XFree86 Project.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
  */
 
 #ifdef HAVE_CONFIG_H
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index a7cae66..9b8dcdf 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
 #include <stdlib.h>
 
 #include "glamor_priv.h"
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 95b070d..def4550 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -19,6 +19,10 @@
  * 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  */
 
 #include "glamor_priv.h"
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 22e2b7c..6d6c8e9 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index e6da94d..f996504 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
 #include "glamor_priv.h"
 #include <dlfcn.h>
 
diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h
index f734d13..d60c696 100644
--- a/glamor/glamor_glext.h
+++ b/glamor/glamor_glext.h
@@ -1,3 +1,32 @@
+/*
+ * Copyright © 2001 Keith Packard
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+
 #ifdef GLAMOR_GLES2
 
 #define GL_BGRA                                 GL_BGRA_EXT
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 38185a4..a6d21f1 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -1,3 +1,31 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
 #include <stdlib.h>
 
 #include "glamor_priv.h"
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 68a7b06..5c46b03 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1,3 +1,32 @@
+/*
+ * Copyright © 2001 Keith Packard
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
 #include <stdlib.h>
 
 #include "glamor_priv.h"
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 0c3c0c5..a1119b6 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 3f3a3bc..0377a8a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -22,6 +22,8 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *    Junyan He <junyan.he at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index e283853..a71efe9 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 8e09553..df66d05 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *    Eric Anholt <eric at anholt.net>
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
  *
  */
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index f39e3a5..d133135 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1,3 +1,30 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
 #ifndef GLAMOR_PRIV_H
 #error This file can only be included by glamor_priv.h
 #endif
commit 0d846d95699fadcddcc77b8d6e432e969467dab2
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 13:43:39 2012 +0800

    Added --enable-debug configuration option.
    
    For release version, we disable asserts.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 081b363..c2627b9 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -287,7 +287,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 				   "Couldn't flink pixmap handle\n");
 			glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-			exit(1);
+			assert(0);
+			return FALSE;
 		}
 	} else
 		name = handle;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2aa03d0..91473c3 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -32,7 +32,9 @@
 #endif
 
 #include <xorg-server.h>
-
+#ifndef DEBUG
+#define NDEBUG
+#endif
 #include "glamor.h"
 
 #define GL_GLEXT_PROTOTYPES
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index de01aab..3f3a3bc 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -427,7 +427,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	}
 
 	if (eb == NULL)
-		FatalError("fatal error, fail to get eb.\n");
+		FatalError("fatal error, fail to get element buffer. GL context may be not created correctly.\n");
 	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
commit 503f8ec1a670e73f41314a5e94cdde8782d7cbab
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 28 13:42:48 2012 +0800

    Remove unecessary header file.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index c608ed8..e6206d0 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -33,7 +33,6 @@
 #include <xf86str.h>
 #endif
 #include <pixmapstr.h>
-#include <windowstr.h>
 #include <gcstruct.h>
 #include <picturestr.h>
 #include <fb.h>
commit 9dfd10dc75efdf4c26b7ff46b55e4a2d2453803b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 27 15:34:15 2012 +0800

    glamor_render: Fix the repeat none for GLES2.
    
    As GLES2 doesn't support clamp to the border, we have to
    handle it seprately from the normal case.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 21ef904..de01aab 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -65,7 +65,7 @@ static struct blendinfo composite_op_info[] = {
 	    {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
 	[PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
 };
-
+#define RepeatFix			10
 static GLuint
 glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 			   struct shader_key *key)
@@ -75,6 +75,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "#define RepeatNormal                     1\n"
 	    "#define RepeatPad                        2\n"
 	    "#define RepeatReflect                    3\n"
+	    "#define RepeatFix		      	      10\n"
 	    "uniform int 			source_repeat_mode;\n"
 	    "uniform int 			mask_repeat_mode;\n";
 	const char *relocate_texture =
@@ -83,7 +84,9 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "{\n"
 	    "   vec2 rel_tex; \n"
 	    "   rel_tex = texture * wh; \n"
-	    "   if (repeat == RepeatNormal) \n"
+	    "	if (repeat == RepeatNone)\n"
+	    "		return rel_tex; \n"
+	    "   else if (repeat == RepeatNormal) \n"
 	    "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
 	    "   else if(repeat == RepeatPad) { \n"
 	    "           if (rel_tex.x > 1.0) rel_tex.x = 1.0;		  \n"
@@ -104,6 +107,24 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "    } \n"
             "   return rel_tex; \n"
 	    "}\n";
+	/* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
+	 * rel_sampler will recalculate the texture coords.*/
+	const char *rel_sampler =
+	    " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec2 wh, int repeat, int set_alpha)\n"
+	    "{\n"
+	    "	tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
+	    "   if (repeat == RepeatFix) {\n"
+	    "		if (!(tex.x >= 0.0 && tex.x <= 1.0 \n"
+	    "		    && tex.y >= 0.0 && tex.y <= 1.0))\n"
+	    "			return vec4(0.0, 0.0, 0.0, set_alpha);\n"
+	    "		tex = (fract(tex) / wh);\n"
+	    "	}\n"
+	    "	if (set_alpha != 1)\n"
+	    "		return texture2D(tex_image, tex);\n"
+	    "	else\n"
+	    "		return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+	    "}\n";
+
 	const char *source_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION
 	    "uniform vec4 source;\n"
@@ -115,12 +136,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
 	    "{\n"
-	    "   if (source_repeat_mode == RepeatNone) \n"
+	    "   if (source_repeat_mode < RepeatFix)\n"
 	    "		return texture2D(source_sampler, source_texture);\n"
-	    "	else \n"
-	    "		return texture2D(source_sampler,\n"
-	    "				 rel_tex_coord(source_texture,\n"
-	    "				 source_wh, source_repeat_mode));\n"
+	    "   else \n"
+	    "		return rel_sampler(source_sampler, source_texture,\n"
+	    "				   source_wh, source_repeat_mode, 0);\n"
 	    "}\n";
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
@@ -128,12 +148,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 source_wh;\n"
 	    "vec4 get_source()\n"
 	    "{\n"
-	    "   if (source_repeat_mode == RepeatNone) \n"
+	    "   if (source_repeat_mode < RepeatFix) \n"
 	    "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
 	    "	else \n"
-	    "   	return vec4(texture2D(source_sampler, \n"
-	    "			    rel_tex_coord(source_texture,\n"
-	    "			    source_wh, source_repeat_mode)).rgb, 1);\n"
+	    "		return rel_sampler(source_sampler, source_texture,\n"
+	    "				   source_wh, source_repeat_mode, 1);\n"
 	    "}\n";
 	const char *mask_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
@@ -144,12 +163,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "   if (mask_repeat_mode == RepeatNone) \n"
+	    "   if (mask_repeat_mode < RepeatFix) \n"
 	    "		return texture2D(mask_sampler, mask_texture);\n"
 	    "   else \n"
-	    "		return texture2D(mask_sampler, \n"
-	    "				 rel_tex_coord(mask_texture, \n"
-	    "				 mask_wh, mask_repeat_mode));\n"
+	    "		return rel_sampler(mask_sampler, mask_texture,\n"
+	    "				   mask_wh, mask_repeat_mode, 0);\n"
 	    "}\n";
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
@@ -157,12 +175,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "   if (mask_repeat_mode == RepeatNone) \n"
+	    "   if (mask_repeat_mode < RepeatFix) \n"
 	    "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
 	    "   else \n"
-	    "   	return vec4(texture2D(mask_sampler, \n"
-	    "			    rel_tex_coord(mask_texture, \n"
-	    "			    mask_wh, mask_repeat_mode)).rgb, 1);\n"
+	    "		return rel_sampler(mask_sampler, mask_texture,\n"
+	    "				   mask_wh, mask_repeat_mode, 1);\n"
 	    "}\n";
 	const char *in_source_only =
 	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
@@ -229,7 +246,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 		FatalError("Bad composite IN type");
 	}
 
-	XNFasprintf(&source, "%s%s%s%s%s", repeat_define, relocate_texture, source_fetch, mask_fetch, in);
+	XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, rel_sampler,source_fetch, mask_fetch, in);
 
 
 	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -524,11 +541,12 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	glamor_gl_dispatch *dispatch;
 	float wh[2];
 	Bool has_repeat;
+	int repeat_type;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
-
+	repeat_type = picture->repeatType;
 	switch (picture->repeatType) {
 	case RepeatNone:
 #ifndef GLAMOR_GLES2
@@ -537,6 +555,11 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 					  GL_CLAMP_TO_BORDER);
 		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
 					  GL_CLAMP_TO_BORDER);
+#else
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_CLAMP_TO_EDGE);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_CLAMP_TO_EDGE);
 #endif
 		break;
 	case RepeatNormal:
@@ -560,6 +583,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	}
 
 	switch (picture->filter) {
+	default:
 	case PictFilterNearest:
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
@@ -569,7 +593,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 					  GL_NEAREST);
 		break;
 	case PictFilterBilinear:
-	default:
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
 					  GL_LINEAR);
@@ -581,14 +604,22 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUniform1i(repeat_location, picture->repeatType);
-	if (picture->repeatType != RepeatNone) {
-		wh[0] = (float)pixmap_priv->fbo->width
-			/ pixmap_priv->container->drawable.width;
-		wh[1] = (float)pixmap_priv->fbo->height
-			/ pixmap_priv->container->drawable.height;
+	/* XXX may be we can eaxctly check whether we need to touch
+	 * the out-of-box area then determine whether we need to fix.
+	 * */
+	if (repeat_type != RepeatNone)
+		repeat_type += RepeatFix;
+	else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		if (picture->transform
+		   || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
+			repeat_type += RepeatFix;
+	}
+
+	if (repeat_type >= RepeatFix) {
+		glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
 		dispatch->glUniform2fv(wh_location, 1, wh);
 	}
+	dispatch->glUniform1i(repeat_location, repeat_type);
 	glamor_put_dispatch(glamor_priv);
 }
 
@@ -694,6 +725,7 @@ glamor_composite_with_copy(CARD8 op,
 		if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
 			goto cleanup_region;
 	}
+
 	ret = glamor_copy_n_to_n_nf(source->pDrawable,
 				    dest->pDrawable, NULL,
 				    REGION_RECTS(&region),
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index c468490..f39e3a5 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -18,6 +18,17 @@
     *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
   } while(0)
 
+#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv)				\
+	(priv->fbo->width != priv->container->drawable.width 	\
+	 || priv->fbo->height != priv->container->drawable.height)
+
+#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv)  do {			\
+	wh[0] = (float)priv->fbo->width					\
+		/ priv->container->drawable.width;			\
+	wh[1] = (float)priv->fbo->height				\
+		/ priv->container->drawable.height;			\
+	} while(0)
+
 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
 			      + ((float)xFixedFrac(_val_) / 65536.0))
 
commit 9fcd123aed80430b220fc4141eaa3723d7cb611e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 26 20:35:09 2012 +0800

    glamor_blockhandler: Don't do glFinish every time.
    
    To do glfinish every time bring some performance overhead.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index cba6623..ea822f3 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -213,7 +213,6 @@ glamor_block_handler(ScreenPtr screen)
 	dispatch = glamor_get_dispatch(glamor_priv);
 	glamor_priv->tick++;
 	dispatch->glFlush();
-	dispatch->glFinish();
 	glamor_fbo_expire(glamor_priv);
 	glamor_put_dispatch(glamor_priv);
 }
@@ -225,7 +224,6 @@ _glamor_block_handler(void *data, OSTimePtr timeout,
 	glamor_screen_private *glamor_priv = data;
 	glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glFlush();
-	dispatch->glFinish();
 	glamor_put_dispatch(glamor_priv);
 }
 
commit 1f83411c9a69a44944fd8afe0c167cece60c1ecb
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 26 19:59:58 2012 +0800

    glamor_copyarea: Return earlier if have zero nbox.
    
    Almost all callers will check whether the regions is empty
    before call to this internal API, but it seems the
    glamor_composite_with_copy may call into here with a zero
    nbox. A little weird, as the miComputeCompositeRegion return
    a Non-NULL, but the region is empty.
    
    Also remove a unecessary glflush.
    
    So let's check it here.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index d19e28b..f282067 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -150,7 +150,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
 	enum glamor_pixmap_status src_status = GLAMOR_NONE;
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-	int flush_needed = 0;
 	int alu = GXcopy;
 
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
@@ -172,8 +171,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 #endif
-	} else
-		flush_needed = 1;
+	}
 
 	if (gc) {
 		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
@@ -265,8 +263,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 #endif
 	dispatch->glUseProgram(0);
 	/* The source texture is bound to a fbo, we have to flush it here. */
-	if (flush_needed)
-		dispatch->glFlush();
 	glamor_put_dispatch(glamor_priv);
 	return TRUE;
 }
@@ -297,12 +293,13 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	int overlaped = 0;
 	Bool ret = FALSE;
 
+	if (nbox == 0)
+		return TRUE;
 	dst_pixmap = glamor_get_drawable_pixmap(dst);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 	src_pixmap = glamor_get_drawable_pixmap(src);
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
-
 	glamor_priv = glamor_get_screen_private(dst->pScreen);
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
commit 20cbaa61cdca41e61526a57f13475cb31e17e5dd
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 26 19:57:21 2012 +0800

    glamor_render: Have to use eaxct size pixmap for transformation.
    
    Use partial texture as the pixmap for the transformation
    source/mask may introduce extra errors. have to use
    eaxct size.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d4ee78a..21ef904 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -522,12 +522,12 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch;
+	float wh[2];
+	Bool has_repeat;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
-	float wh[2];
-	Bool has_repeat;
 
 	switch (picture->repeatType) {
 	case RepeatNone:
@@ -581,19 +581,14 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	if (picture->repeatType == RepeatNone) {
-		has_repeat = picture->transform
-			     && !pixman_transform_is_int_translate(picture->transform);
-		if (has_repeat)
-			dispatch->glUniform1i(repeat_location, RepeatNormal);
-	}
-	else {
-		has_repeat = TRUE;
-		dispatch->glUniform1i(repeat_location, picture->repeatType);
+	dispatch->glUniform1i(repeat_location, picture->repeatType);
+	if (picture->repeatType != RepeatNone) {
+		wh[0] = (float)pixmap_priv->fbo->width
+			/ pixmap_priv->container->drawable.width;
+		wh[1] = (float)pixmap_priv->fbo->height
+			/ pixmap_priv->container->drawable.height;
+		dispatch->glUniform2fv(wh_location, 1, wh);
 	}
-	wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
-	wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
-	dispatch->glUniform2fv(wh_location, 1, wh);
 	glamor_put_dispatch(glamor_priv);
 }
 
@@ -699,7 +694,6 @@ glamor_composite_with_copy(CARD8 op,
 		if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
 			goto cleanup_region;
 	}
-
 	ret = glamor_copy_n_to_n_nf(source->pDrawable,
 				    dest->pDrawable, NULL,
 				    REGION_RECTS(&region),
@@ -1126,6 +1120,22 @@ glamor_composite_with_shader(CARD8 op,
 		}
 	}
 #endif
+
+	/*Before enter the rendering stage, we need to fixup
+	 * transformed source and mask, if the transform is not int translate. */
+	if (key.source != SHADER_SOURCE_SOLID
+	    && source->transform
+	    && !pixman_transform_is_int_translate(source->transform)) {
+		if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
+			goto fail;
+	}
+	if (key.mask != SHADER_SOURCE_SOLID && key.mask != SHADER_MASK_SOLID
+	    && mask->transform
+	    && !pixman_transform_is_int_translate(mask->transform)) {
+		if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
+			goto fail;
+	}
+
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 
 	if (!glamor_set_composite_op(screen, op, dest, mask)) {
@@ -3006,10 +3016,6 @@ _glamor_composite(CARD8 op,
 	if (op >= ARRAY_SIZE(composite_op_info))
 		goto fail;
 
-	/*XXXXX, maybe we can make a copy of dest pixmap.*/
-	if (source_pixmap == dest_pixmap)
-		goto full_fallback;
-
 	if ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	    || (source->pDrawable
@@ -3086,6 +3092,7 @@ _glamor_composite(CARD8 op,
 				goto fail;
 		}
 	}
+
 	if (!mask) {
 		if (glamor_composite_with_copy(op, temp_src, dest,
 					       x_temp_src, y_temp_src,
@@ -3094,6 +3101,10 @@ _glamor_composite(CARD8 op,
 			goto done;
 	}
 
+	/*XXXXX, maybe we can make a copy of dest pixmap.*/
+	if (source_pixmap == dest_pixmap)
+		goto full_fallback;
+
 	x_dest += dest->pDrawable->x;
 	y_dest += dest->pDrawable->y;
 	if (temp_src->pDrawable) {
commit 6e50ee9c108e6d7ce4ebfcd08cfc97896e8e194e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 26 18:31:07 2012 +0800

    glamor_fbo: Added a threshold value for the fbo cache pool.
    
    Currently set it to 256MB. If cache pool watermark increases
    to this value, then don't push any fbo to this pool, will purge
    the fbo directly.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index e261cc2..a7cae66 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -9,6 +9,7 @@
 #define GLAMOR_CACHE_TEXTURE	2
 
 //#define NO_FBO_CACHE 1
+#define FBO_CACHE_THRESHOLD  (256*1024*1024)
 
 /* Loop from the tail to the head. */
 #define xorg_list_for_each_entry_reverse(pos, head, member)             \
@@ -68,7 +69,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 			    int w, int h, GLenum format, int flag)
 {
 	struct xorg_list *cache;
-	glamor_pixmap_fbo *fbo_entry;
+	glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
 	int size;
 	int n_format;
 #ifdef NO_FBO_CACHE
@@ -94,7 +95,8 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 					fbo_entry, fbo_entry->width, fbo_entry->height,
 					fbo_entry->fb, fbo_entry->tex);
 				xorg_list_del(&fbo_entry->list);
-				return fbo_entry;
+				ret_fbo = fbo_entry;
+				break;
 			}
 		}
 	}
@@ -108,12 +110,18 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 					fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
 				assert(format == fbo_entry->format);
 				xorg_list_del(&fbo_entry->list);
-				return fbo_entry;
+				ret_fbo = fbo_entry;
+				break;
 			}
 		}
 	}
 
-	return NULL;
+	if (ret_fbo)
+		glamor_priv->fbo_cache_watermark -= ret_fbo->width * ret_fbo->height;
+
+	assert(glamor_priv->fbo_cache_watermark >= 0);
+
+	return ret_fbo;
 #endif
 }
 
@@ -144,7 +152,9 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 #else
 	n_format = cache_format(fbo->format);
 
-	if (fbo->fb == 0 || n_format == -1) {
+	if (fbo->fb == 0 || n_format == -1
+	   || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
+		fbo->glamor_priv->tick ++;
 		glamor_purge_fbo(fbo);
 		return;
 	}
@@ -159,6 +169,8 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 						    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
 		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
+
+	fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
 	xorg_list_add(&fbo->list, cache);
 	fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
 #endif
@@ -264,6 +276,8 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 						empty_cache = FALSE;
 						break;
 					}
+
+					glamor_priv->fbo_cache_watermark -= fbo_entry->width * fbo_entry->height;
 					xorg_list_del(&fbo_entry->list);
 					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
 						fbo_entry->expire, glamor_priv->tick);
@@ -300,6 +314,7 @@ glamor_init_pixmap_fbo(ScreenPtr screen)
 				xorg_list_init(&glamor_priv->fbo_cache[i][j][k]);
 				xorg_list_init(&glamor_priv->tex_cache[i][j][k]);
 			}
+	glamor_priv->fbo_cache_watermark = 0;
 }
 
 void
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 169436c..2aa03d0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -209,6 +209,7 @@ typedef struct glamor_screen_private {
 
 	struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
 	struct xorg_list tex_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+	unsigned long    fbo_cache_watermark;
 
 	/* glamor_solid */
 	GLint solid_prog;
@@ -742,7 +743,6 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
  * this will increase performance obviously. */
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-#define GLAMOR_DELAYED_FILLING
 #ifndef GLAMOR_GLES2
 //#define GLAMOR_GRADIENT_SHADER
 #endif
commit 540846204cce9239233c5608a29bfe0607d77e44
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 26 18:28:17 2012 +0800

    Fixed a1 bug.
    
    It seems that mesa has bugs when uploading bitmap to texture.
    We switch to convert bitmap to a8 format and then upload the
    a8 texture.
    
    Also added a helper routine to dump 1bpp pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 6f66fb4..68a7b06 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -435,8 +435,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum ty
 	if (bits == NULL)
 		goto ready_to_upload;
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    &&  revert > REVERT_NORMAL) {
+	if (revert > REVERT_NORMAL) {
 		/* XXX if we are restoring the pixmap, then we may not need to allocate
 		 * new buffer */
 		void *converted_bits;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 25ad99d..c468490 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -241,6 +241,7 @@ gl_iformat_for_depth(int depth, GLenum * format)
 {
 	switch (depth) {
 #ifndef GLAMOR_GLES2
+	case 1:
 	case 8:
 		*format = GL_ALPHA;
 		break;
@@ -286,6 +287,9 @@ format_for_pixmap(PixmapPtr pixmap)
  * Map picture's format to the correct gl texture format and type.
  * no_alpha is used to indicate whehter we need to wire alpha to 1. 
  *
+ * Although opengl support A1/GL_BITMAP, we still don't use it
+ * here, it seems that mesa has bugs when uploading a A1 bitmap.
+ *
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
 #ifndef GLAMOR_GLES2
@@ -304,8 +308,9 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
 	switch (format) {
 	case PICT_a1:
-		*tex_format = GL_COLOR_INDEX;
-		*tex_type = GL_BITMAP;
+		*tex_format = GL_ALPHA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		*revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
 		break;
 	case PICT_b8g8r8x8:
 		*no_alpha = 1;
@@ -730,6 +735,24 @@ inline static Bool glamor_tex_format_is_readable(GLenum format)
 
 }
 
+static inline void _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
+{
+	int i,j;
+	unsigned char * p = pixmap->devPrivate.ptr;
+	int stride = pixmap->devKind;
+
+	p = p + y * stride + x;
+
+	for (i = 0; i < h; i++)
+	{
+		ErrorF("line %3d: ", i);
+		for(j = 0; j < w; j++)
+			ErrorF("%2d ", (p[j/8] & (1 << (j%8)))>>(j%8));
+		p += stride;
+		ErrorF("\n");
+	}
+}
+
 static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
 {
 	int i,j;
@@ -803,6 +826,9 @@ static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int
 	case 32:
 		_glamor_dump_pixmap_word(pixmap, x, y, w, h);
 		break;
+	case 1:
+		_glamor_dump_pixmap_bits(pixmap, x, y, w, h);
+		break;
 	default:
 		ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
 	}
commit 9f53cc1c3369fc61630b238f1b347a92fabf5a5a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 22:35:12 2012 +0800

    glamor_render.c: Fixed repeatPad and repeatRelect.
    
    We should use difference calculation for these two repeat mode
    when we are a sub region within one texture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 36bd9cd..169436c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -80,6 +80,8 @@ typedef struct glamor_composite_shader {
 	GLint mask_uniform_location;
 	GLint source_wh;
 	GLint mask_wh;
+	GLint source_repeat_mode;
+	GLint mask_repeat_mode;
 } glamor_composite_shader;
 
 typedef struct {
@@ -742,7 +744,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #define GLAMOR_DELAYED_FILLING
 #ifndef GLAMOR_GLES2
-#define GLAMOR_GRADIENT_SHADER
+//#define GLAMOR_GRADIENT_SHADER
 #endif
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index fa6ef66..d4ee78a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -70,13 +70,38 @@ static GLuint
 glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 			   struct shader_key *key)
 {
+	const char *repeat_define =
+	    "#define RepeatNone               	      0\n"
+	    "#define RepeatNormal                     1\n"
+	    "#define RepeatPad                        2\n"
+	    "#define RepeatReflect                    3\n"
+	    "uniform int 			source_repeat_mode;\n"
+	    "uniform int 			mask_repeat_mode;\n";
 	const char *relocate_texture =
 	    GLAMOR_DEFAULT_PRECISION
-	    "vec2 rel_tex_coord(vec2 texture, vec2 wh) \n"
+	    "vec2 rel_tex_coord(vec2 texture, vec2 wh, int repeat) \n"
 	    "{\n"
 	    "   vec2 rel_tex; \n"
 	    "   rel_tex = texture * wh; \n"
-	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+	    "   if (repeat == RepeatNormal) \n"
+	    "   	rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+	    "   else if(repeat == RepeatPad) { \n"
+	    "           if (rel_tex.x > 1.0) rel_tex.x = 1.0;		  \n"
+	    "		else if(rel_tex.x < 0.0) rel_tex.x = 0.0;		  \n"
+	    "           if (rel_tex.y > 1.0) rel_tex.y = 1.0;		  \n"
+	    "		else if(rel_tex.y < 0.0) rel_tex.y = 0.0;	\n"
+	    "   	rel_tex = rel_tex / wh; \n"
+	    "    } \n"
+	    "   else if(repeat == RepeatReflect) {\n"
+	    "		if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
+	    "			rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n"
+	    "		else \n"
+	    "			rel_tex.x = fract(rel_tex.x)/wh.x;\n"
+	    "		if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n"
+	    "			rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
+	    "		else \n"
+	    "			rel_tex.y = fract(rel_tex.y)/wh.y;\n"
+	    "    } \n"
             "   return rel_tex; \n"
 	    "}\n";
 	const char *source_solid_fetch =
@@ -90,21 +115,25 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
 	    "{\n"
-	    "   if (source_wh.x < 0.0) \n"
+	    "   if (source_repeat_mode == RepeatNone) \n"
 	    "		return texture2D(source_sampler, source_texture);\n"
 	    "	else \n"
-	    "		return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n"
+	    "		return texture2D(source_sampler,\n"
+	    "				 rel_tex_coord(source_texture,\n"
+	    "				 source_wh, source_repeat_mode));\n"
 	    "}\n";
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
 	    "uniform sampler2D source_sampler;\n"
-	    "uniform vec2 source_wh;"
+	    "uniform vec2 source_wh;\n"
 	    "vec4 get_source()\n"
 	    "{\n"
-	    "   if (source_wh.x < 0.0) \n"
+	    "   if (source_repeat_mode == RepeatNone) \n"
 	    "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
 	    "	else \n"
-	    "   	return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n"
+	    "   	return vec4(texture2D(source_sampler, \n"
+	    "			    rel_tex_coord(source_texture,\n"
+	    "			    source_wh, source_repeat_mode)).rgb, 1);\n"
 	    "}\n";
 	const char *mask_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
@@ -112,24 +141,28 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	const char *mask_alpha_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
 	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec2 mask_wh;"
+	    "uniform vec2 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "   if (mask_wh.x < 0.0) \n"
+	    "   if (mask_repeat_mode == RepeatNone) \n"
 	    "		return texture2D(mask_sampler, mask_texture);\n"
 	    "   else \n"
-	    "		return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n"
+	    "		return texture2D(mask_sampler, \n"
+	    "				 rel_tex_coord(mask_texture, \n"
+	    "				 mask_wh, mask_repeat_mode));\n"
 	    "}\n";
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
 	    "uniform sampler2D mask_sampler;\n"
-	    "uniform vec2 mask_wh;"
+	    "uniform vec2 mask_wh;\n"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "   if (mask_wh.x < 0.0) \n"
+	    "   if (mask_repeat_mode == RepeatNone) \n"
 	    "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
 	    "   else \n"
-	    "   	return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n"
+	    "   	return vec4(texture2D(mask_sampler, \n"
+	    "			    rel_tex_coord(mask_texture, \n"
+	    "			    mask_wh, mask_repeat_mode)).rgb, 1);\n"
 	    "}\n";
 	const char *in_source_only =
 	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
@@ -196,7 +229,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 		FatalError("Bad composite IN type");
 	}
 
-	XNFasprintf(&source, "%s%s%s%s", relocate_texture, source_fetch, mask_fetch, in);
+	XNFasprintf(&source, "%s%s%s%s%s", repeat_define, relocate_texture, source_fetch, mask_fetch, in);
 
 
 	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -288,6 +321,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 		    dispatch->glGetUniformLocation(prog, "source_sampler");
 		dispatch->glUniform1i(source_sampler_uniform_location, 0);
 		shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
+		shader->source_repeat_mode = dispatch->glGetUniformLocation(prog, "source_repeat_mode");
 	}
 
 	if (key->mask != SHADER_MASK_NONE) {
@@ -301,6 +335,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 			dispatch->glUniform1i
 			    (mask_sampler_uniform_location, 1);
 			shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
+			shader->mask_repeat_mode = dispatch->glGetUniformLocation(prog, "mask_repeat_mode");
 		}
 	}
 
@@ -482,7 +517,7 @@ static void
 glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv,
-			     GLuint wh_location)
+			     GLuint wh_location, GLuint repeat_location)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
@@ -546,17 +581,18 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	if (picture->repeatType == RepeatNone)
+	if (picture->repeatType == RepeatNone) {
 		has_repeat = picture->transform
 			     && !pixman_transform_is_int_translate(picture->transform);
-	else
+		if (has_repeat)
+			dispatch->glUniform1i(repeat_location, RepeatNormal);
+	}
+	else {
 		has_repeat = TRUE;
-	if (has_repeat) {
-		wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
-		wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
+		dispatch->glUniform1i(repeat_location, picture->repeatType);
 	}
-	else
-		wh[0] = -1;
+	wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
+	wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
 	dispatch->glUniform2fv(wh_location, 1, wh);
 	glamor_put_dispatch(glamor_priv);
 }
@@ -1111,7 +1147,8 @@ glamor_composite_with_shader(CARD8 op,
 					   shader->source_uniform_location);
 	} else {
 		glamor_set_composite_texture(screen, 0, source,
-					     source_pixmap_priv, shader->source_wh);
+					     source_pixmap_priv, shader->source_wh,
+					     shader->source_repeat_mode);
 	}
 	if (key.mask != SHADER_MASK_NONE) {
 		if (key.mask == SHADER_MASK_SOLID) {
@@ -1120,7 +1157,8 @@ glamor_composite_with_shader(CARD8 op,
 						   shader->mask_uniform_location);
 		} else {
 			glamor_set_composite_texture(screen, 1, mask,
-						     mask_pixmap_priv, shader->mask_wh);
+						     mask_pixmap_priv, shader->mask_wh,
+						     shader->mask_repeat_mode);
 		}
 	}
 
@@ -2946,6 +2984,7 @@ _glamor_composite(CARD8 op,
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
+
 	if (source->pDrawable) {
 		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
@@ -2967,6 +3006,10 @@ _glamor_composite(CARD8 op,
 	if (op >= ARRAY_SIZE(composite_op_info))
 		goto fail;
 
+	/*XXXXX, maybe we can make a copy of dest pixmap.*/
+	if (source_pixmap == dest_pixmap)
+		goto full_fallback;
+
 	if ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	    || (source->pDrawable
@@ -3050,6 +3093,7 @@ _glamor_composite(CARD8 op,
 					       height))
 			goto done;
 	}
+
 	x_dest += dest->pDrawable->x;
 	y_dest += dest->pDrawable->y;
 	if (temp_src->pDrawable) {
@@ -3146,16 +3190,21 @@ fail:
 		saved_ ##p ##_y = y_ ##p;						\
 		if (p->pCompositeClip)							\
 			pixman_region_translate (p->pCompositeClip,			\
-						 p ##_x_off - x_ ##p,			\
-						 p ##_y_off - y_ ##p);			\
+						 -p->pDrawable->x - x_ ##p,		\
+						 -p->pDrawable->y - y_ ##p);		\
 		x_ ##p = 0;								\
 		y_ ##p = 0;								\
 	} } while(0)
 
 	GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
+	if (source->pDrawable)
+		GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
+	if (mask && mask->pDrawable)
+		GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
 
+full_fallback:
 	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
-		if (glamor_prepare_access_picture
+		if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
 		    (source, GLAMOR_ACCESS_RO)) {
 			if (!mask
 			    || glamor_prepare_access_picture(mask,
@@ -3169,7 +3218,8 @@ fail:
 				if (mask)
 					glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO);
 			}
-			glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
+			if (source_pixmap != dest_pixmap)
+				glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
 		}
 		glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
 	}
@@ -3180,15 +3230,18 @@ fail:
 		y_ ##p = saved_ ##p ##_y;					\
 		if (p->pCompositeClip)						\
 			pixman_region_translate (p->pCompositeClip,		\
-						 - p ## _x_off + x_ ##p,	\
-						 - p ## _y_off + y_ ##p);	\
+						 p->pDrawable->x + x_ ##p,	\
+						 p->pDrawable->y + y_ ##p);	\
 		p->pDrawable = saved_ ##p ##_drawable;				\
 		glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap,		\
 				      x_ ##p + p ##_x_off + p->pDrawable->x,	\
 				      y_ ##p + p ##_y_off + p->pDrawable->y,	\
 				      width, height, access);			\
 	}} while(0)
-
+	if (mask && mask->pDrawable)
+		PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
+	if (source->pDrawable)
+		PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
 	PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
       done:
 	if (temp_src != source)
@@ -3442,6 +3495,4 @@ glamor_composite_rects_nf (CARD8         op,
 	return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
 }
 
-
-
 #endif				/* RENDER */
commit 67cf3838e4acd788b0ce413dcbe9896e2ca20e56
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 19:50:57 2012 +0800

    gradient: Don't need fixup flag when creating pixmap.
    
    Gradient can use a larger texture/fbo directly, don't need
    an eaxct size texture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a01f9ee..fa6ef66 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -2011,7 +2011,7 @@ _glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
 static int
 _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
                                         glamor_screen_private *glamor_priv,
-                                        PicturePtr dst_picure,
+                                        PicturePtr dst_picture,
                                         GLfloat *xscale, GLfloat *yscale,
                                         int x_source, int y_source,
                                         float vertices[8],
@@ -2021,7 +2021,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	glamor_pixmap_private *pixmap_priv;
 	PixmapPtr pixmap = NULL;
 
-	pixmap = glamor_get_drawable_pixmap(dst_picure->pDrawable);
+	pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
@@ -2039,24 +2039,24 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 	DEBUGF("xscale = %f, yscale = %f,"
 	       " x_source = %d, y_source = %d, width = %d, height = %d\n",
 	       *xscale, *yscale, x_source, y_source,
-	       pixmap_priv->fbo->width, pixmap_priv->fbo->height);
+	       dst_picture->pDrawable->width, dst_picture->pDrawable->height);
 
 	glamor_set_normalize_vcoords(*xscale, *yscale,
 	                             0, 0,
-	                             (INT16)(pixmap_priv->fbo->width),
-	                             (INT16)(pixmap_priv->fbo->height),
+	                             (INT16)(dst_picture->pDrawable->width),
+	                             (INT16)(dst_picture->pDrawable->height),
 	                             glamor_priv->yInverted, vertices);
 
 	if (tex_normalize) {
 		glamor_set_normalize_tcoords(*xscale, *yscale,
 		                             0, 0,
-		                             (INT16)(pixmap_priv->fbo->width),
-		                             (INT16)(pixmap_priv->fbo->height),
+		                             (INT16)(dst_picture->pDrawable->width),
+		                             (INT16)(dst_picture->pDrawable->height),
 		                             glamor_priv->yInverted, tex_vertices);
 	} else {
 		glamor_set_tcoords(0, 0,
-		                   (INT16)(pixmap_priv->fbo->width),
-		                   (INT16)(pixmap_priv->fbo->height),
+		                   (INT16)(dst_picture->pDrawable->width),
+		                   (INT16)(dst_picture->pDrawable->height),
 		                   glamor_priv->yInverted, tex_vertices);
 	}
 
@@ -2224,7 +2224,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	pixmap = glamor_create_pixmap(screen,
 	                              width, height,
 	                              PIXMAN_FORMAT_DEPTH(format),
-	                              GLAMOR_CREATE_PIXMAP_FIXUP);
+	                              0);
 	if (!pixmap)
 		goto GRADIENT_FAIL;
 
@@ -2548,7 +2548,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	pixmap = glamor_create_pixmap(screen,
 	                              width, height,
 	                              PIXMAN_FORMAT_DEPTH(format),
-	                              GLAMOR_CREATE_PIXMAP_FIXUP);
+	                              0);
 
 	if (!pixmap)
 		goto GRADIENT_FAIL;
commit 8a85071edbd90780b286fa4b19205540fb276815
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 18:58:16 2012 +0800

    glamor_copyarea: Don't access a DRM only pixmap.
    
    As EGL image/gbm only support ARGB8888 image, we don't support
    other format. We may change the way to use gbm directly latter.
    But now, we have to face this limitation, and thus if a client
    create a 16bpp drawable, and call get texture from pixmap then
    a copy to here may occur and thus we have to force retur a TRUE
    without do nothing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 6599d65..d19e28b 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -395,6 +395,13 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	    && glamor_ddx_fallback_check_pixmap(dst))
 		goto done;
 
+	if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
+	    || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
+		LogMessage(X_WARNING,
+			   "Access a DRM only pixmap is not allowed within glamor.\n",
+			   dst->pScreen->myNum);
+		return TRUE;
+	}
 	glamor_report_delayed_fallbacks(src->pScreen);
 	glamor_report_delayed_fallbacks(dst->pScreen);
 
commit 0b6867dddbed186c46048c610299ac0dde6a9ef0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 13:54:40 2012 +0800

    Disable A8 texture format for GLES2.
    
    As PVR's GLES2 implementation doesn't support A8 texture as
    rendering target, we disable it for now.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 27fe628..25ad99d 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -240,13 +240,10 @@ static inline void
 gl_iformat_for_depth(int depth, GLenum * format)
 {
 	switch (depth) {
+#ifndef GLAMOR_GLES2
 	case 8:
 		*format = GL_ALPHA;
 		break;
-#if 0
-	case 24:
-		*format = GL_RGB;
-		break;
 #endif
 	default:
 		*format = GL_RGBA;
commit 6b664dda69afa6c47ca083739093fa15fc674380
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 13:51:58 2012 +0800

    gradient: Disable gradient for gles2.
    
    As PVR glsl compiler seems doesn't support external fragment
    function, and fails at compile gradient shader. Disable it
    for now. We may need to modify gradient shader to don't use
    external function.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index d438b9c..cba6623 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -399,7 +399,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_init_tile_shader(screen);
 	glamor_init_putimage_shaders(screen);
 	glamor_init_finish_access_shaders(screen);
+#ifdef GLAMOR_GRADIENT_SHADER
 	glamor_init_gradient_shader(screen);
+#endif
 	glamor_pixmap_init(screen);
 
 	glamor_priv->flags = flags;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a7d89a9..36bd9cd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -741,8 +741,8 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #define GLAMOR_DELAYED_FILLING
+#ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
-
-
+#endif
 
 #endif				/* GLAMOR_PRIV_H */
commit 686a322c76fa20ed45d5bbfc9742024300e83e7d
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Wed Apr 18 08:04:26 2012 +0800

    Fix the bug caused by gradient picture set the stops at the same percentage.
    
     Fix the bug caused by gradient picture set the stops at
     the same percentage. The (stops[i] - stops[i-1]) will
     be used as divisor in the shader, which will cause
     problem. We just keep the later one if stops[i] ==
     stops[i-1].
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 21186a8..a01f9ee 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -2074,26 +2074,35 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
 
 static int
 _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
-                           GLfloat *stop_colors, GLfloat *n_stops)
+        GLfloat *stop_colors, GLfloat *n_stops)
 {
 	int i;
-	int count;
-
-	for (i = 1; i < pgradient->nstops + 1; i++) {
-		stop_colors[i*4] = pixman_fixed_to_double(
-		                       pgradient->stops[i-1].color.red);
-		stop_colors[i*4+1] = pixman_fixed_to_double(
-		                       pgradient->stops[i-1].color.green);
-		stop_colors[i*4+2] = pixman_fixed_to_double(
-		                       pgradient->stops[i-1].color.blue);
-		stop_colors[i*4+3] = pixman_fixed_to_double(
-		                       pgradient->stops[i-1].color.alpha);
-
-		n_stops[i] = (GLfloat)pixman_fixed_to_double(
-		                       pgradient->stops[i-1].x);
-	}
-
-	count = pgradient->nstops + 2;
+	int count = 1;
+
+	for (i = 0; i < pgradient->nstops; i++) {
+		/* We find some gradient picture set the stops at the same percentage, which
+		   will cause the shader problem because the (stops[i] - stops[i-1]) will
+		   be used as divisor. We just keep the later one if stops[i] == stops[i-1] */
+		if (i < pgradient->nstops - 1
+		         && pgradient->stops[i].x == pgradient->stops[i+1].x)
+			continue;
+
+		stop_colors[count*4] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.red);
+		stop_colors[count*4+1] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.green);
+		stop_colors[count*4+2] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.blue);
+		stop_colors[count*4+3] = pixman_fixed_to_double(
+		                                pgradient->stops[i].color.alpha);
+
+		n_stops[count] = (GLfloat)pixman_fixed_to_double(
+		                                pgradient->stops[i].x);
+		count++;
+	}
+
+	/* for the end stop. */
+	count++;
 
 	switch (src_picture->repeatType) {
 #define REPEAT_FILL_STOPS(m, n) \
commit 3d96929596fd3a6da41aab5cb9d7fb1cf28b2a03
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Wed Apr 25 14:25:39 2012 +0800

    Fix the problem of memory leak in gradient pixmap generating.
    
     Fix the problem of memory leak in gradient pixmap
     generating. The problem caused by we do not call
     glDeleteShader when destroy a shader program. This patch
     will split the gradient pixmap generating to three
     category. If nstops < 6, we will use the no array version
     of the shader, which has the best performance. Else if
     nstops < 16, we use array version of the shader, which is
     compiled and linked at screen init stage. Else if nstops >
     16, we dynamically create a new shader program, and this
     program will be cached until bigger nstops.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index fc3c5c0..e6da94d 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -76,6 +76,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glCreateShader, get_proc_address);
 	INIT_FUNC(dispatch, glCompileShader, get_proc_address);
 	INIT_FUNC(dispatch, glAttachShader, get_proc_address);
+	INIT_FUNC(dispatch, glDeleteShader, get_proc_address);
 	INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
 	INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
 	INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index 6adbde9..b3fc3a6 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -108,6 +108,7 @@ typedef struct glamor_gl_dispatch {
 	GLuint (*glCreateShader) (GLenum type);
 	void (*glCompileShader) (GLuint shader);
 	void (*glAttachShader) (GLuint program, GLuint shader);
+	void (*glDeleteShader) (GLuint shader);
 	void (*glGetShaderiv) (GLuint shader, GLenum pname,
 			       GLint * params);
 	void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 68d3617..a7d89a9 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -123,11 +123,18 @@ enum shader_in {
 	SHADER_IN_COUNT,
 };
 
-enum gradient_shader_type {
-	GRADIENT_SHADER_LINEAR,
-	GRADIENT_SHADER_RADIAL,
-	GRADIENT_SHADER_CONICAL,
-	GRADIENT_SHADER_COUNT,
+enum gradient_shader {
+	SHADER_GRADIENT_LINEAR,
+	SHADER_GRADIENT_RADIAL,
+	SHADER_GRADIENT_CONICAL,
+	SHADER_GRADIENT_COUNT,
+};
+
+enum gradient_shader_prog {
+	SHADER_GRADIENT_VS_PROG,
+	SHADER_GRADIENT_FS_MAIN_PROG,
+	SHADER_GRADIENT_FS_GETCOLOR_PROG,
+	SHADER_GRADIENT_PROG_COUNT,
 };
 
 struct glamor_screen_private;
@@ -228,8 +235,13 @@ typedef struct glamor_screen_private {
 	GLint tile_prog;
 	GLint tile_wh;
 
-	/* glamor gradient */
-	GLint gradient_prog[GRADIENT_SHADER_COUNT];
+	/* glamor gradient, 0 for small nstops, 1 for
+	   large nstops and 2 for dynamic generate. */
+	GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
+	GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+	int linear_max_nstops;
+	GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+	int radial_max_nstops;
 
 	/* glamor_putimage */
 	GLint put_image_xybitmap_prog;
@@ -729,7 +741,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #define GLAMOR_DELAYED_FILLING
-//#define GLAMOR_GRADIENT_SHADER
+#define GLAMOR_GRADIENT_SHADER
 
 
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 0e82e98..21186a8 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1412,11 +1412,12 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
 	return fs_getcolor_prog;
 }
 
-static GLint
-_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+static void
+_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
 {
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
+	int index;
 
 	GLint gradient_prog = 0;
 	char *gradient_fs = NULL;
@@ -1564,12 +1565,35 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "}\n";
 
 	glamor_priv = glamor_get_screen_private(screen);
+
+	if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
+		/* Very Good, not to generate again. */
+		return;
+	}
+
+	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
+		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
+	}
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 
 	gradient_prog = dispatch->glCreateProgram();
 
 	vs_prog = glamor_compile_glsl_prog(dispatch,
-	          GL_VERTEX_SHADER, gradient_vs);
+	                                   GL_VERTEX_SHADER, gradient_vs);
 
 	XNFasprintf(&gradient_fs,
 	            gradient_fs_template,
@@ -1580,8 +1604,8 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
 
 	free(gradient_fs);
 
-	fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
-	                                                      stops_count, use_array);
+	fs_getcolor_prog =
+	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
 
 	dispatch->glAttachShader(gradient_prog, vs_prog);
 	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
@@ -1594,16 +1618,30 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
 
 	dispatch->glUseProgram(0);
 
+	if (dyn_gen) {
+		index = 2;
+		glamor_priv->radial_max_nstops = stops_count;
+	} else if (stops_count) {
+		index = 1;
+	} else {
+		index = 0;
+	}
+
+	glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+	glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
 	glamor_put_dispatch(glamor_priv);
-	return gradient_prog;
 }
 
-static GLint
-_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+static void
+_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
 {
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
 
+	int index = 0;
 	GLint gradient_prog = 0;
 	char *gradient_fs = NULL;
 	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
@@ -1757,7 +1795,31 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "    gl_FragColor = get_color(stop_len);\n"
 	    "}\n";
 
+
 	glamor_priv = glamor_get_screen_private(screen);
+
+	if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
+		/* Very Good, not to generate again. */
+		return;
+	}
+
+	if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+		dispatch->glDeleteShader(
+		    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+		dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
+		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
+	}
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 
 	gradient_prog = dispatch->glCreateProgram();
@@ -1773,8 +1835,8 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	                                        GL_FRAGMENT_SHADER, gradient_fs);
 	free(gradient_fs);
 
-	fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
-	                                                      stops_count, use_array);
+	fs_getcolor_prog =
+	    _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
 
 	dispatch->glAttachShader(gradient_prog, vs_prog);
 	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
@@ -1787,26 +1849,56 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 
 	dispatch->glUseProgram(0);
 
+	if (dyn_gen) {
+		index = 2;
+		glamor_priv->linear_max_nstops = stops_count;
+	} else if (stops_count) {
+		index = 1;
+	} else {
+		index = 0;
+	}
+
+	glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+	glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
 	glamor_put_dispatch(glamor_priv);
-	return gradient_prog;
 }
 
-#define LINEAR_DEFAULT_STOPS 6 + 2
-#define RADIAL_DEFAULT_STOPS 6 + 2
+#define LINEAR_SMALL_STOPS 6 + 2
+#define LINEAR_LARGE_STOPS 16 + 2
+
+#define RADIAL_SMALL_STOPS 6 + 2
+#define RADIAL_LARGE_STOPS 16 + 2
 
 void
 glamor_init_gradient_shader(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
+	int i;
 
 	glamor_priv = glamor_get_screen_private(screen);
 
-	glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR] =
-	    _glamor_create_linear_gradient_program(screen,
-	            LINEAR_DEFAULT_STOPS, 0);
-	glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL] =
-	    _glamor_create_radial_gradient_program(screen,
-	            RADIAL_DEFAULT_STOPS, 0);
+	for (i = 0; i < 3; i++) {
+		glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+		glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+
+		glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+		glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+	}
+	glamor_priv->linear_max_nstops = 0;
+	glamor_priv->radial_max_nstops = 0;
+
+	_glamor_create_linear_gradient_program(screen, 0, 0);
+	_glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
+
+	_glamor_create_radial_gradient_program(screen, 0, 0);
+	_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
 }
 
 void
@@ -1814,14 +1906,44 @@ glamor_fini_gradient_shader(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
+	int i = 0;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch = glamor_get_dispatch(glamor_priv);
 
-	dispatch->glDeleteProgram(
-	    glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR]);
-	dispatch->glDeleteProgram(
-	    glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL]);
+	for (i = 0; i < 3; i++) {
+		/* Linear Gradient */
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+		if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+		if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
+			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]);
+
+		/* Radial Gradient */
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+		if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+			dispatch->glDeleteShader(
+			    glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+		if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
+			dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]);
+	}
 
 	glamor_put_dispatch(glamor_priv);
 }
@@ -2053,8 +2175,8 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
 	                                         {0.0, 1.0, 0.0},
 	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[RADIAL_DEFAULT_STOPS*4];
-	GLfloat n_stops_st[RADIAL_DEFAULT_STOPS];
+	GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4];
+	GLfloat n_stops_st[RADIAL_SMALL_STOPS];
 	GLfloat A_value;
 	GLfloat cxy[4];
 	float c1x, c1y, c2x, c2y, r1, r2;
@@ -2110,15 +2232,17 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
 	ValidatePicture(dst_picture);
 
-	stops_count = src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS ?
-	              src_picture->pSourcePict->radial.nstops + 2 : RADIAL_DEFAULT_STOPS;
+	stops_count = src_picture->pSourcePict->radial.nstops + 2;
 
-	/* Because the max value of nstops is unkown, so create a programwhen nstops > default.*/
-	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL];
+	/* Because the max value of nstops is unkown, so create a program
+	   when nstops > LINEAR_LARGE_STOPS.*/
+	if (stops_count <= RADIAL_SMALL_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
+	} else if (stops_count <= RADIAL_LARGE_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
 	} else {
-		gradient_prog = _glamor_create_radial_gradient_program(screen,
-		                          src_picture->pSourcePict->radial.nstops + 2, 1);
+		_glamor_create_radial_gradient_program(screen, src_picture->pSourcePict->linear.nstops + 2, 1);
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
 	}
 
 	/* Bind all the uniform vars .*/
@@ -2141,7 +2265,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	r2_uniform_location =
 	    dispatch->glGetUniformLocation(gradient_prog, "r2");
 
-	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
+	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
 		stop0_uniform_location =
 		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
 		stop1_uniform_location =
@@ -2204,7 +2328,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 		goto GRADIENT_FAIL;
 
 	/* Set all the stops and colors to shader. */
-	if (stops_count > RADIAL_DEFAULT_STOPS) {
+	if (stops_count > RADIAL_SMALL_STOPS) {
 		stop_colors = malloc(4 * stops_count * sizeof(float));
 		if (stop_colors == NULL) {
 			ErrorF("Failed to allocate stop_colors memory.\n");
@@ -2224,7 +2348,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
 	                                   stop_colors, n_stops);
 
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+	if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
 		int j = 0;
 		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
 		                      stop_colors[4*j+2], stop_colors[4*j+3]);
@@ -2309,7 +2433,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
 
 	/* Do the clear logic.*/
-	if (stops_count > RADIAL_DEFAULT_STOPS) {
+	if (stops_count > RADIAL_SMALL_STOPS) {
 		free(n_stops);
 		free(stop_colors);
 	}
@@ -2321,9 +2445,6 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
 
-	if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
-		dispatch->glDeleteProgram(gradient_prog);
-
 	glamor_put_dispatch(glamor_priv);
 	return dst_picture;
 
@@ -2332,7 +2453,7 @@ GRADIENT_FAIL:
 		FreePicture(dst_picture, 0);
 	}
 
-	if (stops_count > RADIAL_DEFAULT_STOPS) {
+	if (stops_count > RADIAL_SMALL_STOPS) {
 		if (n_stops)
 			free(n_stops);
 		if (stop_colors)
@@ -2345,8 +2466,6 @@ GRADIENT_FAIL:
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
-	if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
-		dispatch->glDeleteProgram(gradient_prog);
 	glamor_put_dispatch(glamor_priv);
 	return NULL;
 }
@@ -2381,8 +2500,8 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
 	                                         {0.0, 1.0, 0.0},
 	                                         {0.0, 0.0, 1.0}};
-	GLfloat stop_colors_st[LINEAR_DEFAULT_STOPS*4];
-	GLfloat n_stops_st[LINEAR_DEFAULT_STOPS];
+	GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4];
+	GLfloat n_stops_st[LINEAR_SMALL_STOPS];
 
 	GLint transform_mat_uniform_location;
 	GLint pt1_uniform_location;
@@ -2438,16 +2557,18 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
 	ValidatePicture(dst_picture);
 
-	stops_count = src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS ?
-	              src_picture->pSourcePict->linear.nstops + 2 : LINEAR_DEFAULT_STOPS;
+	stops_count = src_picture->pSourcePict->linear.nstops + 2;
 
 	/* Because the max value of nstops is unkown, so create a program
-	   when nstops > default.*/
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
-		gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR];
+	   when nstops > LINEAR_LARGE_STOPS.*/
+	if (stops_count <= LINEAR_SMALL_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
+	} else if (stops_count <= LINEAR_LARGE_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
 	} else {
-		gradient_prog = _glamor_create_linear_gradient_program(screen,
-		                        src_picture->pSourcePict->linear.nstops + 2, 1);
+		_glamor_create_linear_gradient_program(screen,
+		        src_picture->pSourcePict->linear.nstops + 2, 1);
+		gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
 	}
 
 	/* Bind all the uniform vars .*/
@@ -2472,7 +2593,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	pt_distance_uniform_location =
 	    dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
 
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
 		stop0_uniform_location =
 		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
 		stop1_uniform_location =
@@ -2555,7 +2676,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
 
 	/* Set all the stops and colors to shader. */
-	if (stops_count > LINEAR_DEFAULT_STOPS) {
+	if (stops_count > LINEAR_SMALL_STOPS) {
 		stop_colors = malloc(4 * stops_count * sizeof(float));
 		if (stop_colors == NULL) {
 			ErrorF("Failed to allocate stop_colors memory.\n");
@@ -2575,7 +2696,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
 	                                   stop_colors, n_stops);
 
-	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
 		int j = 0;
 		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
 		                      stop_colors[4*j+2], stop_colors[4*j+3]);
@@ -2670,7 +2791,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	}
 
 	/* Do the clear logic.*/
-	if (stops_count > LINEAR_DEFAULT_STOPS) {
+	if (stops_count > LINEAR_SMALL_STOPS) {
 		free(n_stops);
 		free(stop_colors);
 	}
@@ -2682,9 +2803,6 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
 
-	if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
-		dispatch->glDeleteProgram(gradient_prog);
-
 	glamor_put_dispatch(glamor_priv);
 	return dst_picture;
 
@@ -2693,7 +2811,7 @@ GRADIENT_FAIL:
 		FreePicture(dst_picture, 0);
 	}
 
-	if (stops_count > LINEAR_DEFAULT_STOPS) {
+	if (stops_count > LINEAR_SMALL_STOPS) {
 		if (n_stops)
 			free(n_stops);
 		if (stop_colors)
@@ -2706,8 +2824,6 @@ GRADIENT_FAIL:
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
-	if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
-		dispatch->glDeleteProgram(gradient_prog);
 	glamor_put_dispatch(glamor_priv);
 	return NULL;
 }
commit 05da99106b81465488c9879cfd709fd4f0c7b9e5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 11:59:47 2012 +0800

    glamor_putimage: Optimize for direct uploading and fallback path.
    
    This commit optimize two cases:
    1. When the clip contains the whole area, we can directly upload
    the texel data to the pixmap, and don't need to do one extra
    clipped copy.
    
    2. At fallback path, we don't read back the whole pixmap, just
    need a sub region.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 011e077..0c3c0c5 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -256,9 +256,12 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	int x_off, y_off;
 	float vertices[8], texcoords[8];
 	Bool ret = FALSE;
-	PixmapPtr temp_pixmap;
+	PixmapPtr temp_pixmap, sub_pixmap;
 	glamor_pixmap_private *temp_pixmap_priv;
+	BoxRec box;
 
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+	clip = fbGetCompositeClip(gc);
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
 		goto fail;
@@ -279,9 +282,13 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	}
 	/* create a temporary pixmap and upload the bits to that
 	 * pixmap, then apply clip copy it to the destination pixmap.*/
+	box.x1 = x + drawable->x;
+	box.y1 = y + drawable->y;
+	box.x2 = x + w + drawable->x;
+	box.y2 = y + h + drawable->y;
 
-	clip = fbGetCompositeClip(gc);
-	if (clip != NULL) {
+	if ((clip != NULL && !RegionContainsRect(clip, &box))
+	     || gc->alu != GXcopy) {
 		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
 		if (temp_pixmap == NULL)
 			goto fail;
@@ -298,12 +305,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
 		glamor_destroy_pixmap(temp_pixmap);
-	} else {
-		ErrorF("put image directly. \n");
-		glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-		glamor_upload_sub_pixmap_to_texture(pixmap, drawable->x + x_off, drawable->y + y_off,
+	} else
+		glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off,
 						    w, h, pixmap->devKind, bits, 0);
-	}
 	ret = TRUE;
 	goto done;
 
@@ -316,11 +320,26 @@ fail:
 
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
-	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
+
+	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
+					   y + y_off + drawable->y, w, h,
+					   GLAMOR_ACCESS_RW);
+	if (sub_pixmap) {
+		if (clip != NULL)
+			pixman_region_translate (clip, -x - drawable->x, -y - drawable->y);
+
+		fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
+			   left_pad, image_format, bits);
+
+		glamor_put_sub_pixmap(sub_pixmap, pixmap,
+				      x + x_off + drawable->x,
+				      y + y_off + drawable->y,
+				      w, h, GLAMOR_ACCESS_RW);
+		if (clip != NULL)
+			pixman_region_translate (clip, x + drawable->x, y + drawable->y);
+	} else
 		fbPutImage(drawable, gc, depth, x, y, w, h,
 			   left_pad, image_format, bits);
-		glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RW);
-	}
 	ret = TRUE;
 
 done:
commit ea70ebe0ac9fe5b3d0ad553f9aeb4d2829bf9a62
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 11:56:43 2012 +0800

    Fixed one potential texture size mismatch problem.
    
    There are two cases which we may use a wrong texture size.
    1. A pixmap is modified by the client side after it created
    it. Then the pixmap's width may mismatch the original fbo/tex's
    size. Thus we need to check this condition when preparing
    upload the pixmap.
    
    2. We provide two API to download/upload sub region of a
    textured pixmap. The caller may pass in a larger width then
    the original pixmap's size, this may happen at putimage
    and setspans. We need to validate the width and height
    when do the downloading/uploading.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index c2b196f..6f66fb4 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -559,7 +559,14 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-	if (pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->fb)
+	if (pixmap_priv->fbo
+	     && (pixmap_priv->fbo->width < pixmap->drawable.width
+           || pixmap_priv->fbo->height < pixmap->drawable.height)) {
+		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+		glamor_destroy_fbo(fbo);
+        }
+
+	if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
 		return 0;
 
 	if (!(no_alpha
@@ -1085,6 +1092,9 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	int pbo;
 	int flag;
 
+	assert(x >= 0 && y >= 0);
+	w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
+	h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
 	if (access == GLAMOR_ACCESS_WO) {
 		sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
 						  pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
@@ -1167,6 +1177,10 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
 			bits = sub_pixmap->devPrivate.ptr;
 			pbo = 0;
 		}
+
+		assert(x >= 0 && y >= 0);
+		w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
+		h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
 		glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
 	}
 	glamor_destroy_pixmap(sub_pixmap);
commit 08e8c00fe6a21741ff9f38652c2b9fd2310f1ce5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 25 09:27:06 2012 +0800

    glamor_getimage: Don't fallback to miGetImage.
    
    As miGetImage is very inefficient, we don't fallback to it.
    If the format is not ZPixmap, we download the required sub-
    region, and then call fbGetImage to do the conversion.
    This way is much faster than previous.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index af65826..b53635c 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -34,18 +34,19 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 		  unsigned int format, unsigned long planeMask, char *d,
 		  Bool fallback)
 {
-	PixmapPtr pixmap;
+	PixmapPtr pixmap, sub_pixmap;
 	struct glamor_pixmap_private *pixmap_priv;
 	int x_off, y_off;
 	Bool ret = FALSE;
 	int stride;
 	void *data;
 
+	pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
 	if (format != ZPixmap)
 		goto fall_back;
 
-	pixmap = glamor_get_drawable_pixmap(drawable);
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 	if (!glamor_set_planemask(pixmap, planeMask)) {
 		glamor_fallback
 		    ("Failedto set planemask  in glamor_solid.\n");
@@ -64,12 +65,22 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride,
 						 d, 0, GLAMOR_ACCESS_RO);
 	if (data != NULL) {
-		ret = TRUE;
 		assert(data == d);
+		return TRUE;
 	}
 fall_back:
-	if (ret == FALSE)
-		miGetImage(drawable, x, y, w, h, format, planeMask, d);
+	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
+					   y + y_off + drawable->y, w, h,
+					   GLAMOR_ACCESS_RO);
+	if (sub_pixmap) {
+		fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d);
+		glamor_put_sub_pixmap(sub_pixmap, pixmap,
+				      x + x_off + drawable->x,
+				      y + y_off + drawable->y,
+				      w, h, GLAMOR_ACCESS_RO);
+	} else
+		fbGetImage(drawable, x, y, w, h, format, planeMask, d);
+
 	return TRUE;
 }
 
commit 9bcddff93b79fd8978426d9832a5edd60ac410c0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 13 18:15:49 2012 +0800

    pending_op: Remove the pending operations handling.
    
    We have disabled this feature for a long time, and previous
    testing shows that this(pending fill) will not bring observed
    performance gain. Now remove it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index a373d3d..6599d65 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -49,9 +49,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	}
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
-	if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
-		return FALSE;
-
 	if (gc) {
 		if (gc->alu != GXcopy) {
 			glamor_delayed_fallback(screen, "non-copy ALU\n");
@@ -69,10 +66,8 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 		return FALSE;
 	}
 
-	if (glamor_set_destination_pixmap(dst_pixmap)) {
+	if (glamor_set_destination_pixmap(dst_pixmap))
 		return FALSE;
-	}
-	glamor_validate_pixmap(dst_pixmap);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
@@ -199,58 +194,48 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		return FALSE;
 	}
 
-	if (alu != GXcopy) {
-		glamor_set_destination_pixmap_priv_nc (src_pixmap_priv);
-		glamor_validate_pixmap(src_pixmap);
-	}
 	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	glamor_validate_pixmap(dst_pixmap);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-		glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
-					   &src_y_off);
-		dx += src_x_off;
-		dy += src_y_off;
-		pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
-				      &src_yscale);
-
-		dispatch->glActiveTexture(GL_TEXTURE0);
-		dispatch->glBindTexture(GL_TEXTURE_2D,
-					src_pixmap_priv->fbo->tex);
+	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+				   &src_y_off);
+	dx += src_x_off;
+	dy += src_y_off;
+	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
+			      &src_yscale);
+
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D,
+				src_pixmap_priv->fbo->tex);
 #ifndef GLAMOR_GLES2
-		dispatch->glEnable(GL_TEXTURE_2D);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_WRAP_S,
-					  GL_CLAMP_TO_BORDER);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_WRAP_T,
-					  GL_CLAMP_TO_BORDER);
+	dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_S,
+				  GL_CLAMP_TO_BORDER);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_WRAP_T,
+				  GL_CLAMP_TO_BORDER);
 #endif
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-
-		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-						GL_FLOAT, GL_FALSE,
-						2 * sizeof(float),
-						texcoords);
-		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-		dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-		dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
-				      REVERT_NONE);
-		dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
-				      SWAP_NONE_UPLOADING);
-	} else {
-		GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
-					  src_pixmap_priv);
-	}
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+					GL_FLOAT, GL_FALSE,
+					2 * sizeof(float),
+					texcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+	dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
+			      REVERT_NONE);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
+			      SWAP_NONE_UPLOADING);
 
 	for (i = 0; i < nbox; i++) {
 
@@ -262,26 +247,22 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 					     glamor_priv->yInverted,
 					     vertices);
 
-		if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
-			glamor_set_normalize_tcoords(src_xscale,
-						     src_yscale,
-						     box[i].x1 + dx,
-						     box[i].y1 + dy,
-						     box[i].x2 + dx,
-						     box[i].y2 + dy,
-						     glamor_priv->yInverted,
-						     texcoords);
-
+		glamor_set_normalize_tcoords(src_xscale,
+					     src_yscale,
+					     box[i].x1 + dx,
+					     box[i].y1 + dy,
+					     box[i].x2 + dx,
+					     box[i].y2 + dy,
+					     glamor_priv->yInverted,
+					     texcoords);
 		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 	}
 
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-		dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-		dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	}
 	dispatch->glUseProgram(0);
 	/* The source texture is bound to a fbo, we have to flush it here. */
 	if (flush_needed)
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index e5b98a1..e261cc2 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -538,12 +538,6 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	return TRUE;
 }
-/*
- * XXX how to handle those pending OPs.
- * By default, pending OP is disabled. Maybe we will give up the pending
- * OP latter.
- *
- * */
 
 _X_EXPORT void
 glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 3c171d4..95b070d 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -213,20 +213,8 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 				   &color[1],
 				   &color[2],
 				   &color[3], format_for_pixmap(pixmap));
-#ifdef GLAMOR_DELAYED_FILLING
-	if (x == 0 && y == 0
-	    && width == pixmap->drawable.width
-	    && height == pixmap->drawable.height
-	    && pixmap_priv->fb != glamor_priv->screen_fbo) {
-		pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
-		memcpy(&pixmap_priv->pending_op.fill.color4fv,
-		       color, 4 * sizeof(GLfloat));
-		pixmap_priv->pending_op.fill.colori = fg_pixel;
-		return TRUE;
-	}
-#endif
+
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	glamor_validate_pixmap(pixmap);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (!glamor_set_alu(dispatch, alu)) {
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 78d643a..c2b196f 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -23,47 +23,10 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
 }
 
 
-static void
-_glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
-				glamor_pixmap_private * pixmap_priv)
-{
-	glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
-	GLfloat vertices[8];
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(glamor_priv->solid_prog);
-	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
-			       1, pixmap_priv->pending_op.fill.color4fv);
-	vertices[0] = -1;
-	vertices[1] = -1;
-	vertices[2] = 1;
-	vertices[3] = -1;
-	vertices[4] = 1;
-	vertices[5] = 1;
-	vertices[6] = -1;
-	vertices[7] = 1;
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
-	pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
-	glamor_put_dispatch(glamor_priv);
-}
-
-
-glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
-	NULL,
-	_glamor_pixmap_validate_filling
-};
-
 void
 glamor_pixmap_init(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv;
 
-	glamor_priv = glamor_get_screen_private(screen);
-	glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
 }
 
 void
@@ -72,23 +35,6 @@ glamor_pixmap_fini(ScreenPtr screen)
 }
 
 void
-glamor_validate_pixmap(PixmapPtr pixmap)
-{
-	glamor_pixmap_validate_function_t validate_op;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-
-	validate_op =
-	    glamor_priv->pixmap_validate_funcs[pixmap_priv->
-					       pending_op.type];
-	if (validate_op) {
-		(*validate_op) (glamor_priv, pixmap_priv);
-	}
-}
-
-void
 glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
 {
 	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
@@ -865,9 +811,6 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	}
 
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	/* XXX we may don't need to validate it on GPU here,
-	 * we can just validate it on CPU. */
-	glamor_validate_pixmap(pixmap);
 
 	need_post_conversion = (revert > REVERT_NORMAL);
 	if (need_post_conversion) {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 46e4dc5..68d3617 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -132,11 +132,6 @@ enum gradient_shader_type {
 
 struct glamor_screen_private;
 struct glamor_pixmap_private;
-typedef void (*glamor_pixmap_validate_function_t) (struct
-						   glamor_screen_private *,
-						   struct
-						   glamor_pixmap_private
-						   *);
 
 enum glamor_gl_flavor {
 	GLAMOR_GL_DESKTOP,	// OPENGL API
@@ -246,7 +241,6 @@ typedef struct glamor_screen_private {
 	struct glamor_saved_procs saved_procs;
 	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
 	int delayed_fallback_pending;
-	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
 	int flags;
 	ScreenPtr screen;
 } glamor_screen_private;
@@ -257,22 +251,6 @@ typedef enum glamor_access {
 	GLAMOR_ACCESS_WO,
 } glamor_access_t;
 
-enum _glamor_pending_op_type {
-	GLAMOR_PENDING_NONE,
-	GLAMOR_PENDING_FILL
-};
-
-typedef struct _glamor_pending_fill {
-	unsigned int type;
-	GLfloat color4fv[4];
-	CARD32 colori;
-} glamor_pending_fill;
-
-typedef union _glamor_pending_op {
-	unsigned int type;
-	glamor_pending_fill fill;
-} glamor_pending_op;
-
 #define GLAMOR_FBO_NORMAL     1
 #define GLAMOR_FBO_DOWNLOADED 2
 /* glamor_pixmap_fbo:
@@ -315,7 +293,6 @@ typedef struct glamor_pixmap_fbo {
  * @gl_tex:  The pixmap is in a gl texture originally.
  * @is_picture: The drawable is attached to a picture.
  * @pict_format: the corresponding picture's format.
- * #pending_op: currently only support pending filling.
  * @container: The corresponding pixmap's pointer.
  **/
 typedef struct glamor_pixmap_private {
@@ -325,7 +302,6 @@ typedef struct glamor_pixmap_private {
 	glamor_pixmap_type_t type;
 	glamor_pixmap_fbo *fbo;
 	PictFormatShort pict_format;
-	glamor_pending_op pending_op;
 	PixmapPtr container;
 	int drm_stride;
 	glamor_screen_private *glamor_priv;
@@ -682,8 +658,6 @@ Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenu
  **/
 void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
 
-void glamor_validate_pixmap(PixmapPtr pixmap);
-
 int glamor_create_picture(PicturePtr picture);
 
 Bool
@@ -754,7 +728,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
  * this will increase performance obviously. */
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-//#define GLAMOR_DELAYED_FILLING
+#define GLAMOR_DELAYED_FILLING
 //#define GLAMOR_GRADIENT_SHADER
 
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 3bf04d4..0e82e98 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -997,12 +997,6 @@ glamor_composite_with_shader(CARD8 op,
 			glamor_fallback("no texture in source\n");
 			goto fail;
 #endif
-		} else if (source_pixmap_priv->pending_op.type ==
-			   GLAMOR_PENDING_FILL) {
-			key.source = SHADER_SOURCE_SOLID;
-			memcpy(source_solid_color,
-			       source_pixmap_priv->pending_op.
-			       fill.color4fv, 4 * sizeof(float));
 		}
 	}
 	if (key.mask == SHADER_MASK_TEXTURE ||
@@ -1020,12 +1014,6 @@ glamor_composite_with_shader(CARD8 op,
 			glamor_fallback("no texture in mask\n");
 			goto fail;
 #endif
-		} else if (mask_pixmap_priv->pending_op.type ==
-			   GLAMOR_PENDING_FILL) {
-			key.mask = SHADER_MASK_SOLID;
-			memcpy(mask_solid_color,
-			       mask_pixmap_priv->pending_op.fill.color4fv,
-			       4 * sizeof(float));
 		}
 	}
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
@@ -1103,7 +1091,6 @@ glamor_composite_with_shader(CARD8 op,
 	}
 #endif
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-	glamor_validate_pixmap(dest_pixmap);
 
 	if (!glamor_set_composite_op(screen, op, dest, mask)) {
 		goto fail;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index be873cc..8e09553 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -152,13 +152,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		goto fail;
 	}
 
-	if (alu != GXcopy) {
-		glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
-		glamor_validate_pixmap(tile);
-	}
-
 	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	glamor_validate_pixmap(pixmap);
 	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
@@ -167,45 +161,40 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		goto fail;
 	}
 
-	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-		pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
-				      &src_yscale);
-		dispatch->glUseProgram(glamor_priv->tile_prog);
-
-		wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
-		wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
-
-		dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
-		dispatch->glActiveTexture(GL_TEXTURE0);
-		dispatch->glBindTexture(GL_TEXTURE_2D,
-					src_pixmap_priv->fbo->tex);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-					  GL_REPEAT);
-		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-					  GL_REPEAT);
+	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
+			      &src_yscale);
+	dispatch->glUseProgram(glamor_priv->tile_prog);
+
+	wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
+	wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
+
+	dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D,
+				src_pixmap_priv->fbo->tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+				  GL_REPEAT);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+				  GL_REPEAT);
 #ifndef GLAMOR_GLES2
-		dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-		glamor_set_normalize_tcoords(src_xscale, src_yscale,
-					     tile_x1, tile_y1,
-					     tile_x2, tile_y2,
-					     glamor_priv->yInverted,
-					     source_texcoords);
-		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
-						GL_FLOAT, GL_FALSE,
-						2 * sizeof(float),
-						source_texcoords);
-		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	} else {
-		GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
-					  src_pixmap_priv);
-	}
+	glamor_set_normalize_tcoords(src_xscale, src_yscale,
+				     tile_x1, tile_y1,
+				     tile_x2, tile_y2,
+				     glamor_priv->yInverted,
+				     source_texcoords);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+					GL_FLOAT, GL_FALSE,
+					2 * sizeof(float),
+					source_texcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
 	glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
 				     x1, y1, x2, y2,
@@ -217,12 +206,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-		dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
 		dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-	}
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
 	glamor_set_alu(dispatch, GXcopy);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index d2dc6e4..27fe628 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -207,23 +207,6 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
 #define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
 
-#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
-	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
-	&& (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE))
-
-#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv)   \
-	(pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE)
-
-#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \
-  { \
-      if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
-        _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \
-        _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
-                        _pixmap_priv_->pending_op.fill.color4fv); \
-      } \
-  } while(0)
-
-
 /**
  * Borrow from uxa.
  */
commit 1761768f49a356f50645da53305e6b4bdef5c5f4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 23:50:09 2012 +0800

    glamor_upload_pixmap: Use glTexImage2D for a fully update.
    
    Currently, intel's mesa dri driver will not check pbo for
    a TexSubImage2D. So we use glTexImage2D if we are a fully
    updating.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 5797453..78d643a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -418,40 +418,40 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, int *tex,
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
+	int non_sub = 0;
+	int iformat;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (*tex == 0) {
-		int iformat;
 		dispatch->glGenTextures(1, tex);
 		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 			gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
 		else
 			iformat = format;
+		non_sub = 1;
+		assert(x == 0 && y == 0);
+	}
 
-		dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
-		dispatch->glTexImage2D(GL_TEXTURE_2D,
-				       0,
-				       iformat,
-				       w, h, 0, format, type,
-				       bits);
-	} else
-		dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
-
+	dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
-
 	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
 				       pbo);
-
-	dispatch->glTexSubImage2D(GL_TEXTURE_2D,
-				  0, x, y, w, h,
-				  format, type,
-				  bits);
+	if (non_sub)
+		dispatch->glTexImage2D(GL_TEXTURE_2D,
+				       0, iformat, w, h, 0,
+				       format, type,
+				       bits);
+	else
+		dispatch->glTexSubImage2D(GL_TEXTURE_2D,
+					  0, x, y, w, h,
+					  format, type,
+					  bits);
 
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
commit 2806f1eaced851e4c88055c53d706f7beef8b555
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 23:49:38 2012 +0800

    glamor_setspans: Reuse glamor_upload_sub_pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index c5ecf85..e283853 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -34,17 +34,12 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 {
 	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_pixmap_private *dest_pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(drawable->pScreen);
-	glamor_gl_dispatch *dispatch;
-	GLenum format, type;
-	int no_alpha, revert, i;
+	int i;
 	uint8_t *drawpixels_src = (uint8_t *) src;
 	RegionPtr clip = fbGetCompositeClip(gc);
 	BoxRec *pbox;
 	int x_off, y_off;
 	Bool ret = FALSE;
-	int swap_rb;
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@@ -52,57 +47,32 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		goto fail;
 	}
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		glamor_fallback("ES2 fallback.\n");
-		goto fail;
-	}
-
-	if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &revert,
-						   &swap_rb,
-						   1)) {
-		glamor_fallback("unknown depth. %d \n", drawable->depth);
-		goto fail;
-	}
-
-	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-	glamor_validate_pixmap(dest_pixmap);
+	/* XXX Shall we set alu here? */
 	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 		goto fail;
 
 	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, gc->alu)) {
-		glamor_put_dispatch(glamor_priv);
-		goto fail;
-	}
-
 	for (i = 0; i < n; i++) {
 
 		n = REGION_NUM_RECTS(clip);
 		pbox = REGION_RECTS(clip);
 		while (n--) {
-			if (pbox->y1 > points[i].y)
+			int x1 = points[i].x;
+			int x2 = x1 + widths[i];
+			int y1 = points[i].y;
+
+			if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
 				break;
-			dispatch->glScissor(pbox->x1,
-					    points[i].y + y_off,
-					    pbox->x2 - pbox->x1, 1);
-			dispatch->glEnable(GL_SCISSOR_TEST);
-			dispatch->glRasterPos2i(points[i].x + x_off,
-						points[i].y + y_off);
-			dispatch->glDrawPixels(widths[i], 1, format,
-					       type, drawpixels_src);
+			x1 = x1 > pbox->x1 ? x1 : pbox->x1;
+			x2 = x2 < pbox->x2 ? x2 : pbox->x2;
+			if (x1 >= x2)
+				continue;
+			glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,  y1 + y_off, x2 - x1, 1,
+							    PixmapBytePad(widths[i], drawable->depth),
+							    drawpixels_src, 0);
 		}
-		drawpixels_src +=
-		    PixmapBytePad(widths[i], drawable->depth);
+		drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
 	}
-	glamor_set_planemask(dest_pixmap, ~0);
-	glamor_set_alu(dispatch, GXcopy);
-	dispatch->glDisable(GL_SCISSOR_TEST);
-	glamor_put_dispatch(glamor_priv);
 	ret = TRUE;
 	goto done;
 
commit e15bc1207480d7d198862861d40af58903b4d0f0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 23:18:47 2012 +0800

    code clean up.
    
    Remove unused variables.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index ddf057f..af65826 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -36,30 +36,21 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 {
 	PixmapPtr pixmap;
 	struct glamor_pixmap_private *pixmap_priv;
-	struct glamor_screen_private *glamor_priv;
 	int x_off, y_off;
-	GLenum tex_format, tex_type;
-	int no_alpha, revert;
-	glamor_pixmap_fbo *temp_fbo = NULL;
-	glamor_gl_dispatch * dispatch;
 	Bool ret = FALSE;
-	int swap_rb;
 	int stride;
 	void *data;
 
 	if (format != ZPixmap)
 		goto fall_back;
 
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-
 	if (!glamor_set_planemask(pixmap, planeMask)) {
 		glamor_fallback
 		    ("Failedto set planemask  in glamor_solid.\n");
 		goto fall_back;
 	}
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index cf8bf99..011e077 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -249,20 +249,12 @@ static Bool
 _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int left_pad, int image_format, char *bits, Bool fallback)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(drawable->pScreen);
-	glamor_gl_dispatch *dispatch;
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	GLenum type, format, iformat;
 	RegionPtr clip;
-	BoxPtr pbox;
-	int nbox;
-	int src_stride = PixmapBytePad(w, drawable->depth);
 	int x_off, y_off;
 	float vertices[8], texcoords[8];
-	GLfloat xscale, yscale, txscale, tyscale;
 	Bool ret = FALSE;
 	PixmapPtr temp_pixmap;
 	glamor_pixmap_private *temp_pixmap_priv;
commit 65c5605c9693c8d30e597ac029be936495f23927
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 23:16:51 2012 +0800

    glamor_getspans: Reuse glamor_download_sub_pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index bd6a5ec..22e2b7c 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -34,74 +34,26 @@ _glamor_get_spans(DrawablePtr drawable,
 		  Bool fallback)
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-	GLenum format, type;
-	int no_alpha, revert;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(drawable->pScreen);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch;
-	glamor_pixmap_fbo *temp_fbo = NULL;
 	int i;
 	uint8_t *readpixels_dst = (uint8_t *) dst;
+	void *data;
 	int x_off, y_off;
 	Bool ret = FALSE;
-	int swap_rb;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-		glamor_fallback("pixmap has no fbo.\n");
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		goto fail;
-	}
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &revert, &swap_rb, 0)) {
-		glamor_fallback("unknown depth. %d \n", drawable->depth);
-		goto fail;
-	}
-
-	if (revert > REVERT_NORMAL)
-		goto fail;
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	glamor_validate_pixmap(pixmap);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && ( swap_rb != SWAP_NONE_DOWNLOADING
-		 || revert != REVERT_NONE)) {
-
-		/* XXX prepare whole pixmap is not efficient. */
-		temp_fbo =
-		    glamor_es2_pixmap_read_prepare(pixmap, 0, 0, pixmap->drawable.width, pixmap->drawable.height, format,
-						   type, no_alpha,
-						   revert, swap_rb);
-		if (temp_fbo == NULL)
-			goto fail;
-
-	}
 
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-	dispatch = glamor_get_dispatch(glamor_priv);
 	for (i = 0; i < count; i++) {
-		if (glamor_priv->yInverted) {
-			dispatch->glReadPixels(points[i].x + x_off,
-					       (points[i].y + y_off),
-					       widths[i], 1, format,
-					       type, readpixels_dst);
-		} else {
-			dispatch->glReadPixels(points[i].x + x_off,
-					       pixmap->drawable.height -
-					       1 - (points[i].y + y_off),
-					       widths[i], 1, format,
-					       type, readpixels_dst);
-		}
-		readpixels_dst +=
-		    PixmapBytePad(widths[i], drawable->depth);
+		data = glamor_download_sub_pixmap_to_cpu(pixmap, points[i].x + x_off,
+							 points[i].y + y_off, widths[i], 1,
+							 PixmapBytePad(widths[i], drawable->depth),
+							 readpixels_dst, 0, GLAMOR_ACCESS_RO);
+		assert(data == readpixels_dst);
+		readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
 	}
-	glamor_put_dispatch(glamor_priv);
-	if (temp_fbo)
-		glamor_destroy_fbo(temp_fbo);
 
 	ret = TRUE;
 	goto done;
@@ -112,8 +64,6 @@ fail:
 		goto done;
 
 	ret = TRUE;
-	glamor_fallback("from %p (%c)\n", drawable,
-			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
 		fbGetSpans(drawable, wmax, points, widths, count, dst);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
commit 68a5cc6f371e1f07ce176e154331dafaf5d9ef0e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 19:46:09 2012 +0800

    glamor_render: Don't download whole picture when fallback.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index e9e42c5..5797453 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -674,7 +674,6 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
 				pixmap->drawable.depth);
 		return TRUE;
 	}
-
 	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
 		return FALSE;
 
@@ -1155,7 +1154,6 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return NULL;
-
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
 		flag = GLAMOR_CREATE_PIXMAP_CPU;
 	else
@@ -1215,17 +1213,18 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
 	void *bits;
 	int pbo;
 	glamor_pixmap_private *sub_pixmap_priv;
-
-	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
-	if (sub_pixmap_priv
-	    && sub_pixmap_priv->fbo
-	    && sub_pixmap_priv->fbo->pbo_valid) {
-		bits = NULL;
-		pbo = sub_pixmap_priv->fbo->pbo;
-	} else {
-		bits = sub_pixmap->devPrivate.ptr;
-		pbo = 0;
+	if (access != GLAMOR_ACCESS_RO) {
+		sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+		if (sub_pixmap_priv
+		    && sub_pixmap_priv->fbo
+		    && sub_pixmap_priv->fbo->pbo_valid) {
+			bits = NULL;
+			pbo = sub_pixmap_priv->fbo->pbo;
+		} else {
+			bits = sub_pixmap->devPrivate.ptr;
+			pbo = 0;
+		}
+		glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
 	}
-	glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
 	glamor_destroy_pixmap(sub_pixmap);
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 9410adf..3bf04d4 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -2816,6 +2816,16 @@ _glamor_composite(CARD8 op,
 	RegionRec region;
 	BoxPtr box;
 	int nbox, i, ok;
+	PixmapPtr sub_dest_pixmap = NULL;
+	PixmapPtr sub_source_pixmap = NULL;
+	PixmapPtr sub_mask_pixmap = NULL;
+	int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
+	int source_x_off, source_y_off, saved_source_x, saved_source_y;
+	int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
+	DrawablePtr saved_dest_drawable;
+	DrawablePtr saved_source_drawable;
+	DrawablePtr saved_mask_drawable;
+
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
@@ -2824,10 +2834,6 @@ _glamor_composite(CARD8 op,
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-		goto fail;
-	}
-
 	if (source->pDrawable) {
 		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
@@ -2841,6 +2847,14 @@ _glamor_composite(CARD8 op,
 		if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
 			goto fail;
 	}
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		goto fail;
+	}
+
+	if (op >= ARRAY_SIZE(composite_op_info))
+		goto fail;
+
 	if ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	    || (source->pDrawable
@@ -3006,6 +3020,28 @@ fail:
 	     dest->pDrawable->width, dest->pDrawable->height,
 	     glamor_get_picture_location(dest));
 
+#define GET_SUB_PICTURE(p, access)		do {					\
+	glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap,				\
+				   & p ##_x_off, & p ##_y_off);				\
+	sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap,				\
+					      x_ ##p + p ##_x_off + p->pDrawable->x,	\
+					      y_ ##p + p ##_y_off + p->pDrawable->y,	\
+					      width, height, access);			\
+	if (sub_ ##p ##_pixmap != NULL) {						\
+		saved_ ##p ##_drawable = p->pDrawable;					\
+		p->pDrawable = &sub_ ##p ##_pixmap->drawable;				\
+		saved_ ##p ##_x = x_ ##p;						\
+		saved_ ##p ##_y = y_ ##p;						\
+		if (p->pCompositeClip)							\
+			pixman_region_translate (p->pCompositeClip,			\
+						 p ##_x_off - x_ ##p,			\
+						 p ##_y_off - y_ ##p);			\
+		x_ ##p = 0;								\
+		y_ ##p = 0;								\
+	} } while(0)
+
+	GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
+
 	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
 		if (glamor_prepare_access_picture
 		    (source, GLAMOR_ACCESS_RO)) {
@@ -3025,6 +3061,23 @@ fail:
 		}
 		glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
 	}
+
+#define PUT_SUB_PICTURE(p, access)		do {				\
+	if (sub_ ##p ##_pixmap != NULL) {					\
+		x_ ##p = saved_ ##p ##_x;					\
+		y_ ##p = saved_ ##p ##_y;					\
+		if (p->pCompositeClip)						\
+			pixman_region_translate (p->pCompositeClip,		\
+						 - p ## _x_off + x_ ##p,	\
+						 - p ## _y_off + y_ ##p);	\
+		p->pDrawable = saved_ ##p ##_drawable;				\
+		glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap,		\
+				      x_ ##p + p ##_x_off + p->pDrawable->x,	\
+				      y_ ##p + p ##_y_off + p->pDrawable->y,	\
+				      width, height, access);			\
+	}} while(0)
+
+	PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
       done:
 	if (temp_src != source)
 		FreePicture(temp_src, 0);
@@ -3044,10 +3097,10 @@ glamor_composite(CARD8 op,
 		 INT16 y_source,
 		 INT16 x_mask,
 		 INT16 y_mask,
-		 INT16 x_dest, INT16 y_dest, 
+		 INT16 x_dest, INT16 y_dest,
 		 CARD16 width, CARD16 height)
 {
-	_glamor_composite(op, source, mask, dest, x_source, y_source, 
+	_glamor_composite(op, source, mask, dest, x_source, y_source,
 			  x_mask, y_mask, x_dest, y_dest, width, height,
 			  TRUE);
 }
@@ -3061,10 +3114,10 @@ glamor_composite_nf(CARD8 op,
 		    INT16 y_source,
 		    INT16 x_mask,
 		    INT16 y_mask,
-		    INT16 x_dest, INT16 y_dest, 
+		    INT16 x_dest, INT16 y_dest,
 		    CARD16 width, CARD16 height)
 {
-	return _glamor_composite(op, source, mask, dest, x_source, y_source, 
+	return _glamor_composite(op, source, mask, dest, x_source, y_source,
 				 x_mask, y_mask, x_dest, y_dest, width, height,
 				 FALSE);
 }
commit e38eb675321dce1bbc39cbd177a6398de567dd79
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 19:43:44 2012 +0800

    glamor_put_sub_pixmap: Change to use glamor_upload_sub_pixmap.
    
    As the pixmap may be attached to a picture, we need to use
    glamor_upload_sub_pixmap to process it. glamor_copy_n_to_n
    will not consider the picture case.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index db1b163..e9e42c5 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1170,6 +1170,11 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
 	pbo = sub_pixmap_priv ? (sub_pixmap_priv->fbo ? sub_pixmap_priv->fbo->pbo : 0): 0;
 
+	if (pixmap_priv->is_picture) {
+		sub_pixmap_priv->pict_format = pixmap_priv->pict_format;
+		sub_pixmap_priv->is_picture = pixmap_priv->is_picture;
+	}
+
 	if (pbo)
 		data = NULL;
 	else {
@@ -1207,19 +1212,20 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
 PixmapPtr
 glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
 {
-	struct pixman_box16 box;
-	int dx, dy;
-	box.x1 = x;
-	box.y1 = y;
-	box.x2 = x + w;
-	box.y2 = y + h;
-
-	dx = -(x);
-	dy = -(y);
-
-	glamor_copy_n_to_n(&sub_pixmap->drawable,
-			   &pixmap->drawable,
-			   NULL, &box, 1, dx, dy,
-			   0, 0, 0, NULL);
+	void *bits;
+	int pbo;
+	glamor_pixmap_private *sub_pixmap_priv;
+
+	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+	if (sub_pixmap_priv
+	    && sub_pixmap_priv->fbo
+	    && sub_pixmap_priv->fbo->pbo_valid) {
+		bits = NULL;
+		pbo = sub_pixmap_priv->fbo->pbo;
+	} else {
+		bits = sub_pixmap->devPrivate.ptr;
+		pbo = 0;
+	}
+	glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
 	glamor_destroy_pixmap(sub_pixmap);
 }
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 45c8550..cf8bf99 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -295,8 +295,11 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 			goto fail;
 
 		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-		temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
-		temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
+
+		if (pixmap_priv->is_picture) {
+			temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
+			temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
+		}
 
 		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
 						    pixmap->devKind, bits, 0);
commit ff3d2c796363ea603ab92995091a967a3f8636d7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 17:09:06 2012 +0800

    Fixed a stride problem for textured_drm pixmap.
    
    As a textured_drm pixmap has a drm bo attached to it, and
    it's the DDX layer to set it stride value. In some case,
    the stride value is not equal to PixmapBytePad(w, depth)
    which is used within glamor.
    
    Then if it is the case, we have two choice, one is to set
    the GL_PACK_ROW_LENGTH/GL_UNPACK_ROW_LENGTH when we need
    to download or upload the pixmap. The other option is to
    change the pixmap's devKind to match the one glamor is using
    when downloading the pixmap, and restore it to the drm stride
    after uploading the pixmap.
    
    We choose the 2nd option, as GLES doesn't support the first
    method.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f9c1db2..009a089 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -344,6 +344,9 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 		free(pixmap->devPrivate.ptr);
 	}
 
+	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
+		pixmap->devKind = pixmap_priv->drm_stride;
+
 	if (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED)
 		pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index fbf159f..db1b163 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -688,6 +688,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 	glamor_pixmap_private *pixmap_priv;
 	void *data;
 	int pbo;
+	int ret;
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
@@ -706,11 +707,11 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 						pixmap->drawable.height,
 						pixmap->devKind,
 						data, pbo))
-		return GLAMOR_UPLOAD_DONE;
+		ret = GLAMOR_UPLOAD_DONE;
 	else
-		return GLAMOR_UPLOAD_FAILED;
+		ret = GLAMOR_UPLOAD_FAILED;
 
-	return GLAMOR_UPLOAD_DONE;
+	return ret;
 }
 
 void
@@ -1023,6 +1024,12 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		pbo = pixmap_priv->fbo->pbo;
 	}
 
+	if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
+		stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
+		pixmap_priv->drm_stride = pixmap->devKind;
+		pixmap->devKind = stride;
+	}
+
 	dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
 						pixmap->drawable.width,
 						pixmap->drawable.height,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9a15309..46e4dc5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -327,6 +327,7 @@ typedef struct glamor_pixmap_private {
 	PictFormatShort pict_format;
 	glamor_pending_op pending_op;
 	PixmapPtr container;
+	int drm_stride;
 	glamor_screen_private *glamor_priv;
 } glamor_pixmap_private;
 
commit 70b71718e737872dfdbf4f6c7285d4260a099d17
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 14:36:09 2012 +0800

    glamor_putimage: Reuse copy area to do the clipped copy.
    
    If no clip set, we load the bits to the pixmap directly.
    Otherwise, load the bits to a temporary pixmap and call
    glamor_copy_area to do the clipped copy.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 0d28b53..45c8550 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -288,99 +288,27 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	/* create a temporary pixmap and upload the bits to that
 	 * pixmap, then apply clip copy it to the destination pixmap.*/
 
-	temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
-	if (temp_pixmap == NULL)
-		goto fail;
-
-	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-	temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
-	temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
-
-	glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
-					    pixmap->devKind, bits, 0);
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (!glamor_set_alu(dispatch, gc->alu)) {
-		glamor_put_dispatch(glamor_priv);
-		goto fail;
-	}
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	glamor_validate_pixmap(pixmap);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					texcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
-
-#ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
-#endif
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-	dispatch->glUniform1i(glamor_priv->
-			      finish_access_revert[0],
-			      REVERT_NONE);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
-			      SWAP_NONE_UPLOADING);
-
-	x += drawable->x;
-	y += drawable->y;
-
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 	clip = fbGetCompositeClip(gc);
-
-	pixmap_priv_get_scale(temp_pixmap_priv, &txscale, &tyscale);
-	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
-	for (nbox = REGION_NUM_RECTS(clip),
-	     pbox = REGION_RECTS(clip); nbox--; pbox++) {
-		int x1 = x;
-		int y1 = y;
-		int x2 = x + w;
-		int y2 = y + h;
-
-		if (x1 < pbox->x1)
-			x1 = pbox->x1;
-		if (y1 < pbox->y1)
-			y1 = pbox->y1;
-		if (x2 > pbox->x2)
-			x2 = pbox->x2;
-		if (y2 > pbox->y2)
-			y2 = pbox->y2;
-		if (x1 >= x2 || y1 >= y2)
-			continue;
-
-		glamor_set_normalize_tcoords(txscale, tyscale,
-					     x1 - x, y1 - y,
-					     x2 - x, y2 - y, 1, texcoords);
-
-		glamor_set_normalize_vcoords(xscale, yscale,
-					     x1 + x_off, y1 + y_off,
-					     x2 + x_off, y2 + y_off,
-					     glamor_priv->yInverted,
-					     vertices);
-
-		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	if (clip != NULL) {
+		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
+		if (temp_pixmap == NULL)
+			goto fail;
+
+		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+		temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
+		temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
+
+		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
+						    pixmap->devKind, bits, 0);
+
+		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
+		glamor_destroy_pixmap(temp_pixmap);
+	} else {
+		ErrorF("put image directly. \n");
+		glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+		glamor_upload_sub_pixmap_to_texture(pixmap, drawable->x + x_off, drawable->y + y_off,
+						    w, h, pixmap->devKind, bits, 0);
 	}
-
-#ifndef GLAMOR_GLES2
-	dispatch->glDisable(GL_TEXTURE_2D);
-#endif
-	dispatch->glUseProgram(0);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_set_planemask(pixmap, ~0);
-	glamor_put_dispatch(glamor_priv);
-
-	glamor_destroy_pixmap(temp_pixmap);
 	ret = TRUE;
 	goto done;
 
commit e1be714312df8d596f6be268cb8a4e390e634c36
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 10:30:02 2012 +0800

    Fixed a unbalanced glamor_put_dispatch.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 35eb9c7..fbf159f 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1021,7 +1021,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 					       &pixmap_priv->fbo->pbo);
 		glamor_put_dispatch(glamor_priv);
 		pbo = pixmap_priv->fbo->pbo;
-		glamor_put_dispatch(glamor_priv);
 	}
 
 	dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
commit bd53e24dc32206dc978d3dc2408e1832f5a803e7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Apr 15 22:47:48 2012 +0800

    glamor_pixmap_priv: Always return a valid private pixmap.
    
    If a pixmap doesn't have a private, then set its type to
    GLAMOR_MEMORY, and thus it will get a valid private.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 9b1d425..d438b9c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -67,7 +67,8 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
+					glamor_pixmap_private_key);
 	if (pixmap_priv == NULL) {
 		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
 		glamor_set_pixmap_private(pixmap, pixmap_priv);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 961af47..9a15309 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -370,8 +370,15 @@ glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
-	return dixLookupPrivate(&pixmap->devPrivates,
+	glamor_pixmap_private *priv;
+	priv = dixLookupPrivate(&pixmap->devPrivates,
 				glamor_pixmap_private_key);
+	if (!priv) {
+		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+		priv = dixLookupPrivate(&pixmap->devPrivates,
+					glamor_pixmap_private_key);
+	}
+	return priv;
 }
 
 void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index da05143..d2dc6e4 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -757,7 +757,6 @@ static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int
 	int stride = pixmap->devKind;
 
 	p = p + y * stride + x;
-	ErrorF("devKind %d, x %d y %d w %d h %d width %d height %d\n", stride, x, y, w, h, pixmap->drawable.width, pixmap->drawable.height);
 
 	for (i = 0; i < h; i++)
 	{
commit 420af44a3aaefd4848aa24a28c330cab36049078
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Apr 14 22:40:48 2012 +0800

    Don't need to set GL_PACK_ROW_LENGTH/GL_UNPACK_ROW_LENGTH.
    
    We already adjust the stride of the pixmap, and keep the alignment
    as 4 should be ok to let the GL/GLES match the stride.
    
    Previous version has a unbalanced PACK ROW length seting, and is
    buggy, now fixed it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0b23021..35eb9c7 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -819,7 +819,6 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 				  int stride, void *bits, int pbo, glamor_access_t access)
 {
 	glamor_pixmap_private *pixmap_priv;
-	unsigned int row_length;
 	GLenum format, type, gl_access, gl_usage;
 	int no_alpha, revert, swap_rb;
 	void *data, *read;
@@ -896,13 +895,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	}
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
-		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
-	} else {
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-	}
+	dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+
 	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
 
 		if (!glamor_priv->yInverted) {
@@ -941,17 +935,15 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 				       temp_pbo);
 		dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
 				       stride *
-				       pixmap->drawable.height,
+				       h,
 				       NULL, GL_STREAM_READ);
-		dispatch->glReadPixels(0, 0, row_length,
-				       pixmap->drawable.height,
+		dispatch->glReadPixels(0, 0, w, h,
 				       format, type, 0);
 		read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
 					     GL_READ_ONLY);
 		for (yy = 0; yy < pixmap->drawable.height; yy++)
 			memcpy(data + yy * stride,
-			       read + (pixmap->drawable.height -
-			       yy - 1) * stride, stride);
+			       read + (h - yy - 1) * stride, stride);
 		dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
 		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		dispatch->glDeleteBuffers(1, &temp_pbo);
@@ -995,7 +987,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 {
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	unsigned int stride, row_length, y;
+	unsigned int stride, y;
 	GLenum format, type, gl_access, gl_usage;
 	int no_alpha, revert, swap_rb;
 	void *data = NULL, *dst;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 858fc07..0d28b53 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -376,8 +376,6 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_set_planemask(pixmap, ~0);
 	glamor_put_dispatch(glamor_priv);
commit 18d69fb0142088f7df230ec876c7ce2b55a41ad9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 13 13:47:05 2012 +0800

    glamor_gl: Use GL_ALPHA for depth 8 pixmap.
    
    Use GL_RGBA to represent a8 pixmap is not efficient.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f89632c..961af47 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -185,7 +185,7 @@ struct glamor_saved_procs {
 #ifdef GLAMOR_GLES2
 #define CACHE_FORMAT_COUNT 3
 #else
-#define CACHE_FORMAT_COUNT 1
+#define CACHE_FORMAT_COUNT 2
 #endif
 
 #define CACHE_BUCKET_WCOUNT 4
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 972918c..da05143 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -257,10 +257,10 @@ static inline void
 gl_iformat_for_depth(int depth, GLenum * format)
 {
 	switch (depth) {
-#if 0
 	case 8:
 		*format = GL_ALPHA;
 		break;
+#if 0
 	case 24:
 		*format = GL_RGB;
 		break;
@@ -411,6 +411,8 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 inline static int cache_format(GLenum format)
 {
 	switch (format) {
+	case GL_ALPHA:
+		return 1;
 	case GL_RGBA:
 		return 0;
 	default:
commit 428f2a3f58a91300835aaa083ac0b291ce394dd0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 13 13:45:42 2012 +0800

    glamor_pixmap_ensure_fbo: Should allocate tex if we don't have one.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index e9612bd..e5b98a1 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -527,7 +527,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
 		glamor_pixmap_attach_fbo(pixmap, fbo);
 	} else {
 		/* We do have a fbo, but it may lack of fb or tex. */
-		if (pixmap_priv->fbo->tex)
+		if (!pixmap_priv->fbo->tex)
 			pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
 								   pixmap->drawable.height, format);
 
commit cf0e206a0ff6538eb286c06098023b9e29b00c74
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 11 18:59:27 2012 +0800

    glamor_polylines: Don't fallback for non-solid fill.
    
    As glamor_fill/fbFill will handle non-solid fill correctly.
    We don't fallback it here.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 175e958..70dd6c1 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -54,13 +54,12 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 		 */
 		goto wide_line;
 	}
-	if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) {
+	if (gc->lineStyle != LineSolid) {
 		glamor_fallback
-		    ("non-solid fill line style %d, fill style %d\n",
-		     gc->lineStyle, gc->fillStyle);
+		    ("non-solid fill line style %d\n",
+		     gc->lineStyle);
 		goto fail;
 	}
-
 	rects = malloc(sizeof(xRectangle) * (n - 1));
 	x1 = points[0].x;
 	y1 = points[0].y;
commit b5bd9a2d902d44834fc43199167d7dee71c9b709
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 11 18:57:33 2012 +0800

    glamor_upload/download: fix 1bpp bug.
    
    For A1 to A8's conversion, the stride is different for the
    source and destination. Previous implementation use the same
    stride, and may allocate less memory than required. Thus may
    crash the server when uploading a A1 pixmap. Now fix it.
    
    Tested-by: Peng Li <peng.li at intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 77fd033..0b23021 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -217,13 +217,16 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 	PictFormatShort dst_format, src_format;
 	pixman_image_t *dst_image;
 	pixman_image_t *src_image;
+	int src_stride;
 
 	if (revert == REVERT_UPLOADING_A1) {
 		src_format = PICT_a1;
 		dst_format = PICT_a8;
+		src_stride = PixmapBytePad(w, 1);
 	} else {
 		dst_format = PICT_a1;
 		src_format = PICT_a8;
+		src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
 	}
 
 	dst_image = pixman_image_create_bits(dst_format,
@@ -238,7 +241,7 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
 	src_image = pixman_image_create_bits(src_format,
 					     w, h,
 					     src_bits,
-					     stride);
+					     src_stride);
 
 	if (src_image == NULL) {
 		pixman_image_unref(dst_image);
@@ -490,7 +493,13 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum ty
 	    &&  revert > REVERT_NORMAL) {
 		/* XXX if we are restoring the pixmap, then we may not need to allocate
 		 * new buffer */
-		void *converted_bits = malloc(h * stride);
+		void *converted_bits;
+
+		if (pixmap->drawable.depth == 1)
+			stride = (((w * 8 + 7) / 8) + 3) & ~3;
+
+		converted_bits = malloc(h * stride);
+
 		if (converted_bits == NULL)
 			return FALSE;
 		bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
@@ -864,8 +873,9 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	need_post_conversion = (revert > REVERT_NORMAL);
 	if (need_post_conversion) {
 		if (pixmap->drawable.depth == 1) {
-			stride = (((w * 8 + 7) / 8) + 3) & ~3;
-			data = malloc(stride * h);
+			int temp_stride;
+			temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+			data = malloc(temp_stride * h);
 			if (data == NULL)
 				return NULL;
 			need_free_data = 1;
@@ -877,13 +887,14 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
 		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
 								 format, type, no_alpha,
-								 revert, swap_rb)))
+								 revert, swap_rb))) {
+			free(data);
 			return NULL;
+		}
 		x = 0;
 		y = 0;
 	}
 
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
@@ -954,7 +965,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
 		 * Don't need to consider if the pbo is valid.*/
 		bits = glamor_color_convert_to_bits(data, bits,
 						    w, h,
-						    stride, no_alpha,
+						    stride,
+						    no_alpha,
 						    revert, swap_rb);
 	}
 
commit b0e91f0f5a3a4f74800b89ed4003d300ae138151
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Apr 10 20:50:14 2012 +0800

    glamor_pixmap_upload_texture: Support to upload a sub region of data.
    
    Just as the downloading side, we can upload an sub region data to
    a pixmap's specified region. The data could be in memory or in a
    pbo buffer.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 82002d7..77fd033 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -406,66 +406,60 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int s
  **/
 int in_restore = 0;
 static void
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				  GLenum type, GLuint tex, int sub,
-				  void *bits)
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, int *tex,
+				  GLenum format,
+				  GLenum type,
+				  int x, int y, int w, int h,
+				  void *bits, int pbo)
 {
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
-	unsigned int stride, row_length;
-	GLenum iformat;
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
-		iformat = format;
-	else
-		gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
-
-	stride = pixmap->devKind;
-	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	if (*tex == 0) {
+		int iformat;
+		dispatch->glGenTextures(1, tex);
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+			gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+		else
+			iformat = format;
+
+		dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
+		dispatch->glTexImage2D(GL_TEXTURE_2D,
+				       0,
+				       iformat,
+				       w, h, 0, format, type,
+				       bits);
+	} else
+		dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
+
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-	} else {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-	}
+	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-				       pixmap_priv->fbo->pbo);
+				       pbo);
 
-	if (sub)
-		dispatch->glTexSubImage2D(GL_TEXTURE_2D,
-				       0,0,0,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height, format, type,
-				       bits);
-	else
-		dispatch->glTexImage2D(GL_TEXTURE_2D,
-				       0,
-				       iformat,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height, 0, format, type,
-				       bits);
+	dispatch->glTexSubImage2D(GL_TEXTURE_2D,
+				  0, x, y, w, h,
+				  format, type,
+				  bits);
 
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 	glamor_put_dispatch(glamor_priv);
 }
 
-Bool
-glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
-				     int no_alpha, int revert, int swap_rb, void *bits)
+static Bool
+_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
+				     int no_alpha, int revert,
+				     int swap_rb, int x, int y, int w, int h,
+				     int stride, void* bits, int pbo)
 {
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -483,7 +477,7 @@ glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum typ
 	};
 	float *ptexcoords;
 	float dst_xscale, dst_yscale;
-	GLuint tex;
+	GLuint tex = 0;
 	int need_flip;
 	int need_free_bits = 0;
 
@@ -496,12 +490,11 @@ glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum typ
 	    &&  revert > REVERT_NORMAL) {
 		/* XXX if we are restoring the pixmap, then we may not need to allocate
 		 * new buffer */
-		void *converted_bits = malloc(pixmap->drawable.height * pixmap->devKind);
+		void *converted_bits = malloc(h * stride);
 		if (converted_bits == NULL)
 			return FALSE;
-		bits = glamor_color_convert_to_bits(bits, converted_bits, pixmap->drawable.width,
-						    pixmap->drawable.height,
-						    pixmap->devKind,
+		bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
+						    stride,
 						    no_alpha, revert, swap_rb);
 		if (bits == NULL) {
 			ErrorF("Failed to convert pixmap no_alpha %d, revert mode %d, swap mode %d\n", swap_rb);
@@ -520,9 +513,11 @@ ready_to_upload:
 	    && revert == REVERT_NONE
 	    && swap_rb == SWAP_NONE_UPLOADING
 	    && !need_flip) {
-		__glamor_upload_pixmap_to_texture(pixmap, format, type,
-						  pixmap_priv->fbo->tex, 1,
-						  bits);
+		assert(pixmap_priv->fbo->tex);
+		__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
+						  format, type,
+						  x, y, w, h,
+						  bits, pbo);
 		return TRUE;
 	}
 
@@ -534,8 +529,8 @@ ready_to_upload:
 	pixmap_priv_get_scale(pixmap_priv, &dst_xscale, &dst_yscale);
 	glamor_set_normalize_vcoords(dst_xscale,
 				     dst_yscale,
-				     0, 0,
-				     pixmap->drawable.width, pixmap->drawable.height,
+				     x, y,
+				     x + w, y + h,
 				     glamor_priv->yInverted,
 				     vertices);
 
@@ -551,9 +546,10 @@ ready_to_upload:
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	dispatch->glGenTextures(1, &tex);
-
-	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex, 0, bits);
+	__glamor_upload_pixmap_to_texture(pixmap, &tex,
+					  format, type,
+					  0, 0, w, h,
+					  bits, pbo);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 
@@ -590,40 +586,6 @@ ready_to_upload:
 }
 
 /*
- * Load texture from the pixmap's data pointer and then
- * draw the texture to the fbo, and flip the y axis.
- * */
-
-static Bool
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				 GLenum type, int no_alpha, int revert,
-				 int swap_rb)
-{
-	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-	void *bits;
-	int need_free_bits = 0;
-
-	if (!pixmap_priv)
-		return TRUE;
-
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
-			    "Uploading pixmap %p  %dx%d depth%d.\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
-
-	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid)
-		bits = NULL;
-
-	return glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha,
-						    revert, swap_rb,
-						    pixmap->devPrivate.ptr);
-}
-
-
-/*
  * Prepare to upload a pixmap to texture memory.
  * no_alpha equals 1 means the format needs to wire alpha to 1.
  * Two condtion need to setup a fbo for a pixmap
@@ -642,6 +604,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
+	if (pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->fb)
+		return 0;
+
 	if (!(no_alpha
 	      || (revert != REVERT_NONE)
 	      || (swap_rb != SWAP_NONE_UPLOADING)
@@ -683,8 +648,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	return 0;
 }
 
-enum glamor_pixmap_status
-glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
+Bool
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
+				    int stride, void *bits, int pbo)
 {
 	GLenum format, type;
 	int no_alpha, revert, swap_rb;
@@ -697,14 +663,40 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 						   &swap_rb, 1)) {
 		glamor_fallback("Unknown pixmap depth %d.\n",
 				pixmap->drawable.depth);
-		return GLAMOR_UPLOAD_FAILED;
+		return TRUE;
 	}
 
 	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
-		return GLAMOR_UPLOAD_FAILED;
+		return FALSE;
+
+	return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
+						     x, y, w, h, stride, bits, pbo);
+}
 
-	if (_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					     revert, swap_rb))
+enum glamor_pixmap_status
+glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
+{
+	glamor_pixmap_private *pixmap_priv;
+	void *data;
+	int pbo;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (pixmap_priv
+	    && (pixmap_priv->fbo)
+	    && (pixmap_priv->fbo->pbo_valid)) {
+		data = NULL;
+		pbo = pixmap_priv->fbo->pbo;
+	} else {
+		data = pixmap->devPrivate.ptr;
+		pbo = 0;
+	}
+
+	if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
+						pixmap->drawable.width,
+						pixmap->drawable.height,
+						pixmap->devKind,
+						data, pbo))
 		return GLAMOR_UPLOAD_DONE;
 	else
 		return GLAMOR_UPLOAD_FAILED;
@@ -715,20 +707,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
-	GLenum format, type;
-	int no_alpha, revert, swap_rb;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &revert, &swap_rb, 1)) {
-		ErrorF("Unknown pixmap depth %d.\n",
-		       pixmap->drawable.depth);
-		assert(0);
-	}
-
-	if (!_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					      revert, swap_rb))
+	if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
 		LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n",
 			   pixmap->drawable.pScreen->myNum);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index cfa46e5..f89632c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -639,6 +639,10 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
 enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
 							  pixmap);
 
+Bool
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
+				    int stride, void *bits, int pbo);
+
 
 PixmapPtr
 glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 010950e..858fc07 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -263,10 +263,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	int x_off, y_off;
 	float vertices[8], texcoords[8];
 	GLfloat xscale, yscale, txscale, tyscale;
-	GLuint tex;
-	int no_alpha, revert;
 	Bool ret = FALSE;
-	int swap_rb;
 	PixmapPtr temp_pixmap;
 	glamor_pixmap_private *temp_pixmap_priv;
 
@@ -288,37 +285,19 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (!glamor_set_planemask(pixmap, gc->planemask)) {
 		goto fail;
 	}
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &revert,
-						   &swap_rb,
-						   1)) {
-		glamor_fallback("unknown depth. %d \n", drawable->depth);
-		goto fail;
-	}
-
 	/* create a temporary pixmap and upload the bits to that
 	 * pixmap, then apply clip copy it to the destination pixmap.*/
 
 	temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
-
 	if (temp_pixmap == NULL)
 		goto fail;
-	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-
-	if (temp_pixmap_priv->fbo == NULL) {
-		glamor_destroy_pixmap(temp_pixmap);
-		goto fail;
-	}
 
-	if (!glamor_upload_bits_to_pixmap_texture(temp_pixmap, format, type,
-						  no_alpha, revert, swap_rb, bits)) {
-		glamor_destroy_pixmap(temp_pixmap);
-		goto fail;
-	}
+	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+	temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
+	temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
 
+	glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
+					    pixmap->devKind, bits, 0);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (!glamor_set_alu(dispatch, gc->alu)) {
@@ -345,9 +324,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 #endif
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
 	dispatch->glUniform1i(glamor_priv->
-			      finish_access_revert[no_alpha],
+			      finish_access_revert[0],
 			      REVERT_NONE);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
 			      SWAP_NONE_UPLOADING);
 
 	x += drawable->x;
@@ -397,7 +376,6 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-	dispatch->glDeleteTextures(1, &tex);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glamor_set_alu(dispatch, GXcopy);
commit 3061f348ca2f05d88ca2391e1ad81ce8216d69f2
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Apr 10 10:40:17 2012 +0800

    glamor_getimage: Use glamor_download_sub_pixmap_to_cpu to get image.
    
    Reduce the duplicate logic.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 15ee89d..ddf057f 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -44,6 +44,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	glamor_gl_dispatch * dispatch;
 	Bool ret = FALSE;
 	int swap_rb;
+	int stride;
+	void *data;
 
 	if (format != ZPixmap)
 		goto fall_back;
@@ -63,71 +65,17 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		goto fall_back;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &tex_format,
-						   &tex_type,
-						   &no_alpha,
-						   &revert,
-						   &swap_rb,
-						   0)) {
-		glamor_fallback("unknown depth. %d \n", drawable->depth);
-		goto fall_back;
-	}
-
-	if (revert > REVERT_NORMAL)
-		goto fall_back;
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	glamor_validate_pixmap(pixmap);
+	stride = PixmapBytePad(w, drawable->depth);
 
 	x += drawable->x + x_off;
 	y += drawable->y + y_off;
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && ( swap_rb != SWAP_NONE_DOWNLOADING
-		 || revert != REVERT_NONE)) {
-		temp_fbo =
-		    glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h, tex_format,
-						   tex_type, no_alpha,
-						   revert, swap_rb);
-		if (temp_fbo == NULL) {
-			x -= (drawable->x + x_off);
-			y -= (drawable->y + y_off);
-			goto fall_back;
-		}
-		x = 0;
-		y = 0;
-	}
-
-	dispatch = glamor_get_dispatch(glamor_priv);
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		int row_length = PixmapBytePad(w, drawable->depth);
-		row_length = (row_length * 8) / drawable->bitsPerPixel;
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
-		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
-	} else {
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride,
+						 d, 0, GLAMOR_ACCESS_RO);
+	if (data != NULL) {
+		ret = TRUE;
+		assert(data == d);
 	}
-
-	if (glamor_priv->yInverted)
-		dispatch->glReadPixels(x,
-				       y,
-				       w, h,
-				       tex_format,
-				       tex_type, d);
-	else
-		dispatch->glReadPixels(x,
-				       pixmap->drawable.height - 1 - y,
-				       w,
-				       h,
-				       tex_format,
-				       tex_type, d);
-	glamor_put_dispatch(glamor_priv);
-	if (temp_fbo)
-		glamor_destroy_fbo(temp_fbo);
-	ret = TRUE;
-
 fall_back:
 	if (ret == FALSE)
 		miGetImage(drawable, x, y, w, h, format, planeMask, d);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8a6beee..cfa46e5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -605,6 +605,11 @@ void glamor_pixmap_fini(ScreenPtr screen);
 Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
 				   glamor_access_t access);
 
+void *
+glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
+				  int stride, void *bits, int pbo, glamor_access_t access);
+
+
 /**
  * Restore a pixmap's data which is downloaded by 
  * glamor_download_pixmap_to_cpu to its original 
commit 3a91f169122ea0556f628f11fb473b0feed7e44b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Apr 10 10:19:30 2012 +0800

    glamor_polyfillrect: Fixed a potential bug if fallback at glamor_fill.
    
    We should advance the prect after we successfully excuted the
    glamor_fill. And if failed, we need to add the failed 1 box
    back to nbox.
    
    Although, this bug will never happen currently, as glamor_fill
    will never fallback.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 18f4fed..bbe10a1 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -44,6 +44,7 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	RegionPtr pClip = fbGetCompositeClip(gc);
 	Bool ret = FALSE;
 	glamor_screen_private *glamor_priv;
+	xRectangle *saved_prect = prect;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
@@ -55,7 +56,6 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 		fullY1 = prect->y + yorg;
 		fullX2 = fullX1 + (int) prect->width;
 		fullY2 = fullY1 + (int) prect->height;
-		prect++;
 
 		n = REGION_NUM_RECTS(pClip);
 		pbox = REGION_RECTS(pClip);
@@ -78,14 +78,17 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 				y1 = pbox->y1;
 			if (pbox->y2 < y2)
 				y2 = pbox->y2;
-			pbox++;
 
+			pbox++;
 			if (x1 >= x2 || y1 >= y2)
 				continue;
 			if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
-					 y2 - y1, fallback))
+					 y2 - y1, fallback)) {
+				nrect++;
 				goto fail;
+			}
 		}
+		prect++;
 	}
 	ret = TRUE;
 	goto done;
commit 1f657f72cacaa1170e7e55f4b5149c69492db6a5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Apr 9 20:20:45 2012 +0800

    glamor_polyfillrect: Optimize fallback path.
    
    Download/upload required region only.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 4cee485..3c171d4 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -33,6 +33,10 @@ glamor_fill(DrawablePtr drawable,
 {
 	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
 	int off_x, off_y;
+	PixmapPtr sub_pixmap = NULL;
+	glamor_access_t sub_pixmap_access;
+	DrawablePtr saved_drawable = NULL;
+	int saved_x, saved_y;
 
 	glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
 
@@ -82,7 +86,26 @@ glamor_fill(DrawablePtr drawable,
 		   && glamor_ddx_fallback_check_gc(gc))
 		return FALSE;
 	}
+	/* Is it possible to set the access as WO? */
 
+	sub_pixmap_access = GLAMOR_ACCESS_RW;
+
+	sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
+					   y + off_y, width, height,
+					   sub_pixmap_access);
+
+	if (sub_pixmap != NULL) {
+		if (gc->fillStyle != FillSolid) {
+			gc->patOrg.x += (drawable->x - x);
+			gc->patOrg.y += (drawable->y - y);
+		}
+		saved_drawable = drawable;
+		drawable = &sub_pixmap->drawable;
+		saved_x = x;
+		saved_y = y;
+		x = 0;
+		y = 0;
+	}
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		if (glamor_prepare_access_gc(gc)) {
 			fbFill(drawable, gc, x, y, width, height);
@@ -90,6 +113,23 @@ glamor_fill(DrawablePtr drawable,
 		}
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
+
+	if (sub_pixmap != NULL) {
+		struct pixman_box16 box;
+		int dx, dy;
+		if (gc->fillStyle != FillSolid) {
+			gc->patOrg.x -= (saved_drawable->x - saved_x);
+			gc->patOrg.y -= (saved_drawable->y - saved_y);
+		}
+
+		x = saved_x;
+		y = saved_y;
+
+		glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
+				      x + off_x, y + off_y,
+				      width, height, sub_pixmap_access);
+	}
+
 	return TRUE;
 }
 
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 61e707f..18f4fed 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -47,10 +47,6 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
-	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
-		goto fail;
-	}
-
 	xorg = drawable->x;
 	yorg = drawable->y;
 
commit cea0fe3e1f49fc8d86f0cc653c8089f1ea2c9f1f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Apr 9 20:16:07 2012 +0800

    fallback_optimize: Prepare for downloading/uploading subregion.
    
    Introduced two function glamor_get_sub_pixmap/glamor_put_sub_pixmap,
    can easily used to get and put sub region of a big textured pixmap.
    And it can use pbo if possible.
    
    To support download a big textured pixmap's sub region to another
    pixmap's pbo, we introduce a new type of pixmap GLAMOR_MEMORY_MAP.
    This type of pixmap has a valid devPrivate.ptr pointer, and that
    pointer points to a pbo mapped address.
    
    Now, we are ready to refine those
    glamor_prepare_access/glamor_finish_access pairs.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8fc3b05..9b1d425 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -155,6 +155,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	}
 	glamor_set_pixmap_private(pixmap, pixmap_priv);
 
+	if (usage == GLAMOR_CREATE_PIXMAP_MAP)
+		type = GLAMOR_MEMORY_MAP;
+
 	pixmap_priv->container = pixmap;
 	pixmap_priv->glamor_priv = glamor_priv;
 	pixmap_priv->type = type;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4a4e9bd..c608ed8 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -51,6 +51,7 @@
  */
 typedef enum  glamor_pixmap_type {
 	GLAMOR_MEMORY,
+	GLAMOR_MEMORY_MAP,
 	GLAMOR_TEXTURE_DRM,
 	GLAMOR_SEPARATE_TEXTURE,
 	GLAMOR_DRM_ONLY,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index b15450a..e9612bd 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -132,7 +132,6 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 	free(fbo);
 }
 
-
 static void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
@@ -165,6 +164,55 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 #endif
 }
 
+static void
+glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
+{
+	glamor_gl_dispatch *dispatch;
+	int status;
+
+	dispatch = glamor_get_dispatch(fbo->glamor_priv);
+
+	if (fbo->fb == 0)
+		dispatch->glGenFramebuffers(1, &fbo->fb);
+	assert(fbo->tex != 0);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
+					 GL_COLOR_ATTACHMENT0,
+					 GL_TEXTURE_2D, fbo->tex,
+					 0);
+	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+	if (status != GL_FRAMEBUFFER_COMPLETE) {
+		const char *str;
+		switch (status) {
+		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+			str = "incomplete attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+			str = "incomplete/missing attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+			str = "incomplete draw buffer";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+			str = "incomplete read buffer";
+			break;
+		case GL_FRAMEBUFFER_UNSUPPORTED:
+			str = "unsupported";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+			str = "incomplete multiple";
+			break;
+		default:
+			str = "unknown error";
+			break;
+		}
+
+		FatalError("destination is framebuffer incomplete: %s [%#x]\n",
+			   str, status);
+	}
+	glamor_put_dispatch(fbo->glamor_priv);
+}
+
 glamor_pixmap_fbo *
 glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 		  int w, int h, GLenum format, GLint tex, int flag)
@@ -183,9 +231,18 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 	fbo->format = format;
 	fbo->glamor_priv = glamor_priv;
 
+	if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
+		glamor_gl_dispatch *dispatch;
+		dispatch = glamor_get_dispatch(glamor_priv);
+		dispatch->glGenBuffers(1, &fbo->pbo);
+		glamor_put_dispatch(glamor_priv);
+		goto done;
+	}
+
 	if (flag != GLAMOR_CREATE_FBO_NO_FBO)
 		glamor_pixmap_ensure_fb(fbo);
 
+done:
 	return fbo;
 }
 
@@ -331,6 +388,28 @@ glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
 	glamor_pixmap_fbo_cache_put(tex_obj);
 }
 
+int
+_glamor_create_tex(glamor_screen_private *glamor_priv,
+		   int w, int h, GLenum format)
+{
+	glamor_gl_dispatch *dispatch;
+	int tex;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
+			       GL_UNSIGNED_BYTE, NULL);
+	glamor_put_dispatch(glamor_priv);
+	return tex;
+}
+
+
+
 glamor_pixmap_fbo *
 glamor_create_fbo(glamor_screen_private *glamor_priv,
 		  int w, int h,
@@ -339,7 +418,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 {
 	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *fbo;
-	GLint tex;
+	GLint tex = 0;
 	int cache_flag;
 
 	if (!glamor_check_fbo_size(glamor_priv, w, h))
@@ -348,6 +427,9 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
 		goto new_fbo;
 
+	if (flag == GLAMOR_CREATE_PIXMAP_MAP)
+		goto no_tex;
+
 	if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
 		cache_flag = GLAMOR_CACHE_EXACT_SIZE;
 	else
@@ -358,18 +440,9 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	if (fbo)
 		return fbo;
 new_fbo:
-	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glGenTextures(1, &tex);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
-			       GL_UNSIGNED_BYTE, NULL);
-
+	tex = _glamor_create_tex(glamor_priv, w, h, format);
+no_tex:
 	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
-	glamor_put_dispatch(glamor_priv);
 
 	return fbo;
 }
@@ -424,12 +497,47 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 			/* XXX For the Xephyr only, may be broken now.*/
 			pixmap_priv->gl_tex = 0;
 		}
+	case GLAMOR_MEMORY_MAP:
 		pixmap->devPrivate.ptr = NULL;
 		break;
 	default:
 		break;
 	}
 }
+
+
+Bool
+glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_pixmap_fbo *fbo;
+
+	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
+
+		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
+					pixmap->drawable.height,
+					format,
+					flag);
+		if (fbo == NULL)
+			return FALSE;
+
+		glamor_pixmap_attach_fbo(pixmap, fbo);
+	} else {
+		/* We do have a fbo, but it may lack of fb or tex. */
+		if (pixmap_priv->fbo->tex)
+			pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
+								   pixmap->drawable.height, format);
+
+		if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
+			glamor_pixmap_ensure_fb(pixmap_priv->fbo);
+	}
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	return TRUE;
+}
 /*
  * XXX how to handle those pending OPs.
  * By default, pending OP is disabled. Maybe we will give up the pending
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 02b311a..82002d7 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -622,54 +622,6 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 						    pixmap->devPrivate.ptr);
 }
 
-void
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
-{
-	glamor_gl_dispatch *dispatch;
-	int status;
-
-	dispatch = glamor_get_dispatch(fbo->glamor_priv);
-
-	if (fbo->fb == 0)
-		dispatch->glGenFramebuffers(1, &fbo->fb);
-	assert(fbo->tex != 0);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
-	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
-					 GL_COLOR_ATTACHMENT0,
-					 GL_TEXTURE_2D, fbo->tex,
-					 0);
-	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	if (status != GL_FRAMEBUFFER_COMPLETE) {
-		const char *str;
-		switch (status) {
-		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-			str = "incomplete attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-			str = "incomplete/missing attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-			str = "incomplete draw buffer";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-			str = "incomplete read buffer";
-			break;
-		case GL_FRAMEBUFFER_UNSUPPORTED:
-			str = "unsupported";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-			str = "incomplete multiple";
-			break;
-		default:
-			str = "unknown error";
-			break;
-		}
-
-		FatalError("destination is framebuffer incomplete: %s [%#x]\n",
-			   str, status);
-	}
-	glamor_put_dispatch(fbo->glamor_priv);
-}
 
 /*
  * Prepare to upload a pixmap to texture memory.
@@ -681,7 +633,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 static int
 glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb)
 {
-	int flag;
+	int flag = 0;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	glamor_pixmap_fbo *fbo;
@@ -696,36 +648,38 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
 	      || !glamor_priv->yInverted)) {
 		/* We don't need a fbo, a simple texture uploading should work. */
 
-		if (pixmap_priv && pixmap_priv->fbo)
-			return 0;
 		flag = GLAMOR_CREATE_FBO_NO_FBO;
-	} else {
-
-		if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-			return 0;
-		flag = 0;
 	}
 
+	if ((flag == 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->tex)
+	    || (flag != 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->fb))
+		return 0;
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
 	else
 		iformat = format;
 
+	if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
+
+		fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
+					pixmap->drawable.height,
+					iformat,
+					flag);
+		if (fbo == NULL) {
+			glamor_fallback
+			    ("upload failed, depth %d x %d @depth %d \n",
+			     pixmap->drawable.width, pixmap->drawable.height,
+			     pixmap->drawable.depth);
+			return -1;
+		}
 
-	fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
-				pixmap->drawable.height,
-				iformat,
-				flag);
-	if (fbo == NULL) {
-		glamor_fallback
-		    ("upload failed, depth %d x %d @depth %d \n",
-		     pixmap->drawable.width, pixmap->drawable.height,
-		     pixmap->drawable.depth);
-		return -1;
+		glamor_pixmap_attach_fbo(pixmap, fbo);
+	} else {
+		/* We do have a fbo, but it may lack of fb or tex. */
+		glamor_pixmap_ensure_fbo(pixmap, iformat, flag);
 	}
 
-	glamor_pixmap_attach_fbo(pixmap, fbo);
-
 	return 0;
 }
 
@@ -1173,3 +1127,110 @@ fail:
 
 	return ret;
 }
+
+/*
+ * We may use this function to reduce a large pixmap to a small sub
+ * pixmap. Two scenarios currently:
+ * 1. When fallback a large textured pixmap to CPU but we do need to
+ * do rendering within a small sub region, then we can just get a
+ * sub region.
+ *
+ * 2. When uploading a large pixmap to texture but we only need to
+ * use part of the source/mask picture. As glTexImage2D will be more
+ * efficient to upload a contingent region rather than a sub block
+ * in a large buffer. We use this function to gather the sub region
+ * to a contingent sub pixmap.
+ *
+ * The sub-pixmap must have the same format as the source pixmap.
+ *
+ * */
+PixmapPtr
+glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+{
+	glamor_screen_private *glamor_priv;
+	PixmapPtr sub_pixmap;
+	glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
+	void *data;
+	int pbo;
+	int flag;
+
+	if (access == GLAMOR_ACCESS_WO) {
+		sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+						  pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
+		ErrorF("WO\n");
+		return sub_pixmap;
+	}
+
+	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return NULL;
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+		flag = GLAMOR_CREATE_PIXMAP_CPU;
+	else
+		flag = GLAMOR_CREATE_PIXMAP_MAP;
+
+	sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+					  pixmap->drawable.depth, flag);
+
+	if (sub_pixmap == NULL)
+		return NULL;
+
+	sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+	pbo = sub_pixmap_priv ? (sub_pixmap_priv->fbo ? sub_pixmap_priv->fbo->pbo : 0): 0;
+
+	if (pbo)
+		data = NULL;
+	else {
+		data = sub_pixmap->devPrivate.ptr;
+		assert(flag != GLAMOR_CREATE_PIXMAP_MAP);
+	}
+	data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
+						 data, pbo, access);
+	if (pbo) {
+		assert(sub_pixmap->devPrivate.ptr == NULL);
+		sub_pixmap->devPrivate.ptr = data;
+		sub_pixmap_priv->fbo->pbo_valid = 1;
+	}
+#if 0
+	struct pixman_box16 box;
+	PixmapPtr new_sub_pixmap;
+	int dx, dy;
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = w;
+	box.y2 = h;
+
+	dx = x;
+	dy = y;
+
+	new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+					      pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
+	glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
+	glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
+#endif
+
+	return sub_pixmap;
+}
+
+PixmapPtr
+glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+{
+	struct pixman_box16 box;
+	int dx, dy;
+	box.x1 = x;
+	box.y1 = y;
+	box.x2 = x + w;
+	box.y2 = y + h;
+
+	dx = -(x);
+	dy = -(y);
+
+	glamor_copy_n_to_n(&sub_pixmap->drawable,
+			   &pixmap->drawable,
+			   NULL, &box, 1, dx, dy,
+			   0, 0, 0, NULL);
+	glamor_destroy_pixmap(sub_pixmap);
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3e13ef8..8a6beee 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -145,8 +145,8 @@ enum glamor_gl_flavor {
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
 #define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
-
 #define GLAMOR_CREATE_FBO_NO_FBO   0x103
+#define GLAMOR_CREATE_PIXMAP_MAP 0x104
 
 #define GLAMOR_CREATE_TEXTURE_EXACT_SIZE 0x104
 
@@ -615,15 +615,16 @@ Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
  * must be 1.
  **/
 void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
+
 /**
- * Ensure to have a fbo has a valid/complete glfbo.
+ * According to the flag,
+ * if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure
+ * the fbo has a valid texture. Otherwise, it will ensure
+ * the fbo has valid texture and attach to a valid fb.
  * If the fbo already has a valid glfbo then do nothing.
- * Otherwise, it will generate a new glfbo, and bind
- * the fbo's texture to the glfbo.
- * The fbo must has a valid texture before call this
- * API, othersie, it will trigger a assert.
  */
-void glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo);
+Bool
+glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
@@ -633,6 +634,16 @@ void glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo);
 enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
 							  pixmap);
 
+
+PixmapPtr
+glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
+		      int w, int h, glamor_access_t access);
+
+PixmapPtr
+glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
+		      int w, int h, glamor_access_t access);
+
+
 /**
  * Upload a picture to gl texture. Similar to the
  * glamor_upload_pixmap_to_texture. Used in rendering.
commit d9dfc3d795b7e567d53cfeed61126164be36e233
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Apr 9 16:39:42 2012 +0800

    glamor_download_sub_pixmap_to_cpu: New function to download subregion.
    
    Prepare to optimize the fallback path. We choose the important
    rendering pathes to optimzie it by using shader. For other pathes,
    we have to fallback. We may continue to optimize more pathes in
    the future, but now we have to face those fallbacks.
    
    The original fallback is very slow and will download/upload the whole
    pixmap. From this commit, I will refine it to just download/upload
    needed part.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index bab91af..02b311a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -867,34 +867,50 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
 	return temp_fbo;
 }
 
-/**
- * Move a pixmap to CPU memory.
- * The input data is the pixmap's fbo.
- * The output data is at pixmap->devPrivate.ptr. We always use pbo
- * to read the fbo and then map it to va. If possible, we will use
- * it directly as devPrivate.ptr.
- * If successfully download a fbo to cpu then return TRUE.
- * Otherwise return FALSE.
- **/
-Bool
-glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
+/*
+ * Download a sub region of pixmap to a specified memory region.
+ * The pixmap must have a valid FBO, otherwise return a NULL.
+ * */
+
+void *
+glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
+				  int stride, void *bits, int pbo, glamor_access_t access)
 {
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	unsigned int stride, row_length, y;
+	glamor_pixmap_private *pixmap_priv;
+	unsigned int row_length;
 	GLenum format, type, gl_access, gl_usage;
 	int no_alpha, revert, swap_rb;
-	uint8_t *data = NULL, *read;
+	void *data, *read;
 	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *temp_fbo = NULL;
 	int need_post_conversion = 0;
+	int need_free_data = 0;
 
+	data = bits;
 	screen = pixmap->drawable.pScreen;
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return TRUE;
+		return NULL;
+
+	switch (access) {
+	case GLAMOR_ACCESS_RO:
+		gl_access = GL_READ_ONLY;
+		gl_usage = GL_STREAM_READ;
+		break;
+	case GLAMOR_ACCESS_WO:
+		return bits;
+	case GLAMOR_ACCESS_RW:
+		gl_access = GL_READ_WRITE;
+		gl_usage = GL_DYNAMIC_DRAW;
+		break;
+	default:
+		ErrorF("Glamor: Invalid access code. %d\n", access);
+		assert(0);
+	}
+
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
 						   &type,
@@ -904,64 +920,44 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		ErrorF("Unknown pixmap depth %d.\n",
 		       pixmap->drawable.depth);
 		assert(0);	// Should never happen.
-		return FALSE;
+		return NULL;
 	}
 
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
-			    "Downloading pixmap %p  %dx%d depth%d\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
-
-	stride = pixmap->devKind;
-
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	/* XXX we may don't need to validate it on GPU here,
 	 * we can just validate it on CPU. */
 	glamor_validate_pixmap(pixmap);
 
-
 	need_post_conversion = (revert > REVERT_NORMAL);
+	if (need_post_conversion) {
+		if (pixmap->drawable.depth == 1) {
+			stride = (((w * 8 + 7) / 8) + 3) & ~3;
+			data = malloc(stride * h);
+			if (data == NULL)
+				return NULL;
+			need_free_data = 1;
+		}
+	}
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
 	    && !need_post_conversion
 	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
-		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, 0, 0,
-								 pixmap->drawable.width, pixmap->drawable.height, format,
-								 type, no_alpha,
+		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
+								 format, type, no_alpha,
 								 revert, swap_rb)))
-			return FALSE;
-	}
-	switch (access) {
-	case GLAMOR_ACCESS_RO:
-		gl_access = GL_READ_ONLY;
-		gl_usage = GL_STREAM_READ;
-		break;
-	case GLAMOR_ACCESS_WO:
-		data = malloc(stride * pixmap->drawable.height);
-		goto done;
-		break;
-	case GLAMOR_ACCESS_RW:
-		gl_access = GL_READ_WRITE;
-		gl_usage = GL_DYNAMIC_DRAW;
-		break;
-	default:
-		ErrorF("Glamor: Invalid access code. %d\n", access);
-		assert(0);
+			return NULL;
+		x = 0;
+		y = 0;
 	}
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		data = malloc(stride * pixmap->drawable.height);
-	}
-	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
 	} else {
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-		//  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
 	}
 	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
 
@@ -971,66 +967,50 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
 		}
 
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-			if (pixmap_priv->fbo->pbo == 0)
-				dispatch->glGenBuffers(1,
-						       &pixmap_priv->fbo->pbo);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->fbo->pbo);
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
+			assert(pbo > 0);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
 			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
 					       stride *
-					       pixmap->drawable.height,
+					       h,
 					       NULL, gl_usage);
-			dispatch->glReadPixels(0, 0, row_length,
-					       pixmap->drawable.height,
-					       format, type, 0);
-			data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-						     gl_access);
-			pixmap_priv->fbo->pbo_valid = TRUE;
-
-			if (!glamor_priv->yInverted) {
-				assert(glamor_priv->gl_flavor ==
-				       GLAMOR_GL_DESKTOP);
-				dispatch->glPixelStorei
-				    (GL_PACK_INVERT_MESA, 0);
-			}
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+		}
 
-		} else {
-			dispatch->glReadPixels(0, 0,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height,
-					       format, type, data);
+		dispatch->glReadPixels(x, y, w, h, format, type, data);
+
+		if (!glamor_priv->yInverted) {
+			assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
 		}
-	} else {
-		data = malloc(stride * pixmap->drawable.height);
-		assert(data);
-		if (access != GLAMOR_ACCESS_WO) {
-			if (pixmap_priv->fbo->pbo == 0)
-				dispatch->glGenBuffers(1,
-						       &pixmap_priv->fbo->pbo);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->fbo->pbo);
-			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-					       stride *
-					       pixmap->drawable.height,
-					       NULL, GL_STREAM_READ);
-			dispatch->glReadPixels(0, 0, row_length,
-					       pixmap->drawable.height,
-					       format, type, 0);
-			read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-						     GL_READ_ONLY);
-
-			for (y = 0; y < pixmap->drawable.height; y++)
-				memcpy(data + y * stride,
-				       read + (pixmap->drawable.height -
-					       y - 1) * stride, stride);
-			dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
+			bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+						     gl_access);
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-			pixmap_priv->fbo->pbo_valid = FALSE;
-			dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
-			pixmap_priv->fbo->pbo = 0;
 		}
+	} else {
+		int temp_pbo;
+		int yy;
+
+		dispatch = glamor_get_dispatch(glamor_priv);
+		dispatch->glGenBuffers(1, &temp_pbo);
+		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
+				       temp_pbo);
+		dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+				       stride *
+				       pixmap->drawable.height,
+				       NULL, GL_STREAM_READ);
+		dispatch->glReadPixels(0, 0, row_length,
+				       pixmap->drawable.height,
+				       format, type, 0);
+		read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+					     GL_READ_ONLY);
+		for (yy = 0; yy < pixmap->drawable.height; yy++)
+			memcpy(data + yy * stride,
+			       read + (pixmap->drawable.height -
+			       yy - 1) * stride, stride);
+		dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+		dispatch->glDeleteBuffers(1, &temp_pbo);
 	}
 
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -1039,27 +1019,94 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	if (need_post_conversion) {
 		/* As OpenGL desktop version never enters here.
 		 * Don't need to consider if the pbo is valid.*/
-		int stride;
-		assert(pixmap_priv->fbo->pbo_valid == 0);
-
-		/* Only A1 <--> A8 conversion need to adjust the stride value. */
-		if (pixmap->drawable.depth == 1)
-			stride = (((pixmap->drawable.width * 8 + 7) / 8) + 3) & ~3;
-		else
-			stride = pixmap->devKind;
-		glamor_color_convert_to_bits(data, data, pixmap->drawable.width,
-					     pixmap->drawable.height,
-					     stride, no_alpha,
-					     revert, swap_rb);
+		bits = glamor_color_convert_to_bits(data, bits,
+						    w, h,
+						    stride, no_alpha,
+						    revert, swap_rb);
 	}
 
       done:
 
-	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
-	pixmap->devPrivate.ptr = data;
-
 	if (temp_fbo != NULL)
 		glamor_destroy_fbo(temp_fbo);
+	if (need_free_data)
+		free(data);
+
+	return bits;
+}
+
+
+/**
+ * Move a pixmap to CPU memory.
+ * The input data is the pixmap's fbo.
+ * The output data is at pixmap->devPrivate.ptr. We always use pbo
+ * to read the fbo and then map it to va. If possible, we will use
+ * it directly as devPrivate.ptr.
+ * If successfully download a fbo to cpu then return TRUE.
+ * Otherwise return FALSE.
+ **/
+Bool
+glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
+{
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	unsigned int stride, row_length, y;
+	GLenum format, type, gl_access, gl_usage;
+	int no_alpha, revert, swap_rb;
+	void *data = NULL, *dst;
+	ScreenPtr screen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch;
+	int pbo = 0;
+
+	screen = pixmap->drawable.pScreen;
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return TRUE;
+
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+			    "Downloading pixmap %p  %dx%d depth%d\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+
+	stride = pixmap->devKind;
+
+	if (access == GLAMOR_ACCESS_WO
+	    || glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)) {
+		data = malloc(stride * pixmap->drawable.height);
+	} else {
+		dispatch = glamor_get_dispatch(glamor_priv);
+		if (pixmap_priv->fbo->pbo == 0)
+			dispatch->glGenBuffers(1,
+					       &pixmap_priv->fbo->pbo);
+		glamor_put_dispatch(glamor_priv);
+		pbo = pixmap_priv->fbo->pbo;
+		glamor_put_dispatch(glamor_priv);
+	}
+
+	dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
+						pixmap->drawable.width,
+						pixmap->drawable.height,
+						pixmap->devKind,
+						data, pbo, access);
+
+	if (!dst) {
+		if (data)
+			free(data);
+		return FALSE;
+	}
+
+	if (pbo != 0)
+		pixmap_priv->fbo->pbo_valid = 1;
+
+	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
+
+      done:
+
+	pixmap->devPrivate.ptr = dst;
 
 	return TRUE;
 }
commit d96226ac6f34aa61fc00ad15ef58c1ed1253160e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Apr 9 15:57:05 2012 +0800

    glamor_es2_pixmap_read_prepare: Just prepare the required region.
    
    Don't need to prepare the whole source pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 3aabaa5..15ee89d 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -81,20 +81,25 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
+	x += drawable->x + x_off;
+	y += drawable->y + y_off;
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
 	    && ( swap_rb != SWAP_NONE_DOWNLOADING
 		 || revert != REVERT_NONE)) {
-		/* XXX prepare whole pixmap is not efficient. */
 		temp_fbo =
-		    glamor_es2_pixmap_read_prepare(pixmap, tex_format,
+		    glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h, tex_format,
 						   tex_type, no_alpha,
 						   revert, swap_rb);
-		if (temp_fbo == NULL)
+		if (temp_fbo == NULL) {
+			x -= (drawable->x + x_off);
+			y -= (drawable->y + y_off);
 			goto fall_back;
-
+		}
+		x = 0;
+		y = 0;
 	}
 
-
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		int row_length = PixmapBytePad(w, drawable->depth);
@@ -105,9 +110,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
 	}
 
-	x += drawable->x + x_off;
-	y += drawable->y + y_off;
-
 	if (glamor_priv->yInverted)
 		dispatch->glReadPixels(x,
 				       y,
@@ -124,7 +126,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	glamor_put_dispatch(glamor_priv);
 	if (temp_fbo)
 		glamor_destroy_fbo(temp_fbo);
-
 	ret = TRUE;
 
 fall_back:
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 8341df4..bd6a5ec 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -73,7 +73,7 @@ _glamor_get_spans(DrawablePtr drawable,
 
 		/* XXX prepare whole pixmap is not efficient. */
 		temp_fbo =
-		    glamor_es2_pixmap_read_prepare(pixmap, format,
+		    glamor_es2_pixmap_read_prepare(pixmap, 0, 0, pixmap->drawable.width, pixmap->drawable.height, format,
 						   type, no_alpha,
 						   revert, swap_rb);
 		if (temp_fbo == NULL)
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index de87740..bab91af 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -788,7 +788,7 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
  * */
 
 glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
+glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format,
 			       GLenum type, int no_alpha, int revert, int swap_rb)
 
 {
@@ -806,8 +806,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 	glamor_priv = glamor_get_screen_private(screen);
 	source_priv = glamor_get_pixmap_private(source);
 	temp_fbo = glamor_create_fbo(glamor_priv,
-				     source->drawable.width,
-				     source->drawable.height,
+				     w, h,
 				     format,
 				     0);
 	if (temp_fbo == NULL)
@@ -820,7 +819,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 	glamor_set_normalize_vcoords(temp_xscale,
 				     temp_yscale,
 				     0, 0,
-				     source->drawable.width, source->drawable.height,
+				     w, h,
 				     glamor_priv->yInverted,
 				     vertices);
 
@@ -832,8 +831,8 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 	pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
 	glamor_set_normalize_tcoords(source_xscale,
 				     source_yscale,
-				     0, 0,
-				     source->drawable.width, source->drawable.height,
+				     x, y,
+				     x + w, y + h,
 				     glamor_priv->yInverted,
 				     texcoords);
 
@@ -928,7 +927,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
 	    && !need_post_conversion
 	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
-		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, format,
+		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, 0, 0,
+								 pixmap->drawable.width, pixmap->drawable.height, format,
 								 type, no_alpha,
 								 revert, swap_rb)))
 			return FALSE;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index bea4f66..3e13ef8 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -465,7 +465,7 @@ void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *
 					   pixmap_priv);
 
 glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
+glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format,
 			       GLenum type, int no_alpha, int revert, int swap_rb);
 
 Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch,
commit 3dbdd40c6ce4203619f2a3492029a444bb9217af
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Apr 9 10:00:57 2012 +0800

    glamor_color_convert: Let the caller to provide destination buffer.
    
    As we don't need to allocate new buffer when downloading pixmap
    to CPU, we change the prototype of the color converting function
    and let the caller to provide the buffer to hold the result.
    
    All the color conversion function supports store the result
    just at the same place of the source.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 066d9a7..de87740 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -211,7 +211,7 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 }
 
 void *
-_glamor_color_convert_a1_a8(void *src_bits, int w, int h, int stride, int revert)
+_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert)
 {
 	void *bits;
 	PictFormatShort dst_format, src_format;
@@ -226,12 +226,9 @@ _glamor_color_convert_a1_a8(void *src_bits, int w, int h, int stride, int revert
 		src_format = PICT_a8;
 	}
 
-	bits = malloc(stride * h);
-	if (bits == NULL)
-		return NULL;
 	dst_image = pixman_image_create_bits(dst_format,
 					     w, h,
-					     bits,
+					     dst_bits,
 					     stride);
 	if (dst_image == NULL) {
 		free(bits);
@@ -255,7 +252,7 @@ _glamor_color_convert_a1_a8(void *src_bits, int w, int h, int stride, int revert
 
 	pixman_image_unref(src_image);
 	pixman_image_unref(dst_image);
-	return bits;
+	return dst_bits;
 }
 
 #define ADJUST_BITS(d, src_bits, dst_bits)	(((dst_bits) == (src_bits)) ? (d) : 				\
@@ -298,16 +295,14 @@ _glamor_color_convert_a1_a8(void *src_bits, int w, int h, int stride, int revert
 	}
 
 void *
-_glamor_color_revert_x2b10g10r10(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	int x,y;
 	unsigned int *words, *saved_words, *source_words;
 	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
 
-	words = malloc(stride * h);
 	source_words = src_bits;
-	if (words == NULL)
-		return NULL;
+	words = dst_bits;
 	saved_words = words;
 
 	for (y = 0; y < h; y++)
@@ -337,16 +332,14 @@ _glamor_color_revert_x2b10g10r10(void *src_bits, int w, int h, int stride, int n
 }
 
 void *
-_glamor_color_revert_x1b5g5r5(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	int x,y;
 	unsigned short *words, *saved_words, *source_words;
 	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
 
-	words = malloc(stride * h);
+	words = dst_bits;
 	source_words = src_bits;
-	if (words == NULL)
-		return NULL;
 	saved_words = words;
 
 	for (y = 0; y < h; y++)
@@ -393,14 +386,14 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, int w, int h, int stride, int no_a
  */
 
 void *
-glamor_color_convert_to_bits(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
 {
 	if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
-		return _glamor_color_convert_a1_a8(src_bits, w, h, stride, revert);
+		return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride, revert);
 	} else if (revert == REVERT_DOWNLOADING_2_10_10_10 || revert == REVERT_UPLOADING_2_10_10_10) {
-		return _glamor_color_revert_x2b10g10r10(src_bits, w, h, stride, no_alpha, revert, swap_rb);
+		return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
 	} else if (revert == REVERT_DOWNLOADING_1_5_5_5 || revert == REVERT_UPLOADING_1_5_5_5) {
-		return _glamor_color_revert_x1b5g5r5(src_bits, w, h, stride, no_alpha, revert, swap_rb);
+		return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
 	} else
 		ErrorF("convert a non-supported mode %x.\n", revert);
 
@@ -501,7 +494,12 @@ glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum typ
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
 	    &&  revert > REVERT_NORMAL) {
-		bits = glamor_color_convert_to_bits(bits, pixmap->drawable.width,
+		/* XXX if we are restoring the pixmap, then we may not need to allocate
+		 * new buffer */
+		void *converted_bits = malloc(pixmap->drawable.height * pixmap->devKind);
+		if (converted_bits == NULL)
+			return FALSE;
+		bits = glamor_color_convert_to_bits(bits, converted_bits, pixmap->drawable.width,
 						    pixmap->drawable.height,
 						    pixmap->devKind,
 						    no_alpha, revert, swap_rb);
@@ -1041,7 +1039,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	if (need_post_conversion) {
 		/* As OpenGL desktop version never enters here.
 		 * Don't need to consider if the pbo is valid.*/
-		char *new_data;
 		int stride;
 		assert(pixmap_priv->fbo->pbo_valid == 0);
 
@@ -1050,15 +1047,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 			stride = (((pixmap->drawable.width * 8 + 7) / 8) + 3) & ~3;
 		else
 			stride = pixmap->devKind;
-		new_data = glamor_color_convert_to_bits(data, pixmap->drawable.width,
-							pixmap->drawable.height,
-							stride, no_alpha,
-							revert, swap_rb);
-		free(data);
-		if (new_data == NULL) {
-			return FALSE;
-		}
-		data = new_data;
+		glamor_color_convert_to_bits(data, data, pixmap->drawable.width,
+					     pixmap->drawable.height,
+					     stride, no_alpha,
+					     revert, swap_rb);
 	}
 
       done:
commit 4dc6d4e84b4904540d7701cfc88a9c945464f833
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 21:20:15 2012 +0800

    glyphblt/polyops: Use miFunctions by default.
    
    Calling to miFunctions give some opportunities to jump to
    accelerated path, so we switch to call miFunctions rather
    than fallback to fbFunctions directly.

diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 1630998..18ad536 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -38,17 +38,10 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
-		goto fail;
-
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-	glamor_prepare_access_gc(pGC);
-	fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-	glamor_finish_access_gc(pGC);
-	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+		return FALSE;
+
+	miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	return TRUE;
- fail:
-	return FALSE;
 }
 
 void
@@ -74,17 +67,12 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 {
 	glamor_screen_private *glamor_priv;
 
-	if (!fallback 
+	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
 		return FALSE;
 
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-	glamor_prepare_access_gc(pGC);
-	fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-	glamor_finish_access_gc(pGC);
-	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	return TRUE;
 }
 
@@ -108,19 +96,13 @@ static Bool
 _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 		    DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback)
 {
-	if (!fallback 
+	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
 		return FALSE;
 
-	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-	glamor_prepare_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
-	glamor_prepare_access_gc(pGC);
-	fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
-	glamor_finish_access_gc(pGC);
-	glamor_finish_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
-	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
index 7320c17..5930178 100644
--- a/glamor/glamor_polyops.c
+++ b/glamor/glamor_polyops.c
@@ -37,11 +37,8 @@ _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
 		return FALSE;
 
-	glamor_prepare_access_gc(pGC);
-	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-	fbPolyPoint(pDrawable, pGC, mode, npt, ppt);
-	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-	glamor_finish_access_gc(pGC);
+	miPolyPoint(pDrawable, pGC, mode, npt, ppt);
+
 	return TRUE;
 }
 
@@ -68,15 +65,7 @@ _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
 		return FALSE;
 
-	/* For lineWidth is not zero, fb calls to mi functions. */
-	if (pGC->lineWidth == 0) {
-		glamor_prepare_access_gc(pGC);
-		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-		fbPolySegment(pDrawable, pGC, nseg, pSeg);
-		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-		glamor_finish_access_gc(pGC);
-	} else
-		fbPolySegment(pDrawable, pGC, nseg, pSeg);
+	miPolySegment(pDrawable, pGC, nseg, pSeg);
 
 	return TRUE;
 }
@@ -94,40 +83,3 @@ glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 {
 	return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
 }
-
-static Bool
-_glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		  DDXPointPtr ppt, Bool fallback)
-{
-	if (!fallback 
-	    && glamor_ddx_fallback_check_gc(pGC)
-	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		return FALSE;
-	/* For lineWidth is not zero, fb calls to mi functions. */
-
-	if (pGC->lineWidth == 0) {
-		glamor_prepare_access_gc(pGC);
-		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
-		fbPolyLine(pDrawable, pGC, mode, npt, ppt);
-		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-		glamor_finish_access_gc(pGC);
-	} else
-		fbPolyLine(pDrawable, pGC, mode, npt, ppt);
-
-	return TRUE;
-}
-
-void
-glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		 DDXPointPtr ppt)
-{
-	_glamor_poly_line(pDrawable, pGC, mode, npt, ppt, TRUE);
-}
-
-Bool
-glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
-		    DDXPointPtr ppt)
-{
-	return _glamor_poly_line(pDrawable, pGC, mode, npt, ppt, FALSE);
-}
-
commit 49e3b44aa813c98c05fcb10c19882e10d751580a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 21:17:46 2012 +0800

    glamor_set_alu: Added GXclear support at glamor_solid.
    
    We don't need to issue the glamor_fallback at the glamor_set_alu
    routine, as the caller may support GXclear or other most frequent
    Ops. Leave it to the caller to determine fallback or not.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 53c750a..4cee485 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -190,8 +190,13 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (!glamor_set_alu(dispatch, alu)) {
-		glamor_put_dispatch(glamor_priv);
-		return FALSE;
+		if (alu == GXclear)
+			color[0] = color[1] = color[2] = color[3] = 0.0;
+		else {
+			glamor_fallback("unsupported alu %x\n", alu);
+			glamor_put_dispatch(glamor_priv);
+			return FALSE;
+		}
 	}
 	dispatch->glUseProgram(glamor_priv->solid_prog);
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 35b2d56..066d9a7 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -204,10 +204,8 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 		return FALSE;
 	}
 #else
-	if (alu != GXcopy) {
-		glamor_fallback("unsupported alu %x\n", alu);
+	if (alu != GXcopy)
 		return FALSE;
-	}
 #endif
 	return TRUE;
 }
@@ -872,7 +870,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 	return temp_fbo;
 }
 
-
 /**
  * Move a pixmap to CPU memory.
  * The input data is the pixmap's fbo.
commit 3b8b2c77fc4449c7b63fd2597f73562b33dc1722
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 21:15:12 2012 +0800

    getimage: Enable getimage by default.
    
    Fixed one bug when calculate the coords, should consider the
    drawable's x and y. Now enable it by default. Most of the time,
    it should be more efficient than miGetImage.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index b1093e8..3aabaa5 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -45,14 +45,13 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	Bool ret = FALSE;
 	int swap_rb;
 
-	goto fall_back;
-
-	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-
 	if (format != ZPixmap)
 		goto fall_back;
 
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
 	if (!glamor_set_planemask(pixmap, planeMask)) {
 		glamor_fallback
 		    ("Failedto set planemask  in glamor_solid.\n");
@@ -64,7 +63,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		goto fall_back;
-	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &tex_format,
@@ -77,6 +75,9 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 		goto fall_back;
 	}
 
+	if (revert > REVERT_NORMAL)
+		goto fall_back;
+
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
@@ -93,26 +94,29 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	}
 
-	int row_length = PixmapBytePad(w, drawable->depth);
-	row_length = (row_length * 8) / drawable->bitsPerPixel;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		int row_length = PixmapBytePad(w, drawable->depth);
+		row_length = (row_length * 8) / drawable->bitsPerPixel;
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
 	} else {
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
 	}
 
+	x += drawable->x + x_off;
+	y += drawable->y + y_off;
+
 	if (glamor_priv->yInverted)
-		dispatch->glReadPixels(x + x_off,
-				       y + y_off,
+		dispatch->glReadPixels(x,
+				       y,
 				       w, h,
 				       tex_format,
 				       tex_type, d);
 	else
-		dispatch->glReadPixels(x + x_off,
-				       pixmap->drawable.height - 1 - (y + y_off),
+		dispatch->glReadPixels(x,
+				       pixmap->drawable.height - 1 - y,
 				       w,
 				       h,
 				       tex_format,
commit c6ce44d88134115b42edc76e1ee961b57bae86ff
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 17:01:57 2012 +0800

    render: Enable more componentAlpha support.
    
    Actually only PictOpAtop,PictOpAtopReverse and PictOpXor
    can't be implemented by using single source blending.
    All the other can be easily support. Slightly change
    the code to support them. Consider those three Ops
    are not frequenly used in real application. We simply
    fallback them currently.
    
    PictOpAtop: 		s*mask*dst.a + (1 - s.a*mask)*dst
    PictOpAtopReverse: 	s*mask*(1 - dst.a) + dst *s.a*mask
    PictOpXor:		s*mask*(1 - dst.a) + dst * (1 - s.a*mask)
    
    The two oprands in the above three ops are all reated to dst and
    the blend factors are not constant (0 or 1), it's hardly to
    convert it to single source blend.
    
    Now, the rendercheck is runing more smoothly.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 00a6e1e..9410adf 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -461,11 +461,6 @@ glamor_set_composite_op(ScreenPtr screen,
 	if (mask && mask->componentAlpha
 	    && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha)
 	{
-		if (source_blend != GL_ZERO) {
-			glamor_fallback
-			    ("Dual-source composite blending not supported\n");
-			return GL_FALSE;
-		}
 		if (dest_blend == GL_SRC_ALPHA)
 			dest_blend = GL_SRC_COLOR;
 		else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
@@ -954,15 +949,17 @@ glamor_composite_with_shader(CARD8 op,
 		if (!mask->componentAlpha) {
 			key.in = SHADER_IN_NORMAL;
 		} else {
-			/* We only handle two CA modes. */
-			if (op == PictOpAdd)
+			if (op == PictOpClear)
+				key.mask = SHADER_MASK_NONE;
+			else if (op == PictOpSrc || op == PictOpAdd
+				 || op == PictOpIn || op == PictOpOut
+				 || op == PictOpOverReverse)
 				key.in = SHADER_IN_CA_SOURCE;
-			else if (op == PictOpOutReverse) {
+			else if (op == PictOpOutReverse || op == PictOpInReverse) {
 				key.in = SHADER_IN_CA_ALPHA;
 			} else {
 				glamor_fallback
-				    ("Unsupported component alpha op: %d\n",
-				     op);
+				    ("Unsupported component alpha op: %d\n", op);
 				goto fail;
 			}
 		}
@@ -2911,10 +2908,13 @@ _glamor_composite(CARD8 op,
 					 x_dest, y_dest, width, height);
 			goto done;
 
-		} else if (op != PictOpAdd && op != PictOpOutReverse) {
-			glamor_fallback
-			    ("glamor_composite(): component alpha\n");
-			goto fail;
+		} else if (op == PictOpAtop
+			   || op == PictOpAtopReverse
+			   || op == PictOpXor
+			   || op >= PictOpSaturate) {
+				glamor_fallback
+					("glamor_composite(): component alpha op %x\n", op);
+				goto fail;
 		}
 	}
 	if (!mask) {
commit 3e9c35bdcbdb96a67c9f2a1ea76c382aaacca7e9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 11:02:36 2012 +0800

    glamor_set_alu: Fallback for non GXcopy ops with GLES2.
    
    As GLES2 doesn't support LogiOps, we have to fallback
    here. GLES2 programing guide's statement is as below:
    
    "In addition, LogicOp is removed as it is very
    infrequently used by applications and the OpenGL ES
    working group did not get requests from independent
    software vendors (ISVs) to support this feature in
    OpenGL ES 2.0."
    
    So, I think, fallback here may not a big deal ;).
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index b488037..a373d3d 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -194,7 +194,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 
-	glamor_set_alu(dispatch, alu);
+	if (!glamor_set_alu(dispatch, alu)) {
+		glamor_put_dispatch(glamor_priv);
+		return FALSE;
+	}
+
 	if (alu != GXcopy) {
 		glamor_set_destination_pixmap_priv_nc (src_pixmap_priv);
 		glamor_validate_pixmap(src_pixmap);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index e8419c6..53c750a 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -189,7 +189,10 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	glamor_validate_pixmap(pixmap);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_set_alu(dispatch, alu);
+	if (!glamor_set_alu(dispatch, alu)) {
+		glamor_put_dispatch(glamor_priv);
+		return FALSE;
+	}
 	dispatch->glUseProgram(glamor_priv->solid_prog);
 
 	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 4e8d6b8..35b2d56 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -144,15 +144,13 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 	return GL_FALSE;
 }
 
-
-
-void
+Bool
 glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 {
 #ifndef GLAMOR_GLES2
 	if (alu == GXcopy) {
 		dispatch->glDisable(GL_COLOR_LOGIC_OP);
-		return;
+		return TRUE;
 	}
 	dispatch->glEnable(GL_COLOR_LOGIC_OP);
 	switch (alu) {
@@ -202,12 +200,16 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 		dispatch->glLogicOp(GL_SET);
 		break;
 	default:
-		FatalError("unknown logic op\n");
+		glamor_fallback("unsupported alu %x\n", alu);
+		return FALSE;
 	}
 #else
-	if (alu != GXcopy)
-		ErrorF("unsupported alu %x \n", alu);
+	if (alu != GXcopy) {
+		glamor_fallback("unsupported alu %x\n", alu);
+		return FALSE;
+	}
 #endif
+	return TRUE;
 }
 
 void *
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 71d5bf0..bea4f66 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -468,7 +468,7 @@ glamor_pixmap_fbo *
 glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 			       GLenum type, int no_alpha, int revert, int swap_rb);
 
-void glamor_set_alu(struct glamor_gl_dispatch *dispatch,
+Bool glamor_set_alu(struct glamor_gl_dispatch *dispatch,
 		    unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index d270cae..010950e 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -321,7 +321,11 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_set_alu(dispatch, gc->alu);
+	if (!glamor_set_alu(dispatch, gc->alu)) {
+		glamor_put_dispatch(glamor_priv);
+		goto fail;
+	}
+
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index b6847a9..c5ecf85 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -75,7 +75,11 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_set_alu(dispatch, gc->alu);
+	if (!glamor_set_alu(dispatch, gc->alu)) {
+		glamor_put_dispatch(glamor_priv);
+		goto fail;
+	}
+
 	for (i = 0; i < n; i++) {
 
 		n = REGION_NUM_RECTS(clip);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index aa62d09..be873cc 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -162,7 +162,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	glamor_set_alu(dispatch, alu);
+	if (!glamor_set_alu(dispatch, alu)) {
+		glamor_put_dispatch(glamor_priv);
+		goto fail;
+	}
 
 	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
 		pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
commit 1a238e89f39fd5aeaf6975399971123cd3e15f24
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 5 22:39:41 2012 +0800

    glamor_putimage: Reuse the function in pixmap.c to do the uploading.
    
    We reuse glamor_upload_bits_to_pixmap_texture to do the
    data uploading to texture in putimage. Besides to avoid
    duplicate code, this also fixed the potential problem
    when the data format need extra reversion which is not
    supported by the finish shader, as
    glamor_upload_bits_to_pixmap_texture will handle all
    conditions.
    
    Tested-by: Junyan He <junyan.he at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index e38c45a..d270cae 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -267,6 +267,8 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	int no_alpha, revert;
 	Bool ret = FALSE;
 	int swap_rb;
+	PixmapPtr temp_pixmap;
+	glamor_pixmap_private *temp_pixmap_priv;
 
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
@@ -297,7 +299,27 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		goto fail;
 	}
 
-	/* XXX consider to reuse a function to do the following work. */
+	/* create a temporary pixmap and upload the bits to that
+	 * pixmap, then apply clip copy it to the destination pixmap.*/
+
+	temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
+
+	if (temp_pixmap == NULL)
+		goto fail;
+	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+
+	if (temp_pixmap_priv->fbo == NULL) {
+		glamor_destroy_pixmap(temp_pixmap);
+		goto fail;
+	}
+
+	if (!glamor_upload_bits_to_pixmap_texture(temp_pixmap, format, type,
+						  no_alpha, revert, swap_rb, bits)) {
+		glamor_destroy_pixmap(temp_pixmap);
+		goto fail;
+	}
+
+
 	dispatch = glamor_get_dispatch(glamor_priv);
 	glamor_set_alu(dispatch, gc->alu);
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
@@ -311,43 +333,18 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 					GL_FALSE, 2 * sizeof(float),
 					texcoords);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH,
-					src_stride * 8 /
-					pixmap->drawable.bitsPerPixel);
-	} else {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-	}
-
-	dispatch->glGenTextures(1, &tex);
 	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		iformat = format;
-	} else {
-		iformat = GL_RGBA;
-	}
-
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
-			       w, h, 0, format, type, bits);
-
+	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
 
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
 	dispatch->glUniform1i(glamor_priv->
 			      finish_access_revert[no_alpha],
-			      revert);
+			      REVERT_NONE);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      swap_rb);
+			      SWAP_NONE_UPLOADING);
 
 	x += drawable->x;
 	y += drawable->y;
@@ -355,8 +352,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 	clip = fbGetCompositeClip(gc);
 
-	txscale = 1.0 / w;
-	tyscale = 1.0 / h;
+	pixmap_priv_get_scale(temp_pixmap_priv, &txscale, &tyscale);
 	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
 
 	for (nbox = REGION_NUM_RECTS(clip),
@@ -404,6 +400,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	glamor_set_planemask(pixmap, ~0);
 	glamor_put_dispatch(glamor_priv);
 
+	glamor_destroy_pixmap(temp_pixmap);
 	ret = TRUE;
 	goto done;
 
commit 0650c7d4be6d4c21510c953543599aea32780f24
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 5 22:31:44 2012 +0800

    gles2: Added 1555/2101010 formats support.
    
    Added color conversion code to support 1555/2101010
    formats,now gles2 can pass the render check with all
    formats.
    
    We use  5551 to represent 1555, and do the revertion
    if downloading/uploading is needed.
    
    For 2101010, as gles2 doesn't support reading the
    identical formats. We have to use 8888 to represent,
    thus we may introduce some accurate problem. But anyway,
    we can pass the error checking in render check, so that
    may not be a big problem.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0570a9a..4e8d6b8 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -210,8 +210,202 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 #endif
 }
 
+void *
+_glamor_color_convert_a1_a8(void *src_bits, int w, int h, int stride, int revert)
+{
+	void *bits;
+	PictFormatShort dst_format, src_format;
+	pixman_image_t *dst_image;
+	pixman_image_t *src_image;
+
+	if (revert == REVERT_UPLOADING_A1) {
+		src_format = PICT_a1;
+		dst_format = PICT_a8;
+	} else {
+		dst_format = PICT_a1;
+		src_format = PICT_a8;
+	}
+
+	bits = malloc(stride * h);
+	if (bits == NULL)
+		return NULL;
+	dst_image = pixman_image_create_bits(dst_format,
+					     w, h,
+					     bits,
+					     stride);
+	if (dst_image == NULL) {
+		free(bits);
+		return NULL;
+	}
+
+	src_image = pixman_image_create_bits(src_format,
+					     w, h,
+					     src_bits,
+					     stride);
+
+	if (src_image == NULL) {
+		pixman_image_unref(dst_image);
+		free(bits);
+		return NULL;
+	}
+
+	pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
+			       0, 0, 0, 0, 0, 0,
+			       w,h);
+
+	pixman_image_unref(src_image);
+	pixman_image_unref(dst_image);
+	return bits;
+}
+
+#define ADJUST_BITS(d, src_bits, dst_bits)	(((dst_bits) == (src_bits)) ? (d) : 				\
+							(((dst_bits) > (src_bits)) ? 				\
+							  (((d) << ((dst_bits) - (src_bits))) 			\
+								   + (( 1 << ((dst_bits) - (src_bits))) >> 1))	\
+								:  ((d) >> ((src_bits) - (dst_bits)))))
+
+#define GLAMOR_DO_CONVERT(src, dst, no_alpha, swap,		\
+			  a_shift_src, a_bits_src,		\
+			  b_shift_src, b_bits_src,		\
+			  g_shift_src, g_bits_src,		\
+			  r_shift_src, r_bits_src,		\
+			  a_shift, a_bits,			\
+			  b_shift, b_bits,			\
+			  g_shift, g_bits,			\
+			  r_shift, r_bits)			\
+	{								\
+		typeof(src) a,b,g,r;					\
+		typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
+		a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
+		b_mask_src = (((1 << (b_bits_src)) - 1) << b_shift_src);\
+		g_mask_src = (((1 << (g_bits_src)) - 1) << g_shift_src);\
+		r_mask_src = (((1 << (r_bits_src)) - 1) << r_shift_src);\
+		if (no_alpha)						\
+			a = (a_mask_src) >> (a_shift_src);			\
+		else							\
+			a = ((src) & (a_mask_src)) >> (a_shift_src);	\
+		b = ((src) & (b_mask_src)) >> (b_shift_src);		\
+		g = ((src) & (g_mask_src)) >> (g_shift_src);		\
+		r = ((src) & (r_mask_src)) >> (r_shift_src);		\
+		a = ADJUST_BITS(a, a_bits_src, a_bits);			\
+		b = ADJUST_BITS(b, b_bits_src, b_bits);			\
+		g = ADJUST_BITS(g, g_bits_src, g_bits);			\
+		r = ADJUST_BITS(r, r_bits_src, r_bits);			\
+		if (swap == 0)						\
+			(*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
+		else 												    \
+			(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
+	}
+
+void *
+_glamor_color_revert_x2b10g10r10(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+{
+	int x,y;
+	unsigned int *words, *saved_words, *source_words;
+	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
+
+	words = malloc(stride * h);
+	source_words = src_bits;
+	if (words == NULL)
+		return NULL;
+	saved_words = words;
+
+	for (y = 0; y < h; y++)
+	{
+		DEBUGF("Line %d :  ", y);
+		for (x = 0; x < w; x++)
+		{
+			unsigned int pixel = source_words[x];
+
+			if (revert == REVERT_DOWNLOADING_2_10_10_10)
+				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+						  24, 8, 16, 8, 8, 8, 0, 8,
+						  30, 2, 20, 10, 10, 10, 0, 10)
+			else
+				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+						  30, 2, 20, 10, 10, 10, 0, 10,
+						  24, 8, 16, 8, 8, 8, 0, 8);
+			DEBUGF("%x:%x ", pixel, words[x]);
+		}
+		DEBUGF("\n");
+		words += stride / sizeof(*words);
+		source_words += stride / sizeof(*words);
+	}
+	DEBUGF("\n");
+	return saved_words;
+
+}
+
+void *
+_glamor_color_revert_x1b5g5r5(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+{
+	int x,y;
+	unsigned short *words, *saved_words, *source_words;
+	int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
+
+	words = malloc(stride * h);
+	source_words = src_bits;
+	if (words == NULL)
+		return NULL;
+	saved_words = words;
+
+	for (y = 0; y < h; y++)
+	{
+		DEBUGF("Line %d :  ", y);
+		for (x = 0; x < w; x++)
+		{
+			unsigned short pixel = source_words[x];
+
+			if (revert == REVERT_DOWNLOADING_1_5_5_5)
+				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+						  0, 1, 1, 5, 6, 5, 11, 5,
+						  15, 1, 10, 5, 5, 5, 0, 5)
+			else
+				GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+						  15, 1, 10, 5, 5, 5, 0, 5,
+						  0, 1, 1, 5, 6, 5, 11, 5);
+			DEBUGF("%04x:%04x ", pixel, words[x]);
+		}
+		DEBUGF("\n");
+		words += stride / sizeof(*words);
+		source_words += stride / sizeof(*words);
+	}
+	DEBUGF("\n");
+	return saved_words;
+}
 
+/*
+ * This function is to convert an unsupported color format to/from a
+ * supported GL format.
+ * Here are the current scenarios:
+ *
+ * @no_alpha:
+ * 	If it is set, then we need to wire the alpha value to 1.
+ * @revert:
+	REVERT_DOWNLOADING_A1		: convert an Alpha8 buffer to a A1 buffer.
+	REVERT_UPLOADING_A1		: convert an A1 buffer to an Alpha8 buffer
+	REVERT_DOWNLOADING_2_10_10_10 	: convert r10G10b10X2 to X2B10G10R10
+	REVERT_UPLOADING_2_10_10_10 	: convert X2B10G10R10 to R10G10B10X2
+	REVERT_DOWNLOADING_1_5_5_5  	: convert B5G5R5X1 to X1R5G5B5
+	REVERT_UPLOADING_1_5_5_5    	: convert X1R5G5B5 to B5G5R5X1
+   @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
+ *
+ */
+
+void *
+glamor_color_convert_to_bits(void *src_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+{
+	if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
+		return _glamor_color_convert_a1_a8(src_bits, w, h, stride, revert);
+	} else if (revert == REVERT_DOWNLOADING_2_10_10_10 || revert == REVERT_UPLOADING_2_10_10_10) {
+		return _glamor_color_revert_x2b10g10r10(src_bits, w, h, stride, no_alpha, revert, swap_rb);
+	} else if (revert == REVERT_DOWNLOADING_1_5_5_5 || revert == REVERT_UPLOADING_1_5_5_5) {
+		return _glamor_color_revert_x1b5g5r5(src_bits, w, h, stride, no_alpha, revert, swap_rb);
+	} else
+		ErrorF("convert a non-supported mode %x.\n", revert);
 
+	return NULL;
+}
 
 /**
  * Upload pixmap to a specified texture.
@@ -220,7 +414,8 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 int in_restore = 0;
 static void
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				  GLenum type, GLuint tex, int sub)
+				  GLenum type, GLuint tex, int sub,
+				  void *bits)
 {
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
@@ -228,7 +423,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	unsigned int stride, row_length;
-	void *texels;
 	GLenum iformat;
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
@@ -253,47 +447,35 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 	}
 
-	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid) {
-		texels = NULL;
+	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
 				       pixmap_priv->fbo->pbo);
-	} else
-		texels = pixmap->devPrivate.ptr;
 
 	if (sub)
 		dispatch->glTexSubImage2D(GL_TEXTURE_2D,
 				       0,0,0,
 				       pixmap->drawable.width,
 				       pixmap->drawable.height, format, type,
-				       texels);
+				       bits);
 	else
 		dispatch->glTexImage2D(GL_TEXTURE_2D,
 				       0,
 				       iformat,
 				       pixmap->drawable.width,
 				       pixmap->drawable.height, 0, format, type,
-				       texels);
+				       bits);
 
-	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid)
+	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 	glamor_put_dispatch(glamor_priv);
 }
 
-
-/* 
- * Load texture from the pixmap's data pointer and then
- * draw the texture to the fbo, and flip the y axis.
- * */
-
-static void
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
-				int no_alpha, int revert, int swap_rb)
+Bool
+glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
+				     int no_alpha, int revert, int swap_rb, void *bits)
 {
-
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	static float vertices[8];
 	static float texcoords[8] = { 0, 1,
@@ -310,28 +492,40 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 	float dst_xscale, dst_yscale;
 	GLuint tex;
 	int need_flip;
+	int need_free_bits = 0;
 
-	if (!pixmap_priv)
-		return;
 	need_flip = !glamor_priv->yInverted;
 
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
-			    "Uploading pixmap %p  %dx%d depth%d.\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
+	if (bits == NULL)
+		goto ready_to_upload;
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    &&  revert > REVERT_NORMAL) {
+		bits = glamor_color_convert_to_bits(bits, pixmap->drawable.width,
+						    pixmap->drawable.height,
+						    pixmap->devKind,
+						    no_alpha, revert, swap_rb);
+		if (bits == NULL) {
+			ErrorF("Failed to convert pixmap no_alpha %d, revert mode %d, swap mode %d\n", swap_rb);
+			return FALSE;
+		}
+		no_alpha = 0;
+		revert = REVERT_NONE;
+		swap_rb = SWAP_NONE_UPLOADING;
+		need_free_bits = TRUE;
+	}
 
+ready_to_upload:
 	/* Try fast path firstly, upload the pixmap to the texture attached
 	 * to the fbo directly. */
 	if (no_alpha == 0
 	    && revert == REVERT_NONE
 	    && swap_rb == SWAP_NONE_UPLOADING
 	    && !need_flip) {
-
 		__glamor_upload_pixmap_to_texture(pixmap, format, type,
-						  pixmap_priv->fbo->tex, 1);
-		return;
+						  pixmap_priv->fbo->tex, 1,
+						  bits);
+		return TRUE;
 	}
 
 	if (need_flip)
@@ -361,7 +555,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	dispatch->glGenTextures(1, &tex);
 
-	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex, 0);
+	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex, 0, bits);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 
@@ -391,6 +585,43 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
 	glamor_put_dispatch(glamor_priv);
+
+	if (need_free_bits)
+		free(bits);
+	return TRUE;
+}
+
+/*
+ * Load texture from the pixmap's data pointer and then
+ * draw the texture to the fbo, and flip the y axis.
+ * */
+
+static Bool
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
+				 GLenum type, int no_alpha, int revert,
+				 int swap_rb)
+{
+	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+	void *bits;
+	int need_free_bits = 0;
+
+	if (!pixmap_priv)
+		return TRUE;
+
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
+			    "Uploading pixmap %p  %dx%d depth%d.\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+
+	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid)
+		bits = NULL;
+
+	return glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha,
+						    revert, swap_rb,
+						    pixmap->devPrivate.ptr);
 }
 
 void
@@ -442,7 +673,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 	glamor_put_dispatch(fbo->glamor_priv);
 }
 
-/*  
+/*
  * Prepare to upload a pixmap to texture memory.
  * no_alpha equals 1 means the format needs to wire alpha to 1.
  * Two condtion need to setup a fbo for a pixmap
@@ -520,27 +751,14 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
 		return GLAMOR_UPLOAD_FAILED;
 
-	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 revert, swap_rb);
-	return GLAMOR_UPLOAD_DONE;
-}
-
-#if 0
-enum glamor_pixmap_status
-glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
-{
-	enum glamor_pixmap_status upload_status;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
+	if (_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					     revert, swap_rb))
+		return GLAMOR_UPLOAD_DONE;
+	else
+		return GLAMOR_UPLOAD_FAILED;
 
-	assert(pixmap_priv->pbo_valid == 0);
-	assert(pixmap->devPrivate.ptr == NULL);
-	pixmap->devPrivate.ptr = data;
-	upload_status = glamor_upload_pixmap_to_texture(pixmap);
-	pixmap->devPrivate.ptr = NULL;
-	return upload_status;
+	return GLAMOR_UPLOAD_DONE;
 }
-#endif
 
 void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
@@ -557,14 +775,16 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 		assert(0);
 	}
 
-	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 revert, swap_rb);
+	if (!_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					      revert, swap_rb))
+		LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n",
+			   pixmap->drawable.pScreen->myNum);
 }
 
-/* 
+/*
  * as gles2 only support a very small set of color format and
- * type when do glReadPixel,  
- * Before we use glReadPixels to get back a textured pixmap, 
+ * type when do glReadPixel,
+ * Before we use glReadPixels to get back a textured pixmap,
  * Use shader to convert it to a supported format and thus
  * get a new temporary pixmap returned.
  * */
@@ -654,7 +874,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
 /**
  * Move a pixmap to CPU memory.
  * The input data is the pixmap's fbo.
- * The output data is at pixmap->devPrivate.ptr. We always use pbo 
+ * The output data is at pixmap->devPrivate.ptr. We always use pbo
  * to read the fbo and then map it to va. If possible, we will use
  * it directly as devPrivate.ptr.
  * If successfully download a fbo to cpu then return TRUE.
@@ -674,6 +894,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *temp_fbo = NULL;
+	int need_post_conversion = 0;
 
 	screen = pixmap->drawable.pScreen;
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -704,7 +925,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	 * we can just validate it on CPU. */
 	glamor_validate_pixmap(pixmap);
 
+
+	need_post_conversion = (revert > REVERT_NORMAL);
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    && !need_post_conversion
 	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
 		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, format,
 								 type, no_alpha,
@@ -775,8 +1000,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 
 		} else {
-			if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
-				type = GL_UNSIGNED_SHORT_5_5_5_1;
 			dispatch->glReadPixels(0, 0,
 					       pixmap->drawable.width,
 					       pixmap->drawable.height,
@@ -815,6 +1038,30 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	glamor_put_dispatch(glamor_priv);
+
+	if (need_post_conversion) {
+		/* As OpenGL desktop version never enters here.
+		 * Don't need to consider if the pbo is valid.*/
+		char *new_data;
+		int stride;
+		assert(pixmap_priv->fbo->pbo_valid == 0);
+
+		/* Only A1 <--> A8 conversion need to adjust the stride value. */
+		if (pixmap->drawable.depth == 1)
+			stride = (((pixmap->drawable.width * 8 + 7) / 8) + 3) & ~3;
+		else
+			stride = pixmap->devKind;
+		new_data = glamor_color_convert_to_bits(data, pixmap->drawable.width,
+							pixmap->drawable.height,
+							stride, no_alpha,
+							revert, swap_rb);
+		free(data);
+		if (new_data == NULL) {
+			return FALSE;
+		}
+		data = new_data;
+	}
+
       done:
 
 	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 828b08e..71d5bf0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -633,7 +633,7 @@ void glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo);
 enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
 							  pixmap);
 
-/** 
+/**
  * Upload a picture to gl texture. Similar to the
  * glamor_upload_pixmap_to_texture. Used in rendering.
  **/
@@ -641,6 +641,14 @@ enum glamor_pixmap_status
  glamor_upload_picture_to_texture(PicturePtr picture);
 
 /**
+ * Upload bits to a pixmap's texture. This function will
+ * convert the bits to the specified format/type format
+ * if the conversion is unavoidable.
+ **/
+Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum type,
+					  int no_alpha, int revert, int swap_rb, void *bits);
+
+/**
  * Destroy all the resources allocated on the uploading
  * phase, includs the tex and fbo.
  **/
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 35e8d61..972918c 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -286,9 +286,17 @@ format_for_pixmap(PixmapPtr pixmap)
 	return pict_format;
 }
 
-
 #define REVERT_NONE       		0
 #define REVERT_NORMAL     		1
+#define REVERT_DOWNLOADING_A1		2
+#define REVERT_UPLOADING_A1		3
+#define REVERT_DOWNLOADING_2_10_10_10 	4
+#define REVERT_UPLOADING_2_10_10_10 	5
+#define REVERT_DOWNLOADING_1_5_5_5  	7
+#define REVERT_UPLOADING_1_5_5_5    	8
+#define REVERT_DOWNLOADING_10_10_10_2 	9
+#define REVERT_UPLOADING_10_10_10_2 	10
+
 #define SWAP_NONE_DOWNLOADING  	0
 #define SWAP_DOWNLOADING  	1
 #define SWAP_UPLOADING	  	2
@@ -455,17 +463,48 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	case PICT_x2r10g10b10:
 		*no_alpha = 1;
 	case PICT_a2r10g10b10:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
-		*revert = REVERT_NONE;
+		*tex_format = GL_RGBA;
+		/* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
+		 * we have to use GL_UNSIGNED_BYTE and do the conversion in
+		 * shader latter.*/
+		*tex_type = GL_UNSIGNED_BYTE;
+		if (is_upload == 1) {
+			if (!IS_LITTLE_ENDIAN)
+				*revert = REVERT_UPLOADING_10_10_10_2;
+			else
+				*revert = REVERT_UPLOADING_2_10_10_10;
+		}
+		else {
+			if (!IS_LITTLE_ENDIAN) {
+				*revert = REVERT_DOWNLOADING_10_10_10_2;
+			}
+			else {
+				*revert = REVERT_DOWNLOADING_2_10_10_10;
+			}
+		}
+		need_swap_rb = 1;
+
 		break;
 
 	case PICT_x2b10g10r10:
 		*no_alpha = 1;
 	case PICT_a2b10g10r10:
 		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
-		*revert = REVERT_NONE;
+		*tex_type = GL_UNSIGNED_BYTE;
+		if (is_upload == 1) {
+			if (!IS_LITTLE_ENDIAN)
+				*revert = REVERT_UPLOADING_10_10_10_2;
+			else
+				*revert = REVERT_UPLOADING_2_10_10_10;
+		}
+		else {
+			if (!IS_LITTLE_ENDIAN) {
+				*revert = REVERT_DOWNLOADING_10_10_10_2;
+			}
+			else {
+				*revert = REVERT_DOWNLOADING_2_10_10_10;
+			}
+		}
 		break;
 
 	case PICT_r5g6b5:
@@ -485,16 +524,29 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 		*no_alpha = 1;
 	case PICT_a1b5g5r5:
 		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		*revert = REVERT_NONE;
+		*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+		if (IS_LITTLE_ENDIAN) {
+			*revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5;
+		} else
+			*revert = REVERT_NONE;
 		break;
 
 	case PICT_x1r5g5b5:
 		*no_alpha = 1;
 	case PICT_a1r5g5b5:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		*revert = REVERT_NONE;
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+		if (IS_LITTLE_ENDIAN) {
+			*revert = is_upload ? REVERT_UPLOADING_1_5_5_5 : REVERT_DOWNLOADING_1_5_5_5;
+		} else
+			*revert = REVERT_NONE;
+		need_swap_rb = 1;
+		break;
+
+	case PICT_a1:
+		*tex_format = GL_ALPHA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		*revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
 		break;
 
 	case PICT_a8:
commit 3add3750658107bd18592a8672caa8bed0c8931c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 5 21:53:44 2012 +0800

    gles2: Fixed color conversion for the formats except 1555 and 2101010.
    
    This patch fixed two major problems when we do the color convesion with
    GLES2.
    
    1. lack of necessary formats in FBO pool.
    GLES2 has three different possible texture formats, GL_RGBA,
    GL_BGRA and GL_ALPHA. Previous implementation only has one bucket
    for all the three formats which may reuse a incorrect texture format
    when do the cache lookup. After this fix, we can enable fbo safely
    when running with GLES2.
    
    2. Refine the format matching method in
    glamor_get_tex_format_type_from_pictformat.
    If both revertion and swap_rb are needed, for example use GL_RGBA
    to represent PICT_b8g8r8a8. Then the downloading and uploading should
    be handled differently.
    
        The picture's format is PICT_b8g8r8a8,
        Then the expecting color layout is as below (little endian):
        0   1       2       3   : address
        a   r       g       b
    
        Now the in GLES2 the supported color format is GL_RGBA, type is
        GL_UNSIGNED_TYPE, then we need to shuffle the fragment
        color as :
            frag_color = sample(texture).argb;
        before we use glReadPixel to get it back.
    
        For the uploading process, the shuffle is a revert shuffle.
        We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
        to a texture, then let's see
        0   1       2       3   : address
        a   r       g       b   : correct colors
        R   G       B       A   : GL_RGBA with GL_UNSIGNED_BYTE
    
        Now we need to shuffle again, the mapping rule is
        r = G, g = B, b = A, a = R. Then the uploading shuffle is as
        below:
            frag_color = sample(texture).gbar;
    
    After this commit, gles2 version can pass render check with all
    the formats except those 1555/2101010.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 532b9ef..8fc3b05 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -84,6 +84,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	glamor_pixmap_fbo *fbo;
+	GLenum format;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -93,9 +94,10 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 		glamor_destroy_fbo(fbo);
 	}
 
+	gl_iformat_for_depth(pixmap->drawable.depth, &format);
 	fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
 					 pixmap->drawable.height,
-					 pixmap->drawable.depth, tex, 0);
+					 format, tex, 0);
 
 	if (fbo == NULL) {
 		ErrorF("XXX fail to create fbo.\n");
@@ -133,11 +135,14 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	glamor_pixmap_fbo *fbo;
 	int pitch;
 	int flag;
+	GLenum format;
 
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
-	if (usage == GLAMOR_CREATE_PIXMAP_CPU || (w == 0 && h == 0))
+	if (usage == GLAMOR_CREATE_PIXMAP_CPU
+	    || (w == 0 && h == 0)
+	    || !glamor_check_pixmap_fbo_depth(depth))
 		return fbCreatePixmap(screen, w, h, depth, usage);
 	else
 		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
@@ -154,7 +159,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	pixmap_priv->glamor_priv = glamor_priv;
 	pixmap_priv->type = type;
 
-	fbo = glamor_create_fbo(glamor_priv, w, h, depth, usage);
+	gl_iformat_for_depth(depth, &format);
+	fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
 
 	if (fbo == NULL) {
 		fbDestroyPixmap(pixmap);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 87b53a9..b488037 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -239,12 +239,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 						texcoords);
 		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 		dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-		dispatch->
-		    glUniform1i(glamor_priv->finish_access_no_revert[0],
-				1);
-		dispatch->
-		    glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
-
+		dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
+				      REVERT_NONE);
+		dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
+				      SWAP_NONE_UPLOADING);
 	} else {
 		GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
 					  src_pixmap_priv);
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 0376388..f9c1db2 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -107,6 +107,35 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	return glamor_download_pixmap_to_cpu(pixmap, access);
 }
 
+/*
+ *  When downloading a unsupported color format to CPU memory,
+    we need to shuffle the color elements and then use a supported
+    color format to read it back to CPU memory.
+
+    For an example, the picture's format is PICT_b8g8r8a8,
+    Then the expecting color layout is as below (little endian):
+    0	1	2	3   : address
+    a	r	g	b
+
+    Now the in GLES2 the supported color format is GL_RGBA, type is
+    GL_UNSIGNED_TYPE, then we need to shuffle the fragment
+    color as :
+	frag_color = sample(texture).argb;
+    before we use glReadPixel to get it back.
+
+    For the uploading process, the shuffle is a revert shuffle.
+    We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
+    to a texture, then let's see
+    0	1	2	3   : address
+    a	r	g	b   : correct colors
+    R	G	B	A   : GL_RGBA with GL_UNSIGNED_BYTE
+
+    Now we need to shuffle again, the mapping rule is
+    r = G, g = B, b = A, a = R. Then the uploading shuffle is as
+    below:
+	frag_color = sample(texture).gbar;
+*/
+
 void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
@@ -121,53 +150,67 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	    "	gl_Position = v_position;\n"
 	    "	source_texture = v_texcoord0.xy;\n" "}\n";
 
-	const char *fs_source =
+	const char *common_source =
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 source_texture;\n"
 	    "uniform sampler2D sampler;\n"
-	    "uniform int no_revert;\n"
+	    "uniform int revert;\n"
 	    "uniform int swap_rb;\n"
+
+	    "#define REVERT_NONE       			0\n"
+	    "#define REVERT_NORMAL     			1\n"
+	    "#define SWAP_NONE_DOWNLOADING  		0\n"
+	    "#define SWAP_DOWNLOADING  			1\n"
+	    "#define SWAP_UPLOADING	  		2\n"
+	    "#define SWAP_NONE_UPLOADING		3\n";
+
+	const char *fs_source =
 	    "void main()\n"
 	    "{\n"
-	    "   if (no_revert == 1) \n"
+	    "   if (revert == REVERT_NONE) \n"
 	    "    { \n"
-	    "     if (swap_rb == 1)   \n"
-	    "	  gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+	    "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
 	    "     else \n"
-	    "	  gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
 	    "    } \n"
 	    "   else \n"
 	    "    { \n"
-	    "     if (swap_rb == 1)   \n"
-	    "	    gl_FragColor = texture2D(sampler, source_texture).argb;\n"
-	    "     else \n"
-	    "	    gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+	    "     if (swap_rb == SWAP_DOWNLOADING)   \n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+	    "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+	    "     else if (swap_rb == SWAP_UPLOADING)\n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
+	    "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
+	    "	  	gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
 	    "    } \n" "}\n";
 
 	const char *set_alpha_source =
-	    GLAMOR_DEFAULT_PRECISION
-	    "varying vec2 source_texture;\n"
-	    "uniform sampler2D sampler;\n"
-	    "uniform int no_revert;\n"
-	    "uniform int swap_rb;\n"
 	    "void main()\n"
 	    "{\n"
-	    "   if (no_revert == 1) \n"
+	    "   if (revert == REVERT_NONE) \n"
 	    "    { \n"
-	    "     if (swap_rb == 1)   \n"
-	    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+	    "     if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING))   \n"
+	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
 	    "     else \n"
-	    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
 	    "    } \n"
 	    "   else \n"
 	    "    { \n"
-	    "     if (swap_rb == 1)   \n"
-	    "	  gl_FragColor = vec4(1,  texture2D(sampler, source_texture).rgb);\n"
-	    "     else \n"
-	    "	  gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
-	    "    } \n" "}\n";
+	    "     if (swap_rb == SWAP_DOWNLOADING)   \n"
+	    "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
+	    "     else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
+	    "	  	gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+	    "     else if (swap_rb == SWAP_UPLOADING)\n"
+	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
+	    "     else if (swap_rb == SWAP_NONE_UPLOADING)\n"
+	    "	  	gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
+	    "    } \n"
+	    "}\n";
 	GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
 	GLint sampler_uniform_location;
+	char *source;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch =  glamor_get_dispatch(glamor_priv);
@@ -176,8 +219,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 
 	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
 				     vs_source);
+
+	XNFasprintf(&source, "%s%s", common_source, fs_source);
 	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-				     fs_source);
+				     source);
+	free(source);
+
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
 				 vs_prog);
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
@@ -185,8 +232,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 
 	avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
 				     vs_source);
+
+	XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
 	set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-				     set_alpha_source);
+						  source);
+	free(source);
+
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
 				 avs_prog);
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
@@ -208,10 +259,10 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	glamor_link_glsl_prog(dispatch,
 			      glamor_priv->finish_access_prog[1]);
 
-	glamor_priv->finish_access_no_revert[0] =
+	glamor_priv->finish_access_revert[0] =
 	    dispatch->
 	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
-				 "no_revert");
+				 "revert");
 
 	glamor_priv->finish_access_swap_rb[0] =
 	    dispatch->
@@ -223,14 +274,14 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 				 "sampler");
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
 	dispatch->glUniform1i(sampler_uniform_location, 0);
-	dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
+	dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
 	dispatch->glUseProgram(0);
 
-	glamor_priv->finish_access_no_revert[1] =
+	glamor_priv->finish_access_revert[1] =
 	    dispatch->
 	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
-				 "no_revert");
+				 "revert");
 	glamor_priv->finish_access_swap_rb[1] =
 	    dispatch->
 	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
@@ -240,7 +291,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
 				 "sampler");
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
-	dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1], 1);
+	dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0);
 	dispatch->glUniform1i(sampler_uniform_location, 0);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
 	dispatch->glUseProgram(0);
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d212bd4..b15450a 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -62,18 +62,6 @@ inline static int cache_hbucket(int size)
 		order = CACHE_BUCKET_HCOUNT - 1;
 	return order;
 }
-inline static int cache_format(GLenum format)
-{
-	switch (format) {
-#if 0
-	case GL_ALPHA:
-		return 1;
-#endif
-	case GL_RGBA:
-	default:
-		return 0;
-	}
-}
 
 glamor_pixmap_fbo *
 glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
@@ -82,23 +70,27 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry;
 	int size;
+	int n_format;
 #ifdef NO_FBO_CACHE
 	return NULL;
 #else
+	n_format = cache_format(format);
+	if (n_format == -1)
+		return NULL;
 	if (!(flag & GLAMOR_CACHE_TEXTURE))
-		cache = &glamor_priv->fbo_cache[cache_format(format)]
+		cache = &glamor_priv->fbo_cache[n_format]
 					       [cache_wbucket(w)]
 					       [cache_hbucket(h)];
 	else
-		cache = &glamor_priv->tex_cache[cache_format(format)]
+		cache = &glamor_priv->tex_cache[n_format]
 					       [cache_wbucket(w)]
 					       [cache_hbucket(h)];
 	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
 		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
-				DEBUGF("Request w %d h %d \n", w, h);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+				DEBUGF("Request w %d h %d format %x \n", w, h, format);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
 					fbo_entry->fb, fbo_entry->tex);
 				xorg_list_del(&fbo_entry->list);
@@ -110,10 +102,11 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width == w && fbo_entry->height == h) {
 
-				DEBUGF("Request w %d h %d \n", w, h);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+				DEBUGF("Request w %d h %d format %x \n", w, h, format);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
-					fbo_entry->fb, fbo_entry->tex);
+					fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+				assert(format == fbo_entry->format);
 				xorg_list_del(&fbo_entry->list);
 				return fbo_entry;
 			}
@@ -144,21 +137,25 @@ static void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
 	struct xorg_list *cache;
+	int n_format;
+
 #ifdef NO_FBO_CACHE
 	glamor_purge_fbo(fbo);
 	return;
 #else
-	if (fbo->fb == 0) {
+	n_format = cache_format(fbo->format);
+
+	if (fbo->fb == 0 || n_format == -1) {
 		glamor_purge_fbo(fbo);
 		return;
 	}
 
 	if (fbo->fb)
-		cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
+		cache = &fbo->glamor_priv->fbo_cache[n_format]
 						    [cache_wbucket(fbo->width)]
 						    [cache_hbucket(fbo->height)];
 	else
-		cache = &fbo->glamor_priv->tex_cache[cache_format(fbo->format)]
+		cache = &fbo->glamor_priv->tex_cache[n_format]
 						    [cache_wbucket(fbo->width)]
 						    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
@@ -170,17 +167,15 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 
 glamor_pixmap_fbo *
 glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
-		  int w, int h, int depth, GLint tex, int flag)
+		  int w, int h, GLenum format, GLint tex, int flag)
 {
 	glamor_pixmap_fbo *fbo;
-	GLenum format;
 
 	fbo = calloc(1, sizeof(*fbo));
 	if (fbo == NULL)
 		return NULL;
 
 	xorg_list_init(&fbo->list);
-	gl_iformat_for_depth(depth, &format);
 
 	fbo->tex = tex;
 	fbo->width = w;
@@ -338,19 +333,18 @@ glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
 
 glamor_pixmap_fbo *
 glamor_create_fbo(glamor_screen_private *glamor_priv,
-		  int w, int h, int depth, int flag)
+		  int w, int h,
+		  GLenum format,
+		  int flag)
 {
 	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *fbo;
-	GLenum format;
 	GLint tex;
 	int cache_flag;
 
-	if (!glamor_check_fbo_size(glamor_priv, w, h)
-	    || !glamor_check_fbo_depth(depth))
+	if (!glamor_check_fbo_size(glamor_priv, w, h))
 		return NULL;
 
-	gl_iformat_for_depth(depth, &format);
 	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
 		goto new_fbo;
 
@@ -374,7 +368,7 @@ new_fbo:
 	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
 			       GL_UNSIGNED_BYTE, NULL);
 
-	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
+	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
 	glamor_put_dispatch(glamor_priv);
 
 	return fbo;
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index efbd1ba..b1093e8 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -39,10 +39,11 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	struct glamor_screen_private *glamor_priv;
 	int x_off, y_off;
 	GLenum tex_format, tex_type;
-	int no_alpha, no_revert;
-	PixmapPtr temp_pixmap = NULL;
+	int no_alpha, revert;
+	glamor_pixmap_fbo *temp_fbo = NULL;
 	glamor_gl_dispatch * dispatch;
 	Bool ret = FALSE;
+	int swap_rb;
 
 	goto fall_back;
 
@@ -69,7 +70,9 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 						   &tex_format,
 						   &tex_type,
 						   &no_alpha,
-						   &no_revert)) {
+						   &revert,
+						   &swap_rb,
+						   0)) {
 		glamor_fallback("unknown depth. %d \n", drawable->depth);
 		goto fall_back;
 	}
@@ -78,14 +81,16 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
+	    && ( swap_rb != SWAP_NONE_DOWNLOADING
+		 || revert != REVERT_NONE)) {
 		/* XXX prepare whole pixmap is not efficient. */
-		temp_pixmap =
-		    glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
-						   &tex_type, no_alpha,
-						   no_revert);
-		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+		temp_fbo =
+		    glamor_es2_pixmap_read_prepare(pixmap, tex_format,
+						   tex_type, no_alpha,
+						   revert, swap_rb);
+		if (temp_fbo == NULL)
+			goto fall_back;
+
 	}
 
 	int row_length = PixmapBytePad(w, drawable->depth);
@@ -113,8 +118,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 				       tex_format,
 				       tex_type, d);
 	glamor_put_dispatch(glamor_priv);
-	if (temp_pixmap)
-		glamor_destroy_pixmap(temp_pixmap);
+	if (temp_fbo)
+		glamor_destroy_fbo(temp_fbo);
 
 	ret = TRUE;
 
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 91030a3..8341df4 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -35,17 +35,18 @@ _glamor_get_spans(DrawablePtr drawable,
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	GLenum format, type;
-	int no_alpha, no_revert;
+	int no_alpha, revert;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
 	glamor_gl_dispatch *dispatch;
-	PixmapPtr temp_pixmap = NULL;
+	glamor_pixmap_fbo *temp_fbo = NULL;
 	int i;
 	uint8_t *readpixels_dst = (uint8_t *) dst;
 	int x_off, y_off;
 	Bool ret = FALSE;
+	int swap_rb;
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
@@ -55,24 +56,29 @@ _glamor_get_spans(DrawablePtr drawable,
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
 						   &type, &no_alpha,
-						   &no_revert)) {
+						   &revert, &swap_rb, 0)) {
 		glamor_fallback("unknown depth. %d \n", drawable->depth);
 		goto fail;
 	}
 
+	if (revert > REVERT_NORMAL)
+		goto fail;
+
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && (!glamor_tex_format_is_readable(format) || !no_revert)) {
+	    && ( swap_rb != SWAP_NONE_DOWNLOADING
+		 || revert != REVERT_NONE)) {
 
 		/* XXX prepare whole pixmap is not efficient. */
-		temp_pixmap =
-		    glamor_es2_pixmap_read_prepare(pixmap, &format,
-						   &type, no_alpha,
-						   no_revert);
-		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+		temp_fbo =
+		    glamor_es2_pixmap_read_prepare(pixmap, format,
+						   type, no_alpha,
+						   revert, swap_rb);
+		if (temp_fbo == NULL)
+			goto fail;
+
 	}
 
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
@@ -94,8 +100,8 @@ _glamor_get_spans(DrawablePtr drawable,
 		    PixmapBytePad(widths[i], drawable->depth);
 	}
 	glamor_put_dispatch(glamor_priv);
-	if (temp_pixmap)
-		glamor_destroy_pixmap(temp_pixmap);
+	if (temp_fbo)
+		glamor_destroy_fbo(temp_fbo);
 
 	ret = TRUE;
 	goto done;
@@ -105,6 +111,7 @@ fail:
 	    && glamor_ddx_fallback_check_pixmap(drawable))
 		goto done;
 
+	ret = TRUE;
 	glamor_fallback("from %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 7f4a90b..0570a9a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -89,10 +89,10 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 }
 
 void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
+glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
 {
-	glamor_gl_dispatch *dispatch = glamor_get_dispatch(pixmap_priv->glamor_priv);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fbo->fb);
+	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 #ifndef GLAMOR_GLES2
 	dispatch->glMatrixMode(GL_PROJECTION);
 	dispatch->glLoadIdentity();
@@ -100,10 +100,16 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 	dispatch->glLoadIdentity();
 #endif
 	dispatch->glViewport(0, 0,
-			     pixmap_priv->fbo->width,
-			     pixmap_priv->fbo->height);
+			     fbo->width,
+			     fbo->height);
+
+	glamor_put_dispatch(fbo->glamor_priv);
+}
 
-	glamor_put_dispatch(pixmap_priv->glamor_priv);
+void
+glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
+{
+	glamor_set_destination_pixmap_fbo(pixmap_priv->fbo);
 }
 
 int
@@ -280,9 +286,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
  * */
 
 static void
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				 GLenum type, int no_alpha, int no_revert,
-				 int flip)
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
+				int no_alpha, int revert, int swap_rb)
 {
 
 	glamor_pixmap_private *pixmap_priv =
@@ -308,7 +313,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
 	if (!pixmap_priv)
 		return;
-	need_flip = (flip && !glamor_priv->yInverted);
+	need_flip = !glamor_priv->yInverted;
 
 	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
 			    "Uploading pixmap %p  %dx%d depth%d.\n",
@@ -319,7 +324,11 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
 	/* Try fast path firstly, upload the pixmap to the texture attached
 	 * to the fbo directly. */
-	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
+	if (no_alpha == 0
+	    && revert == REVERT_NONE
+	    && swap_rb == SWAP_NONE_UPLOADING
+	    && !need_flip) {
+
 		__glamor_upload_pixmap_to_texture(pixmap, format, type,
 						  pixmap_priv->fbo->tex, 1);
 		return;
@@ -365,10 +374,10 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 #endif
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 	dispatch->glUniform1i(glamor_priv->
-			      finish_access_no_revert[no_alpha],
-			      no_revert);
+			      finish_access_revert[no_alpha],
+			      revert);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      0);
+			      swap_rb);
 
 	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
@@ -441,18 +450,22 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
  * 2. no_alpha != 0, we need to wire the alpha.
  * */
 static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb)
 {
 	int flag;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
-	GLenum format;
 	glamor_pixmap_fbo *fbo;
+	GLenum iformat;
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-	if (!(no_alpha || !no_revert || !glamor_priv->yInverted)) {
+	if (!(no_alpha
+	      || (revert != REVERT_NONE)
+	      || (swap_rb != SWAP_NONE_UPLOADING)
+	      || !glamor_priv->yInverted)) {
+		/* We don't need a fbo, a simple texture uploading should work. */
 
 		if (pixmap_priv && pixmap_priv->fbo)
 			return 0;
@@ -464,9 +477,15 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 		flag = 0;
 	}
 
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+		gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+	else
+		iformat = format;
+
+
 	fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 				pixmap->drawable.height,
-				pixmap->drawable.depth,
+				iformat,
 				flag);
 	if (fbo == NULL) {
 		glamor_fallback
@@ -485,20 +504,24 @@ enum glamor_pixmap_status
 glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 {
 	GLenum format, type;
-	int no_alpha, no_revert;
+	int no_alpha, revert, swap_rb;
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
-						   &type, &no_alpha,
-						   &no_revert)) {
+						   &type,
+						   &no_alpha,
+						   &revert,
+						   &swap_rb, 1)) {
 		glamor_fallback("Unknown pixmap depth %d.\n",
 				pixmap->drawable.depth);
 		return GLAMOR_UPLOAD_FAILED;
 	}
-	if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
+
+	if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
 		return GLAMOR_UPLOAD_FAILED;
+
 	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 no_revert, 1);
+					 revert, swap_rb);
 	return GLAMOR_UPLOAD_DONE;
 }
 
@@ -523,21 +546,19 @@ void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
 	GLenum format, type;
-	int no_alpha, no_revert;
+	int no_alpha, revert, swap_rb;
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
 						   &type, &no_alpha,
-						   &no_revert)) {
+						   &revert, &swap_rb, 1)) {
 		ErrorF("Unknown pixmap depth %d.\n",
 		       pixmap->drawable.depth);
 		assert(0);
 	}
 
-	in_restore = 1;
 	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 no_revert, 1);
-	in_restore = 0;
+					 revert, swap_rb);
 }
 
 /* 
@@ -548,65 +569,56 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
  * get a new temporary pixmap returned.
  * */
 
-PixmapPtr
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
-			       GLenum * type, int no_alpha, int no_revert)
+glamor_pixmap_fbo *
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
+			       GLenum type, int no_alpha, int revert, int swap_rb)
+
 {
 	glamor_pixmap_private *source_priv;
 	glamor_screen_private *glamor_priv;
 	ScreenPtr screen;
-	PixmapPtr temp_pixmap;
-	glamor_pixmap_private *temp_pixmap_priv;
+	glamor_pixmap_fbo *temp_fbo;
 	glamor_gl_dispatch *dispatch;
-	static float vertices[8] = { -1, -1,
-		1, -1,
-		1, 1,
-		-1, 1
-	};
-	static float texcoords[8] = { 0, 0,
-		1, 0,
-		1, 1,
-		0, 1
-	};
-
-	int swap_rb = 0;
+	float temp_xscale, temp_yscale, source_xscale, source_yscale;
+	static float vertices[8];
+	static float texcoords[8];
 
 	screen = source->drawable.pScreen;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	source_priv = glamor_get_pixmap_private(source);
-	if (*format == GL_BGRA) {
-		*format = GL_RGBA;
-		swap_rb = 1;
-	}
-
-
-	temp_pixmap = glamor_create_pixmap (screen,
-					    source->drawable.width,
-					    source->drawable.height,
-					    source->drawable.depth, 0);
-
-	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+	temp_fbo = glamor_create_fbo(glamor_priv,
+				     source->drawable.width,
+				     source->drawable.height,
+				     format,
+				     0);
+	if (temp_fbo == NULL)
+		return NULL;
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
+	temp_xscale = 1.0 / temp_fbo->width;
+	temp_yscale = 1.0 / temp_fbo->height;
 
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
-			       source->drawable.width,
-			       source->drawable.height, 0, *format, *type,
-			       NULL);
+	glamor_set_normalize_vcoords(temp_xscale,
+				     temp_yscale,
+				     0, 0,
+				     source->drawable.width, source->drawable.height,
+				     glamor_priv->yInverted,
+				     vertices);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
+	pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
+	glamor_set_normalize_tcoords(source_xscale,
+				     source_yscale,
+				     0, 0,
+				     source->drawable.width, source->drawable.height,
+				     glamor_priv->yInverted,
+				     texcoords);
+
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					texcoords);
@@ -621,12 +633,11 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 				  GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
 
-	glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
-
+	glamor_set_destination_pixmap_fbo(temp_fbo);
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 	dispatch->glUniform1i(glamor_priv->
-			      finish_access_no_revert[no_alpha],
-			      no_revert);
+			      finish_access_revert[no_alpha],
+			      revert);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
 			      swap_rb);
 
@@ -636,7 +647,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
 	glamor_put_dispatch(glamor_priv);
-	return temp_pixmap;
+	return temp_fbo;
 }
 
 
@@ -656,21 +667,23 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	    glamor_get_pixmap_private(pixmap);
 	unsigned int stride, row_length, y;
 	GLenum format, type, gl_access, gl_usage;
-	int no_alpha, no_revert;
+	int no_alpha, revert, swap_rb;
 	uint8_t *data = NULL, *read;
-	PixmapPtr temp_pixmap = NULL;
 	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_fbo *temp_fbo = NULL;
 
 	screen = pixmap->drawable.pScreen;
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return TRUE;
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
-						   &type, &no_alpha,
-						   &no_revert)) {
+						   &type,
+						   &no_alpha,
+						   &revert,
+						   &swap_rb, 0)) {
 		ErrorF("Unknown pixmap depth %d.\n",
 		       pixmap->drawable.depth);
 		assert(0);	// Should never happen.
@@ -692,11 +705,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && (!glamor_tex_format_is_readable(format) || !no_revert)) {
-		temp_pixmap =
-		    glamor_es2_pixmap_read_prepare(pixmap, &format,
-						   &type, no_alpha,
-						   no_revert);
+	    && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
+		 if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, format,
+								 type, no_alpha,
+								 revert, swap_rb)))
+			return FALSE;
 	}
 	switch (access) {
 	case GLAMOR_ACCESS_RO:
@@ -807,8 +820,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
 	pixmap->devPrivate.ptr = data;
 
-	if (temp_pixmap)
-		glamor_destroy_pixmap(temp_pixmap);
+	if (temp_fbo != NULL)
+		glamor_destroy_fbo(temp_fbo);
 
 	return TRUE;
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 54bbdb1..828b08e 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -182,7 +182,12 @@ struct glamor_saved_procs {
 	UnrealizeGlyphProcPtr unrealize_glyph;
 };
 
+#ifdef GLAMOR_GLES2
+#define CACHE_FORMAT_COUNT 3
+#else
 #define CACHE_FORMAT_COUNT 1
+#endif
+
 #define CACHE_BUCKET_WCOUNT 4
 #define CACHE_BUCKET_HCOUNT 4
 
@@ -221,7 +226,7 @@ typedef struct glamor_screen_private {
 
 	/* shaders to restore a texture to another texture.*/
 	GLint finish_access_prog[2];
-	GLint finish_access_no_revert[2];
+	GLint finish_access_revert[2];
 	GLint finish_access_swap_rb[2];
 
 	/* glamor_tile */
@@ -395,9 +400,9 @@ Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
 void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
 glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
-					       int w, int h, int depth, GLint tex, int flag);
+					       int w, int h, GLenum format, GLint tex, int flag);
 glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
-				      int w, int h, int depth, int flag);
+				      int w, int h, GLenum format, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
 void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
@@ -451,6 +456,7 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
 int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
 				       pixmap_priv);
+void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
@@ -458,10 +464,9 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
 void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *
 					   pixmap_priv);
 
-
-PixmapPtr
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
-			       GLenum * type, int no_alpha, int no_revert);
+glamor_pixmap_fbo *
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
+			       GLenum type, int no_alpha, int revert, int swap_rb);
 
 void glamor_set_alu(struct glamor_gl_dispatch *dispatch,
 		    unsigned char alu);
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 75e5b4c..e38c45a 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -264,8 +264,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	float vertices[8], texcoords[8];
 	GLfloat xscale, yscale, txscale, tyscale;
 	GLuint tex;
-	int no_alpha, no_revert;
+	int no_alpha, revert;
 	Bool ret = FALSE;
+	int swap_rb;
 
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
@@ -289,7 +290,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
 						   &type, &no_alpha,
-						   &no_revert)) {
+						   &revert,
+						   &swap_rb,
+						   1)) {
 		glamor_fallback("unknown depth. %d \n", drawable->depth);
 		goto fail;
 	}
@@ -341,10 +344,10 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 #endif
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 	dispatch->glUniform1i(glamor_priv->
-			      finish_access_no_revert[no_alpha],
-			      no_revert);
+			      finish_access_revert[no_alpha],
+			      revert);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      0);
+			      swap_rb);
 
 	x += drawable->x;
 	y += drawable->y;
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index a947169..b6847a9 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -38,12 +38,13 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_gl_dispatch *dispatch;
 	GLenum format, type;
-	int no_alpha, no_revert, i;
+	int no_alpha, revert, i;
 	uint8_t *drawpixels_src = (uint8_t *) src;
 	RegionPtr clip = fbGetCompositeClip(gc);
 	BoxRec *pbox;
 	int x_off, y_off;
 	Bool ret = FALSE;
+	int swap_rb;
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@@ -59,7 +60,9 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
 						   &format,
 						   &type, &no_alpha,
-						   &no_revert)) {
+						   &revert,
+						   &swap_rb,
+						   1)) {
 		glamor_fallback("unknown depth. %d \n", drawable->depth);
 		goto fail;
 	}
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 29b7b12..35e8d61 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -194,14 +194,14 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
                                                     && (_w_) < _glamor_->max_fbo_size  \
                                                     && (_h_) < _glamor_->max_fbo_size)
 
-#define glamor_check_fbo_depth(_depth_) (			\
-                                         _depth_ == 8		\
-	                                 || _depth_ == 15	\
-                                         || _depth_ == 16	\
-                                         || _depth_ == 24	\
-                                         || _depth_ == 30	\
-                                         || _depth_ == 32)
-
+/* For 1bpp pixmap, we don't store it as texture. */
+#define glamor_check_pixmap_fbo_depth(_depth_) (			\
+						_depth_ == 8		\
+						|| _depth_ == 15	\
+						|| _depth_ == 16	\
+						|| _depth_ == 24	\
+						|| _depth_ == 30	\
+						|| _depth_ == 32)
 
 #define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
 #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
@@ -286,6 +286,14 @@ format_for_pixmap(PixmapPtr pixmap)
 	return pict_format;
 }
 
+
+#define REVERT_NONE       		0
+#define REVERT_NORMAL     		1
+#define SWAP_NONE_DOWNLOADING  	0
+#define SWAP_DOWNLOADING  	1
+#define SWAP_UPLOADING	  	2
+#define SWAP_NONE_UPLOADING	3
+
 /*
  * Map picture's format to the correct gl texture format and type.
  * no_alpha is used to indicate whehter we need to wire alpha to 1. 
@@ -297,10 +305,15 @@ static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 					   GLenum * tex_format,
 					   GLenum * tex_type,
-					   int *no_alpha, int *no_revert)
+					   int *no_alpha,
+					   int *revert,
+					   int *swap_rb,
+					   int is_upload)
+
 {
 	*no_alpha = 0;
-	*no_revert = 1;
+	*revert = REVERT_NONE;
+	*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
 	switch (format) {
 	case PICT_a1:
 		*tex_format = GL_COLOR_INDEX;
@@ -385,6 +398,18 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	}
 	return 0;
 }
+
+/* Currently, we use RGBA to represent all formats. */
+inline static int cache_format(GLenum format)
+{
+	switch (format) {
+	case GL_RGBA:
+		return 0;
+	default:
+		return -1;
+	}
+}
+
 #else
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
@@ -392,25 +417,32 @@ static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 					   GLenum * tex_format,
 					   GLenum * tex_type,
-					   int *no_alpha, int *no_revert)
+					   int *no_alpha,
+					   int *revert,
+					   int *swap_rb,
+					   int is_upload)
 {
+	int need_swap_rb = 0;
+
 	*no_alpha = 0;
-	*no_revert = IS_LITTLE_ENDIAN;
+	*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
 
 	switch (format) {
 	case PICT_b8g8r8x8:
 		*no_alpha = 1;
 	case PICT_b8g8r8a8:
-		*tex_format = GL_BGRA;
+		*tex_format = GL_RGBA;
 		*tex_type = GL_UNSIGNED_BYTE;
-		*no_revert = !IS_LITTLE_ENDIAN;
+		need_swap_rb = 1;
+		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
 		break;
 
 	case PICT_x8r8g8b8:
 		*no_alpha = 1;
 	case PICT_a8r8g8b8:
-		*tex_format = GL_BGRA;
+		*tex_format = GL_RGBA;
 		*tex_type = GL_UNSIGNED_BYTE;
+		need_swap_rb = 1;
 		break;
 
 	case PICT_x8b8g8r8:
@@ -425,7 +457,7 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	case PICT_a2r10g10b10:
 		*tex_format = GL_BGRA;
 		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
-		*no_revert = TRUE;
+		*revert = REVERT_NONE;
 		break;
 
 	case PICT_x2b10g10r10:
@@ -433,19 +465,20 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	case PICT_a2b10g10r10:
 		*tex_format = GL_RGBA;
 		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
-		*no_revert = TRUE;
+		*revert = REVERT_NONE;
 		break;
 
 	case PICT_r5g6b5:
 		*tex_format = GL_RGB;
 		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
-		*no_revert = TRUE;
+		*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
 		break;
 
 	case PICT_b5g6r5:
 		*tex_format = GL_RGB;
 		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
-		*no_revert = FALSE;
+		need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
 		break;
 
 	case PICT_x1b5g5r5:
@@ -453,7 +486,7 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	case PICT_a1b5g5r5:
 		*tex_format = GL_RGBA;
 		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		*no_revert = TRUE;
+		*revert = REVERT_NONE;
 		break;
 
 	case PICT_x1r5g5b5:
@@ -461,29 +494,30 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	case PICT_a1r5g5b5:
 		*tex_format = GL_BGRA;
 		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		*no_revert = TRUE;
+		*revert = REVERT_NONE;
 		break;
 
 	case PICT_a8:
 		*tex_format = GL_ALPHA;
 		*tex_type = GL_UNSIGNED_BYTE;
-		*no_revert = TRUE;
+		*revert = REVERT_NONE;
 		break;
 
 	case PICT_x4r4g4b4:
 		*no_alpha = 1;
 	case PICT_a4r4g4b4:
-		*tex_format = GL_BGRA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		*no_revert = TRUE;
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+		need_swap_rb = 1;
 		break;
 
 	case PICT_x4b4g4r4:
 		*no_alpha = 1;
 	case PICT_a4b4g4r4:
 		*tex_format = GL_RGBA;
-		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		*no_revert = TRUE;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+		*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
 		break;
 
 	default:
@@ -492,9 +526,27 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 			       format);
 		return -1;
 	}
+
+	if (need_swap_rb)
+		*swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
+	else
+		*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
 	return 0;
 }
 
+inline static int cache_format(GLenum format)
+{
+	switch (format) {
+	case GL_ALPHA:
+		return 2;
+	case GL_RGB:
+		return 1;
+	case GL_RGBA:
+		return 0;
+	default:
+		return -1;
+	}
+}
 
 #endif
 
@@ -503,7 +555,10 @@ static inline int
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
 				       GLenum * format,
 				       GLenum * type,
-				       int *no_alpha, int *no_revert)
+				       int *no_alpha,
+				       int *revert,
+				       int *swap_rb,
+				       int is_upload)
 {
 	glamor_pixmap_private *pixmap_priv;
 	PictFormatShort pict_format;
@@ -517,7 +572,9 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
 	return glamor_get_tex_format_type_from_pictformat(pict_format,
 							  format, type,
 							  no_alpha,
-							  no_revert);
+							  revert,
+							  swap_rb,
+							  is_upload);
 }
 
 
commit 55fdc7b196904a4e537f429d06d36081a0c9a60d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Apr 5 20:27:35 2012 +0800

    glamor_utils: Added debug function to dump depth 15/16 pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 75ebc7e..29b7b12 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -658,6 +658,24 @@ static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int
 	}
 }
 
+static inline void _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
+{
+	int i,j;
+	unsigned short * p = pixmap->devPrivate.ptr;
+	int stride = pixmap->devKind / 2;
+
+	p = p + y * stride + x;
+
+	for (i = 0; i < h; i++)
+	{
+		ErrorF("line %3d: ", i);
+		for(j = 0; j < w; j++)
+			ErrorF("%2x ", p[j]);
+		p += stride;
+		ErrorF("\n");
+	}
+}
+
 static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
 {
 	int i,j;
@@ -678,17 +696,25 @@ static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int
 
 static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
 {
+	w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
+	h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
+
 	glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 	switch (pixmap->drawable.depth) {
 	case 8:
 		_glamor_dump_pixmap_byte(pixmap, x, y, w, h);
 		break;
+	case 15:
+	case 16:
+		_glamor_dump_pixmap_sword(pixmap, x, y, w, h);
+		break;
+
 	case 24:
 	case 32:
 		_glamor_dump_pixmap_word(pixmap, x, y, w, h);
 		break;
 	default:
-		assert(0);
+		ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
 	}
 	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 }
commit 57e29ebdc13d0ef145e4c70c1406af3229a92ad8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 6 11:14:21 2012 +0800

    glamor_render: Disable gradient shader conversion due to bug.
    
    I found when enable the gradient shader, the firefox's tab's
    background has incorrect rendering result.
    
    Need furthr investigation, for now, just disable it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ad68737..54bbdb1 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -714,6 +714,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 //#define GLAMOR_DELAYED_FILLING
+//#define GLAMOR_GRADIENT_SHADER
 
 
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 042fabe..00a6e1e 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -2743,7 +2743,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 		format = PICT_a8r8g8b8;
 	else
 		format = source->format;
-
+#ifdef GLAMOR_GRADIENT_SHADER
 	if (!source->pDrawable) {
 		if (source->pSourcePict->type == SourcePictTypeLinear) {
 			dst = _glamor_generate_linear_gradient_picture(screen,
@@ -2762,7 +2762,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 			return dst;
 		}
 	}
-
+#endif
 	pixmap = glamor_create_pixmap(screen,
 				      width,
 				      height,
commit 7036cfdd0d29f4e13d432893a4f386cd3d632de7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Mar 16 16:42:46 2012 +0800

    glamor_fbo: Added one macro to disable fbo cache.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 3ae6562..d212bd4 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -8,6 +8,8 @@
 #define GLAMOR_CACHE_EXACT_SIZE 1
 #define GLAMOR_CACHE_TEXTURE	2
 
+//#define NO_FBO_CACHE 1
+
 /* Loop from the tail to the head. */
 #define xorg_list_for_each_entry_reverse(pos, head, member)             \
     for (pos = __container_of((head)->prev, pos, member);               \
@@ -80,7 +82,9 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry;
 	int size;
-
+#ifdef NO_FBO_CACHE
+	return NULL;
+#else
 	if (!(flag & GLAMOR_CACHE_TEXTURE))
 		cache = &glamor_priv->fbo_cache[cache_format(format)]
 					       [cache_wbucket(w)]
@@ -117,6 +121,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	}
 
 	return NULL;
+#endif
 }
 
 void
@@ -135,11 +140,14 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 }
 
 
-void
+static void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
 	struct xorg_list *cache;
-
+#ifdef NO_FBO_CACHE
+	glamor_purge_fbo(fbo);
+	return;
+#else
 	if (fbo->fb == 0) {
 		glamor_purge_fbo(fbo);
 		return;
@@ -157,6 +165,7 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
 	xorg_list_add(&fbo->list, cache);
 	fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+#endif
 }
 
 glamor_pixmap_fbo *
commit 94186db527b33b2623eb26a7f1ae0c4c0fca66a4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Mar 26 19:03:20 2012 +0800

    glamor_fill: Should restore alu to GXcopy.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 8573309..e8419c6 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -206,6 +206,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
+	glamor_set_alu(dispatch, GXcopy);
 	glamor_put_dispatch(glamor_priv);
 	return TRUE;
 }
commit 1f4486c10bb2201830af251eede8cc4dbb857953
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Mar 23 04:06:06 2012 +0800

    Add the feature for radial gradient using shader.
    
     Add the feature for radial gradient using shader. The
     transform matrix and the 4 type of repeat mode are
     supported. Less than 2/255 difference for every color
     component comparing to pixman's result. Extract the
     common logic of linear and radial's to another shader.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6304167..042fabe 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1276,6 +1276,345 @@ done:
 }
 
 static GLint
+_glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_array)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	char *gradient_fs = NULL;
+	GLint gradient_prog = 0;
+	GLint fs_getcolor_prog;
+
+	const char *gradient_fs_getcolor =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform int n_stop;\n"
+	    "uniform float stops[%d];\n"
+	    "uniform vec4 stop_colors[%d];\n"
+	    "vec4 get_color(float stop_len)\n"
+	    "{\n"
+	    "    int i = 0;\n"
+	    "    float new_alpha; \n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    for(i = 0; i < n_stop - 1; i++) {\n"
+	    "        if(stop_len < stops[i])\n"
+	    "            break; \n"
+	    "    }\n"
+	    "    \n"
+	    "    percentage = (stop_len - stops[i-1])/(stops[i] - stops[i-1]);\n"
+	    "    if(stops[i] - stops[i-1] > 2.0)\n"
+	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_colors[i].a + \n"
+	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
+	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
+	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n";
+
+	/* Because the array access for shader is very slow, the performance is very low
+	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
+	const char *gradient_fs_getcolor_no_array =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform int n_stop;\n"
+	    "uniform float stop0;\n"
+	    "uniform float stop1;\n"
+	    "uniform float stop2;\n"
+	    "uniform float stop3;\n"
+	    "uniform float stop4;\n"
+	    "uniform float stop5;\n"
+	    "uniform float stop6;\n"
+	    "uniform float stop7;\n"
+	    "uniform vec4 stop_color0;\n"
+	    "uniform vec4 stop_color1;\n"
+	    "uniform vec4 stop_color2;\n"
+	    "uniform vec4 stop_color3;\n"
+	    "uniform vec4 stop_color4;\n"
+	    "uniform vec4 stop_color5;\n"
+	    "uniform vec4 stop_color6;\n"
+	    "uniform vec4 stop_color7;\n"
+	    "\n"
+	    "vec4 get_color(float stop_len)\n"
+	    "{\n"
+	    "    float stop_after;\n"
+	    "    float stop_before;\n"
+	    "    vec4 stop_color_before;\n"
+	    "    vec4 stop_color_after;\n"
+	    "    float new_alpha; \n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    \n"
+	    "    if((stop_len < stop0) && (n_stop >= 1)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color0;\n"
+	    "        stop_after = stop0;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = 0.0;\n"
+	    "    } else if((stop_len < stop1) && (n_stop >= 2)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color1;\n"
+	    "        stop_after = stop1;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = (stop_len - stop0)/(stop1 - stop0);\n"
+	    "    } else if((stop_len < stop2) && (n_stop >= 3)) {\n"
+	    "        stop_color_before = stop_color1;\n"
+	    "        stop_color_after = stop_color2;\n"
+	    "        stop_after = stop2;\n"
+	    "        stop_before = stop1;\n"
+	    "        percentage = (stop_len - stop1)/(stop2 - stop1);\n"
+	    "    } else if((stop_len < stop3) && (n_stop >= 4)){\n"
+	    "        stop_color_before = stop_color2;\n"
+	    "        stop_color_after = stop_color3;\n"
+	    "        stop_after = stop3;\n"
+	    "        stop_before = stop2;\n"
+	    "        percentage = (stop_len - stop2)/(stop3 - stop2);\n"
+	    "    } else if((stop_len < stop4) && (n_stop >= 5)){\n"
+	    "        stop_color_before = stop_color3;\n"
+	    "        stop_color_after = stop_color4;\n"
+	    "        stop_after = stop4;\n"
+	    "        stop_before = stop3;\n"
+	    "        percentage = (stop_len - stop3)/(stop4 - stop3);\n"
+	    "    } else if((stop_len < stop5) && (n_stop >= 6)){\n"
+	    "        stop_color_before = stop_color4;\n"
+	    "        stop_color_after = stop_color5;\n"
+	    "        stop_after = stop5;\n"
+	    "        stop_before = stop4;\n"
+	    "        percentage = (stop_len - stop4)/(stop5 - stop4);\n"
+	    "    } else if((stop_len < stop6) && (n_stop >= 7)){\n"
+	    "        stop_color_before = stop_color5;\n"
+	    "        stop_color_after = stop_color6;\n"
+	    "        stop_after = stop6;\n"
+	    "        stop_before = stop5;\n"
+	    "        percentage = (stop_len - stop5)/(stop6 - stop5);\n"
+	    "    } else if((stop_len < stop7) && (n_stop >= 8)){\n"
+	    "        stop_color_before = stop_color6;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop6;\n"
+	    "        percentage = (stop_len - stop6)/(stop7 - stop6);\n"
+	    "    } else {\n"
+	    "        stop_color_before = stop_color7;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop7;\n"
+	    "        percentage = 0.0;\n"
+	    "    }\n"
+	    "    if(stop_after - stop_before > 2.0)\n"
+	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_color_after.a + \n"
+	    "                       (1.0-percentage) * stop_color_before.a; \n"
+	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
+	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	if(use_array) {
+		XNFasprintf(&gradient_fs,
+		    gradient_fs_getcolor, stops_count, stops_count);
+		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+		                                            gradient_fs);
+		free(gradient_fs);
+	} else {
+		fs_getcolor_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+		                                            gradient_fs_getcolor_no_array);
+	}
+
+	return fs_getcolor_prog;
+}
+
+static GLint
+_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	GLint gradient_prog = 0;
+	char *gradient_fs = NULL;
+	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
+
+	const char *gradient_vs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_Position = v_position;\n"
+	    "    source_texture = v_texcoord.xy;\n"
+	    "}\n";
+
+	/*
+	 *     Refer to pixman radial gradient.
+	 *
+	 *     The problem is given the two circles of c1 and c2 with the radius of r1 and
+	 *     r1, we need to caculate the t, which is used to do interpolate with stops,
+	 *     using the fomula:
+	 *     length((1-t)*c1 + t*c2 - p) = (1-t)*r1 + t*r2
+	 *     expand the fomula with xy coond, get the following:
+	 *     sqrt(sqr((1-t)*c1.x + t*c2.x - p.x) + sqr((1-t)*c1.y + t*c2.y - p.y))
+	 *           = (1-t)r1 + t*r2
+	 *     <====> At*t- 2Bt + C = 0
+	 *     where A = sqr(c2.x - c1.x) + sqr(c2.y - c1.y) - sqr(r2 -r1)
+	 *           B = (p.x - c1.x)*(c2.x - c1.x) + (p.y - c1.y)*(c2.y - c1.y) + r1*(r2 -r1)
+	 *           C = sqr(p.x - c1.x) + sqr(p.y - c1.y) - r1*r1
+	 *
+	 *     solve the fomula and we get the result of
+	 *     t = (B + sqrt(B*B - A*C)) / A  or
+	 *     t = (B - sqrt(B*B - A*C)) / A  (quadratic equation have two solutions)
+	 *
+	 *     The solution we are going to prefer is the bigger one, unless the
+	 *     radius associated to it is negative (or it falls outside the valid t range)
+	 */
+
+	const char *gradient_fs_template =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform mat3 transform_mat;\n"
+	    "uniform int repeat_type;\n"
+	    "uniform float A_value;\n"
+	    "uniform vec2 c1;\n"
+	    "uniform float r1;\n"
+	    "uniform vec2 c2;\n"
+	    "uniform float r2;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "vec4 get_color(float stop_len);\n"
+	    "\n"
+	    "int t_invalid;\n"
+	    "\n"
+	    "float get_stop_len()\n"
+	    "{\n"
+	    "    float t = 0.0;\n"
+	    "    float sqrt_value;\n"
+	    "    int revserse = 0;\n"
+	    "    t_invalid = 0;\n"
+	    "    \n"
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
+	    "    source_texture_trans.xy = source_texture_trans.xy/source_texture_trans.z;\n"
+	    "    float B_value = (source_texture_trans.x - c1.x) * (c2.x - c1.x)\n"
+	    "                     + (source_texture_trans.y - c1.y) * (c2.y - c1.y)\n"
+	    "                     + r1 * (r2 - r1);\n"
+	    "    float C_value = (source_texture_trans.x - c1.x) * (source_texture_trans.x - c1.x)\n"
+	    "                     + (source_texture_trans.y - c1.y) * (source_texture_trans.y - c1.y)\n"
+	    "                     - r1*r1;\n"
+	    "    if(abs(A_value) < 0.00001) {\n"
+	    "        if(B_value == 0.0) {\n"
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "        t = 0.5 * C_value / B_value;"
+	    "    } else {\n"
+	    "        sqrt_value = B_value * B_value - A_value * C_value;\n"
+	    "        if(sqrt_value < 0.0) {\n"
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "        sqrt_value = sqrt(sqrt_value);\n"
+	    "        t = (B_value + sqrt_value) / A_value;\n"
+	    "    }\n"
+	    "    if(repeat_type == %d) {\n" // RepeatNone case.
+	    "        if((t <= 0.0) || (t > 1.0))\n"
+	    //           try another if first one invalid
+	    "            t = (B_value - sqrt_value) / A_value;\n"
+	    "        \n"
+	    "        if((t <= 0.0) || (t > 1.0)) {\n" //still invalid, return.
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "    } else {\n"
+	    "        if(t * (r2 - r1) <= -1.0 * r1)\n"
+	    //           try another if first one invalid
+	    "            t = (B_value - sqrt_value) / A_value;\n"
+	    "        \n"
+	    "        if(t * (r2 -r1) <= -1.0 * r1) {\n" //still invalid, return.
+	    "            t_invalid = 1;\n"
+	    "            return t;\n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d){\n" // repeat normal
+	    "        while(t > 1.0) \n"
+	    "            t = t - 1.0; \n"
+	    "        while(t < 0.0) \n"
+	    "            t = t + 1.0; \n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d) {\n" // repeat reflect
+	    "        while(t > 1.0) {\n"
+	    "            t = t - 1.0; \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        while(t < 0.0) {\n"
+	    "            t = t + 1.0; \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        if(revserse == 1) {\n"
+	    "            t = 1.0 - t; \n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    return t;\n"
+	    "}\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    float stop_len = get_stop_len();\n"
+	    "    if(t_invalid == 1) {\n"
+	    "        gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
+	    "    } else {\n"
+	    "        gl_FragColor = get_color(stop_len);\n"
+	    "    }\n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	gradient_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch,
+	          GL_VERTEX_SHADER, gradient_vs);
+
+	XNFasprintf(&gradient_fs,
+	            gradient_fs_template,
+	            PIXMAN_REPEAT_NONE, PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+
+	fs_main_prog = glamor_compile_glsl_prog(dispatch,
+	                                        GL_FRAGMENT_SHADER, gradient_fs);
+
+	free(gradient_fs);
+
+	fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
+	                                                      stops_count, use_array);
+
+	dispatch->glAttachShader(gradient_prog, vs_prog);
+	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+	dispatch->glAttachShader(gradient_prog, fs_main_prog);
+
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_positionsition");
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
+
+	glamor_link_glsl_prog(dispatch, gradient_prog);
+
+	dispatch->glUseProgram(0);
+
+	glamor_put_dispatch(glamor_priv);
+	return gradient_prog;
+}
+
+static GLint
 _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int use_array)
 {
 	glamor_screen_private *glamor_priv;
@@ -1283,7 +1622,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 
 	GLint gradient_prog = 0;
 	char *gradient_fs = NULL;
-	GLint fs_prog, vs_prog;
+	GLint fs_main_prog, fs_getcolor_prog, vs_prog;
 
 	const char *gradient_vs =
 	    GLAMOR_DEFAULT_PRECISION
@@ -1350,9 +1689,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "uniform mat3 transform_mat;\n"
 	    "uniform int repeat_type;\n"
 	    "uniform int hor_ver;\n"
-	    "uniform int n_stop;\n"
-	    "uniform float stops[%d];\n"
-	    "uniform vec4 stop_colors[%d];\n"
 	    "uniform vec4 pt1;\n"
 	    "uniform vec4 pt2;\n"
 	    "uniform float pt_slope;\n"
@@ -1361,7 +1697,9 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "uniform float pt_distance;\n"
 	    "varying vec2 source_texture;\n"
 	    "\n"
-	    "vec4 get_color()\n"
+	    "vec4 get_color(float stop_len);\n"
+	    "\n"
+	    "float get_stop_len()\n"
 	    "{\n"
 	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
 	    "    float len_percentage;\n"
@@ -1369,8 +1707,11 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "    float _p1_distance;\n"
 	    "    float _pt_distance;\n"
 	    "    float y_dist;\n"
+	    "    float stop_after;\n"
+	    "    float stop_before;\n"
+	    "    vec4 stop_color_before;\n"
+	    "    vec4 stop_color_after;\n"
 	    "    float new_alpha; \n"
-	    "    int i = n_stop - 1;\n"
 	    "    int revserse = 0;\n"
 	    "    vec4 gradient_color;\n"
 	    "    float percentage; \n"
@@ -1414,7 +1755,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "            if(revserse == 0)\n"
 	    "                revserse = 1;\n"
 	    "            else\n"
-	    "	             revserse = 0;\n"
+	    "                revserse = 0;\n"
 	    "        }\n"
 	    "        if(revserse == 1) {\n"
 	    "            distance = (_pt_distance) - distance; \n"
@@ -1422,193 +1763,14 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	    "    }\n"
 	    "    \n"
 	    "    len_percentage = distance/(_pt_distance);\n"
-	    "    for(i = 0; i < n_stop - 1; i++) {\n"
-	    "        if(len_percentage < stops[i])\n"
-	    "            break; \n"
-	    "    }\n"
-	    "    \n"
-	    "    percentage = (len_percentage - stops[i-1])/(stops[i] - stops[i-1]);\n"
-	    "    if(stops[i] - stops[i-1] > 2.0)\n"
-	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
-	    "    new_alpha = percentage * stop_colors[i].a + \n"
-	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
-	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
-	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
 	    "    \n"
-	    "    return gradient_color;\n"
+	    "    return len_percentage;\n"
 	    "}\n"
 	    "\n"
 	    "void main()\n"
 	    "{\n"
-	    "    gl_FragColor = get_color();\n"
-	    "}\n";
-
-	/* Because the array access for shader is very slow, the performance is very low
-	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
-	const char *gradient_fs_no_array_template =
-	    GLAMOR_DEFAULT_PRECISION
-	    "uniform mat3 transform_mat;\n"
-	    "uniform int repeat_type;\n"
-	    "uniform int hor_ver;\n"
-	    "uniform int n_stop;\n"
-	    "uniform float stop0;\n"
-	    "uniform float stop1;\n"
-	    "uniform float stop2;\n"
-	    "uniform float stop3;\n"
-	    "uniform float stop4;\n"
-	    "uniform float stop5;\n"
-	    "uniform float stop6;\n"
-	    "uniform float stop7;\n"
-	    "uniform vec4 stop_color0;\n"
-	    "uniform vec4 stop_color1;\n"
-	    "uniform vec4 stop_color2;\n"
-	    "uniform vec4 stop_color3;\n"
-	    "uniform vec4 stop_color4;\n"
-	    "uniform vec4 stop_color5;\n"
-	    "uniform vec4 stop_color6;\n"
-	    "uniform vec4 stop_color7;\n"
-	    "uniform vec4 pt1;\n"
-	    "uniform vec4 pt2;\n"
-	    "uniform float pt_slope;\n"
-	    "uniform float cos_val;\n"
-	    "uniform float p1_distance;\n"
-	    "uniform float pt_distance;\n"
-	    "varying vec2 source_texture;\n"
-	    "\n"
-	    "vec4 get_color()\n"
-	    "{\n"
-	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
-	    "    float len_percentage;\n"
-	    "    float distance;\n"
-	    "    float _p1_distance;\n"
-	    "    float _pt_distance;\n"
-	    "    float y_dist;\n"
-	    "    float stop_after;\n"
-	    "    float stop_before;\n"
-	    "    vec4 stop_color_before;\n"
-	    "    vec4 stop_color_after;\n"
-	    "    float new_alpha; \n"
-	    "    int revserse = 0;\n"
-	    "    vec4 gradient_color;\n"
-	    "    float percentage; \n"
-	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
-	    "    \n"
-	    "    if(hor_ver == 0) { \n" //Normal case.
-	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
-	    "        distance = y_dist * cos_val;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "        \n"
-	    "    } else if (hor_ver == 1) {\n"//horizontal case.
-	    "        distance = source_texture_trans.x;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } else if (hor_ver == 2) {\n"//vertical case.
-	    "        distance = source_texture_trans.y;\n"
-	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
-	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
-	    "    } \n"
-	    "    \n"
-	    "    distance = distance - _p1_distance; \n"
-	    "    \n"
-	    "    if(repeat_type == %d){\n" // repeat normal
-	    "        while(distance > _pt_distance) \n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "        while(distance < 0.0) \n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "    }\n"
-	    "    \n"
-	    "    if(repeat_type == %d) {\n" // repeat reflect
-	    "        while(distance > _pt_distance) {\n"
-	    "            distance = distance - (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "                revserse = 0;\n"
-	    "        }\n"
-	    "        while(distance < 0.0) {\n"
-	    "            distance = distance + (_pt_distance); \n"
-	    "            if(revserse == 0)\n"
-	    "                revserse = 1;\n"
-	    "            else\n"
-	    "	             revserse = 0;\n"
-	    "        }\n"
-	    "        if(revserse == 1) {\n"
-	    "            distance = (_pt_distance) - distance; \n"
-	    "        }\n"
-	    "    }\n"
-	    "    \n"
-	    "    len_percentage = distance/(_pt_distance);\n"
-	    "    if((len_percentage < stop0) && (n_stop >= 1)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color0;\n"
-	    "        stop_after = stop0;\n"
-	    "        stop_before = stop0;\n"
-	    "        percentage = 0.0;\n"
-	    "    } else if((len_percentage < stop1) && (n_stop >= 2)) {\n"
-	    "        stop_color_before = stop_color0;\n"
-	    "        stop_color_after = stop_color1;\n"
-	    "        stop_after = stop1;\n"
-	    "        stop_before = stop0;\n"
-	    "        percentage = (len_percentage - stop0)/(stop1 - stop0);\n"
-	    "    } else if((len_percentage < stop2) && (n_stop >= 3)) {\n"
-	    "        stop_color_before = stop_color1;\n"
-	    "        stop_color_after = stop_color2;\n"
-	    "        stop_after = stop2;\n"
-	    "        stop_before = stop1;\n"
-	    "        percentage = (len_percentage - stop1)/(stop2 - stop1);\n"
-	    "    } else if((len_percentage < stop3) && (n_stop >= 4)){\n"
-	    "        stop_color_before = stop_color2;\n"
-	    "        stop_color_after = stop_color3;\n"
-	    "        stop_after = stop3;\n"
-	    "        stop_before = stop2;\n"
-	    "        percentage = (len_percentage - stop2)/(stop3 - stop2);\n"
-	    "    } else if((len_percentage < stop4) && (n_stop >= 5)){\n"
-	    "        stop_color_before = stop_color3;\n"
-	    "        stop_color_after = stop_color4;\n"
-	    "        stop_after = stop4;\n"
-	    "        stop_before = stop3;\n"
-	    "        percentage = (len_percentage - stop3)/(stop4 - stop3);\n"
-	    "    } else if((len_percentage < stop5) && (n_stop >= 6)){\n"
-	    "        stop_color_before = stop_color4;\n"
-	    "        stop_color_after = stop_color5;\n"
-	    "        stop_after = stop5;\n"
-	    "        stop_before = stop4;\n"
-	    "        percentage = (len_percentage - stop4)/(stop5 - stop4);\n"
-	    "    } else if((len_percentage < stop6) && (n_stop >= 7)){\n"
-	    "        stop_color_before = stop_color5;\n"
-	    "        stop_color_after = stop_color6;\n"
-	    "        stop_after = stop6;\n"
-	    "        stop_before = stop5;\n"
-	    "        percentage = (len_percentage - stop5)/(stop6 - stop5);\n"
-	    "    } else if((len_percentage < stop7) && (n_stop >= 8)){\n"
-	    "        stop_color_before = stop_color6;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop6;\n"
-	    "        percentage = (len_percentage - stop6)/(stop7 - stop6);\n"
-	    "    } else {\n"
-	    "        stop_color_before = stop_color7;\n"
-	    "        stop_color_after = stop_color7;\n"
-	    "        stop_after = stop7;\n"
-	    "        stop_before = stop7;\n"
-	    "        percentage = 0.0;\n"
-	    "    }\n"
-	    "    if(stop_after - stop_before > 2.0)\n"
-	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
-	    "    new_alpha = percentage * stop_color_after.a + \n"
-	    "                       (1.0-percentage) * stop_color_before.a; \n"
-	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
-	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
-	    "                          new_alpha);\n"
-	    "    \n"
-	    "    return gradient_color;\n"
-	    "}\n"
-	    "\n"
-	    "void main()\n"
-	    "{\n"
-	    "    gl_FragColor = get_color();\n"
+	    "    float stop_len = get_stop_len();\n"
+	    "    gl_FragColor = get_color(stop_len);\n"
 	    "}\n";
 
 	glamor_priv = glamor_get_screen_private(screen);
@@ -1617,23 +1779,22 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 	gradient_prog = dispatch->glCreateProgram();
 
 	vs_prog = glamor_compile_glsl_prog(dispatch,
-	          GL_VERTEX_SHADER, gradient_vs);
+	                                   GL_VERTEX_SHADER, gradient_vs);
 
-	if (use_array) {
-		XNFasprintf(&gradient_fs,
-		            gradient_fs_template, stops_count, stops_count,
-		            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-	} else {
-		XNFasprintf(&gradient_fs,
-		            gradient_fs_no_array_template,
-		            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
-	}
-	fs_prog = glamor_compile_glsl_prog(dispatch,
-	          GL_FRAGMENT_SHADER, gradient_fs);
+	XNFasprintf(&gradient_fs,
+	            gradient_fs_template,
+	            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+
+	fs_main_prog = glamor_compile_glsl_prog(dispatch,
+	                                        GL_FRAGMENT_SHADER, gradient_fs);
 	free(gradient_fs);
 
+	fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
+	                                                      stops_count, use_array);
+
 	dispatch->glAttachShader(gradient_prog, vs_prog);
-	dispatch->glAttachShader(gradient_prog, fs_prog);
+	dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
+	dispatch->glAttachShader(gradient_prog, fs_main_prog);
 
 	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
 	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
@@ -1647,6 +1808,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
 }
 
 #define LINEAR_DEFAULT_STOPS 6 + 2
+#define RADIAL_DEFAULT_STOPS 6 + 2
 
 void
 glamor_init_gradient_shader(ScreenPtr screen)
@@ -1658,6 +1820,9 @@ glamor_init_gradient_shader(ScreenPtr screen)
 	glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR] =
 	    _glamor_create_linear_gradient_program(screen,
 	            LINEAR_DEFAULT_STOPS, 0);
+	glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL] =
+	    _glamor_create_radial_gradient_program(screen,
+	            RADIAL_DEFAULT_STOPS, 0);
 }
 
 void
@@ -1671,13 +1836,15 @@ glamor_fini_gradient_shader(ScreenPtr screen)
 
 	dispatch->glDeleteProgram(
 	    glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR]);
+	dispatch->glDeleteProgram(
+	    glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL]);
 
 	glamor_put_dispatch(glamor_priv);
 }
 
 static void
 _glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
-				      int width, int height)
+				      int width, int height, int normalize)
 {
 	/*
 	 * Because in the shader program, we normalize all the pixel cood to [0, 1],
@@ -1713,20 +1880,20 @@ _glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
 
 	to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]);
 	to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1])
-	                                         * ((float)height) / ((float)width);
+	                        * (normalize ? (((float)height) / ((float)width)) : 1.0);
 	to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2])
-	                                         / ((float)width);
+	                        / (normalize ? ((float)width) : 1.0);
 
 	to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0])
-	                                         * ((float)width) / ((float)height);
+	                        * (normalize ? (((float)width) / ((float)height)) : 1.0);
 	to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]);
 	to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2])
-	                                         / ((float)height);
+	                        / (normalize ? ((float)height) : 1.0);
 
 	to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0])
-	                                         * ((float)width);
+	                        * (normalize ? ((float)width) : 1.0);
 	to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1])
-	                                         * ((float)height);
+	                        * (normalize ? ((float)height) : 1.0);
 	to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]);
 
 	DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
@@ -1878,6 +2045,329 @@ _glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
 }
 
 static PicturePtr
+_glamor_generate_radial_gradient_picture(ScreenPtr screen,
+                                         PicturePtr src_picture,
+                                         int x_source, int y_source,
+                                         int width, int height,
+                                         PictFormatShort format)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	PicturePtr dst_picture = NULL;
+	PixmapPtr pixmap = NULL;
+	glamor_pixmap_private *pixmap_priv;
+	GLint gradient_prog = 0;
+	int error;
+	float tex_vertices[8];
+	int stops_count;
+	int count = 0;
+	GLfloat *stop_colors = NULL;
+	GLfloat *n_stops = NULL;
+	GLfloat xscale, yscale;
+	float vertices[8];
+	float transform_mat[3][3];
+	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
+	                                         {0.0, 1.0, 0.0},
+	                                         {0.0, 0.0, 1.0}};
+	GLfloat stop_colors_st[RADIAL_DEFAULT_STOPS*4];
+	GLfloat n_stops_st[RADIAL_DEFAULT_STOPS];
+	GLfloat A_value;
+	GLfloat cxy[4];
+	float c1x, c1y, c2x, c2y, r1, r2;
+
+	GLint transform_mat_uniform_location;
+	GLint repeat_type_uniform_location;
+	GLint n_stop_uniform_location;
+	GLint stops_uniform_location;
+	GLint stop_colors_uniform_location;
+	GLint stop0_uniform_location;
+	GLint stop1_uniform_location;
+	GLint stop2_uniform_location;
+	GLint stop3_uniform_location;
+	GLint stop4_uniform_location;
+	GLint stop5_uniform_location;
+	GLint stop6_uniform_location;
+	GLint stop7_uniform_location;
+	GLint stop_color0_uniform_location;
+	GLint stop_color1_uniform_location;
+	GLint stop_color2_uniform_location;
+	GLint stop_color3_uniform_location;
+	GLint stop_color4_uniform_location;
+	GLint stop_color5_uniform_location;
+	GLint stop_color6_uniform_location;
+	GLint stop_color7_uniform_location;
+	GLint A_value_uniform_location;
+	GLint c1_uniform_location;
+	GLint r1_uniform_location;
+	GLint c2_uniform_location;
+	GLint r2_uniform_location;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	/* Create a pixmap with VBO. */
+	pixmap = glamor_create_pixmap(screen,
+	                              width, height,
+	                              PIXMAN_FORMAT_DEPTH(format),
+	                              GLAMOR_CREATE_PIXMAP_FIXUP);
+	if (!pixmap)
+		goto GRADIENT_FAIL;
+
+	dst_picture = CreatePicture(0, &pixmap->drawable,
+	                            PictureMatchFormat(screen,
+	                                 PIXMAN_FORMAT_DEPTH(format), format),
+	                            0, 0, serverClient, &error);
+
+	/* Release the reference, picture will hold the last one. */
+	glamor_destroy_pixmap(pixmap);
+
+	if (!dst_picture)
+		goto GRADIENT_FAIL;
+
+	ValidatePicture(dst_picture);
+
+	stops_count = src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS ?
+	              src_picture->pSourcePict->radial.nstops + 2 : RADIAL_DEFAULT_STOPS;
+
+	/* Because the max value of nstops is unkown, so create a programwhen nstops > default.*/
+	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL];
+	} else {
+		gradient_prog = _glamor_create_radial_gradient_program(screen,
+		                          src_picture->pSourcePict->radial.nstops + 2, 1);
+	}
+
+	/* Bind all the uniform vars .*/
+	transform_mat_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	n_stop_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+	A_value_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "A_value");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	c1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "c1");
+	r1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "r1");
+	c2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "c2");
+	r2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "r2");
+
+	if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
+		stop0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
+		stop1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
+		stop2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
+		stop3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
+		stop4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
+		stop5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
+		stop6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
+		stop7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+		stop_color0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+		stop_color1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+		stop_color2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+		stop_color3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+		stop_color4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+		stop_color5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+		stop_color6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+		stop_color7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+	} else {
+		stops_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stops");
+		stop_colors_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+	}
+
+	dispatch->glUseProgram(gradient_prog);
+
+	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
+
+
+	if (src_picture->transform) {
+		_glamor_gradient_convert_trans_matrix(src_picture->transform,
+		                                      transform_mat,
+		                                      width, height, 0);
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &transform_mat[0][0]);
+	} else {
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &identity_mat[0][0]);
+	}
+
+	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
+	                                             &xscale, &yscale, x_source, y_source,
+	                                             vertices, tex_vertices, 0))
+		goto GRADIENT_FAIL;
+
+	/* Set all the stops and colors to shader. */
+	if (stops_count > RADIAL_DEFAULT_STOPS) {
+		stop_colors = malloc(4 * stops_count * sizeof(float));
+		if (stop_colors == NULL) {
+			ErrorF("Failed to allocate stop_colors memory.\n");
+			goto GRADIENT_FAIL;
+		}
+
+		n_stops = malloc(stops_count * sizeof(float));
+		if (n_stops == NULL) {
+			ErrorF("Failed to allocate n_stops memory.\n");
+			goto GRADIENT_FAIL;
+		}
+	} else {
+		stop_colors = stop_colors_st;
+		n_stops = n_stops_st;
+	}
+
+	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
+	                                   stop_colors, n_stops);
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+		int j = 0;
+		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color1_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color2_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color3_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color4_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color5_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color6_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color7_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+
+		j = 0;
+		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	} else {
+		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	}
+
+	c1x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.x);
+	c1y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.y);
+	c2x = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.x);
+	c2y = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.y);
+
+	r1 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c1.radius);
+	r2 = (float)pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.radius);
+
+
+	cxy[0] = c1x;
+	cxy[1] = c1y;
+	dispatch->glUniform2fv(c1_uniform_location, 1, cxy);
+	dispatch->glUniform1f(r1_uniform_location, r1);
+
+	cxy[0] = c2x;
+	cxy[1] = c2y;
+	dispatch->glUniform2fv(c2_uniform_location, 1, cxy);
+	dispatch->glUniform1f(r2_uniform_location, r2);
+
+	A_value = (c2x - c1x) * (c2x - c1x) + (c2y - c1y) * (c2y - c1y) - (r2 - r1) * (r2 - r1);
+	dispatch->glUniform1f(A_value_uniform_location, A_value);
+
+	DEBUGF("C1:(%f, %f) R1:%f\nC2:(%f, %f) R2:%f\nA = %f\n",
+	       c1x, c1y, r1, c2x, c2y, r2, A_value);
+
+	glamor_emit_composite_rect(screen, tex_vertices, NULL, vertices);
+
+	if (glamor_priv->render_nr_verts) {
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+		else {
+
+			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+			dispatch->glBufferData(GL_ARRAY_BUFFER,
+			                       glamor_priv->vbo_offset,
+			                       glamor_priv->vb, GL_DYNAMIC_DRAW);
+		}
+
+		dispatch->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL);
+	}
+
+
+	/* Do the clear logic.*/
+	if (stops_count > RADIAL_DEFAULT_STOPS) {
+		free(n_stops);
+		free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+
+	if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
+		dispatch->glDeleteProgram(gradient_prog);
+
+	glamor_put_dispatch(glamor_priv);
+	return dst_picture;
+
+GRADIENT_FAIL:
+	if (dst_picture) {
+		FreePicture(dst_picture, 0);
+	}
+
+	if (stops_count > RADIAL_DEFAULT_STOPS) {
+		if (n_stops)
+			free(n_stops);
+		if (stop_colors)
+			free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
+		dispatch->glDeleteProgram(gradient_prog);
+	glamor_put_dispatch(glamor_priv);
+	return NULL;
+}
+
+static PicturePtr
 _glamor_generate_linear_gradient_picture(ScreenPtr screen,
                                          PicturePtr src_picture,
                                          int x_source, int y_source,
@@ -1905,8 +2395,8 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	float vertices[8];
 	float transform_mat[3][3];
 	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
-		                                 {0.0, 1.0, 0.0},
-		                                 {0.0, 0.0, 1.0}};
+	                                         {0.0, 1.0, 0.0},
+	                                         {0.0, 0.0, 1.0}};
 	GLfloat stop_colors_st[LINEAR_DEFAULT_STOPS*4];
 	GLfloat n_stops_st[LINEAR_DEFAULT_STOPS];
 
@@ -2046,7 +2536,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
 	if (src_picture->transform) {
 		_glamor_gradient_convert_trans_matrix(src_picture->transform,
 		                                      transform_mat,
-		                                      width, height);
+		                                      width, height, 1);
 		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
 		                             1, 1, &transform_mat[0][0]);
 	} else {
@@ -2258,6 +2748,9 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 		if (source->pSourcePict->type == SourcePictTypeLinear) {
 			dst = _glamor_generate_linear_gradient_picture(screen,
 				source, x_source, y_source, width, height, format);
+		} else if (source->pSourcePict->type == SourcePictTypeRadial) {
+			dst = _glamor_generate_radial_gradient_picture(screen,
+		                  source, x_source, y_source, width, height, format);
 		}
 
 		if (dst) {
commit 1026327cdc90bc0c801a493b7b76b3efc5f33fe2
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Mar 23 04:05:56 2012 +0800

    Add the feature of generating linear gradient picture by using shader.
    
     Add the feature of generating linear gradient picture
     by using shader.  This logic will replace the original
     linear gradient picture generating manner in glamor
     which firstly use pixman and then upload it to GPU.
     Compare it to the result generated by pixman, the
     difference of each color component of each pixel is
     normally 0, sometimes 1/255, and 2/255 at most. The
     pixman use fixed-point but shader use float-point, so may have
     difference. The feature of transform matrix and 4 types
     of repeat modes have been supported. The array usage in
     shader seems slow, so use 8 uniform variables to avoid
     using array when stops number is not very big. This
     make code look verbose but the performance improved a
     lot.
    
     We still have slightly performance regression compare to
     original pixman version. There are one further optimization
     opportunity which is to merge the gradient pixmap generation
     and the latter compositing into one shader, then we don't need
     to generate the extra texture, we can use the gradient value
     directly at the compositing shader. Hope that can beat pixman
     version. Will do that latter.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 093e01d..6304167 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1275,6 +1275,378 @@ done:
 	return ret;
 }
 
+static GLint
+_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	GLint gradient_prog = 0;
+	char *gradient_fs = NULL;
+	GLint fs_prog, vs_prog;
+
+	const char *gradient_vs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_Position = v_position;\n"
+	    "    source_texture = v_texcoord.xy;\n"
+	    "}\n";
+
+	/*
+	 *                                      |
+	 *                                      |\
+	 *                                      | \
+	 *                                      |  \
+	 *                                      |   \
+	 *                                      |\   \
+	 *                                      | \   \
+	 *     cos_val =                        |\ p1d \   /
+	 *      sqrt(1/(slope*slope+1.0))  ------>\ \   \ /
+	 *                                      |  \ \   \
+	 *                                      |   \ \ / \
+	 *                                      |    \ *Pt1\
+	 *         *p1                          |     \     \     *P
+	 *          \                           |    / \     \   /
+	 *           \                          |   /   \     \ /
+	 *            \                         |       pd     \
+	 *             \                        |         \   / \
+	 *            p2*                       |          \ /   \       /
+	 *        slope = (p2.y - p1.y) /       |           /     p2d   /
+	 *                    (p2.x - p1.x)     |          /       \   /
+	 *                                      |         /         \ /
+	 *                                      |        /           /
+	 *                                      |       /           /
+	 *                                      |      /           *Pt2
+	 *                                      |                 /
+	 *                                      |                /
+	 *                                      |               /
+	 *                                      |              /
+	 *                                      |             /
+	 *                               -------+---------------------------------
+	 *                                     O|
+	 *                                      |
+	 *                                      |
+	 *
+	 *	step 1: compute the distance of p, pt1 and pt2 in the slope direction.
+	 *		Caculate the distance on Y axis first and multiply cos_val to
+	 *		get the value on slope direction(pd, p1d and p2d represent the
+	 *		distance of p, pt1, and pt2 respectively).
+	 *
+	 *	step 2: caculate the percentage of (pd - p1d)/(p2d - p1d).
+	 *		If (pd - p1d) > (p2d - p1d) or < 0, then sub or add (p2d - p1d)
+	 *		to make it in the range of [0, (p2d - p1d)].
+	 *
+	 *	step 3: compare the percentage to every stop and find the stpos just
+	 *		before and after it. Use the interpolation fomula to compute RGBA.
+	 */
+
+	const char *gradient_fs_template =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform mat3 transform_mat;\n"
+	    "uniform int repeat_type;\n"
+	    "uniform int hor_ver;\n"
+	    "uniform int n_stop;\n"
+	    "uniform float stops[%d];\n"
+	    "uniform vec4 stop_colors[%d];\n"
+	    "uniform vec4 pt1;\n"
+	    "uniform vec4 pt2;\n"
+	    "uniform float pt_slope;\n"
+	    "uniform float cos_val;\n"
+	    "uniform float p1_distance;\n"
+	    "uniform float pt_distance;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "vec4 get_color()\n"
+	    "{\n"
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
+	    "    float len_percentage;\n"
+	    "    float distance;\n"
+	    "    float _p1_distance;\n"
+	    "    float _pt_distance;\n"
+	    "    float y_dist;\n"
+	    "    float new_alpha; \n"
+	    "    int i = n_stop - 1;\n"
+	    "    int revserse = 0;\n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
+	    "    \n"
+	    "    if(hor_ver == 0) { \n" //Normal case.
+	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
+	    "        distance = y_dist * cos_val;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "        \n"
+	    "    } else if (hor_ver == 1) {\n"//horizontal case.
+	    "        distance = source_texture_trans.x;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } else if (hor_ver == 2) {\n"//vertical case.
+	    "        distance = source_texture_trans.y;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } \n"
+	    "    \n"
+	    "    distance = distance - _p1_distance; \n"
+	    "    \n"
+	    "    if(repeat_type == %d){\n" // repeat normal
+	    "        while(distance > _pt_distance) \n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "        while(distance < 0.0) \n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d) {\n" // repeat reflect
+	    "        while(distance > _pt_distance) {\n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        while(distance < 0.0) {\n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "	             revserse = 0;\n"
+	    "        }\n"
+	    "        if(revserse == 1) {\n"
+	    "            distance = (_pt_distance) - distance; \n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    len_percentage = distance/(_pt_distance);\n"
+	    "    for(i = 0; i < n_stop - 1; i++) {\n"
+	    "        if(len_percentage < stops[i])\n"
+	    "            break; \n"
+	    "    }\n"
+	    "    \n"
+	    "    percentage = (len_percentage - stops[i-1])/(stops[i] - stops[i-1]);\n"
+	    "    if(stops[i] - stops[i-1] > 2.0)\n"
+	    "        percentage = 0.0;\n" //For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_colors[i].a + \n"
+	    "                       (1.0-percentage) * stop_colors[i-1].a; \n"
+	    "    gradient_color = vec4((percentage * stop_colors[i].rgb \n"
+	    "                          + (1.0-percentage) * stop_colors[i-1].rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_FragColor = get_color();\n"
+	    "}\n";
+
+	/* Because the array access for shader is very slow, the performance is very low
+	   if use array. So use global uniform to replace for it if the number of n_stops is small.*/
+	const char *gradient_fs_no_array_template =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform mat3 transform_mat;\n"
+	    "uniform int repeat_type;\n"
+	    "uniform int hor_ver;\n"
+	    "uniform int n_stop;\n"
+	    "uniform float stop0;\n"
+	    "uniform float stop1;\n"
+	    "uniform float stop2;\n"
+	    "uniform float stop3;\n"
+	    "uniform float stop4;\n"
+	    "uniform float stop5;\n"
+	    "uniform float stop6;\n"
+	    "uniform float stop7;\n"
+	    "uniform vec4 stop_color0;\n"
+	    "uniform vec4 stop_color1;\n"
+	    "uniform vec4 stop_color2;\n"
+	    "uniform vec4 stop_color3;\n"
+	    "uniform vec4 stop_color4;\n"
+	    "uniform vec4 stop_color5;\n"
+	    "uniform vec4 stop_color6;\n"
+	    "uniform vec4 stop_color7;\n"
+	    "uniform vec4 pt1;\n"
+	    "uniform vec4 pt2;\n"
+	    "uniform float pt_slope;\n"
+	    "uniform float cos_val;\n"
+	    "uniform float p1_distance;\n"
+	    "uniform float pt_distance;\n"
+	    "varying vec2 source_texture;\n"
+	    "\n"
+	    "vec4 get_color()\n"
+	    "{\n"
+	    "    vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"
+	    "    float len_percentage;\n"
+	    "    float distance;\n"
+	    "    float _p1_distance;\n"
+	    "    float _pt_distance;\n"
+	    "    float y_dist;\n"
+	    "    float stop_after;\n"
+	    "    float stop_before;\n"
+	    "    vec4 stop_color_before;\n"
+	    "    vec4 stop_color_after;\n"
+	    "    float new_alpha; \n"
+	    "    int revserse = 0;\n"
+	    "    vec4 gradient_color;\n"
+	    "    float percentage; \n"
+	    "    vec3 source_texture_trans = transform_mat * tmp;\n"
+	    "    \n"
+	    "    if(hor_ver == 0) { \n" //Normal case.
+	    "        y_dist = source_texture_trans.y - source_texture_trans.x*pt_slope;\n"
+	    "        distance = y_dist * cos_val;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "        \n"
+	    "    } else if (hor_ver == 1) {\n"//horizontal case.
+	    "        distance = source_texture_trans.x;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } else if (hor_ver == 2) {\n"//vertical case.
+	    "        distance = source_texture_trans.y;\n"
+	    "        _p1_distance = p1_distance * source_texture_trans.z;\n"
+	    "        _pt_distance = pt_distance * source_texture_trans.z;\n"
+	    "    } \n"
+	    "    \n"
+	    "    distance = distance - _p1_distance; \n"
+	    "    \n"
+	    "    if(repeat_type == %d){\n" // repeat normal
+	    "        while(distance > _pt_distance) \n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "        while(distance < 0.0) \n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "    }\n"
+	    "    \n"
+	    "    if(repeat_type == %d) {\n" // repeat reflect
+	    "        while(distance > _pt_distance) {\n"
+	    "            distance = distance - (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "                revserse = 0;\n"
+	    "        }\n"
+	    "        while(distance < 0.0) {\n"
+	    "            distance = distance + (_pt_distance); \n"
+	    "            if(revserse == 0)\n"
+	    "                revserse = 1;\n"
+	    "            else\n"
+	    "	             revserse = 0;\n"
+	    "        }\n"
+	    "        if(revserse == 1) {\n"
+	    "            distance = (_pt_distance) - distance; \n"
+	    "        }\n"
+	    "    }\n"
+	    "    \n"
+	    "    len_percentage = distance/(_pt_distance);\n"
+	    "    if((len_percentage < stop0) && (n_stop >= 1)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color0;\n"
+	    "        stop_after = stop0;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = 0.0;\n"
+	    "    } else if((len_percentage < stop1) && (n_stop >= 2)) {\n"
+	    "        stop_color_before = stop_color0;\n"
+	    "        stop_color_after = stop_color1;\n"
+	    "        stop_after = stop1;\n"
+	    "        stop_before = stop0;\n"
+	    "        percentage = (len_percentage - stop0)/(stop1 - stop0);\n"
+	    "    } else if((len_percentage < stop2) && (n_stop >= 3)) {\n"
+	    "        stop_color_before = stop_color1;\n"
+	    "        stop_color_after = stop_color2;\n"
+	    "        stop_after = stop2;\n"
+	    "        stop_before = stop1;\n"
+	    "        percentage = (len_percentage - stop1)/(stop2 - stop1);\n"
+	    "    } else if((len_percentage < stop3) && (n_stop >= 4)){\n"
+	    "        stop_color_before = stop_color2;\n"
+	    "        stop_color_after = stop_color3;\n"
+	    "        stop_after = stop3;\n"
+	    "        stop_before = stop2;\n"
+	    "        percentage = (len_percentage - stop2)/(stop3 - stop2);\n"
+	    "    } else if((len_percentage < stop4) && (n_stop >= 5)){\n"
+	    "        stop_color_before = stop_color3;\n"
+	    "        stop_color_after = stop_color4;\n"
+	    "        stop_after = stop4;\n"
+	    "        stop_before = stop3;\n"
+	    "        percentage = (len_percentage - stop3)/(stop4 - stop3);\n"
+	    "    } else if((len_percentage < stop5) && (n_stop >= 6)){\n"
+	    "        stop_color_before = stop_color4;\n"
+	    "        stop_color_after = stop_color5;\n"
+	    "        stop_after = stop5;\n"
+	    "        stop_before = stop4;\n"
+	    "        percentage = (len_percentage - stop4)/(stop5 - stop4);\n"
+	    "    } else if((len_percentage < stop6) && (n_stop >= 7)){\n"
+	    "        stop_color_before = stop_color5;\n"
+	    "        stop_color_after = stop_color6;\n"
+	    "        stop_after = stop6;\n"
+	    "        stop_before = stop5;\n"
+	    "        percentage = (len_percentage - stop5)/(stop6 - stop5);\n"
+	    "    } else if((len_percentage < stop7) && (n_stop >= 8)){\n"
+	    "        stop_color_before = stop_color6;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop6;\n"
+	    "        percentage = (len_percentage - stop6)/(stop7 - stop6);\n"
+	    "    } else {\n"
+	    "        stop_color_before = stop_color7;\n"
+	    "        stop_color_after = stop_color7;\n"
+	    "        stop_after = stop7;\n"
+	    "        stop_before = stop7;\n"
+	    "        percentage = 0.0;\n"
+	    "    }\n"
+	    "    if(stop_after - stop_before > 2.0)\n"
+	    "        percentage = 0.0;\n"//For comply with pixman, walker->stepper overflow.
+	    "    new_alpha = percentage * stop_color_after.a + \n"
+	    "                       (1.0-percentage) * stop_color_before.a; \n"
+	    "    gradient_color = vec4((percentage * stop_color_after.rgb \n"
+	    "                          + (1.0-percentage) * stop_color_before.rgb)*new_alpha, \n"
+	    "                          new_alpha);\n"
+	    "    \n"
+	    "    return gradient_color;\n"
+	    "}\n"
+	    "\n"
+	    "void main()\n"
+	    "{\n"
+	    "    gl_FragColor = get_color();\n"
+	    "}\n";
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	gradient_prog = dispatch->glCreateProgram();
+
+	vs_prog = glamor_compile_glsl_prog(dispatch,
+	          GL_VERTEX_SHADER, gradient_vs);
+
+	if (use_array) {
+		XNFasprintf(&gradient_fs,
+		            gradient_fs_template, stops_count, stops_count,
+		            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+	} else {
+		XNFasprintf(&gradient_fs,
+		            gradient_fs_no_array_template,
+		            PIXMAN_REPEAT_NORMAL, PIXMAN_REPEAT_REFLECT);
+	}
+	fs_prog = glamor_compile_glsl_prog(dispatch,
+	          GL_FRAGMENT_SHADER, gradient_fs);
+	free(gradient_fs);
+
+	dispatch->glAttachShader(gradient_prog, vs_prog);
+	dispatch->glAttachShader(gradient_prog, fs_prog);
+
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
+
+	glamor_link_glsl_prog(dispatch, gradient_prog);
+
+	dispatch->glUseProgram(0);
+
+	glamor_put_dispatch(glamor_priv);
+	return gradient_prog;
+}
+
+#define LINEAR_DEFAULT_STOPS 6 + 2
 
 void
 glamor_init_gradient_shader(ScreenPtr screen)
@@ -1283,6 +1655,9 @@ glamor_init_gradient_shader(ScreenPtr screen)
 
 	glamor_priv = glamor_get_screen_private(screen);
 
+	glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR] =
+	    _glamor_create_linear_gradient_program(screen,
+	            LINEAR_DEFAULT_STOPS, 0);
 }
 
 void
@@ -1294,17 +1669,584 @@ glamor_fini_gradient_shader(ScreenPtr screen)
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch = glamor_get_dispatch(glamor_priv);
 
+	dispatch->glDeleteProgram(
+	    glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR]);
+
+	glamor_put_dispatch(glamor_priv);
+}
+
+static void
+_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
+				      int width, int height)
+{
+	/*
+	 * Because in the shader program, we normalize all the pixel cood to [0, 1],
+	 * so with the transform matrix, the correct logic should be:
+	 * v_s = A*T*v
+	 * v_s: point vector in shader after normalized.
+	 * A: The transition matrix from   width X height --> 1.0 X 1.0
+	 * T: The transform matrix.
+	 * v: point vector in width X height space.
+	 *
+	 * result is OK if we use this fomula. But for every point in width X height space,
+	 * we can just use their normalized point vector in shader, namely we can just
+	 * use the result of A*v in shader. So we have no chance to insert T in A*v.
+	 * We can just convert v_s = A*T*v to v_s = A*T*inv(A)*A*v, where inv(A) is the
+	 * inverse matrix of A. Now, v_s = (A*T*inv(A)) * (A*v)
+	 * So, to get the correct v_s, we need to cacula1 the matrix: (A*T*inv(A)), and
+	 * we name this matrix T_s.
+	 *
+	 * Firstly, because A is for the scale convertion, we find
+	 *      --         --
+	 *      |1/w  0   0 |
+	 * A =  | 0  1/h  0 |
+	 *      | 0   0  1.0|
+	 *      --         --
+	 * so T_s = A*T*inv(a) and result
+	 *
+	 *       --                      --
+	 *       | t11      h*t12/w  t13/w|
+	 * T_s = | w*t21/h  t22      t23/h|
+	 *       | w*t31    h*t32    t33  |
+	 *       --                      --
+	 */
+
+	to[0][0] = (float)pixman_fixed_to_double(from->matrix[0][0]);
+	to[0][1] = (float)pixman_fixed_to_double(from->matrix[0][1])
+	                                         * ((float)height) / ((float)width);
+	to[0][2] = (float)pixman_fixed_to_double(from->matrix[0][2])
+	                                         / ((float)width);
+
+	to[1][0] = (float)pixman_fixed_to_double(from->matrix[1][0])
+	                                         * ((float)width) / ((float)height);
+	to[1][1] = (float)pixman_fixed_to_double(from->matrix[1][1]);
+	to[1][2] = (float)pixman_fixed_to_double(from->matrix[1][2])
+	                                         / ((float)height);
+
+	to[2][0] = (float)pixman_fixed_to_double(from->matrix[2][0])
+	                                         * ((float)width);
+	to[2][1] = (float)pixman_fixed_to_double(from->matrix[2][1])
+	                                         * ((float)height);
+	to[2][2] = (float)pixman_fixed_to_double(from->matrix[2][2]);
+
+	DEBUGF("the transform matrix is:\n%f\t%f\t%f\n%f\t%f\t%f\n%f\t%f\t%f\n",
+	       to[0][0], to[0][1], to[0][2],
+	       to[1][0], to[1][1], to[1][2],
+	       to[2][0], to[2][1], to[2][2]);
+}
+
+static int
+_glamor_gradient_set_pixmap_destination(ScreenPtr screen,
+                                        glamor_screen_private *glamor_priv,
+                                        PicturePtr dst_picure,
+                                        GLfloat *xscale, GLfloat *yscale,
+                                        int x_source, int y_source,
+                                        float vertices[8],
+                                        float tex_vertices[8],
+					int tex_normalize)
+{
+	glamor_pixmap_private *pixmap_priv;
+	PixmapPtr pixmap = NULL;
+
+	pixmap = glamor_get_drawable_pixmap(dst_picure->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */
+		return 0;
+	}
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+	pixmap_priv_get_scale(pixmap_priv, xscale, yscale);
+
+	glamor_priv->has_source_coords = 1;
+	glamor_priv->has_mask_coords = 0;
+	glamor_setup_composite_vbo(screen, 4*2);
+
+	DEBUGF("xscale = %f, yscale = %f,"
+	       " x_source = %d, y_source = %d, width = %d, height = %d\n",
+	       *xscale, *yscale, x_source, y_source,
+	       pixmap_priv->fbo->width, pixmap_priv->fbo->height);
+
+	glamor_set_normalize_vcoords(*xscale, *yscale,
+	                             0, 0,
+	                             (INT16)(pixmap_priv->fbo->width),
+	                             (INT16)(pixmap_priv->fbo->height),
+	                             glamor_priv->yInverted, vertices);
+
+	if (tex_normalize) {
+		glamor_set_normalize_tcoords(*xscale, *yscale,
+		                             0, 0,
+		                             (INT16)(pixmap_priv->fbo->width),
+		                             (INT16)(pixmap_priv->fbo->height),
+		                             glamor_priv->yInverted, tex_vertices);
+	} else {
+		glamor_set_tcoords(0, 0,
+		                   (INT16)(pixmap_priv->fbo->width),
+		                   (INT16)(pixmap_priv->fbo->height),
+		                   glamor_priv->yInverted, tex_vertices);
+	}
+
+	DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
+	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+	       vertices[0], vertices[1], vertices[2], vertices[3],
+	       vertices[4], vertices[5], vertices[6], vertices[7]);
+	DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
+	       "rightbottom: %f X %f, leftbottom : %f X %f\n",
+	       tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
+	       tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+
+	return 1;
+}
+
+static int
+_glamor_gradient_set_stops(PicturePtr src_picture, PictGradient * pgradient,
+                           GLfloat *stop_colors, GLfloat *n_stops)
+{
+	int i;
+	int count;
+
+	for (i = 1; i < pgradient->nstops + 1; i++) {
+		stop_colors[i*4] = pixman_fixed_to_double(
+		                       pgradient->stops[i-1].color.red);
+		stop_colors[i*4+1] = pixman_fixed_to_double(
+		                       pgradient->stops[i-1].color.green);
+		stop_colors[i*4+2] = pixman_fixed_to_double(
+		                       pgradient->stops[i-1].color.blue);
+		stop_colors[i*4+3] = pixman_fixed_to_double(
+		                       pgradient->stops[i-1].color.alpha);
+
+		n_stops[i] = (GLfloat)pixman_fixed_to_double(
+		                       pgradient->stops[i-1].x);
+	}
+
+	count = pgradient->nstops + 2;
+
+	switch (src_picture->repeatType) {
+#define REPEAT_FILL_STOPS(m, n) \
+			stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \
+			stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \
+			stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \
+			stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3];
+
+		default:
+		case PIXMAN_REPEAT_NONE:
+			stop_colors[0] = 0.0;	   //R
+			stop_colors[1] = 0.0;	   //G
+			stop_colors[2] = 0.0;	   //B
+			stop_colors[3] = 0.0;	   //Alpha
+			n_stops[0] = -(float)INT_MAX;  //should be small enough.
+
+			stop_colors[0 + (count-1)*4] = 0.0;	 //R
+			stop_colors[1 + (count-1)*4] = 0.0;	 //G
+			stop_colors[2 + (count-1)*4] = 0.0;	 //B
+			stop_colors[3 + (count-1)*4] = 0.0;	 //Alpha
+			n_stops[count-1] = (float)INT_MAX;  //should be large enough.
+			break;
+		case PIXMAN_REPEAT_NORMAL:
+			REPEAT_FILL_STOPS(0, count - 2);
+			n_stops[0] = n_stops[count-2] - 1.0;
+
+			REPEAT_FILL_STOPS(count - 1, 1);
+			n_stops[count-1] = n_stops[1] + 1.0;
+			break;
+		case PIXMAN_REPEAT_REFLECT:
+			REPEAT_FILL_STOPS(0, 1);
+			n_stops[0] = -n_stops[1];
+
+			REPEAT_FILL_STOPS(count - 1, count - 2);
+			n_stops[count-1] = 1.0 + 1.0 - n_stops[count-2];
+			break;
+		case PIXMAN_REPEAT_PAD:
+			REPEAT_FILL_STOPS(0, 1);
+			n_stops[0] = -(float)INT_MAX;
+
+			REPEAT_FILL_STOPS(count - 1, count - 2);
+			n_stops[count-1] = (float)INT_MAX;
+			break;
+#undef REPEAT_FILL_STOPS
+	}
+
+	for (i = 0; i < count; i++) {
+		DEBUGF("n_stops[%d] = %f, color = r:%f g:%f b:%f a:%f\n",
+		       i, n_stops[i],
+		       stop_colors[i*4], stop_colors[i*4+1],
+		       stop_colors[i*4+2], stop_colors[i*4+3]);
+	}
+
+	return count;
+}
+
+static PicturePtr
+_glamor_generate_linear_gradient_picture(ScreenPtr screen,
+                                         PicturePtr src_picture,
+                                         int x_source, int y_source,
+                                         int width, int height,
+                                         PictFormatShort format)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	PicturePtr dst_picture = NULL;
+	PixmapPtr pixmap = NULL;
+	GLint gradient_prog = 0;
+	int error;
+	float pt_distance;
+	float p1_distance;
+	GLfloat cos_val;
+	float tex_vertices[8];
+	int stops_count;
+	GLfloat *stop_colors = NULL;
+	GLfloat *n_stops = NULL;
+	int i = 0;
+	int count = 0;
+	float slope;
+	GLfloat xscale, yscale;
+	GLfloat pt1[4], pt2[4];
+	float vertices[8];
+	float transform_mat[3][3];
+	static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
+		                                 {0.0, 1.0, 0.0},
+		                                 {0.0, 0.0, 1.0}};
+	GLfloat stop_colors_st[LINEAR_DEFAULT_STOPS*4];
+	GLfloat n_stops_st[LINEAR_DEFAULT_STOPS];
+
+	GLint transform_mat_uniform_location;
+	GLint pt1_uniform_location;
+	GLint pt2_uniform_location;
+	GLint n_stop_uniform_location;
+	GLint stops_uniform_location;
+	GLint stop0_uniform_location;
+	GLint stop1_uniform_location;
+	GLint stop2_uniform_location;
+	GLint stop3_uniform_location;
+	GLint stop4_uniform_location;
+	GLint stop5_uniform_location;
+	GLint stop6_uniform_location;
+	GLint stop7_uniform_location;
+	GLint stop_colors_uniform_location;
+	GLint stop_color0_uniform_location;
+	GLint stop_color1_uniform_location;
+	GLint stop_color2_uniform_location;
+	GLint stop_color3_uniform_location;
+	GLint stop_color4_uniform_location;
+	GLint stop_color5_uniform_location;
+	GLint stop_color6_uniform_location;
+	GLint stop_color7_uniform_location;
+	GLint pt_slope_uniform_location;
+	GLint repeat_type_uniform_location;
+	GLint hor_ver_uniform_location;
+	GLint cos_val_uniform_location;
+	GLint p1_distance_uniform_location;
+	GLint pt_distance_uniform_location;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	/* Create a pixmap with VBO. */
+	pixmap = glamor_create_pixmap(screen,
+	                              width, height,
+	                              PIXMAN_FORMAT_DEPTH(format),
+	                              GLAMOR_CREATE_PIXMAP_FIXUP);
+
+	if (!pixmap)
+		goto GRADIENT_FAIL;
+
+	dst_picture = CreatePicture(0, &pixmap->drawable,
+	                            PictureMatchFormat(screen,
+	                                    PIXMAN_FORMAT_DEPTH(format), format),
+	                            0, 0, serverClient, &error);
+
+	/* Release the reference, picture will hold the last one. */
+	glamor_destroy_pixmap(pixmap);
+
+	if (!dst_picture)
+		goto GRADIENT_FAIL;
+
+	ValidatePicture(dst_picture);
+
+	stops_count = src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS ?
+	              src_picture->pSourcePict->linear.nstops + 2 : LINEAR_DEFAULT_STOPS;
+
+	/* Because the max value of nstops is unkown, so create a program
+	   when nstops > default.*/
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+		gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR];
+	} else {
+		gradient_prog = _glamor_create_linear_gradient_program(screen,
+		                        src_picture->pSourcePict->linear.nstops + 2, 1);
+	}
+
+	/* Bind all the uniform vars .*/
+	pt1_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt1");
+	pt2_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt2");
+	n_stop_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "n_stop");
+	pt_slope_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt_slope");
+	repeat_type_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "repeat_type");
+	hor_ver_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "hor_ver");
+	transform_mat_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "transform_mat");
+	cos_val_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "cos_val");
+	p1_distance_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "p1_distance");
+	pt_distance_uniform_location =
+	    dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+		stop0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop0");
+		stop1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop1");
+		stop2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop2");
+		stop3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop3");
+		stop4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop4");
+		stop5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop5");
+		stop6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop6");
+		stop7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop7");
+
+		stop_color0_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color0");
+		stop_color1_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color1");
+		stop_color2_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color2");
+		stop_color3_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color3");
+		stop_color4_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color4");
+		stop_color5_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color5");
+		stop_color6_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color6");
+		stop_color7_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_color7");
+	} else {
+		stops_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stops");
+		stop_colors_uniform_location =
+		    dispatch->glGetUniformLocation(gradient_prog, "stop_colors");
+	}
+
+	dispatch->glUseProgram(gradient_prog);
+
+	dispatch->glUniform1i(repeat_type_uniform_location, src_picture->repeatType);
+
+	if (src_picture->transform) {
+		_glamor_gradient_convert_trans_matrix(src_picture->transform,
+		                                      transform_mat,
+		                                      width, height);
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &transform_mat[0][0]);
+	} else {
+		dispatch->glUniformMatrix3fv(transform_mat_uniform_location,
+		                             1, 1, &identity_mat[0][0]);
+	}
+
+	if (!_glamor_gradient_set_pixmap_destination(screen, glamor_priv, dst_picture,
+	                                             &xscale, &yscale, x_source, y_source,
+	                                             vertices, tex_vertices, 1))
+		goto GRADIENT_FAIL;
+
+	/* Normalize the PTs. */
+	glamor_set_normalize_pt(xscale, yscale,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.x),
+	                        x_source,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p1.y),
+	                        y_source,
+	                        glamor_priv->yInverted,
+	                        pt1);
+	dispatch->glUniform4fv(pt1_uniform_location, 1, pt1);
+	DEBUGF("pt1:(%f %f)\n", pt1[0], pt1[1]);
+
+	glamor_set_normalize_pt(xscale, yscale,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.x),
+	                        x_source,
+	                        pixman_fixed_to_int(src_picture->pSourcePict->linear.p2.y),
+	                        y_source,
+	                        glamor_priv->yInverted,
+	                        pt2);
+	dispatch->glUniform4fv(pt2_uniform_location, 1, pt2);
+	DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
+
+	/* Set all the stops and colors to shader. */
+	if (stops_count > LINEAR_DEFAULT_STOPS) {
+		stop_colors = malloc(4 * stops_count * sizeof(float));
+		if (stop_colors == NULL) {
+			ErrorF("Failed to allocate stop_colors memory.\n");
+			goto GRADIENT_FAIL;
+		}
+
+		n_stops = malloc(stops_count * sizeof(float));
+		if (n_stops == NULL) {
+			ErrorF("Failed to allocate n_stops memory.\n");
+			goto GRADIENT_FAIL;
+		}
+	} else {
+		stop_colors = stop_colors_st;
+		n_stops = n_stops_st;
+	}
+
+	count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
+	                                   stop_colors, n_stops);
+
+	if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+		int j = 0;
+		dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color1_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color2_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color3_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color4_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color5_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color6_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+		j++;
+		dispatch->glUniform4f(stop_color7_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
+		                      stop_colors[4*j+2], stop_colors[4*j+3]);
+
+		j = 0;
+		dispatch->glUniform1f(stop0_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop1_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop2_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop3_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop4_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop5_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop6_uniform_location, n_stops[j++]);
+		dispatch->glUniform1f(stop7_uniform_location, n_stops[j++]);
+
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	} else {
+		dispatch->glUniform4fv(stop_colors_uniform_location, count, stop_colors);
+		dispatch->glUniform1fv(stops_uniform_location, count, n_stops);
+		dispatch->glUniform1i(n_stop_uniform_location, count);
+	}
+
+	if ((pt2[1] - pt1[1]) / yscale < 1.0) { // The horizontal case.
+		dispatch->glUniform1i(hor_ver_uniform_location, 1);
+		DEBUGF("p1.x: %f, p2.x: %f, enter the horizontal case\n", pt1[1], pt2[1]);
+
+		p1_distance = pt1[0];
+		pt_distance = (pt2[0] - p1_distance);
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	} else if ((pt2[0] - pt1[0]) / xscale < 1.0) { //The vertical case.
+		dispatch->glUniform1i(hor_ver_uniform_location, 2);
+		DEBUGF("p1.y: %f, p2.y: %f, enter the vertical case\n", pt1[0], pt2[0]);
+
+		p1_distance = pt1[1];
+		pt_distance = (pt2[1] - p1_distance);
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	} else {
+		/* The slope need to compute here. In shader, the viewport set will change
+		   the orginal slope and the slope which is vertical to it will not be correct.*/
+		slope = - (float)(src_picture->pSourcePict->linear.p2.x - src_picture->pSourcePict->linear.p1.x) /
+		        (float)(src_picture->pSourcePict->linear.p2.y - src_picture->pSourcePict->linear.p1.y);
+		slope = slope * yscale / xscale;
+		dispatch->glUniform1f(pt_slope_uniform_location, slope);
+		dispatch->glUniform1i(hor_ver_uniform_location, 0);
+
+		cos_val = sqrt(1.0 / (slope * slope + 1.0));
+		dispatch->glUniform1f(cos_val_uniform_location, cos_val);
+
+		p1_distance = (pt1[1] - pt1[0] * slope) * cos_val;
+		pt_distance = (pt2[1] - pt2[0] * slope) * cos_val - p1_distance;
+		dispatch->glUniform1f(p1_distance_uniform_location, p1_distance);
+		dispatch->glUniform1f(pt_distance_uniform_location, pt_distance);
+	}
+
+	/* set the transform matrix. */	/* Now rendering. */
+	glamor_emit_composite_rect(screen, tex_vertices, NULL, vertices);
+
+	if (glamor_priv->render_nr_verts) {
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+			dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+		else {
+
+			dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+			dispatch->glBufferData(GL_ARRAY_BUFFER,
+			                       glamor_priv->vbo_offset,
+			                       glamor_priv->vb, GL_DYNAMIC_DRAW);
+		}
+
+		dispatch->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL);
+	}
+
+	/* Do the clear logic.*/
+	if (stops_count > LINEAR_DEFAULT_STOPS) {
+		free(n_stops);
+		free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+
+	if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
+		dispatch->glDeleteProgram(gradient_prog);
+
 	glamor_put_dispatch(glamor_priv);
+	return dst_picture;
+
+GRADIENT_FAIL:
+	if (dst_picture) {
+		FreePicture(dst_picture, 0);
+	}
+
+	if (stops_count > LINEAR_DEFAULT_STOPS) {
+		if (n_stops)
+			free(n_stops);
+		if (stop_colors)
+			free(stop_colors);
+	}
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
+		dispatch->glDeleteProgram(gradient_prog);
+	glamor_put_dispatch(glamor_priv);
+	return NULL;
 }
+#undef LINEAR_DEFAULT_STOPS
 
 static PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
-				PicturePtr source,
-				int x_source,
-				int y_source, int width, int height)
+                                PicturePtr source,
+                                int x_source,
+                                int y_source, int width, int height)
 {
 	PixmapPtr pixmap;
-	PicturePtr dst;
+	PicturePtr dst = NULL;
 	int error;
 	PictFormatShort format;
 	if (!source->pDrawable)
@@ -1312,6 +2254,22 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	else
 		format = source->format;
 
+	if (!source->pDrawable) {
+		if (source->pSourcePict->type == SourcePictTypeLinear) {
+			dst = _glamor_generate_linear_gradient_picture(screen,
+				source, x_source, y_source, width, height, format);
+		}
+
+		if (dst) {
+#if 0			/* Debug to compare it to pixman, Enable it if needed. */
+			glamor_compare_pictures(screen, source,
+					dst, x_source, y_source, width, height,
+					0, 3);
+#endif
+			return dst;
+		}
+	}
+
 	pixmap = glamor_create_pixmap(screen,
 				      width,
 				      height,
@@ -1322,11 +2280,11 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 		return NULL;
 
 	dst = CreatePicture(0,
-			    &pixmap->drawable,
-			    PictureMatchFormat(screen,
-					       PIXMAN_FORMAT_DEPTH(format),
-					       format),
-			    0, 0, serverClient, &error);
+	                    &pixmap->drawable,
+	                    PictureMatchFormat(screen,
+	                                       PIXMAN_FORMAT_DEPTH(format),
+	                                       format),
+	                    0, 0, serverClient, &error);
 	glamor_destroy_pixmap(pixmap);
 	if (!dst)
 		return NULL;
@@ -1334,7 +2292,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	ValidatePicture(dst);
 
 	fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
-		    0, 0, 0, 0, width, height);
+	            0, 0, 0, 0, width, height);
 	return dst;
 }
 
commit ccf5d7f52bae664f90d2c33c9fcff099a820575f
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Fri Mar 23 04:05:48 2012 +0800

    Prepare for modification of gradient using shader.
    
     Prepare for modification of gradient using shader. The
     gradient pixmaps now is generated by pixman and we will
     replace them with shader. Add structure fields and
     dispatch functions which will be needed. Some auxiliary
     macro for vertex convert.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0d9ba28..532b9ef 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -389,6 +389,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_init_tile_shader(screen);
 	glamor_init_putimage_shaders(screen);
 	glamor_init_finish_access_shaders(screen);
+	glamor_init_gradient_shader(screen);
 	glamor_pixmap_init(screen);
 
 	glamor_priv->flags = flags;
@@ -416,6 +417,7 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_fini_tile_shader(screen);
 	glamor_fini_putimage_shaders(screen);
 	glamor_fini_finish_access_shaders(screen);
+	glamor_fini_gradient_shader(screen);
 	glamor_pixmap_fini(screen);
 	free(glamor_priv);
 
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index ef0ac43..fc3c5c0 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -65,10 +65,12 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 
 	INIT_FUNC(dispatch, glUseProgram, get_proc_address);
 	INIT_FUNC(dispatch, glUniform1i, get_proc_address);
+	INIT_FUNC(dispatch, glUniform1f, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
 	INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
 	INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
-	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
+	INIT_FUNC(dispatch, glUniformMatrix3fv, get_proc_address);
 	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
 	INIT_FUNC(dispatch, glCreateShader, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index bd33bcc..6adbde9 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -60,7 +60,7 @@ typedef struct glamor_gl_dispatch {
 			      const GLvoid * data, GLenum usage);
 	GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
 	GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
-	GLboolean(*glUnmapBuffer) (GLenum target);
+	GLboolean (*glUnmapBuffer) (GLenum target);
 	void (*glBindBuffer) (GLenum target, GLuint buffer);
 	void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
 
@@ -71,7 +71,7 @@ typedef struct glamor_gl_dispatch {
 	void (*glDeleteFramebuffers) (GLsizei n,
 				      const GLuint * framebuffers);
 	void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers);
-	 GLenum(*glCheckFramebufferStatus) (GLenum target);
+	GLenum (*glCheckFramebufferStatus) (GLenum target);
 	void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1,
 				   GLint srcY1, GLint dstX0, GLint dstY0,
 				   GLint dstX1, GLint dstY1,
@@ -92,6 +92,7 @@ typedef struct glamor_gl_dispatch {
 				const GLint * length);
 	void (*glUseProgram) (GLuint program);
 	void (*glUniform1i) (GLint location, GLint v0);
+	void (*glUniform1f) (GLint location, GLfloat v0);
 	void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
 			     GLfloat v2, GLfloat v3);
 	void (*glUniform1fv) (GLint location, GLsizei count,
@@ -100,9 +101,11 @@ typedef struct glamor_gl_dispatch {
 			      const GLfloat * value);
 	void (*glUniform4fv) (GLint location, GLsizei count,
 			      const GLfloat * value);
-	 GLuint(*glCreateProgram) (void);
-	 GLuint(*glDeleteProgram) (GLuint);
-	 GLuint(*glCreateShader) (GLenum type);
+	void (*glUniformMatrix3fv) (GLint location, GLsizei count,
+		           GLboolean transpose, const GLfloat* value);
+	GLuint (*glCreateProgram) (void);
+	GLuint (*glDeleteProgram) (GLuint);
+	GLuint (*glCreateShader) (GLenum type);
 	void (*glCompileShader) (GLuint shader);
 	void (*glAttachShader) (GLuint program, GLuint shader);
 	void (*glGetShaderiv) (GLuint shader, GLenum pname,
@@ -113,7 +116,7 @@ typedef struct glamor_gl_dispatch {
 				GLint * params);
 	void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize,
 				     GLsizei * length, GLchar * infoLog);
-	 GLint(*glGetUniformLocation) (GLuint program,
+	GLint (*glGetUniformLocation) (GLuint program,
 				       const GLchar * name);
 
 } glamor_gl_dispatch;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
old mode 100755
new mode 100644
index 1404703..ad68737
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -123,6 +123,13 @@ enum shader_in {
 	SHADER_IN_COUNT,
 };
 
+enum gradient_shader_type {
+	GRADIENT_SHADER_LINEAR,
+	GRADIENT_SHADER_RADIAL,
+	GRADIENT_SHADER_CONICAL,
+	GRADIENT_SHADER_COUNT,
+};
+
 struct glamor_screen_private;
 struct glamor_pixmap_private;
 typedef void (*glamor_pixmap_validate_function_t) (struct
@@ -221,6 +228,9 @@ typedef struct glamor_screen_private {
 	GLint tile_prog;
 	GLint tile_wh;
 
+	/* glamor gradient */
+	GLint gradient_prog[GRADIENT_SHADER_COUNT];
+
 	/* glamor_putimage */
 	GLint put_image_xybitmap_prog;
 	GLint put_image_xybitmap_fg_uniform_location;
@@ -562,6 +572,9 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 void glamor_init_tile_shader(ScreenPtr screen);
 void glamor_fini_tile_shader(ScreenPtr screen);
 
+void glamor_init_gradient_shader(ScreenPtr screen);
+void glamor_fini_gradient_shader(ScreenPtr screen);
+
 /* glamor_triangles.c */
 void
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 9f0b034..093e01d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1275,6 +1275,28 @@ done:
 	return ret;
 }
 
+
+void
+glamor_init_gradient_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+
+	glamor_priv = glamor_get_screen_private(screen);
+
+}
+
+void
+glamor_fini_gradient_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	glamor_put_dispatch(glamor_priv);
+}
+
 static PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
 				PicturePtr source,
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 36cc9bd..75ebc7e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -99,6 +99,24 @@
     (vertices)[7] = (vertices)[5];					\
   } while(0)
 
+#define glamor_set_tcoords(x1, y1, x2, y2, yInverted, vertices)	    \
+    do {                                                            \
+      (vertices)[0] = (x1);                                         \
+      (vertices)[2] = (x2);                                         \
+      (vertices)[4] = (vertices)[2];                                \
+      (vertices)[6] = (vertices)[0];                                \
+      if (yInverted) {                                              \
+          (vertices)[1] = (y1);                                     \
+          (vertices)[5] = (y2);                                     \
+      }                                                             \
+      else {                                                        \
+          (vertices)[1] = (y2);                                     \
+          (vertices)[5] = (y1);                                     \
+      }                                                             \
+      (vertices)[3] = (vertices)[1];                \
+      (vertices)[7] = (vertices)[5];                \
+    } while(0)
+
 
 #define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,	\
                                      yInverted, vertices)		\
@@ -119,6 +137,17 @@
     (vertices)[7] = (vertices)[5];					\
   } while(0)
 
+#define glamor_set_normalize_pt(xscale, yscale, x, x_start, y, y_start,     \
+                                yInverted, pt)                              \
+    do {                                                                    \
+        (pt)[0] = t_from_x_coord_x(xscale, x - x_start);                    \
+        if (yInverted) {                                                    \
+            (pt)[1] = t_from_x_coord_y_inverted(yscale, y - y_start);       \
+        } else {                                                            \
+            (pt)[1] = t_from_x_coord_y(yscale, y - y_start);                \
+        }                                                                   \
+        (pt)[2] = (pt)[3] = 0.0;                                            \
+    } while(0)
 
 inline static void
 glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
commit a57bf66d492a0eec7b1f2a08b2f424835694e3fb
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Mon Mar 26 13:51:13 2012 +0800

    glamor_utils: Add some assistant functions to compare pixmaps/pictures.
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 4a51ba5..36cc9bd 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -664,6 +664,278 @@ static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int
 	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 }
 
+static inline void _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
+                                           int x, int y, int w, int h,
+                                           PictFormatShort short_format,
+                                           int all, int diffs)
+{
+	int i, j;
+	unsigned char * p1 = pixmap1->devPrivate.ptr;
+	unsigned char * p2 = pixmap2->devPrivate.ptr;
+	int line_need_printed = 0;
+	int test_code = 0xAABBCCDD;
+	int little_endian = 0;
+	unsigned char *p_test;
+	int bpp = pixmap1->drawable.depth == 8 ? 1 : 4;
+
+	assert(pixmap1->devKind == pixmap2->devKind);
+	int stride = pixmap1->devKind;
+
+	ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h);
+
+	p1 = p1 + y * stride + x;
+	p2 = p2 + y * stride + x;
+
+	if (all) {
+		for (i = 0; i < h; i++) {
+			ErrorF("line %3d: ", i);
+
+			for (j = 0; j < stride; j++) {
+				if (j % bpp == 0)
+					ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
+				else
+					ErrorF("%2x:%2x ", p1[j], p2[j]);
+			}
+
+			p1 += stride;
+			p2 += stride;
+			ErrorF("\n");
+		}
+	} else {
+		if (short_format == PICT_a8r8g8b8) {
+			p_test = (unsigned char *) & test_code;
+			little_endian = (*p_test == 0xDD);
+			bpp = 4;
+
+			for (i = 0; i < h; i++) {
+				line_need_printed = 0;
+
+				for (j = 0; j < stride; j++) {
+					if (p1[j] != p2[j] && (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) {
+						if (line_need_printed) {
+							if (little_endian) {
+								switch (j % 4) {
+									case 2:
+										ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 1:
+										ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 0:
+										ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 3:
+										ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+								}
+							} else {
+								switch (j % 4) {
+									case 1:
+										ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 2:
+										ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 3:
+										ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+									case 0:
+										ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], p2[j]);
+										break;
+								}
+							}
+						} else {
+							line_need_printed = 1;
+							j = -1;
+							ErrorF("line %3d: ", i);
+							continue;
+						}
+					}
+				}
+
+				p1 += stride;
+				p2 += stride;
+				ErrorF("\n");
+			}
+		} //more format can be added here.
+		else { // the default format, just print.
+			for (i = 0; i < h; i++) {
+				line_need_printed = 0;
+
+				for (j = 0; j < stride; j++) {
+					if (p1[j] != p2[j]) {
+						if (line_need_printed) {
+							ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
+						} else {
+							line_need_printed = 1;
+							j = -1;
+							ErrorF("line %3d: ", i);
+							continue;
+						}
+					}
+				}
+
+				p1 += stride;
+				p2 += stride;
+				ErrorF("\n");
+			}
+		}
+	}
+}
+
+static inline void glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
+                                          int x, int y, int w, int h, int all, int diffs)
+{
+	assert(pixmap1->drawable.depth == pixmap2->drawable.depth);
+
+	glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
+	glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
+
+	_glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
+
+	glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
+	glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
+}
+
+/* This function is used to compare two pictures.
+   If the picture has no drawable, we use fb functions to generate it. */
+static inline void glamor_compare_pictures( ScreenPtr screen,
+                                            PicturePtr fst_picture,
+                                            PicturePtr snd_picture,
+                                            int x_source, int y_source,
+                                            int width, int height,
+                                            int all, int diffs)
+{
+	PixmapPtr fst_pixmap;
+	PixmapPtr snd_pixmap;
+	int fst_generated, snd_generated;
+	glamor_pixmap_private *fst_pixmap_priv;
+	glamor_pixmap_private *snd_pixmap_priv;
+	int error;
+	int fst_type = -1;
+	int snd_type = -1; // -1 represent has drawable.
+
+	if (fst_picture->format != snd_picture->format) {
+		ErrorF("Different picture format can not compare!\n");
+		return;
+	}
+
+	if (!fst_picture->pDrawable) {
+		fst_type = fst_picture->pSourcePict->type;
+	}
+
+	if (!snd_picture->pDrawable) {
+		snd_type = snd_picture->pSourcePict->type;
+	}
+
+	if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) {
+		ErrorF("Different picture type will never be same!\n");
+		return;
+	}
+
+	fst_generated = snd_generated = 0;
+
+	if (!fst_picture->pDrawable) {
+		PicturePtr pixman_pic;
+		PixmapPtr pixmap = NULL;
+		PictFormatShort format;
+
+		format = fst_picture->format;
+
+		pixmap = glamor_create_pixmap(screen,
+		                              width, height,
+		                              PIXMAN_FORMAT_DEPTH(format),
+		                              GLAMOR_CREATE_PIXMAP_CPU);
+
+		pixman_pic = CreatePicture(0,
+		                           &pixmap->drawable,
+		                           PictureMatchFormat(screen,
+		                               PIXMAN_FORMAT_DEPTH(format), format),
+		                           0, 0, serverClient, &error);
+
+		fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic,
+		            x_source, y_source,
+		            0, 0,
+		            0, 0,
+		            width, height);
+
+		glamor_destroy_pixmap(pixmap);
+
+		fst_picture = pixman_pic;
+		fst_generated = 1;
+	}
+
+	if (!snd_picture->pDrawable) {
+		PicturePtr pixman_pic;
+		PixmapPtr pixmap = NULL;
+		PictFormatShort format;
+
+		format = snd_picture->format;
+
+		pixmap = glamor_create_pixmap(screen,
+		                              width, height,
+		                              PIXMAN_FORMAT_DEPTH(format),
+		                              GLAMOR_CREATE_PIXMAP_CPU);
+
+		pixman_pic = CreatePicture(0,
+		                           &pixmap->drawable,
+		                           PictureMatchFormat(screen,
+		                               PIXMAN_FORMAT_DEPTH(format), format),
+		                           0, 0, serverClient, &error);
+
+		fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic,
+		            x_source, y_source,
+		            0, 0,
+		            0, 0,
+		            width, height);
+
+		glamor_destroy_pixmap(pixmap);
+
+		snd_picture = pixman_pic;
+		snd_generated = 1;
+	}
+
+	fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable);
+	snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable);
+
+	if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) {
+		if (fst_generated)
+			glamor_destroy_picture(fst_picture);
+		if (snd_generated)
+			glamor_destroy_picture(snd_picture);
+
+		ErrorF("Different pixmap depth can not compare!\n");
+		return;
+	}
+
+	glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
+	glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
+
+	if ((fst_type == SourcePictTypeLinear) ||
+	     (fst_type == SourcePictTypeRadial) ||
+	     (fst_type == SourcePictTypeConical) ||
+	     (snd_type == SourcePictTypeLinear) ||
+	     (snd_type == SourcePictTypeRadial) ||
+	     (snd_type == SourcePictTypeConical)) {
+		x_source = y_source = 0;
+	}
+
+	_glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
+	                        x_source, y_source,
+	                        width, height,
+	                        fst_picture->format, all, diffs);
+
+	glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
+	glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
+
+	if (fst_generated)
+		glamor_destroy_picture(fst_picture);
+	if (snd_generated)
+		glamor_destroy_picture(snd_picture);
+
+	return;
+}
+
 static inline void glamor_make_current(ScreenPtr screen)
 {
 	glamor_egl_make_current(screen);
commit cd75e85ff36827b8438d965750faab0615d01e86
Author: Junyan He <junyan.he at linux.intel.com>
Date:   Mon Mar 5 08:24:20 2012 +0800

    Fixup For list.h change in xorg
    
     Because the file list.h in xorg/include has changed the
     functions and struct names, adding xorg_ prefix before
     the original name. So Modify glamor_screen_private
     struct and the code which use list's functions in
     glamor_fbo.c. We hack at glamor_priv.h avoid the
     compile error when using old version xserver header
     file.
    
    Signed-off-by: Junyan He <junyan.he at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index b4e4af7..3ae6562 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -9,13 +9,13 @@
 #define GLAMOR_CACHE_TEXTURE	2
 
 /* Loop from the tail to the head. */
-#define list_for_each_entry_reverse(pos, head, member)                  \
+#define xorg_list_for_each_entry_reverse(pos, head, member)             \
     for (pos = __container_of((head)->prev, pos, member);               \
          &pos->member != (head);                                        \
          pos = __container_of(pos->member.prev, pos, member))
 
 
-#define list_for_each_entry_safe_reverse(pos, tmp, head, member)        \
+#define xorg_list_for_each_entry_safe_reverse(pos, tmp, head, member)   \
     for (pos = __container_of((head)->prev, pos, member),               \
          tmp = __container_of(pos->member.prev, pos, member);           \
          &pos->member != (head);                                        \
@@ -77,7 +77,7 @@ glamor_pixmap_fbo *
 glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 			    int w, int h, GLenum format, int flag)
 {
-	struct list *cache;
+	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry;
 	int size;
 
@@ -90,27 +90,27 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 					       [cache_wbucket(w)]
 					       [cache_hbucket(h)];
 	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
-		list_for_each_entry(fbo_entry, cache, list) {
+		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
 				DEBUGF("Request w %d h %d \n", w, h);
 				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
 					fbo_entry->fb, fbo_entry->tex);
-				list_del(&fbo_entry->list);
+				xorg_list_del(&fbo_entry->list);
 				return fbo_entry;
 			}
 		}
 	}
 	else {
-		list_for_each_entry(fbo_entry, cache, list) {
+		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width == w && fbo_entry->height == h) {
 
 				DEBUGF("Request w %d h %d \n", w, h);
 				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
 					fbo_entry->fb, fbo_entry->tex);
-				list_del(&fbo_entry->list);
+				xorg_list_del(&fbo_entry->list);
 				return fbo_entry;
 			}
 		}
@@ -138,7 +138,7 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
-	struct list *cache;
+	struct xorg_list *cache;
 
 	if (fbo->fb == 0) {
 		glamor_purge_fbo(fbo);
@@ -155,7 +155,7 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 						    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
 		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
-	list_add(&fbo->list, cache);
+	xorg_list_add(&fbo->list, cache);
 	fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
 }
 
@@ -170,7 +170,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 	if (fbo == NULL)
 		return NULL;
 
-	list_init(&fbo->list);
+	xorg_list_init(&fbo->list);
 	gl_iformat_for_depth(depth, &format);
 
 	fbo->tex = tex;
@@ -189,7 +189,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 void
 glamor_fbo_expire(glamor_screen_private *glamor_priv)
 {
-	struct list *cache;
+	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry, *tmp;
 	int i,j,k;
 	int empty_cache = TRUE;
@@ -198,24 +198,24 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
 			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
 				cache = &glamor_priv->fbo_cache[i][j][k];
-				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
 					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
 						empty_cache = FALSE;
 						break;
 					}
-					list_del(&fbo_entry->list);
+					xorg_list_del(&fbo_entry->list);
 					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
 						fbo_entry->expire, glamor_priv->tick);
 					glamor_purge_fbo(fbo_entry);
 				}
 #if 0
 				cache = &glamor_priv->tex_cache[i][j][k];
-				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
 					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
 						empty_cache = FALSE;
 						break;
 					}
-					list_del(&fbo_entry->list);
+					xorg_list_del(&fbo_entry->list);
 					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
 						fbo_entry->expire, glamor_priv->tick);
 					glamor_purge_fbo(fbo_entry);
@@ -236,15 +236,15 @@ glamor_init_pixmap_fbo(ScreenPtr screen)
 		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
 			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
 			{
-				list_init(&glamor_priv->fbo_cache[i][j][k]);
-				list_init(&glamor_priv->tex_cache[i][j][k]);
+				xorg_list_init(&glamor_priv->fbo_cache[i][j][k]);
+				xorg_list_init(&glamor_priv->tex_cache[i][j][k]);
 			}
 }
 
 void
 glamor_fini_pixmap_fbo(ScreenPtr screen)
 {
-	struct list *cache;
+	struct xorg_list *cache;
 	glamor_screen_private *glamor_priv;
 	glamor_pixmap_fbo *fbo_entry, *tmp;
 	int i,j,k;
@@ -255,14 +255,14 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
 			{
 				cache = &glamor_priv->fbo_cache[i][j][k];
-				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					list_del(&fbo_entry->list);
+				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					xorg_list_del(&fbo_entry->list);
 					glamor_purge_fbo(fbo_entry);
 				}
 #if 0
 				cache = &glamor_priv->tex_cache[i][j][k];
-				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
-					list_del(&fbo_entry->list);
+				xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					xorg_list_del(&fbo_entry->list);
 					glamor_purge_fbo(fbo_entry);
 				}
 #endif
@@ -272,7 +272,7 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 void
 glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 {
-	list_del(&fbo->list);
+	xorg_list_del(&fbo->list);
 	glamor_pixmap_fbo_cache_put(fbo);
 
 }
@@ -297,7 +297,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	if (fbo == NULL)
 		return NULL;
 
-	list_init(&fbo->list);
+	xorg_list_init(&fbo->list);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glGenTextures(1, &tex);
@@ -323,7 +323,7 @@ void
 glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
 {
 	assert(tex_obj->fb == 0);
-	list_del(&tex_obj->list);
+	xorg_list_del(&tex_obj->list);
 	glamor_pixmap_fbo_cache_put(tex_obj);
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
old mode 100644
new mode 100755
index b9670a3..1404703
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -56,6 +56,20 @@
 #include "glamor_debug.h"
 
 #include <list.h>
+/* The list.h rename all the function to add xorg_ prefix.
+   We add hack here to avoid the compile error when using
+   old version xserver header file.
+   These will be removed in future. */
+#ifndef xorg_list_entry
+#define xorg_list list
+#define xorg_list_for_each_entry list_for_each_entry
+#define xorg_list_for_each_entry_safe list_for_each_entry_safe
+#define xorg_list_del list_del
+#define xorg_list_add list_add
+#define xorg_list_append list_append
+#define xorg_list_init list_init
+#endif
+
 
 typedef struct glamor_composite_shader {
 	GLuint prog;
@@ -177,8 +191,8 @@ typedef struct glamor_screen_private {
 	int has_fbo_blit;
 	int max_fbo_size;
 
-	struct list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
-	struct list tex_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+	struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+	struct xorg_list tex_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
 
 	/* glamor_solid */
 	GLint solid_prog;
@@ -262,7 +276,7 @@ typedef union _glamor_pending_op {
  * @glamor_priv: point to glamor private data.
  */
 typedef struct glamor_pixmap_fbo {
-	struct list list;
+	struct xorg_list list;
 	unsigned int expire;
 	unsigned char pbo_valid;
 	GLuint tex;
commit 213285f2b8c6578e01783a77d954ccc3ec313663
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 17 16:56:05 2012 +0800

    For DRI swap buffers.
    
    This commit added two APIs to support the DRI swap buffer.
    one is glamor_egl_exchange_buffers() which can swap two
    pixmaps' underlying KHRimages/fbos/texs. The DDX layer should
    exchange the DRM bos to make them consistent to each other.
    
    Another API is glamor_egl_create_textured_screen_ext(), which
    extent one more parameters to track the DDX layer's back pixmap
    pointer. This is for the triple buffer support. When using triple
    buffer, the DDX layer will keep a back pixmap rather then the
    front pixmap and the pixmap used by the DRI2 client. And during
    the closing screen stage, we have to dereference all the back
    pixmap's glamor resources. Thus we have to extent this API to
    register it when create new screen.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 86de115..0d9ba28 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -106,7 +106,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 }
 
 void
-glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
+glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
 {
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
@@ -117,6 +117,8 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
 
 	pixmap_priv->fbo->width = screen_pixmap->drawable.width;
 	pixmap_priv->fbo->height = screen_pixmap->drawable.height;
+
+	glamor_priv->back_pixmap = back_pixmap;
 }
 
 PixmapPtr
@@ -420,6 +422,29 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_set_screen_private(screen, NULL);
 }
 
+_X_EXPORT void
+glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
+{
+	glamor_pixmap_private *old_priv;
+	glamor_pixmap_fbo *fbo;
+
+	old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+
+	if (priv) {
+		assert(old_priv == NULL);
+	} else {
+		if (old_priv == NULL)
+			return;
+		fbo = glamor_pixmap_detach_fbo(old_priv);
+		glamor_purge_fbo(fbo);
+		free(old_priv);
+	}
+
+	dixSetPrivate(&pixmap->devPrivates,
+		      glamor_pixmap_private_key,
+		      priv);
+}
+
 Bool
 glamor_close_screen(int idx, ScreenPtr screen)
 {
@@ -458,9 +483,10 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	}
 #endif
 	screen_pixmap = screen->GetScreenPixmap(screen);
-	screen_pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
-	fbo = glamor_pixmap_detach_fbo(screen_pixmap_priv);
-	glamor_purge_fbo(fbo);
+	glamor_set_pixmap_private(screen_pixmap, NULL);
+	if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
+		glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
+
 	glamor_release_screen_priv(screen);
 
 	return screen->CloseScreen(idx, screen);
diff --git a/glamor/glamor.h b/glamor/glamor.h
index d3437d3..4a4e9bd 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -120,7 +120,7 @@ extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen);
 /* Let glamor to know the screen's fbo. The low level
  * driver should already assign a tex
  * to this pixmap through the set_pixmap_texture. */
-extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap);
+extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap);
 
 /* @glamor_glyphs_init: Initialize glyphs internal data structures.
  *
@@ -146,6 +146,16 @@ extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 extern _X_EXPORT void glamor_egl_make_current(ScreenPtr screen);
 extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
 
+/* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
+ *
+ * @front: front pixmap.
+ * @back: back pixmap.
+ *
+ * Used by the DRI2 page flip. This function will exchange the KHR images and
+ * fbos of the two pixmaps.
+ * */
+extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back);
+
 #ifdef GLAMOR_FOR_XORG
 
 #define GLAMOR_EGL_MODULE_NAME  "glamoregl"
@@ -183,6 +193,18 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
 extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
 							int handle,
 							int stride);
+
+/* @glamor_egl_create_textured_screen_ext:
+ *
+ * extent one parameter to track the pointer of the DDX layer's back pixmap.
+ * We need this pointer during the closing screen stage. As before back to
+ * the DDX's close screen, we have to free all the glamor related resources.
+ */
+extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen,
+							    int handle,
+							    int stride,
+							    PixmapPtr *back_pixmap);
+
 /*
  * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
  * 				       a BO handle.
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index ecbc186..081b363 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -85,6 +85,7 @@ struct glamor_egl_screen_private {
 	CloseScreenProcPtr CloseScreen;
 	int fd;
 	EGLImageKHR front_image;
+	PixmapPtr *back_pixmap;
 	int cpp;
 #ifdef GLAMOR_HAS_GBM
 	struct gbm_device *gbm;
@@ -233,7 +234,24 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 
 	glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
 						    glamor_egl_pixmap_private_key);
-	glamor_set_screen_pixmap(screen_pixmap);
+	glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
+	return TRUE;
+}
+
+Bool
+glamor_egl_create_textured_screen_ext(ScreenPtr screen,
+				      int handle,
+				      int stride,
+				      PixmapPtr *back_pixmap)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_egl_screen_private *glamor_egl;
+
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+
+	glamor_egl->back_pixmap = back_pixmap;
+	if (!glamor_egl_create_textured_screen(screen, handle, stride))
+		return FALSE;
 	return TRUE;
 }
 
@@ -280,9 +298,10 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 					 ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
 					 name,
 					 pixmap->drawable.depth);
-	if (image == EGL_NO_IMAGE_KHR)
+	if (image == EGL_NO_IMAGE_KHR) {
+		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
 		goto done;
-
+	}
 	glamor_create_texture_from_image(glamor_egl, image, &texture);
 	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	glamor_set_pixmap_texture(pixmap, texture);
@@ -315,6 +334,28 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 	}
 }
 
+extern void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
+
+_X_EXPORT void
+glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
+{
+	ScrnInfoPtr scrn = xf86Screens[front->drawable.pScreen->myNum];
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+	EGLImageKHR old_front_image;
+	EGLImageKHR new_front_image;
+
+	glamor_pixmap_exchange_fbos(front, back);
+	new_front_image = dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
+	old_front_image = dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
+	dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, new_front_image);
+	dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, old_front_image);
+	glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
+	glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
+	glamor_egl->front_image = new_front_image;
+
+}
+
 void
 glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 {
@@ -329,13 +370,24 @@ glamor_egl_close_screen(int idx, ScreenPtr screen)
 	ScrnInfoPtr scrn;
 	struct glamor_egl_screen_private *glamor_egl;
 	PixmapPtr screen_pixmap;
+	EGLImageKHR back_image;
 
 	scrn = xf86Screens[screen->myNum];
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 	screen_pixmap = screen->GetScreenPixmap(screen);
+
 	glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image);
 	dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
 	glamor_egl->front_image = NULL;
+	if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
+		back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
+					       glamor_egl_pixmap_private_key);
+		if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
+			glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
+			dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
+				      glamor_egl_pixmap_private_key, NULL);
+		}
+	}
 
 	screen->CloseScreen = glamor_egl->saved_close_screen;
 
@@ -383,7 +435,6 @@ glamor_egl_free_screen(int scrnIndex, int flags)
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_egl_screen_private *glamor_egl;
 
-	ErrorF("free egl screen resources\n");
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 	if (glamor_egl != NULL) {
 
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index ec1a5b0..b4e4af7 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -427,3 +427,22 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
 		break;
 	}
 }
+/*
+ * XXX how to handle those pending OPs.
+ * By default, pending OP is disabled. Maybe we will give up the pending
+ * OP latter.
+ *
+ * */
+
+_X_EXPORT void
+glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
+{
+	glamor_pixmap_private *front_priv, *back_priv;
+	glamor_pixmap_fbo *temp_fbo;
+
+	front_priv = glamor_get_pixmap_private(front);
+	back_priv = glamor_get_pixmap_private(back);
+	temp_fbo = front_priv->fbo;
+	front_priv->fbo = back_priv->fbo;
+	back_priv->fbo = temp_fbo;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0d3aa82..b9670a3 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -212,6 +212,7 @@ typedef struct glamor_screen_private {
 	GLint put_image_xybitmap_fg_uniform_location;
 	GLint put_image_xybitmap_bg_uniform_location;
 
+	PixmapPtr *back_pixmap;
 	int screen_fbo;
 	struct glamor_saved_procs saved_procs;
 	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
@@ -344,16 +345,7 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
 				glamor_pixmap_private_key);
 }
 
-static inline void
-glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
-{
-	dixSetPrivate(&pixmap->devPrivates,
-		      glamor_pixmap_private_key,
-		      priv);
-}
-
-
-
+void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
commit 8012b030c3144b02af036107179c5b4c94567292
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 17 16:26:59 2012 +0800

    glamor_copyarea: Don't use GL_CLAMP_TO_BORDER when GLES2 enabled.
    
    We may need to modify all the shader to handle GL_CLAMP_TO_BORDER
    when using GLES2. XXX, for now, we just ignore them.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index de02224..87b53a9 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -219,6 +219,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 					src_pixmap_priv->fbo->tex);
 #ifndef GLAMOR_GLES2
 		dispatch->glEnable(GL_TEXTURE_2D);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_WRAP_S,
+					  GL_CLAMP_TO_BORDER);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_WRAP_T,
+					  GL_CLAMP_TO_BORDER);
 #endif
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
@@ -226,12 +232,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MAG_FILTER,
 					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_WRAP_S,
-					  GL_CLAMP_TO_BORDER);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_WRAP_T,
-					  GL_CLAMP_TO_BORDER);
 
 		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
 						GL_FLOAT, GL_FALSE,
commit 5ccf721d386a62f411d77bbc9a142e0c395162b3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Feb 14 17:39:11 2012 +0800

    glamor_fbo: Fix a bug when create No gl FBO pixmap.
    
    Need to get format before goto create a new fbo.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index e5675d8..ec1a5b0 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -341,6 +341,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	    || !glamor_check_fbo_depth(depth))
 		return NULL;
 
+	gl_iformat_for_depth(depth, &format);
 	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
 		goto new_fbo;
 
@@ -349,7 +350,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	else
 		cache_flag = 0;
 
-	gl_iformat_for_depth(depth, &format);
 	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
 					  format, cache_flag);
 	if (fbo)
commit ce634e84d4bb559f01203653c5ffd6397f4b0366
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Feb 12 09:18:51 2012 +0800

    glamor_render: Only recalculate texture for repeat case.
    
    Slightly optimize the fragment shader, as if we are not
    repeat case and not exceed the valid texture range, then
    we don't need to recalculate the coords.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 7388192..9f0b034 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -89,7 +89,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform sampler2D source_sampler;\n"
 	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
-	    "{\n" "	return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n"
+	    "{\n"
+	    "   if (source_wh.x < 0.0) \n"
+	    "		return texture2D(source_sampler, source_texture);\n"
+	    "	else \n"
+	    "		return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n"
 	    "}\n";
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
@@ -97,7 +101,10 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
 	    "{\n"
-	    "       return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n"
+	    "   if (source_wh.x < 0.0) \n"
+	    "		return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
+	    "	else \n"
+	    "   	return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *mask_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
@@ -108,14 +115,21 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    "uniform vec2 mask_wh;"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "	return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n" "}\n";
+	    "   if (mask_wh.x < 0.0) \n"
+	    "		return texture2D(mask_sampler, mask_texture);\n"
+	    "   else \n"
+	    "		return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n"
+	    "}\n";
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
 	    "uniform sampler2D mask_sampler;\n"
 	    "uniform vec2 mask_wh;"
 	    "vec4 get_mask()\n"
 	    "{\n"
-	    "       return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n"
+	    "   if (mask_wh.x < 0.0) \n"
+	    "   	return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+	    "   else \n"
+	    "   	return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *in_source_only =
 	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
@@ -483,6 +497,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
 	float wh[2];
+	Bool has_repeat;
 
 	switch (picture->repeatType) {
 	case RepeatNone:
@@ -536,8 +551,17 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-	wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
-	wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
+	if (picture->repeatType == RepeatNone)
+		has_repeat = picture->transform
+			     && !pixman_transform_is_int_translate(picture->transform);
+	else
+		has_repeat = TRUE;
+	if (has_repeat) {
+		wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
+		wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
+	}
+	else
+		wh[0] = -1;
 	dispatch->glUniform2fv(wh_location, 1, wh);
 	glamor_put_dispatch(glamor_priv);
 }
commit 53387728ddc0c871821b68d728bb5f96a53ba227
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 10 17:40:37 2012 +0800

    glamor_tile/composite: Modify fs to re-calculate texture coords.
    
    Then we don't need to fixup the larger pixmap to the exact
    size, just need to let the shader to re-calculate the correct
    texture coords.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index da66380..ef0ac43 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -66,6 +66,8 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glUseProgram, get_proc_address);
 	INIT_FUNC(dispatch, glUniform1i, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+	INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
+	INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
 	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index 024de26..bd33bcc 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -94,6 +94,10 @@ typedef struct glamor_gl_dispatch {
 	void (*glUniform1i) (GLint location, GLint v0);
 	void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
 			     GLfloat v2, GLfloat v3);
+	void (*glUniform1fv) (GLint location, GLsizei count,
+			      const GLfloat * value);
+	void (*glUniform2fv) (GLint location, GLsizei count,
+			      const GLfloat * value);
 	void (*glUniform4fv) (GLint location, GLsizei count,
 			      const GLfloat * value);
 	 GLuint(*glCreateProgram) (void);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 05bb18a..0d3aa82 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -64,6 +64,8 @@ typedef struct glamor_composite_shader {
 	GLint dest_to_mask_uniform_location;
 	GLint source_uniform_location;
 	GLint mask_uniform_location;
+	GLint source_wh;
+	GLint mask_wh;
 } glamor_composite_shader;
 
 typedef struct {
@@ -203,6 +205,7 @@ typedef struct glamor_screen_private {
 
 	/* glamor_tile */
 	GLint tile_prog;
+	GLint tile_wh;
 
 	/* glamor_putimage */
 	GLint put_image_xybitmap_prog;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 89e8265..7388192 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -70,6 +70,15 @@ static GLuint
 glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 			   struct shader_key *key)
 {
+	const char *relocate_texture =
+	    GLAMOR_DEFAULT_PRECISION
+	    "vec2 rel_tex_coord(vec2 texture, vec2 wh) \n"
+	    "{\n"
+	    "   vec2 rel_tex; \n"
+	    "   rel_tex = texture * wh; \n"
+	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+            "   return rel_tex; \n"
+	    "}\n";
 	const char *source_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION
 	    "uniform vec4 source;\n"
@@ -78,26 +87,35 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 source_texture;\n"
 	    "uniform sampler2D source_sampler;\n"
+	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
-	    "{\n" "	return texture2D(source_sampler, source_texture);\n"
+	    "{\n" "	return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n"
 	    "}\n";
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
-	    "uniform sampler2D source_sampler;\n" "vec4 get_source()\n"
+	    "uniform sampler2D source_sampler;\n"
+	    "uniform vec2 source_wh;"
+	    "vec4 get_source()\n"
 	    "{\n"
-	    "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
+	    "       return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *mask_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
 	    "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
 	const char *mask_alpha_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
-	    "	return texture2D(mask_sampler, mask_texture);\n" "}\n";
+	    "uniform sampler2D mask_sampler;\n"
+	    "uniform vec2 mask_wh;"
+	    "vec4 get_mask()\n"
+	    "{\n"
+	    "	return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n" "}\n";
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
-	    "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+	    "uniform sampler2D mask_sampler;\n"
+	    "uniform vec2 mask_wh;"
+	    "vec4 get_mask()\n"
+	    "{\n"
+	    "       return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *in_source_only =
 	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
@@ -164,7 +182,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 		FatalError("Bad composite IN type");
 	}
 
-	XNFasprintf(&source, "%s%s%s", source_fetch, mask_fetch, in);
+	XNFasprintf(&source, "%s%s%s%s", relocate_texture, source_fetch, mask_fetch, in);
 
 
 	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -255,6 +273,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 		source_sampler_uniform_location =
 		    dispatch->glGetUniformLocation(prog, "source_sampler");
 		dispatch->glUniform1i(source_sampler_uniform_location, 0);
+		shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
 	}
 
 	if (key->mask != SHADER_MASK_NONE) {
@@ -267,6 +286,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 							   "mask_sampler");
 			dispatch->glUniform1i
 			    (mask_sampler_uniform_location, 1);
+			shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
 		}
 	}
 
@@ -450,35 +470,10 @@ glamor_set_composite_op(ScreenPtr screen,
 }
 
 static void
-glamor_composite_texture_fixup(ScreenPtr screen,
-			       PicturePtr picture,
-			       glamor_pixmap_private * pixmap_priv)
-{
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	Bool has_repeat;
-	int width, height;
-
-	if (picture->repeatType == RepeatNone)
-		has_repeat = FALSE;
-	else
-		has_repeat = TRUE;
-
-	if (has_repeat
-	    && ( (pixmap_priv->container->drawable.width != pixmap_priv->fbo->width)
-		 || (pixmap_priv->container->drawable.height != pixmap_priv->fbo->height))) {
-	/* Currently, we can't support repeat on partial texture, now redirect it
-	 * to an exact size fbo. */
-		DEBUGF("prepare to fixup texture \n");
-		if (!glamor_fixup_pixmap_priv(screen, pixmap_priv))
-			ErrorF("Failed to fixup a unmatch size of repeat picture. \n");
-	}
-}
-
-static void
 glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
-			     glamor_pixmap_private * pixmap_priv)
+			     glamor_pixmap_private * pixmap_priv,
+			     GLuint wh_location)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
@@ -487,6 +482,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
+	float wh[2];
+
 	switch (picture->repeatType) {
 	case RepeatNone:
 #ifndef GLAMOR_GLES2
@@ -539,6 +536,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
+	wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
+	wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
+	dispatch->glUniform2fv(wh_location, 1, wh);
 	glamor_put_dispatch(glamor_priv);
 }
 
@@ -1081,12 +1081,6 @@ glamor_composite_with_shader(CARD8 op,
 		}
 	}
 #endif
-
-	if (key.source != SHADER_SOURCE_SOLID)
-		glamor_composite_texture_fixup(screen, source, source_pixmap_priv);
-	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID)
-		glamor_composite_texture_fixup(screen, mask, mask_pixmap_priv);
-
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
 
@@ -1109,7 +1103,7 @@ glamor_composite_with_shader(CARD8 op,
 					   shader->source_uniform_location);
 	} else {
 		glamor_set_composite_texture(screen, 0, source,
-					     source_pixmap_priv);
+					     source_pixmap_priv, shader->source_wh);
 	}
 	if (key.mask != SHADER_MASK_NONE) {
 		if (key.mask == SHADER_MASK_SOLID) {
@@ -1118,7 +1112,7 @@ glamor_composite_with_shader(CARD8 op,
 						   shader->mask_uniform_location);
 		} else {
 			glamor_set_composite_texture(screen, 1, mask,
-						     mask_pixmap_priv);
+						     mask_pixmap_priv, shader->mask_wh);
 		}
 	}
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 917078f..aa62d09 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -49,8 +49,13 @@ glamor_init_tile_shader(ScreenPtr screen)
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 tile_texture;\n"
 	    "uniform sampler2D sampler;\n"
+	    "uniform vec2	wh;"
 	    "void main()\n"
-	    "{\n" "	gl_FragColor = texture2D(sampler, tile_texture);\n"
+	    "{\n"
+	    "   vec2 rel_tex;"
+	    "   rel_tex = tile_texture * wh; \n"
+	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+	    "	gl_FragColor = texture2D(sampler, rel_tex);\n"
 	    "}\n";
 	GLint fs_prog, vs_prog;
 	GLint sampler_uniform_location;
@@ -76,6 +81,10 @@ glamor_init_tile_shader(ScreenPtr screen)
 					   "sampler");
 	dispatch->glUseProgram(glamor_priv->tile_prog);
 	dispatch->glUniform1i(sampler_uniform_location, 0);
+
+	glamor_priv->tile_wh =
+	    dispatch->glGetUniformLocation(glamor_priv->tile_prog,
+					   "wh");
 	dispatch->glUseProgram(0);
 	glamor_put_dispatch(glamor_priv);
 }
@@ -115,6 +124,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
 	glamor_pixmap_private *src_pixmap_priv;
 	glamor_pixmap_private *dst_pixmap_priv;
+	float wh[2];
 
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -142,14 +152,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		goto fail;
 	}
 
-	if (src_pixmap_priv->fbo->width != tile->drawable.width
-	    || src_pixmap_priv->fbo->height != tile->drawable.height) {
-		if (!glamor_fixup_pixmap_priv(screen, src_pixmap_priv)) {
-			glamor_fallback("Failed to create a fixup pixmap for partial tiling. \n");
-			goto fail;
-		}
-	}
-
 	if (alu != GXcopy) {
 		glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
 		glamor_validate_pixmap(tile);
@@ -167,6 +169,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				      &src_yscale);
 		dispatch->glUseProgram(glamor_priv->tile_prog);
 
+		wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
+		wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
+
+		dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
 		dispatch->glActiveTexture(GL_TEXTURE0);
 		dispatch->glBindTexture(GL_TEXTURE_2D,
 					src_pixmap_priv->fbo->tex);
commit 556adfa6b90f4c1ef12635cf78fa0bba046cf123
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Feb 10 12:54:44 2012 +0000

    Fixup glx support
    
    Renaming glamor_priv->dispatch and wrapping the access to
    the dispatch table with a function that also ensured the
    context was bound.
    
     dispatch = glamor_get_dispatch(glamor_priv);
     ...
     glamor_put_dispatch(glamor_priv);
    
    So that we catch all places where we attempt to call into GL withouta
    context. As an optimisation we can then do glamor_get_context();
    glamor_put_context() around the rendering entry points to reduce the
    frequency of having to restore the old context. (Along with allowing
    the context to be recursively acquired and making the old context part of
    the glamor_egl state.)
    
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6b6330f..86de115 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -196,24 +196,25 @@ glamor_block_handler(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-	GLAMOR_DEFINE_CONTEXT;
+	glamor_gl_dispatch *dispatch;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
+	dispatch = glamor_get_dispatch(glamor_priv);
 	glamor_priv->tick++;
 	dispatch->glFlush();
 	dispatch->glFinish();
 	glamor_fbo_expire(glamor_priv);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	glamor_put_dispatch(glamor_priv);
 }
 
 static void
 _glamor_block_handler(void *data, OSTimePtr timeout,
 		      void *last_select_mask)
 {
-	glamor_gl_dispatch *dispatch = data;
+	glamor_screen_private *glamor_priv = data;
+	glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glFlush();
 	dispatch->glFinish();
+	glamor_put_dispatch(glamor_priv);
 }
 
 static void
@@ -289,8 +290,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	}
 #endif
 
-	glamor_gl_dispatch_init(screen, &glamor_priv->dispatch,
-				gl_version);
+	glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version);
 
 #ifdef GLAMOR_GLES2
 	if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
@@ -303,8 +303,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	    glamor_gl_has_extension("GL_MESA_pack_invert");
 	glamor_priv->has_fbo_blit =
 	    glamor_gl_has_extension("GL_EXT_framebuffer_blit");
-	glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
-					    &glamor_priv->max_fbo_size);
+	glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
+					     &glamor_priv->max_fbo_size);
 
 	glamor_set_debug_level(&glamor_debug_level);
 
@@ -324,8 +324,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	if (flags & GLAMOR_USE_SCREEN) {
 		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
 						    _glamor_wakeup_handler,
-						    (void *)
-						    &glamor_priv->dispatch)) {
+						    glamor_priv)) {
 			goto fail;
 		}
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 712a7a9..d3437d3 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -28,18 +28,16 @@
 #ifndef GLAMOR_H
 #define GLAMOR_H
 
-#include "scrnintstr.h"
+#include <scrnintstr.h>
 #ifdef GLAMOR_FOR_XORG
-#include "xf86str.h"
+#include <xf86str.h>
 #endif
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "gcstruct.h"
-#include "picturestr.h"
-#include "fb.h"
-#include "fbpict.h"
-
-#endif				/* GLAMOR_H */
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include <gcstruct.h>
+#include <picturestr.h>
+#include <fb.h>
+#include <fbpict.h>
 
 /*
  * glamor_pixmap_type : glamor pixmap's type.
@@ -145,9 +143,8 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 
-extern _X_EXPORT void * glamor_egl_make_current(ScreenPtr screen);
-
-extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen, void *context);
+extern _X_EXPORT void glamor_egl_make_current(ScreenPtr screen);
+extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
 
 #ifdef GLAMOR_FOR_XORG
 
@@ -320,3 +317,4 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int
 extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
 					   DDXPointPtr points);
 
+#endif /* GLAMOR_H */
diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c
index 28775e5..ac85296 100644
--- a/glamor/glamor_addtraps.c
+++ b/glamor/glamor_addtraps.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index e656934..de02224 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -21,10 +21,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_copyarea.c
@@ -43,7 +39,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	glamor_pixmap_private *src_pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
 	if (!glamor_priv->has_fbo_blit) {
@@ -78,6 +74,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	}
 	glamor_validate_pixmap(dst_pixmap);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
 				    src_pixmap_priv->fbo->fb);
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
@@ -136,6 +133,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 						    GL_NEAREST);
 		}
 	}
+	glamor_put_dispatch(glamor_priv);
 	return TRUE;
 }
 #endif
@@ -147,7 +145,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(dst->pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
 	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
 	int i;
@@ -158,23 +156,24 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	enum glamor_pixmap_status src_status = GLAMOR_NONE;
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
 	int flush_needed = 0;
+	int alu = GXcopy;
 
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
-		goto fail;
+		return FALSE;
 	}
 
 	if (!src_pixmap_priv || !src_pixmap_priv->gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
-		goto fail;
+		return FALSE;
 #else
 		src_status = glamor_upload_pixmap_to_texture(src_pixmap);
 		if (src_status != GLAMOR_UPLOAD_DONE)
-			goto fail;
+			return FALSE;
 
 		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 #endif
@@ -182,25 +181,26 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		flush_needed = 1;
 
 	if (gc) {
-		glamor_set_alu(dispatch, gc->alu);
 		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-			goto fail;
-		if (gc->alu != GXcopy) {
-			glamor_set_destination_pixmap_priv_nc
-			    (src_pixmap_priv);
-			glamor_validate_pixmap(src_pixmap);
-		}
+			return FALSE;
+		alu = gc->alu;
 	}
 
-	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-	glamor_validate_pixmap(dst_pixmap);
-
 	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	glamor_set_alu(dispatch, alu);
+	if (alu != GXcopy) {
+		glamor_set_destination_pixmap_priv_nc (src_pixmap_priv);
+		glamor_validate_pixmap(src_pixmap);
+	}
+	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+	glamor_validate_pixmap(dst_pixmap);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
@@ -284,12 +284,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	/* The source texture is bound to a fbo, we have to flush it here. */
 	if (flush_needed)
 		dispatch->glFlush();
+	glamor_put_dispatch(glamor_priv);
 	return TRUE;
-
-      fail:
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_set_planemask(dst_pixmap, ~0);
-	return FALSE;
 }
 
 static Bool 
@@ -317,7 +313,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	int i;
 	int overlaped = 0;
 	Bool ret = FALSE;
-	GLAMOR_DEFINE_CONTEXT;
 
 	dst_pixmap = glamor_get_drawable_pixmap(dst);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
@@ -326,7 +321,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	screen = dst_pixmap->drawable.pScreen;
 
 	glamor_priv = glamor_get_screen_private(dst->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_fallback("dest pixmap %p has no fbo. \n",
@@ -448,7 +442,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	glamor_clear_delayed_fallbacks(dst->pScreen);
 	if (temp_src != src)
 		glamor_destroy_pixmap(temp_pixmap);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
index b6b26a5..6487ff7 100644
--- a/glamor/glamor_copyplane.c
+++ b/glamor/glamor_copyplane.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
@@ -37,7 +33,6 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		   int srcx, int srcy, int w, int h, int dstx, int dsty,
 		   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
 	glamor_screen_private *glamor_priv;
 
 	if (!fallback 
@@ -47,14 +42,12 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		goto fail;
 
 	glamor_priv = glamor_get_screen_private(pDst->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
 	glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
 	*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
 			  dstx, dsty, bitPlane);
 	glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
 	glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 
  fail:
diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c
index 11b3036..b181ff5 100644
--- a/glamor/glamor_copywindow.c
+++ b/glamor/glamor_copywindow.c
@@ -21,10 +21,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_copywindow.c
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 01c9aea..0376388 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -31,10 +31,6 @@
  * This file covers core X rendering in glamor.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
@@ -174,7 +170,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	GLint sampler_uniform_location;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch =  glamor_get_dispatch(glamor_priv);
 	glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
 	glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
 
@@ -248,7 +244,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	dispatch->glUniform1i(sampler_uniform_location, 0);
 	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
 	dispatch->glUseProgram(0);
-
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
@@ -258,9 +254,10 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch =  glamor_get_dispatch(glamor_priv);
 	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
 	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
@@ -271,7 +268,6 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 	    glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
 		return;
@@ -281,11 +277,17 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 	}
 
 	if (pixmap_priv->fbo->pbo != 0 && pixmap_priv->fbo->pbo_valid) {
+		glamor_gl_dispatch *dispatch;
+
 		assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+
+		dispatch = glamor_get_dispatch(glamor_priv);
 		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-		pixmap_priv->fbo->pbo_valid = FALSE;
 		dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
+		glamor_put_dispatch(glamor_priv);
+
+		pixmap_priv->fbo->pbo_valid = FALSE;
 		pixmap_priv->fbo->pbo = 0;
 	} else {
 		free(pixmap->devPrivate.ptr);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a339527..ecbc186 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -31,11 +31,8 @@
 #include "config.h"
 #endif
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
 #define GLAMOR_FOR_XORG
-#include "xorg-server.h"
+#include <xorg-server.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -93,7 +90,8 @@ struct glamor_egl_screen_private {
 	struct gbm_device *gbm;
 #endif
 	int has_gem;
-	void *gl_context;
+	void *gl_context, *old_context;
+	int gl_context_depth;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
@@ -112,13 +110,18 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 	    scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
 #ifdef GLX_USE_SHARED_DISPATCH
-_X_EXPORT void *
+_X_EXPORT void
 glamor_egl_make_current(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
+
+	if (glamor_egl->gl_context_depth++)
+		return;
+
 	GET_CURRENT_CONTEXT(current);
+	glamor_egl->old_context = current;
 
 	if (glamor_egl->gl_context != current) {
 		eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
@@ -126,24 +129,28 @@ glamor_egl_make_current(ScreenPtr screen)
 		if (!eglMakeCurrent(glamor_egl->display,
 				    EGL_NO_SURFACE, EGL_NO_SURFACE,
 				    glamor_egl->context)) {
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-				   "Failed to make EGL context current\n");
-			return NULL;
+			FatalError("Failed to make EGL context current\n");
 		}
-		return current;
 	}
-	return NULL;
 }
 
 _X_EXPORT void
-glamor_egl_restore_context(ScreenPtr screen, void *context)
+glamor_egl_restore_context(ScreenPtr screen)
 {
-	if (context)
-		SET_CURRENT_CONTEXT(context);
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+
+	if (--glamor_egl->gl_context_depth)
+		return;
+
+	if (glamor_egl->old_context &&
+	    glamor_egl->gl_context != glamor_egl->old_context)
+		SET_CURRENT_CONTEXT(glamor_egl->old_context);
 }
 #else
-#define glamor_egl_make_current(x)  NULL
-#define glamor_egl_restore_context(s, c)
+#define glamor_egl_make_current(x)
+#define glamor_egl_restore_context(s)
 #endif
 
 static EGLImageKHR
@@ -252,12 +259,11 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
-	void *prev_context;
 	Bool ret = FALSE;
 
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 
-	prev_context = glamor_egl_make_current(screen);
+	glamor_egl_make_current(screen);
 	if (glamor_egl->has_gem) {
 		if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -285,8 +291,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	ret = TRUE;
 
 done:
-	if (prev_context)
-		glamor_egl_restore_context(screen, prev_context);
+	glamor_egl_restore_context(screen);
 	return ret;
 }
 
@@ -497,6 +502,13 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 #endif
 	glamor_egl->saved_free_screen = scrn->FreeScreen;
 	scrn->FreeScreen = glamor_egl_free_screen;
+#ifdef GLAMOR_GLES2
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using GLES2.\n");
+#ifdef GLX_USE_SHARED_DISPATCH
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Glamor is using GLES2 but GLX needs GL. "
+					       "Indirect GLX may not work correctly.\n");
+#endif
+#endif
 	return TRUE;
 }
 
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index e1f6672..0961651 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -28,10 +28,10 @@
 #include "config.h"
 #endif
 
-#include <xorg-server.h>
 #define GLAMOR_FOR_XORG
 #include "glamor.h"
-#include "xf86Module.h"
+#include <xf86Module.h>
+#include <xorg-server.h>
 
 static XF86ModuleVersionInfo VersRec = {
 	GLAMOR_EGL_MODULE_NAME,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 929caba..e5675d8 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -1,7 +1,3 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
@@ -126,17 +122,14 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
-	GLAMOR_DEFINE_CONTEXT;
-
-	GLAMOR_SET_CONTEXT(fbo->glamor_priv);
-	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
 	if (fbo->fb)
 		dispatch->glDeleteFramebuffers(1, &fbo->fb);
 	if (fbo->tex)
 		dispatch->glDeleteTextures(1, &fbo->tex);
 	if (fbo->pbo)
 		dispatch->glDeleteBuffers(1, &fbo->pbo);
-	GLAMOR_RESTORE_CONTEXT(fbo->glamor_priv);
+	glamor_put_dispatch(fbo->glamor_priv);
 
 	free(fbo);
 }
@@ -292,7 +285,6 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	glamor_pixmap_fbo *fbo;
 	int cache_flag = GLAMOR_CACHE_TEXTURE;
 	GLuint tex;
-	GLAMOR_DEFINE_CONTEXT;
 
 	if (flag == GLAMOR_CREATE_TEXTURE_EXACT_SIZE)
 		cache_flag |= GLAMOR_CACHE_EXACT_SIZE;
@@ -305,10 +297,9 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	if (fbo == NULL)
 		return NULL;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	list_init(&fbo->list);
 
-	dispatch = &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
@@ -317,12 +308,13 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 				  GL_NEAREST);
 	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
 			       GL_UNSIGNED_BYTE, NULL);
+	glamor_put_dispatch(glamor_priv);
+
 	fbo->tex = tex;
 	fbo->width = w;
 	fbo->height = h;
 	fbo->format = format;
 	fbo->glamor_priv = glamor_priv;
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 
 	return fbo;
 }
@@ -344,7 +336,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	GLenum format;
 	GLint tex;
 	int cache_flag;
-	GLAMOR_DEFINE_CONTEXT;
 
 	if (!glamor_check_fbo_size(glamor_priv, w, h)
 	    || !glamor_check_fbo_depth(depth))
@@ -364,9 +355,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	if (fbo)
 		return fbo;
 new_fbo:
-
-	GLAMOR_SET_CONTEXT(glamor_priv);
-	dispatch = &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
@@ -377,7 +366,7 @@ new_fbo:
 			       GL_UNSIGNED_BYTE, NULL);
 
 	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	glamor_put_dispatch(glamor_priv);
 
 	return fbo;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index b462f59..8573309 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -21,10 +21,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_fillspans.c
@@ -112,7 +108,7 @@ glamor_init_solid_shader(ScreenPtr screen)
 	GLint fs_prog, vs_prog;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch =  glamor_get_dispatch(glamor_priv);
 	glamor_priv->solid_prog = dispatch->glCreateProgram();
 	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
 	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -127,6 +123,7 @@ glamor_init_solid_shader(ScreenPtr screen)
 	glamor_priv->solid_color_uniform_location =
 	    dispatch->glGetUniformLocation(glamor_priv->solid_prog,
 					   "color");
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
@@ -136,8 +133,9 @@ glamor_fini_solid_shader(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glDeleteProgram(glamor_priv->solid_prog);
+	glamor_put_dispatch(glamor_priv);
 }
 
 Bool
@@ -150,7 +148,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	    glamor_get_screen_private(screen);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	int x1 = x;
 	int x2 = x + width;
 	int y1 = y;
@@ -158,15 +156,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	GLfloat color[4];
 	float vertices[8];
 	GLfloat xscale, yscale;
+
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("dest %p has no fbo.\n", pixmap);
-		goto fail;
+		return FALSE;
 	}
-	glamor_set_alu(dispatch, alu);
+
 	if (!glamor_set_planemask(pixmap, planemask)) {
 		glamor_fallback
 		    ("Failedto set planemask  in glamor_solid.\n");
-		goto fail;
+		return FALSE;
 	}
 
 	glamor_get_rgba_from_pixel(fg_pixel,
@@ -189,6 +188,8 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
+	glamor_set_alu(dispatch, alu);
 	dispatch->glUseProgram(glamor_priv->solid_prog);
 
 	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
@@ -205,9 +206,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
 	return TRUE;
-      fail:
-	glamor_set_alu(dispatch, GXcopy);
-	glamor_set_planemask(pixmap, ~0);
-	return FALSE;
 }
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 97e4497..6598249 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -20,10 +20,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 /** @file glamor_fillspans.c
  *
  * FillSpans implementation, taken from fb_fillsp.c
@@ -41,11 +37,9 @@ _glamor_fill_spans(DrawablePtr drawable,
 	int x1, x2, y;
 	RegionPtr pClip = fbGetCompositeClip(gc);
 	glamor_screen_private *glamor_priv;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 
 	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 		goto fail;
@@ -99,7 +93,6 @@ fail:
 	ret = TRUE;
 
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 7caf2a3..efbd1ba 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 
@@ -46,13 +42,11 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	int no_alpha, no_revert;
 	PixmapPtr temp_pixmap = NULL;
 	glamor_gl_dispatch * dispatch;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
 	goto fall_back;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 
 	if (format != ZPixmap)
 		goto fall_back;
@@ -65,7 +59,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	}
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	dispatch = &glamor_priv->dispatch;
 
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -97,6 +90,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	int row_length = PixmapBytePad(w, drawable->depth);
 	row_length = (row_length * 8) / drawable->bitsPerPixel;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
@@ -117,14 +112,13 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 				       h,
 				       tex_format,
 				       tex_type, d);
+	glamor_put_dispatch(glamor_priv);
 	if (temp_pixmap)
 		glamor_destroy_pixmap(temp_pixmap);
 
 	ret = TRUE;
 
 fall_back:
-
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	if (ret == FALSE)
 		miGetImage(drawable, x, y, w, h, format, planeMask, d);
 	return TRUE;
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 2d30f37..91030a3 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -25,10 +25,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool 
@@ -44,15 +40,13 @@ _glamor_get_spans(DrawablePtr drawable,
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	PixmapPtr temp_pixmap = NULL;
 	int i;
 	uint8_t *readpixels_dst = (uint8_t *) dst;
 	int x_off, y_off;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
 		goto fail;
@@ -82,6 +76,7 @@ _glamor_get_spans(DrawablePtr drawable,
 	}
 
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+	dispatch = glamor_get_dispatch(glamor_priv);
 	for (i = 0; i < count; i++) {
 		if (glamor_priv->yInverted) {
 			dispatch->glReadPixels(points[i].x + x_off,
@@ -98,6 +93,7 @@ _glamor_get_spans(DrawablePtr drawable,
 		readpixels_dst +=
 		    PixmapBytePad(widths[i], drawable->depth);
 	}
+	glamor_put_dispatch(glamor_priv);
 	if (temp_pixmap)
 		glamor_destroy_pixmap(temp_pixmap);
 
@@ -116,7 +112,6 @@ fail:
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
 	}
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 8c853e9..1630998 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
@@ -37,7 +33,6 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
 	glamor_screen_private *glamor_priv;
 
 	if (!fallback 
@@ -46,13 +41,11 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
 		goto fail;
 
 	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access_gc(pGC);
 	fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
  fail:
 	return FALSE;
@@ -79,25 +72,20 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
 	glamor_screen_private *glamor_priv;
 
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
-		goto fail;
+		return FALSE;
 
 	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access_gc(pGC);
 	fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
- fail:
-	return FALSE;
 }
 
 void
@@ -120,17 +108,12 @@ static Bool
 _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 		    DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
-		goto fail;
+		return FALSE;
 
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
 	glamor_prepare_access_gc(pGC);
@@ -138,10 +121,7 @@ _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
- fail:
-	return FALSE;
 }
 
 void
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 33e06f1..fe7d9de 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -40,15 +40,11 @@
  * Based on code by: Keith Packard
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
 
-#include "mipict.h"
+#include <mipict.h>
 
 #if DEBUG_GLYPH_CACHE
 #define DBG_GLYPH_CACHE(a) ErrorF a
@@ -163,7 +159,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 		glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
 		PixmapPtr pixmap;
 		PicturePtr picture;
-		CARD32 component_alpha;
+		XID component_alpha;
 		int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
 		int error;
 		PictFormatPtr pPictFormat =
@@ -652,7 +648,7 @@ glamor_glyphs_via_mask(CARD8 op,
 	GlyphPtr glyph;
 	int error;
 	BoxRec extents = { 0, 0, 0, 0 };
-	CARD32 component_alpha;
+	XID component_alpha;
 	glamor_glyph_buffer_t buffer;
 	xRectangle fill_rect;
 
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 217fd40..38185a4 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -1,7 +1,3 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 1a63ffd..7f4a90b 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1,7 +1,3 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
@@ -31,7 +27,7 @@ static void
 _glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
 				glamor_pixmap_private * pixmap_priv)
 {
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch = glamor_get_dispatch(glamor_priv);
 	GLfloat vertices[8];
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
@@ -52,6 +48,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glUseProgram(0);
 	pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
+	glamor_put_dispatch(glamor_priv);
 }
 
 
@@ -94,7 +91,7 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch = glamor_get_dispatch(pixmap_priv->glamor_priv);
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fbo->fb);
 #ifndef GLAMOR_GLES2
 	dispatch->glMatrixMode(GL_PROJECTION);
@@ -106,6 +103,7 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 			     pixmap_priv->fbo->width,
 			     pixmap_priv->fbo->height);
 
+	glamor_put_dispatch(pixmap_priv->glamor_priv);
 }
 
 int
@@ -222,7 +220,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	    glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	unsigned int stride, row_length;
 	void *texels;
 	GLenum iformat;
@@ -235,6 +233,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	stride = pixmap->devKind;
 	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
@@ -271,6 +270,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
 	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+	glamor_put_dispatch(glamor_priv);
 }
 
 
@@ -289,7 +289,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	    glamor_get_pixmap_private(pixmap);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	static float vertices[8];
 	static float texcoords[8] = { 0, 1,
 		1, 1,
@@ -339,6 +339,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 				     vertices);
 
 	/* Slow path, we need to flip y or wire alpha to 1. */
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
@@ -379,13 +380,17 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glDeleteTextures(1, &tex);
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
 glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
+	glamor_gl_dispatch *dispatch;
 	int status;
-	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+
+	dispatch = glamor_get_dispatch(fbo->glamor_priv);
 
 	if (fbo->fb == 0)
 		dispatch->glGenFramebuffers(1, &fbo->fb);
@@ -422,11 +427,10 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 			break;
 		}
 
-		LogMessageVerb(X_INFO, 0,
-			       "destination is framebuffer incomplete: %s [%#x]\n",
-			       str, status);
-		assert(0);
+		FatalError("destination is framebuffer incomplete: %s [%#x]\n",
+			   str, status);
 	}
+	glamor_put_dispatch(fbo->glamor_priv);
 }
 
 /*  
@@ -571,7 +575,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 
 	glamor_priv = glamor_get_screen_private(screen);
 	source_priv = glamor_get_pixmap_private(source);
-	dispatch = &glamor_priv->dispatch;
 	if (*format == GL_BGRA) {
 		*format = GL_RGBA;
 		swap_rb = 1;
@@ -585,6 +588,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 
 	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
 				  GL_TEXTURE_MIN_FILTER,
@@ -631,6 +635,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
 	return temp_pixmap;
 }
 
@@ -657,7 +662,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	ScreenPtr screen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 
 	screen = pixmap->drawable.pScreen;
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -715,6 +720,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	}
 	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
@@ -795,6 +801,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	}
 
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+	glamor_put_dispatch(glamor_priv);
       done:
 
 	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 8b36241..61e707f 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_fillspans.c
@@ -48,10 +44,8 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	RegionPtr pClip = fbGetCompositeClip(gc);
 	Bool ret = FALSE;
 	glamor_screen_private *glamor_priv;
-	GLAMOR_DEFINE_CONTEXT;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 
 	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
 		goto fail;
@@ -119,7 +113,6 @@ fail:
 	ret = TRUE;
 
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 0d37a1d..175e958 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_polylines.c
@@ -50,7 +46,6 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	int x1, x2, y1, y2;
 	int i;
 	glamor_screen_private *glamor_priv;
-	GLAMOR_DEFINE_CONTEXT;
 
 	/* Don't try to do wide lines or non-solid fill style. */
 	if (gc->lineWidth != 0) {
@@ -112,7 +107,6 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 		return FALSE;
 
 	glamor_priv = glamor_get_screen_private(drawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (gc->lineWidth == 0) {
 		if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 			if (glamor_prepare_access_gc(gc)) {
@@ -126,7 +120,6 @@ wide_line:
 		/* fb calls mi functions in the lineWidth != 0 case. */
 		fbPolyLine(drawable, gc, mode, n, points);
 	}
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
index ca21b8b..7320c17 100644
--- a/glamor/glamor_polyops.c
+++ b/glamor/glamor_polyops.c
@@ -26,36 +26,23 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
 _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		   DDXPointPtr ppt, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		goto fail;
+		return FALSE;
 
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access_gc(pGC);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	fbPolyPoint(pDrawable, pGC, mode, npt, ppt);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_finish_access_gc(pGC);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
-
-fail:
-	return FALSE;
 }
 
 void
@@ -76,16 +63,11 @@ static Bool
 _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		     xSegment *pSeg, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		goto fail;
+		return FALSE;
 
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	/* For lineWidth is not zero, fb calls to mi functions. */
 	if (pGC->lineWidth == 0) {
 		glamor_prepare_access_gc(pGC);
@@ -94,13 +76,9 @@ _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
 		glamor_finish_access_gc(pGC);
 	} else
-	fbPolySegment(pDrawable, pGC, nseg, pSeg);
+		fbPolySegment(pDrawable, pGC, nseg, pSeg);
 
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
-
-fail:
-	return FALSE;
 }
 
 void
@@ -121,17 +99,12 @@ static Bool
 _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr ppt, Bool fallback)
 {
-	GLAMOR_DEFINE_CONTEXT;
-	glamor_screen_private *glamor_priv;
-
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
-		goto fail;
+		return FALSE;
 	/* For lineWidth is not zero, fb calls to mi functions. */
 
-	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (pGC->lineWidth == 0) {
 		glamor_prepare_access_gc(pGC);
 		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
@@ -139,13 +112,9 @@ _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
 		glamor_finish_access_gc(pGC);
 	} else
-	fbPolyLine(pDrawable, pGC, mode, npt, ppt);
+		fbPolyLine(pDrawable, pGC, mode, npt, ppt);
 
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
-
-fail:
-	return FALSE;
 }
 
 void
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d04421b..05bb18a 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,10 +31,6 @@
 #include "config.h"
 #endif
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#include <xorg-config.h>
-#endif
 #include <xorg-server.h>
 
 #include "glamor.h"
@@ -171,7 +167,7 @@ struct glamor_saved_procs {
 	(((int)(t1) - (int)(t0)) < 0)
 
 typedef struct glamor_screen_private {
-	struct glamor_gl_dispatch dispatch;
+	struct glamor_gl_dispatch _dispatch;
 	int yInverted;
 	unsigned int tick;
 	enum glamor_gl_flavor gl_flavor;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 5813822..75e5b4c 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -251,7 +251,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
@@ -265,10 +265,8 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	GLfloat xscale, yscale, txscale, tyscale;
 	GLuint tex;
 	int no_alpha, no_revert;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
 		goto fail;
@@ -287,7 +285,6 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (!glamor_set_planemask(pixmap, gc->planemask)) {
 		goto fail;
 	}
-	glamor_set_alu(dispatch, gc->alu);
 
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
@@ -298,6 +295,8 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	}
 
 	/* XXX consider to reuse a function to do the following work. */
+	dispatch = glamor_get_dispatch(glamor_priv);
+	glamor_set_alu(dispatch, gc->alu);
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -400,6 +399,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_set_planemask(pixmap, ~0);
+	glamor_put_dispatch(glamor_priv);
 
 	ret = TRUE;
 	goto done;
@@ -421,7 +421,6 @@ fail:
 	ret = TRUE;
 
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b240eac..89e8265 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -220,15 +220,16 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 	GLuint vs, fs, prog;
 	GLint source_sampler_uniform_location,
 	    mask_sampler_uniform_location;
-	glamor_screen_private *glamor = glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor->dispatch;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch;
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	vs = glamor_create_composite_vs(dispatch, key);
 	if (vs == 0)
-		return;
+		goto out;
 	fs = glamor_create_composite_fs(dispatch, key);
 	if (fs == 0)
-		return;
+		goto out;
 
 	prog = dispatch->glCreateProgram();
 	dispatch->glAttachShader(prog, vs);
@@ -268,6 +269,9 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 			    (mask_sampler_uniform_location, 1);
 		}
 	}
+
+out:
+	glamor_put_dispatch(glamor_priv);
 }
 
 static glamor_composite_shader *
@@ -316,7 +320,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	int vb_size;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glGenBuffers(1, &glamor_priv->vbo);
 	dispatch->glGenBuffers(1, &glamor_priv->ebo);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
@@ -331,17 +335,13 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	}
 	else {
 		vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
-		if (vb == NULL) {
-			ErrorF("Failed to allocate vb memory.\n");
-			exit(1);
-		}
+		if (vb == NULL)
+			FatalError("Failed to allocate vb memory.\n");
 		eb = malloc(eb_size);
 	}
 
-	if (eb == NULL) {
-		ErrorF("fatal error, fail to get eb.\n");
-		exit(1);
-	}
+	if (eb == NULL)
+		FatalError("fatal error, fail to get eb.\n");
 	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
@@ -362,6 +362,8 @@ glamor_init_composite_shaders(ScreenPtr screen)
 		free(eb);
 		glamor_priv->vb = (char*)vb;
 	}
+
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
@@ -373,7 +375,7 @@ glamor_fini_composite_shaders(ScreenPtr screen)
 	int i,j,k;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch = &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
 	dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
 
@@ -388,8 +390,9 @@ glamor_fini_composite_shaders(ScreenPtr screen)
 	if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
 	    && glamor_priv->vb)
 		free(glamor_priv->vb);
-}
 
+	glamor_put_dispatch(glamor_priv);
+}
 
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
@@ -399,7 +402,7 @@ glamor_set_composite_op(ScreenPtr screen,
 	struct blendinfo *op_info;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 
 	if (op >= ARRAY_SIZE(composite_op_info)) {
 		glamor_fallback("unsupported render op %d \n", op);
@@ -435,12 +438,14 @@ glamor_set_composite_op(ScreenPtr screen,
 			dest_blend = GL_ONE_MINUS_SRC_COLOR;
 	}
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
 		dispatch->glDisable(GL_BLEND);
 	} else {
 		dispatch->glEnable(GL_BLEND);
 		dispatch->glBlendFunc(source_blend, dest_blend);
 	}
+	glamor_put_dispatch(glamor_priv);
 	return TRUE;
 }
 
@@ -451,7 +456,6 @@ glamor_composite_texture_fixup(ScreenPtr screen,
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	Bool has_repeat;
 	int width, height;
 
@@ -478,7 +482,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
 	switch (picture->repeatType) {
@@ -533,6 +539,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
+	glamor_put_dispatch(glamor_priv);
 }
 
 static void
@@ -654,7 +661,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 
 	glamor_priv->vbo_offset = 0;
 	glamor_priv->vbo_offset = 0;
@@ -667,6 +674,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	if (glamor_priv->has_mask_coords)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		dispatch->glBufferData(GL_ARRAY_BUFFER,
@@ -706,6 +714,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 							  sizeof(float)));
 		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
 	}
+	glamor_put_dispatch(glamor_priv);
 }
 
 static void
@@ -739,9 +748,12 @@ glamor_flush_composite_rects(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
+
 	if (!glamor_priv->render_nr_verts)
 		return;
+
+	dispatch = glamor_get_dispatch(glamor_priv);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
 	else {
@@ -754,6 +766,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
 
 	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 				 GL_UNSIGNED_SHORT, NULL);
+	glamor_put_dispatch(glamor_priv);
 }
 
 static void
@@ -846,7 +859,7 @@ glamor_composite_with_shader(CARD8 op,
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	PixmapPtr dest_pixmap =
 	    glamor_get_drawable_pixmap(dest->pDrawable);
 	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
@@ -870,10 +883,8 @@ glamor_composite_with_shader(CARD8 op,
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	int vert_stride = 4;
 	int nrect_max;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
@@ -1090,6 +1101,7 @@ glamor_composite_with_shader(CARD8 op,
 		goto fail;
 	}
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glUseProgram(shader->prog);
 
 	if (key.source == SHADER_SOURCE_SOLID) {
@@ -1233,6 +1245,7 @@ glamor_composite_with_shader(CARD8 op,
 	dispatch->glUseProgram(0);
 	if (saved_source_format)
 		source->format = saved_source_format;
+	glamor_put_dispatch(glamor_priv);
 
 	ret = TRUE;
 	goto done;
@@ -1240,12 +1253,7 @@ glamor_composite_with_shader(CARD8 op,
 fail:
 	if (saved_source_format)
 		source->format = saved_source_format;
-
-	dispatch->glDisable(GL_BLEND);
-	dispatch->glUseProgram(0);
-
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
@@ -1320,7 +1328,6 @@ _glamor_composite(CARD8 op,
 	RegionRec region;
 	BoxPtr box;
 	int nbox, i, ok;
-	GLAMOR_DEFINE_CONTEXT;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
@@ -1328,7 +1335,6 @@ _glamor_composite(CARD8 op,
 	y_temp_mask = y_mask;
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		goto fail;
@@ -1535,7 +1541,6 @@ fail:
 		FreePicture(temp_mask, 0);
 	if (prect != rect)
 		free(prect);
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 07c94ab..a947169 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -25,10 +25,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
@@ -40,17 +36,15 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	glamor_pixmap_private *dest_pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	GLenum format, type;
 	int no_alpha, no_revert, i;
 	uint8_t *drawpixels_src = (uint8_t *) src;
 	RegionPtr clip = fbGetCompositeClip(gc);
 	BoxRec *pbox;
 	int x_off, y_off;
-	GLAMOR_DEFINE_CONTEXT;
 	Bool ret = FALSE;
 
-	GLAMOR_SET_CONTEXT(glamor_priv);
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
@@ -70,17 +64,15 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		goto fail;
 	}
 
-
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
 	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 		goto fail;
-	glamor_set_alu(dispatch, gc->alu);
-	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
-		goto fail;
 
 	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
+	glamor_set_alu(dispatch, gc->alu);
 	for (i = 0; i < n; i++) {
 
 		n = REGION_NUM_RECTS(clip);
@@ -103,6 +95,7 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	glamor_set_planemask(dest_pixmap, ~0);
 	glamor_set_alu(dispatch, GXcopy);
 	dispatch->glDisable(GL_SCISSOR_TEST);
+	glamor_put_dispatch(glamor_priv);
 	ret = TRUE;
 	goto done;
 
@@ -120,7 +113,6 @@ fail:
 	ret = TRUE;
 
 done:
-	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 3087bea..917078f 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -25,10 +25,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_tile.c
@@ -60,7 +56,7 @@ glamor_init_tile_shader(ScreenPtr screen)
 	GLint sampler_uniform_location;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	glamor_priv->tile_prog = dispatch->glCreateProgram();
 	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
 	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -81,6 +77,7 @@ glamor_init_tile_shader(ScreenPtr screen)
 	dispatch->glUseProgram(glamor_priv->tile_prog);
 	dispatch->glUniform1i(sampler_uniform_location, 0);
 	dispatch->glUseProgram(0);
+	glamor_put_dispatch(glamor_priv);
 }
 
 void
@@ -90,8 +87,9 @@ glamor_fini_tile_shader(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch =  &glamor_priv->dispatch;
+	dispatch = glamor_get_dispatch(glamor_priv);
 	dispatch->glDeleteProgram(glamor_priv->tile_prog);
+	glamor_put_dispatch(glamor_priv);
 }
 
 Bool
@@ -103,7 +101,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_gl_dispatch *dispatch;
 	int x1 = x;
 	int x2 = x + width;
 	int y1 = y;
@@ -161,6 +159,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	glamor_validate_pixmap(pixmap);
 	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 
+	dispatch = glamor_get_dispatch(glamor_priv);
 	glamor_set_alu(dispatch, alu);
 
 	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
@@ -219,6 +218,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	dispatch->glUseProgram(0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_set_planemask(pixmap, ~0);
+	glamor_put_dispatch(glamor_priv);
 	return TRUE;
 
       fail:
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index 208ac77..e0f4a97 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -26,10 +26,6 @@
  *
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 static Bool
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index a66e248..4a51ba5 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -664,31 +664,44 @@ static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int
 	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 }
 
-static inline void *glamor_make_current(ScreenPtr screen)
+static inline void glamor_make_current(ScreenPtr screen)
 {
-	return glamor_egl_make_current(screen);
+	glamor_egl_make_current(screen);
 }
 
-static inline void glamor_restore_current(ScreenPtr screen, void *previous_context)
+static inline void glamor_restore_current(ScreenPtr screen)
 {
-	glamor_egl_restore_context(screen, previous_context);
+	glamor_egl_restore_context(screen);
 }
 
 #ifdef GLX_USE_SHARED_DISPATCH
-#define GLAMOR_DEFINE_CONTEXT		void *_previous_context_ = NULL
-#define GLAMOR_SET_CONTEXT(glamor_priv)			\
-	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) \
-		_previous_context_ = glamor_make_current(glamor_priv->screen)
-
-#define GLAMOR_RESTORE_CONTEXT(glamor_priv)			\
-	if ((glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)	\
-	     && _previous_context_ != NULL) 			\
-		glamor_restore_current(glamor_priv->screen, _previous_context_)
+static inline glamor_gl_dispatch *
+glamor_get_dispatch(glamor_screen_private *glamor_priv)
+{
+	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
+		glamor_make_current(glamor_priv->screen);
+
+	return &glamor_priv->_dispatch;
+}
+
+static inline void
+glamor_put_dispatch(glamor_screen_private *glamor_priv)
+{
+	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
+		glamor_restore_current(glamor_priv->screen);
+}
 #else
+#warning "Indirect GLX may be broken, need to implement context switch."
+static inline glamor_gl_dispatch *
+glamor_get_dispatch(glamor_screen_private *glamor_priv)
+{
+	return &glamor_priv->_dispatch;
+}
 
-#define GLAMOR_DEFINE_CONTEXT
-#define GLAMOR_SET_CONTEXT(glamor_priv)
-#define GLAMOR_RESTORE_CONTEXT(glamor_priv)
+static inline void
+glamor_put_dispatch(glamor_screen_private *glamor_priv)
+{
+}
 
 #endif
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
index f6e4cd1..3da11e4 100644
--- a/glamor/glamor_window.c
+++ b/glamor/glamor_window.c
@@ -21,10 +21,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include "glamor_priv.h"
 
 /** @file glamor_window.c
commit 430bc16ca03b3ea00255a4045c8e9fd11aea95ad
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 10 16:04:07 2012 +0800

    GLX: Enable glx support.
    
    If we are using MESA as our GL library, then both xserver's
    GLX and glamor are link to the same library. As xserver's
    GLX has its own _glapi_get/set_context/dispatch etc, and it
    is a simplified version derived from mesa thus is not
    sufficient for mesa/egl's dri loader which is used by glamor.
    
    Then if glx module is loaded before glamoregl module, the
    initialization of mesa/egl/opengl will not be correct, and
    will fail at a very early stage, most likely fail to map
    the element buffer.
    
    Two methodis to fix this problem, first is to modify the xserver's
    glx's glapi.c to fit mesa's requirement. The second is to put
    a glamor.conf as below, to the system's xorg.conf path.
    
    Section "Module"
            Load  "glamoregl"
    EndSection
    
    Then glamor will be loaded firstly, and the mesa's libglapi.so
    will be used. As current xserver's dispatch table is the same
    as mesa's, then the glx's dri loader can work without problem.
    
    We took the second method as it don't need any change to xorg.:)
    Although this is not a graceful implementation as it depends
    on the xserver's dispatch table and the mesa's dispatch table
    is the same and the context set and get is using the same method.
    Anyway it works.
    
    As by default, xserver will enable GLX_USE_TLS. But mesa will not
    enable it, you may need to enable that when build mesa.
    
    Three pre-requirements to make this glamor version work:
    
    0. Make sure xserver has commit 66e603, if not please pull the latest
       master branch.
    1. Rebuild mesa by enable GLX_USE_TLS.
    2. Put the glamor.conf to your system's xorg.conf path and make sure
       it loaded prior to glx module.
    
    Preliminary testing shows indirect glxgears works fine.
    
    If user want to use GLES2 for glamor by using MESA, GLX will not
    work correctly.
    
    If you are not using normal MESA, for example PVR's private GLES
    implementation, then it should be ok to use GLES2 glamor and the
    GLX should work as expected. In this commit, I use gbm to check
    whether we are using MESA or non-mesa. Maybe not the best way.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index ca8fc3f..c7e3000 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -53,9 +53,9 @@ if EGL
 LIBGLAMOREGL = libglamoregl.la
 module_LTLIBRARIES = $(LIBGLAMOREGL)
 libglamoregl_la_DEPENDENCIES = libglamor.la
-libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
+libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor $(GLX_SYS_LIBS)
 libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
-libglamoregl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
+libglamoregl_la_CFLAGS = $(AM_CFLAGS) $(GLX_DEFINES) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
 endif
 
 
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0245fda..6b6330f 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -83,11 +83,9 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
-	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *fbo;
 
 	glamor_priv = glamor_get_screen_private(screen);
-	dispatch  = &glamor_priv->dispatch;
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
 	if (pixmap_priv->fbo) {
@@ -130,7 +128,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	glamor_pixmap_fbo *fbo;
 	int pitch;
 	int flag;
@@ -149,7 +146,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		fbDestroyPixmap(pixmap);
 		return fbCreatePixmap(screen, w, h, depth, usage);
 	}
-
 	glamor_set_pixmap_private(pixmap, pixmap_priv);
 
 	pixmap_priv->container = pixmap;
@@ -201,11 +197,14 @@ glamor_block_handler(ScreenPtr screen)
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	GLAMOR_DEFINE_CONTEXT;
 
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_priv->tick++;
 	dispatch->glFlush();
 	dispatch->glFinish();
 	glamor_fbo_expire(glamor_priv);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 }
 
 static void
@@ -392,6 +391,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_pixmap_init(screen);
 
 	glamor_priv->flags = flags;
+	glamor_priv->screen = screen;
 
 	return TRUE;
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 3d6e5fe..712a7a9 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -145,6 +145,10 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 
+extern _X_EXPORT void * glamor_egl_make_current(ScreenPtr screen);
+
+extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen, void *context);
+
 #ifdef GLAMOR_FOR_XORG
 
 #define GLAMOR_EGL_MODULE_NAME  "glamoregl"
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index f2d710a..e656934 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -308,6 +308,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
 	DrawablePtr temp_src = src;
 	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+	glamor_screen_private *glamor_priv;
 	BoxRec bound;
 	ScreenPtr screen;
 	int temp_dx = dx;
@@ -315,7 +316,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
 	int i;
 	int overlaped = 0;
-	Bool ret = TRUE;
+	Bool ret = FALSE;
+	GLAMOR_DEFINE_CONTEXT;
 
 	dst_pixmap = glamor_get_drawable_pixmap(dst);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
@@ -323,6 +325,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
 
+	glamor_priv = glamor_get_screen_private(dst->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
+
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_fallback("dest pixmap %p has no fbo. \n",
 				dst_pixmap);
@@ -356,6 +361,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	     || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
 	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
 					   dy)) {
+		ret = TRUE;
 		goto done;
 	}
 #endif
@@ -400,6 +406,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 
 	if (glamor_copy_n_to_n_textured
 	    (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
+		ret = TRUE;
 		goto done;
 	}
 
@@ -408,10 +415,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(src)
-	    && glamor_ddx_fallback_check_pixmap(dst)) {
-		ret = FALSE;
+	    && glamor_ddx_fallback_check_pixmap(dst))
 		goto done;
-	} 
 
 	glamor_report_delayed_fallbacks(src->pScreen);
 	glamor_report_delayed_fallbacks(dst->pScreen);
@@ -436,12 +441,14 @@ _glamor_copy_n_to_n(DrawablePtr src,
 		}
 		glamor_finish_access(dst, GLAMOR_ACCESS_RW);
 	}
+	ret = TRUE;
 
       done:
 	glamor_clear_delayed_fallbacks(src->pScreen);
 	glamor_clear_delayed_fallbacks(dst->pScreen);
 	if (temp_src != src)
 		glamor_destroy_pixmap(temp_pixmap);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
index 288d7ed..b6b26a5 100644
--- a/glamor/glamor_copyplane.c
+++ b/glamor/glamor_copyplane.c
@@ -37,17 +37,24 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		   int srcx, int srcy, int w, int h, int dstx, int dsty,
 		   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pSrc)
 	    && glamor_ddx_fallback_check_pixmap(pDst))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDst->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
 	glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
 	*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
 			  dstx, dsty, bitPlane);
 	glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
 	glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 
  fail:
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 027722e..a339527 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -63,6 +63,9 @@
 
 #include "glamor.h"
 #include "glamor_gl_dispatch.h"
+#ifdef GLX_USE_SHARED_DISPATCH
+#include "glapi.h"
+#endif
 
 static const char glamor_name[] = "glamor";
 
@@ -90,6 +93,7 @@ struct glamor_egl_screen_private {
 	struct gbm_device *gbm;
 #endif
 	int has_gem;
+	void *gl_context;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
@@ -101,13 +105,46 @@ struct glamor_egl_screen_private {
 
 int xf86GlamorEGLPrivateIndex = -1;
 
-static struct glamor_egl_screen_private
-*
+static struct glamor_egl_screen_private *
 glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 {
 	return (struct glamor_egl_screen_private *)
 	    scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
+#ifdef GLX_USE_SHARED_DISPATCH
+_X_EXPORT void *
+glamor_egl_make_current(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+	GET_CURRENT_CONTEXT(current);
+
+	if (glamor_egl->gl_context != current) {
+		eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+			       EGL_NO_SURFACE, EGL_NO_CONTEXT);
+		if (!eglMakeCurrent(glamor_egl->display,
+				    EGL_NO_SURFACE, EGL_NO_SURFACE,
+				    glamor_egl->context)) {
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				   "Failed to make EGL context current\n");
+			return NULL;
+		}
+		return current;
+	}
+	return NULL;
+}
+
+_X_EXPORT void
+glamor_egl_restore_context(ScreenPtr screen, void *context)
+{
+	if (context)
+		SET_CURRENT_CONTEXT(context);
+}
+#else
+#define glamor_egl_make_current(x)  NULL
+#define glamor_egl_restore_context(s, c)
+#endif
 
 static EGLImageKHR
 _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
@@ -215,9 +252,12 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
+	void *prev_context;
+	Bool ret = FALSE;
 
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 
+	prev_context = glamor_egl_make_current(screen);
 	if (glamor_egl->has_gem) {
 		if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -234,16 +274,20 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 					 ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
 					 name,
 					 pixmap->drawable.depth);
-	if (image == EGL_NO_IMAGE_KHR) 
-		return FALSE;
+	if (image == EGL_NO_IMAGE_KHR)
+		goto done;
 
 	glamor_create_texture_from_image(glamor_egl, image, &texture);
 	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	glamor_set_pixmap_texture(pixmap, texture);
 	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
 		      image);
+	ret = TRUE;
 
-	return TRUE;
+done:
+	if (prev_context)
+		glamor_egl_restore_context(screen, prev_context);
+	return ret;
 }
 
 static void
@@ -447,7 +491,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 			   "Failed to make EGL context current\n");
 		return FALSE;
 	}
-
+#ifdef GLX_USE_SHARED_DISPATCH
+	GET_CURRENT_CONTEXT(current);
+	glamor_egl->gl_context = current;
+#endif
 	glamor_egl->saved_free_screen = scrn->FreeScreen;
 	scrn->FreeScreen = glamor_egl_free_screen;
 	return TRUE;
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 2243564..929caba 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -126,6 +126,9 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
+	GLAMOR_DEFINE_CONTEXT;
+
+	GLAMOR_SET_CONTEXT(fbo->glamor_priv);
 	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
 	if (fbo->fb)
 		dispatch->glDeleteFramebuffers(1, &fbo->fb);
@@ -133,6 +136,7 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 		dispatch->glDeleteTextures(1, &fbo->tex);
 	if (fbo->pbo)
 		dispatch->glDeleteBuffers(1, &fbo->pbo);
+	GLAMOR_RESTORE_CONTEXT(fbo->glamor_priv);
 
 	free(fbo);
 }
@@ -166,7 +170,6 @@ glamor_pixmap_fbo *
 glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 		  int w, int h, int depth, GLint tex, int flag)
 {
-	glamor_gl_dispatch *dispatch;
 	glamor_pixmap_fbo *fbo;
 	GLenum format;
 
@@ -276,8 +279,6 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 void
 glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 {
-	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
-
 	list_del(&fbo->list);
 	glamor_pixmap_fbo_cache_put(fbo);
 
@@ -291,6 +292,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	glamor_pixmap_fbo *fbo;
 	int cache_flag = GLAMOR_CACHE_TEXTURE;
 	GLuint tex;
+	GLAMOR_DEFINE_CONTEXT;
 
 	if (flag == GLAMOR_CREATE_TEXTURE_EXACT_SIZE)
 		cache_flag |= GLAMOR_CACHE_EXACT_SIZE;
@@ -303,6 +305,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	if (fbo == NULL)
 		return NULL;
 
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	list_init(&fbo->list);
 
 	dispatch = &glamor_priv->dispatch;
@@ -319,6 +322,7 @@ glamor_create_tex_obj(glamor_screen_private *glamor_priv,
 	fbo->height = h;
 	fbo->format = format;
 	fbo->glamor_priv = glamor_priv;
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 
 	return fbo;
 }
@@ -340,6 +344,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	GLenum format;
 	GLint tex;
 	int cache_flag;
+	GLAMOR_DEFINE_CONTEXT;
 
 	if (!glamor_check_fbo_size(glamor_priv, w, h)
 	    || !glamor_check_fbo_depth(depth))
@@ -359,6 +364,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	if (fbo)
 		return fbo;
 new_fbo:
+
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	dispatch = &glamor_priv->dispatch;
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
@@ -370,6 +377,7 @@ new_fbo:
 			       GL_UNSIGNED_BYTE, NULL);
 
 	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 
 	return fbo;
 }
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 97c4403..97e4497 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -40,6 +40,12 @@ _glamor_fill_spans(DrawablePtr drawable,
 	BoxPtr pbox;
 	int x1, x2, y;
 	RegionPtr pClip = fbGetCompositeClip(gc);
+	glamor_screen_private *glamor_priv;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
+
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 
 	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 		goto fail;
@@ -71,13 +77,15 @@ _glamor_fill_spans(DrawablePtr drawable,
 			pbox++;
 		}
 	}
-	return TRUE;
+	ret = TRUE;
+	goto done;
 
-      fail:
+fail:
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(drawable)
-	    && glamor_ddx_fallback_check_gc(gc))
-		return FALSE;
+	    && glamor_ddx_fallback_check_gc(gc)) {
+		goto done;
+	}
 	glamor_fallback("to %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
@@ -88,7 +96,11 @@ _glamor_fill_spans(DrawablePtr drawable,
 		}
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
-	return TRUE;
+	ret = TRUE;
+
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 377783c..7caf2a3 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -46,8 +46,14 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	int no_alpha, no_revert;
 	PixmapPtr temp_pixmap = NULL;
 	glamor_gl_dispatch * dispatch;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
 
 	goto fall_back;
+
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
+
 	if (format != ZPixmap)
 		goto fall_back;
 
@@ -113,10 +119,14 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 				       tex_type, d);
 	if (temp_pixmap)
 		glamor_destroy_pixmap(temp_pixmap);
-	return TRUE;
+
+	ret = TRUE;
 
 fall_back:
-	miGetImage(drawable, x, y, w, h, format, planeMask, d);
+
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	if (ret == FALSE)
+		miGetImage(drawable, x, y, w, h, format, planeMask, d);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 6c50d1b..2d30f37 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -49,7 +49,10 @@ _glamor_get_spans(DrawablePtr drawable,
 	int i;
 	uint8_t *readpixels_dst = (uint8_t *) dst;
 	int x_off, y_off;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
 
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
 		goto fail;
@@ -97,20 +100,24 @@ _glamor_get_spans(DrawablePtr drawable,
 	}
 	if (temp_pixmap)
 		glamor_destroy_pixmap(temp_pixmap);
-	return TRUE;
 
-      fail:
+	ret = TRUE;
+	goto done;
+fail:
 
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(drawable))
-		return FALSE; 
+		goto done;
+
 	glamor_fallback("from %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
 		fbGetSpans(drawable, wmax, points, widths, count, dst);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
 	}
-	return TRUE;
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 void
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index c9a35a0..8c853e9 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -37,15 +37,22 @@ _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access_gc(pGC);
 	fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
  fail:
 	return FALSE;
@@ -72,15 +79,22 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                     int x, int y, unsigned int nglyph,
                     CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access_gc(pGC);
 	fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
  fail:
 	return FALSE;
@@ -106,11 +120,17 @@ static Bool
 _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 		    DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_pixmap(pDrawable)
 	    && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
 	    && glamor_ddx_fallback_check_gc(pGC))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_prepare_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
 	glamor_prepare_access_gc(pGC);
@@ -118,6 +138,7 @@ _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
 	glamor_finish_access_gc(pGC);
 	glamor_finish_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
  fail:
 	return FALSE;
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 32afd09..8b36241 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -45,8 +45,14 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	int xorg, yorg;
 	int n;
 	register BoxPtr pbox;
-
 	RegionPtr pClip = fbGetCompositeClip(gc);
+	Bool ret = FALSE;
+	glamor_screen_private *glamor_priv;
+	GLAMOR_DEFINE_CONTEXT;
+
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
+
 	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
 		goto fail;
 	}
@@ -91,14 +97,15 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 				goto fail;
 		}
 	}
-	return TRUE;
+	ret = TRUE;
+	goto done;
 
-      fail:
+fail:
 
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(drawable)
 	    && glamor_ddx_fallback_check_gc(gc))
-		return FALSE;
+		goto done;
 
 	glamor_fallback(" to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
@@ -109,7 +116,11 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 		}
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
-	return TRUE;
+	ret = TRUE;
+
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 0217e8f..0d37a1d 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -49,6 +49,9 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	xRectangle *rects;
 	int x1, x2, y1, y2;
 	int i;
+	glamor_screen_private *glamor_priv;
+	GLAMOR_DEFINE_CONTEXT;
+
 	/* Don't try to do wide lines or non-solid fill style. */
 	if (gc->lineWidth != 0) {
 		/* This ends up in miSetSpans, which is accelerated as well as we
@@ -108,6 +111,8 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	    && glamor_ddx_fallback_check_gc(gc))
 		return FALSE;
 
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (gc->lineWidth == 0) {
 		if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 			if (glamor_prepare_access_gc(gc)) {
@@ -121,6 +126,7 @@ wide_line:
 		/* fb calls mi functions in the lineWidth != 0 case. */
 		fbPolyLine(drawable, gc, mode, n, points);
 	}
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 }
 
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
index 6188bb2..ca21b8b 100644
--- a/glamor/glamor_polyops.c
+++ b/glamor/glamor_polyops.c
@@ -36,15 +36,22 @@ static Bool
 _glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		   DDXPointPtr ppt, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	glamor_prepare_access_gc(pGC);
 	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
 	fbPolyPoint(pDrawable, pGC, mode, npt, ppt);
 	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
 	glamor_finish_access_gc(pGC);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 
 fail:
@@ -69,10 +76,16 @@ static Bool
 _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		     xSegment *pSeg, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
 		goto fail;
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	/* For lineWidth is not zero, fb calls to mi functions. */
 	if (pGC->lineWidth == 0) {
 		glamor_prepare_access_gc(pGC);
@@ -83,6 +96,7 @@ _glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
 	} else
 	fbPolySegment(pDrawable, pGC, nseg, pSeg);
 
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 
 fail:
@@ -107,11 +121,17 @@ static Bool
 _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr ppt, Bool fallback)
 {
+	GLAMOR_DEFINE_CONTEXT;
+	glamor_screen_private *glamor_priv;
+
 	if (!fallback 
 	    && glamor_ddx_fallback_check_gc(pGC)
 	    && glamor_ddx_fallback_check_pixmap(pDrawable))
 		goto fail;
 	/* For lineWidth is not zero, fb calls to mi functions. */
+
+	glamor_priv = glamor_get_screen_private(pDrawable->pScreen);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (pGC->lineWidth == 0) {
 		glamor_prepare_access_gc(pGC);
 		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
@@ -121,6 +141,7 @@ _glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	} else
 	fbPolyLine(pDrawable, pGC, mode, npt, ppt);
 
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return TRUE;
 
 fail:
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b19a304..d04421b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -219,6 +219,7 @@ typedef struct glamor_screen_private {
 	int delayed_fallback_pending;
 	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
 	int flags;
+	ScreenPtr screen;
 } glamor_screen_private;
 
 typedef enum glamor_access {
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 26d5cf7..5813822 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -230,7 +230,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	glamor_set_planemask(pixmap, ~0);
 	glamor_fallback(": to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
-      fail:
+fail:
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
 			   bits);
@@ -265,6 +265,10 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	GLfloat xscale, yscale, txscale, tyscale;
 	GLuint tex;
 	int no_alpha, no_revert;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
+
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
 		goto fail;
@@ -396,14 +400,16 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_set_planemask(pixmap, ~0);
-	return TRUE;
 
-      fail:
+	ret = TRUE;
+	goto done;
+
+fail:
 	glamor_set_planemask(pixmap, ~0);
 
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
-		return FALSE;
+		goto done;
 
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
@@ -412,7 +418,11 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 			   left_pad, image_format, bits);
 		glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RW);
 	}
-	return TRUE;
+	ret = TRUE;
+
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 void
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 789c684..b240eac 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -870,7 +870,10 @@ glamor_composite_with_shader(CARD8 op,
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	int vert_stride = 4;
 	int nrect_max;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
 
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
@@ -1230,15 +1233,20 @@ glamor_composite_with_shader(CARD8 op,
 	dispatch->glUseProgram(0);
 	if (saved_source_format)
 		source->format = saved_source_format;
-	return TRUE;
 
-      fail:
+	ret = TRUE;
+	goto done;
+
+fail:
 	if (saved_source_format)
 		source->format = saved_source_format;
 
 	dispatch->glDisable(GL_BLEND);
 	dispatch->glUseProgram(0);
-	return FALSE;
+
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 static PicturePtr
@@ -1308,11 +1316,11 @@ _glamor_composite(CARD8 op,
 	int prect_size = ARRAY_SIZE(rect);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	Bool ret = TRUE;
 	RegionRec region;
 	BoxPtr box;
 	int nbox, i, ok;
+	GLAMOR_DEFINE_CONTEXT;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
@@ -1320,6 +1328,7 @@ _glamor_composite(CARD8 op,
 	y_temp_mask = y_mask;
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		goto fail;
@@ -1473,10 +1482,8 @@ _glamor_composite(CARD8 op,
 	if (ok)
 		goto done;
 
-      fail:
+fail:
 
-	dispatch->glUseProgram(0);
-	dispatch->glDisable(GL_BLEND);
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
 	    && (!source_pixmap 
@@ -1528,6 +1535,7 @@ _glamor_composite(CARD8 op,
 		FreePicture(temp_mask, 0);
 	if (prect != rect)
 		free(prect);
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
 	return ret;
 }
 
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 26e774b..07c94ab 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -47,7 +47,10 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	RegionPtr clip = fbGetCompositeClip(gc);
 	BoxRec *pbox;
 	int x_off, y_off;
+	GLAMOR_DEFINE_CONTEXT;
+	Bool ret = FALSE;
 
+	GLAMOR_SET_CONTEXT(glamor_priv);
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
@@ -100,18 +103,25 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	glamor_set_planemask(dest_pixmap, ~0);
 	glamor_set_alu(dispatch, GXcopy);
 	dispatch->glDisable(GL_SCISSOR_TEST);
-	return TRUE;
-      fail:
+	ret = TRUE;
+	goto done;
+
+fail:
 	if (!fallback
 	    && glamor_ddx_fallback_check_pixmap(drawable))
-		return FALSE;
+		goto done;
+
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		fbSetSpans(drawable, gc, src, points, widths, n, sorted);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
-	return TRUE;
+	ret = TRUE;
+
+done:
+	GLAMOR_RESTORE_CONTEXT(glamor_priv);
+	return ret;
 }
 
 void
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 74ce6cd..a66e248 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -663,4 +663,33 @@ static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int
 	}
 	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 }
+
+static inline void *glamor_make_current(ScreenPtr screen)
+{
+	return glamor_egl_make_current(screen);
+}
+
+static inline void glamor_restore_current(ScreenPtr screen, void *previous_context)
+{
+	glamor_egl_restore_context(screen, previous_context);
+}
+
+#ifdef GLX_USE_SHARED_DISPATCH
+#define GLAMOR_DEFINE_CONTEXT		void *_previous_context_ = NULL
+#define GLAMOR_SET_CONTEXT(glamor_priv)			\
+	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN) \
+		_previous_context_ = glamor_make_current(glamor_priv->screen)
+
+#define GLAMOR_RESTORE_CONTEXT(glamor_priv)			\
+	if ((glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)	\
+	     && _previous_context_ != NULL) 			\
+		glamor_restore_current(glamor_priv->screen, _previous_context_)
+#else
+
+#define GLAMOR_DEFINE_CONTEXT
+#define GLAMOR_SET_CONTEXT(glamor_priv)
+#define GLAMOR_RESTORE_CONTEXT(glamor_priv)
+
+#endif
+
 #endif
diff --git a/glamor/glapi.h b/glamor/glapi.h
new file mode 100644
index 0000000..da521aa
--- /dev/null
+++ b/glamor/glapi.h
@@ -0,0 +1,121 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+
+/**
+ * \mainpage Mesa GL API Module
+ *
+ * \section GLAPIIntroduction Introduction
+ *
+ * The Mesa GL API module is responsible for dispatching all the
+ * gl*() functions.  All GL functions are dispatched by jumping through
+ * the current dispatch table (basically a struct full of function
+ * pointers.)
+ *
+ * A per-thread current dispatch table and per-thread current context
+ * pointer are managed by this module too.
+ *
+ * This module is intended to be non-Mesa-specific so it can be used
+ * with the X/DRI libGL also.
+ */
+
+#ifndef _GLAPI_H
+#define _GLAPI_H
+
+#define GL_GLEXT_PROTOTYPES
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include <GL/gl.h>
+#include "GL/glext.h"
+#endif
+
+/* Is this needed?  It is incomplete anyway. */
+#ifdef USE_MGL_NAMESPACE
+#define _glapi_set_dispatch _mglapi_set_dispatch
+#define _glapi_get_dispatch _mglapi_get_dispatch
+#define _glapi_set_context _mglapi_set_context
+#define _glapi_get_context _mglapi_get_context
+#define _glapi_Dispatch _mglapi_Dispatch
+#define _glapi_Context _mglapi_Context
+#endif
+
+typedef void (*_glapi_proc)(void);
+struct _glapi_table;
+
+
+#if defined (GLX_USE_TLS)
+
+extern __thread struct _glapi_table * _glapi_tls_Dispatch
+    __attribute__((tls_model("initial-exec")));
+
+extern __thread void * _glapi_tls_Context
+    __attribute__((tls_model("initial-exec")));
+
+extern const struct _glapi_table *_glapi_Dispatch;
+extern const void *_glapi_Context;
+
+# define GET_DISPATCH() _glapi_tls_Dispatch
+# define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_tls_Context
+# define SET_CURRENT_CONTEXT(C)  _glapi_tls_Context = (void*)C
+
+#else
+
+extern struct _glapi_table *_glapi_Dispatch;
+extern void *_glapi_Context;
+
+# ifdef THREADS
+
+#  define GET_DISPATCH() \
+     (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
+
+#  define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) \
+     (likely(_glapi_Context) ? _glapi_Context : _glapi_get_context())
+
+
+# define SET_CURRENT_CONTEXT(C) do { if (likely(_glapi_Context))   \
+					_glapi_Context = (void*)C; \
+				     else \
+					_glapi_set_context(C); } while(0)
+
+# else
+
+#  define GET_DISPATCH() _glapi_Dispatch
+#  define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_Context
+# define SET_CURRENT_CONTEXT(C)  _glapi_Context = (void*)C
+
+# endif
+
+#endif /* defined (GLX_USE_TLS) */
+
+
+extern void
+_glapi_set_context(void *context);
+
+extern void *
+_glapi_get_context(void);
+
+#endif
commit 0a8fb8563f3cecf2019d3a35d5a61ec2b3a069cd
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 10 15:34:43 2012 +0800

    glamor_pixmap: Should bind unpack buffer to 0 after the uploading.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 6563e94..1a63ffd 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -268,6 +268,9 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 				       pixmap->drawable.width,
 				       pixmap->drawable.height, 0, format, type,
 				       texels);
+
+	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid)
+		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 }
 
 
commit e03ad27dfb885e58298e1fd2accac0b6ad409fce
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Feb 11 07:37:17 2012 +0800

    glamor_picture: Fix the wrong order of header file.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 6904dab..217fd40 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -4,8 +4,8 @@
 
 #include <stdlib.h>
 
-#include "mipict.h"
 #include "glamor_priv.h"
+#include "mipict.h"
 
 /* Upload picture to texture.  We may need to flip the y axis or
  * wire alpha to 1. So we may conditional create fbo for the picture.
commit bf24c2c06870dc38b21795f4f6fc51b053134181
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 3 11:46:01 2012 +0800

    glamor_dump_pixmap: Add helper routine to dump pixmap.
    
    For debug purpose only to dump the pixmap's content.
    As this function will call glamor_prepare_access/glamor_finish_access
    internally. Please use it carefully.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index a60b146..74ce6cd 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -610,4 +610,57 @@ inline static Bool glamor_tex_format_is_readable(GLenum format)
 
 }
 
+static inline void _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
+{
+	int i,j;
+	unsigned char * p = pixmap->devPrivate.ptr;
+	int stride = pixmap->devKind;
+
+	p = p + y * stride + x;
+	ErrorF("devKind %d, x %d y %d w %d h %d width %d height %d\n", stride, x, y, w, h, pixmap->drawable.width, pixmap->drawable.height);
+
+	for (i = 0; i < h; i++)
+	{
+		ErrorF("line %3d: ", i);
+		for(j = 0; j < w; j++)
+			ErrorF("%2x ", p[j]);
+		p += stride;
+		ErrorF("\n");
+	}
+}
+
+static inline void _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
+{
+	int i,j;
+	unsigned int * p = pixmap->devPrivate.ptr;
+	int stride = pixmap->devKind / 4;
+
+	p = p + y * stride + x;
+
+	for (i = 0; i < h; i++)
+	{
+		ErrorF("line %3d: ", i);
+		for(j = 0; j < w; j++)
+			ErrorF("%2x ", p[j]);
+		p += stride;
+		ErrorF("\n");
+	}
+}
+
+static inline void glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
+{
+	glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+	switch (pixmap->drawable.depth) {
+	case 8:
+		_glamor_dump_pixmap_byte(pixmap, x, y, w, h);
+		break;
+	case 24:
+	case 32:
+		_glamor_dump_pixmap_word(pixmap, x, y, w, h);
+		break;
+	default:
+		assert(0);
+	}
+	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+}
 #endif
commit 91891b3711b1fe1402bb7742c20e976fab63c6fe
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 3 11:44:51 2012 +0800

    glamor_fill/tile: Fixed a tileX/tileY calculation bug.
    
    The previous's calculation is incorrect, now fix it and then
    we don't need to fallback at glamor_tile.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Tested-by: Peng Li <peng.li at intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index df97ad0..b462f59 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -31,7 +31,6 @@
  *
  * GC fill implementation, based loosely on fb_fill.c
  */
-
 Bool
 glamor_fill(DrawablePtr drawable,
 	    GCPtr gc, int x, int y, int width, int height, Bool fallback)
@@ -74,8 +73,8 @@ glamor_fill(DrawablePtr drawable,
 				 height,
 				 gc->alu,
 				 gc->planemask,
-				 drawable->x + x + off_x - gc->patOrg.x,
-				 drawable->y + y + off_y - gc->patOrg.y))
+				 x - drawable->x - gc->patOrg.x,
+				 y - drawable->y - gc->patOrg.y))
 			goto fail;
 		break;
 	}
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 4ff4fa1..3087bea 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -124,13 +124,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
 		goto fail;
 
-	if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
-	    || ((tile_y != 0)
-		&& (tile_y + height > tile->drawable.height))) {
-		/* XXX We can recreate a new pixmap here to avoid partial tiling. */
-		goto fail;
-	}
-
 	if (glamor_priv->tile_prog == 0) {
 		glamor_fallback("Tiling unsupported\n");
 		goto fail;
commit 39d9e6c693a4c3ad12c6569f1fd56e0a87b164d2
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Feb 3 11:21:37 2012 +0800

    prepare_access: Don't use fbo after it was downloaded.
    
    We add a new gl_fbo status GLAMOR_FBO_DOWNLOADED to indicate
    the fbo was already downloaded to CPU. Then latter the access
    to this pixmap will be treated as pure CPU access. In glamor,
    if we fallback to DDX/fbXXX, then we fallback everything
    currently. We don't support to jump into glamor acceleration
    layer between a prepare_access/finish_access. Actually, fbCopyPlane
    is such a function which may call to acceleration function within
    it. Then we must mark the downloaded pixmap to another state
    rather than a normal fbo textured pixmap, and then stick to use
    it as a in-memory pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Tested-by: Peng Li <peng.li at intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 395e912..01c9aea 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -263,8 +263,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
 	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
 }
 
-
-
 void
 glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 {
@@ -275,7 +273,7 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
 		return;
 
 	if (access_mode != GLAMOR_ACCESS_RO) {
@@ -293,6 +291,9 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 		free(pixmap->devPrivate.ptr);
 	}
 
+	if (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED)
+		pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
+
 	pixmap->devPrivate.ptr = NULL;
 }
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index e154273..6563e94 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -641,7 +641,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
  * If successfully download a fbo to cpu then return TRUE.
  * Otherwise return FALSE.
  **/
-
 Bool
 glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 {
@@ -794,6 +793,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
       done:
+
+	pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
 	pixmap->devPrivate.ptr = data;
 
 	if (temp_pixmap)
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0b75588..b19a304 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -243,19 +243,23 @@ typedef union _glamor_pending_op {
 	glamor_pending_fill fill;
 } glamor_pending_op;
 
-/*
- * glamor_pixmap_private - glamor pixmap's private structure.
- * @gl_fbo:  The pixmap is attached to a fbo originally.
- * @gl_tex:  The pixmap is in a gl texture originally.
+#define GLAMOR_FBO_NORMAL     1
+#define GLAMOR_FBO_DOWNLOADED 2
+/* glamor_pixmap_fbo:
+ * @list:    to be used to link to the cache pool list.
+ * @expire:  when push to cache pool list, set a expire count.
+ * 	     will be freed when glamor_priv->tick is equal or
+ * 	     larger than this expire count in block handler.
  * @pbo_valid: The pbo has a valid copy of the pixmap's data.
- * @is_picture: The drawable is attached to a picture.
  * @tex:     attached texture.
  * @fb:      attached fbo.
  * @pbo:     attached pbo.
- * @pict_format: the corresponding picture's format.
- * #pending_op: currently only support pending filling.
- * @container: The corresponding pixmap's pointer.
- **/
+ * @width:   width of this fbo.
+ * @height:  height of this fbo.
+ * @format:  internal format of this fbo's texture.
+ * @type:    internal type of this fbo's texture.
+ * @glamor_priv: point to glamor private data.
+ */
 typedef struct glamor_pixmap_fbo {
 	struct list list;
 	unsigned int expire;
@@ -270,9 +274,22 @@ typedef struct glamor_pixmap_fbo {
 	glamor_screen_private *glamor_priv;
 } glamor_pixmap_fbo;
 
-
+/*
+ * glamor_pixmap_private - glamor pixmap's private structure.
+ * @gl_fbo:
+ * 	0 		  	- The pixmap doesn't has a fbo attached to it.
+ * 	GLAMOR_FBO_NORMAL 	- The pixmap has a fbo and can be accessed normally.
+ * 	GLAMOR_FBO_DOWNLOADED 	- The pixmap has a fbo and already downloaded to
+ * 				  CPU, so it can only be treated as a in-memory pixmap
+ * 				  if this bit is set.
+ * @gl_tex:  The pixmap is in a gl texture originally.
+ * @is_picture: The drawable is attached to a picture.
+ * @pict_format: the corresponding picture's format.
+ * #pending_op: currently only support pending filling.
+ * @container: The corresponding pixmap's pointer.
+ **/
 typedef struct glamor_pixmap_private {
-	unsigned char gl_fbo:1;
+	unsigned char gl_fbo:2;
 	unsigned char is_picture:1;
 	unsigned char gl_tex:1;
 	glamor_pixmap_type_t type;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b292928..a60b146 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -175,7 +175,8 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 
 
 #define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)    (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
 
 #define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
 	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
commit 1817b6c0cf20aa6fc1e1aa5b68e47473f341b85a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Feb 2 11:21:05 2012 +0800

    glamor_eglmodule: Change module name according to normalize naming rule.
    
    As Xorg module loader will normalize module name which will
    remove '_' when we put "glamor_egl" to the configure file,
    then it will fail to find us.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index d6105d0..ca8fc3f 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -50,13 +50,12 @@ libglamor_la_SOURCES = \
 sdk_HEADERS = glamor.h
 
 if EGL
-LIBGLAMOR_EGL = libglamor_egl.la
-module_LTLIBRARIES = $(LIBGLAMOR_EGL) 
-libglamor_egl_la_DEPENDENCIES = libglamor.la
-libglamor_egl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
-#libglamor_egl_la_LIBADD = $(top_builddir)/src/libglamor.la
-libglamor_egl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
-libglamor_egl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
+LIBGLAMOREGL = libglamoregl.la
+module_LTLIBRARIES = $(LIBGLAMOREGL)
+libglamoregl_la_DEPENDENCIES = libglamor.la
+libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
+libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
+libglamoregl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
 endif
 
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index e29a3e4..3d6e5fe 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -146,6 +146,9 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 
 #ifdef GLAMOR_FOR_XORG
+
+#define GLAMOR_EGL_MODULE_NAME  "glamoregl"
+
 /* @glamor_egl_init: Initialize EGL environment.
  *
  * @scrn: Current screen info pointer.
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 4da57af..e1f6672 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -29,11 +29,12 @@
 #endif
 
 #include <xorg-server.h>
-
+#define GLAMOR_FOR_XORG
+#include "glamor.h"
 #include "xf86Module.h"
 
 static XF86ModuleVersionInfo VersRec = {
-	"glamor_egl",
+	GLAMOR_EGL_MODULE_NAME,
 	MODULEVENDORSTRING,
 	MODINFOSTRING1,
 	MODINFOSTRING2,
@@ -45,4 +46,4 @@ static XF86ModuleVersionInfo VersRec = {
 	{0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
 };
 
-_X_EXPORT XF86ModuleData glamor_eglModuleData = { &VersRec, NULL, NULL };
+_X_EXPORT XF86ModuleData glamoreglModuleData = { &VersRec, NULL, NULL };
commit 1ab40028740efad1ba2ee16d425b0fbdd822c6ab
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Feb 2 09:34:42 2012 +0800

    Don't call dixSetPrivate directly.
    
    We may change the way to set/get those private data latter.
    consolidate to glamor_set_pixmap/screen_private is better
    than call those dixSetPrivate directly.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index e900a91..0245fda 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -70,8 +70,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (pixmap_priv == NULL) {
 		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
-		dixSetPrivate(&pixmap->devPrivates,
-			      glamor_pixmap_private_key, pixmap_priv);
+		glamor_set_pixmap_private(pixmap, pixmap_priv);
 		pixmap_priv->container = pixmap;
 		pixmap_priv->glamor_priv = glamor_priv;
 	}
@@ -151,9 +150,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		return fbCreatePixmap(screen, w, h, depth, usage);
 	}
 
-	dixSetPrivate(&pixmap->devPrivates,
-		      glamor_pixmap_private_key,
-		      pixmap_priv);
+	glamor_set_pixmap_private(pixmap, pixmap_priv);
 
 	pixmap_priv->container = pixmap;
 	pixmap_priv->glamor_priv = glamor_priv;
@@ -269,8 +266,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		goto fail;
 	}
 
-	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
-		      glamor_priv);
+	glamor_set_screen_private(screen, glamor_priv);
 
 	if (!dixRegisterPrivateKey
 	    (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
@@ -401,8 +397,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
       fail:
 	free(glamor_priv);
-	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
-		      NULL);
+	glamor_set_screen_private(screen, NULL);
 	return FALSE;
 }
 
@@ -423,8 +418,7 @@ glamor_release_screen_priv(ScreenPtr screen)
 	glamor_pixmap_fini(screen);
 	free(glamor_priv);
 
-	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
-		      NULL);
+	glamor_set_screen_private(screen, NULL);
 }
 
 Bool
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d8168a5..0b75588 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -310,6 +310,16 @@ glamor_get_screen_private(ScreenPtr screen)
 			     glamor_screen_private_key);
 }
 
+static inline void
+glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
+{
+	dixSetPrivate(&screen->devPrivates,
+		      glamor_screen_private_key,
+		      priv);
+}
+
+
+
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
@@ -317,6 +327,16 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
 				glamor_pixmap_private_key);
 }
 
+static inline void
+glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
+{
+	dixSetPrivate(&pixmap->devPrivates,
+		      glamor_pixmap_private_key,
+		      priv);
+}
+
+
+
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
commit bf7d79dc0ac2e97ed97e22c1d2c95e77bf959327
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jan 31 18:16:58 2012 +0800

    Refine CloseScreen and FreeScreen processes.
    
    This commit move the calling to glamor_close_screen from
    glamor_egl_free_screen to glamor_egl_close_screen, as this
    is the right place to do this.
    
    We should detach screen fbo and destroy the corresponding
    KHR image at glamor_egl_close_screen stage. As latter
    DDX driver will call DestroyPixmap to destroy screen pixmap,
    if the fbo and image are still there but glamor screen private
    data pointer has been freed, then it causes segfault.
    
    This commit also introduces a new flag GLAMOR_USE_EGL_SCREEN.
    if DDX driver is using EGL layer then should set this bit
    when call to glamor_init and then both glamor_close_screen
    and glamor_egl_close_screen will be registered correctly,
    DDX layer will not need to call these two functions manually.
    This way is also the preferred method within Xorg domain.
    
    As interfaces changed, bump the version to 0.3.0.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Tested-by: Peng Li <peng.li at intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 80434e9..e900a91 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -318,6 +318,13 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #else
 	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
 #endif
+	/* If we are using egl screen, call egl screen init to
+	 * register correct close screen function. */
+	if (flags & GLAMOR_USE_EGL_SCREEN)
+		glamor_egl_screen_init(screen);
+
+	glamor_priv->saved_procs.close_screen = screen->CloseScreen;
+	screen->CloseScreen = glamor_close_screen;
 
 	if (flags & GLAMOR_USE_SCREEN) {
 		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
@@ -327,9 +334,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 			goto fail;
 		}
 
-		glamor_priv->saved_procs.close_screen = screen->CloseScreen;
-		screen->CloseScreen = glamor_close_screen;
-
 		glamor_priv->saved_procs.create_gc = screen->CreateGC;
 		screen->CreateGC = glamor_create_gc;
 
@@ -427,6 +431,9 @@ Bool
 glamor_close_screen(int idx, ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
+	PixmapPtr screen_pixmap;
+	glamor_pixmap_private *screen_pixmap_priv;
+	glamor_pixmap_fbo *fbo;
 	int flags;
 
 	glamor_priv = glamor_get_screen_private(screen);
@@ -435,9 +442,9 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
 	glamor_glyphs_fini(screen);
+	screen->CloseScreen = glamor_priv->saved_procs.close_screen;
 	if (flags & GLAMOR_USE_SCREEN) {
 
-		screen->CloseScreen = glamor_priv->saved_procs.close_screen;
 		screen->CreateGC = glamor_priv->saved_procs.create_gc;
 		screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
 		screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
@@ -457,12 +464,13 @@ glamor_close_screen(int idx, ScreenPtr screen)
 		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
 	}
 #endif
+	screen_pixmap = screen->GetScreenPixmap(screen);
+	screen_pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
+	fbo = glamor_pixmap_detach_fbo(screen_pixmap_priv);
+	glamor_purge_fbo(fbo);
 	glamor_release_screen_priv(screen);
 
-	if (flags & GLAMOR_USE_SCREEN)
-		return screen->CloseScreen(idx, screen);
-	else
-		return TRUE;
+	return screen->CloseScreen(idx, screen);
 }
 
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index fe15700..e29a3e4 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -41,36 +41,6 @@
 
 #endif				/* GLAMOR_H */
 
-/* @GLAMOR_INVERTED_Y_AXIS:
- * set 1 means the GL env's origin (0,0) is at top-left.
- * EGL/DRM platform is an example need to set this bit.
- * glx platform's origin is at bottom-left thus need to
- * clear this bit.*/
-
-#define GLAMOR_INVERTED_Y_AXIS  	1
-
-/* @GLAMOR_USE_SCREEN:
- * If want to let glamor to do everything including the
- * create/destroy pixmap and handle the gc ops. need to
- * set this bit. Standalone glamor DDX driver need to set
- * this bit.
- * Otherwise, need to clear this bit, as the intel video
- * driver with glamor enabled.
- * */
-#define GLAMOR_USE_SCREEN		2
-/* @GLAMOR_USE_PICTURE_SCREEN:
- * If want to let glamor to do all the composition related
- * things, need to set this bit. Just as standalone glamor
- * DDX driver.
- * Otherwise, need to clear this bit, as the intel video
- * driver with glamor enabled.
- */
-#define GLAMOR_USE_PICTURE_SCREEN 	4
-
-#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
-				 | GLAMOR_USE_SCREEN 			\
-                                 | GLAMOR_USE_PICTURE_SCREEN)
-
 /*
  * glamor_pixmap_type : glamor pixmap's type.
  * @MEMORY: pixmap is in memory.
@@ -90,15 +60,49 @@ typedef enum  glamor_pixmap_type {
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
+#define GLAMOR_INVERTED_Y_AXIS  	1
+#define GLAMOR_USE_SCREEN		(1 << 1)
+#define GLAMOR_USE_PICTURE_SCREEN 	(1 << 2)
+#define GLAMOR_USE_EGL_SCREEN		(1 << 3)
+#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
+				 | GLAMOR_USE_SCREEN 			\
+                                 | GLAMOR_USE_PICTURE_SCREEN		\
+				 | GLAMOR_USE_EGL_SCREEN)
+
 /* @glamor_init: Initialize glamor internal data structure.
  *
  * @screen: Current screen pointer.
  * @flags:  Please refer the flags description above.
  *
+ * 	@GLAMOR_INVERTED_Y_AXIS:
+ * 	set 1 means the GL env's origin (0,0) is at top-left.
+ * 	EGL/DRM platform is an example need to set this bit.
+ * 	glx platform's origin is at bottom-left thus need to
+ * 	clear this bit.
+ *
+ * 	@GLAMOR_USE_SCREEN:
+ *	If running in an pre-existing X environment, and the
+ * 	gl context is GLX, then you should set this bit and
+ * 	let the glamor to handle all the screen related
+ * 	functions such as GC ops and CreatePixmap/DestroyPixmap.
+ *
+ * 	@GLAMOR_USE_PICTURE_SCREEN:
+ * 	If don't use any other underlying DDX driver to handle
+ * 	the picture related rendering functions, please set this
+ * 	bit on. Otherwise, clear this bit. And then it is the DDX
+ * 	driver's responsibility to determine how/when to jump to
+ * 	glamor's picture compositing path.
+ *
+ * 	@GLAMOR_USE_EGL_SCREEN:
+ * 	If you are using EGL layer, then please set this bit
+ * 	on, otherwise, clear it.
+ *
  * This function initializes necessary internal data structure
  * for glamor. And before calling into this function, the OpenGL
  * environment should be ready. Should be called before any real
- * glamor rendering or texture allocation functions.
+ * glamor rendering or texture allocation functions. And should
+ * be called after the DDX's screen initialization or at the last
+ * step of the DDX's screen initialization.
  */
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
@@ -139,6 +143,8 @@ extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 						unsigned int usage);
 
+extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
+
 #ifdef GLAMOR_FOR_XORG
 /* @glamor_egl_init: Initialize EGL environment.
  *
@@ -173,7 +179,6 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
 extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
 							int handle,
 							int stride);
-
 /*
  * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
  * 				       a BO handle.
@@ -191,10 +196,6 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
 							int stride);
 
 extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
-
-extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen);
-extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
-
 #endif
 
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 71121bc..027722e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -84,7 +84,7 @@ struct glamor_egl_screen_private {
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
 	int fd;
-	int front_buffer_handle;
+	EGLImageKHR front_image;
 	int cpp;
 #ifdef GLAMOR_HAS_GBM
 	struct gbm_device *gbm;
@@ -95,6 +95,8 @@ struct glamor_egl_screen_private {
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
 	struct glamor_gl_dispatch *dispatch;
+	CloseScreenProcPtr saved_close_screen;
+	xf86FreeScreenProc *saved_free_screen;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
@@ -185,6 +187,8 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 		return FALSE;
 	}
 
+	glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
+						    glamor_egl_pixmap_private_key);
 	glamor_set_screen_pixmap(screen_pixmap);
 	return TRUE;
 }
@@ -242,37 +246,51 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	return TRUE;
 }
 
-void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+static void
+_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-	EGLImageKHR image;
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+	EGLImageKHR image;
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 
-	if (pixmap->refcnt == 1) {
-		image = dixLookupPrivate(&pixmap->devPrivates,
-					 glamor_egl_pixmap_private_key);
-		if (image != EGL_NO_IMAGE_KHR && image != NULL) {
-			/* Before destroy an image which was attached to 
- 			 * a texture. we must call glFlush to make sure the 
- 			 * operation on that texture has been done.*/
-			glamor_block_handler(pixmap->drawable.pScreen);
-			glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-		}
+	image = dixLookupPrivate(&pixmap->devPrivates,
+				 glamor_egl_pixmap_private_key);
+	if (image != EGL_NO_IMAGE_KHR && image != NULL) {
+		/* Before destroy an image which was attached to
+		 * a texture. we must call glFlush to make sure the
+		 * operation on that texture has been done.*/
+		glamor_block_handler(pixmap->drawable.pScreen);
+		glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+		dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
 	}
+}
+
+void
+glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+	if (pixmap->refcnt == 1)
+		_glamor_egl_destroy_pixmap_image(pixmap);
 	glamor_destroy_textured_pixmap(pixmap);
 }
 
-Bool
-glamor_egl_close_screen(ScreenPtr screen)
+static Bool
+glamor_egl_close_screen(int idx, ScreenPtr screen)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-	glamor_fini(screen);
+	ScrnInfoPtr scrn;
+	struct glamor_egl_screen_private *glamor_egl;
+	PixmapPtr screen_pixmap;
 
-	return TRUE;
+	scrn = xf86Screens[screen->myNum];
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+	screen_pixmap = screen->GetScreenPixmap(screen);
+	glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image);
+	dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
+	glamor_egl->front_image = NULL;
+
+	screen->CloseScreen = glamor_egl->saved_close_screen;
+
+	return screen->CloseScreen(idx, screen);
 }
 
 static Bool
@@ -299,6 +317,40 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
 	return FALSE;
 }
 
+void
+glamor_egl_screen_init(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+
+	glamor_egl->saved_close_screen = screen->CloseScreen;
+	screen->CloseScreen = glamor_egl_close_screen;
+}
+
+static void
+glamor_egl_free_screen(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_egl_screen_private *glamor_egl;
+
+	ErrorF("free egl screen resources\n");
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+	if (glamor_egl != NULL) {
+
+		eglMakeCurrent(glamor_egl->display,
+			       EGL_NO_SURFACE, EGL_NO_SURFACE,
+			       EGL_NO_CONTEXT);
+#ifdef GLAMOR_HAS_GBM
+		if (glamor_egl->gbm)
+			gbm_device_destroy(glamor_egl->gbm);
+#endif
+		scrn->FreeScreen = glamor_egl->saved_free_screen;
+		free(glamor_egl);
+		scrn->FreeScreen(scrnIndex, flags);
+	}
+}
+
 Bool
 glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
@@ -396,6 +448,8 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 		return FALSE;
 	}
 
+	glamor_egl->saved_free_screen = scrn->FreeScreen;
+	scrn->FreeScreen = glamor_egl_free_screen;
 	return TRUE;
 }
 
@@ -412,27 +466,6 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen)
 	return TRUE;
 }
 
-void
-glamor_egl_free_screen(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-
-	if (glamor_egl != NULL) {
-		if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
-			eglMakeCurrent(glamor_egl->display,
-				       EGL_NO_SURFACE, EGL_NO_SURFACE,
-				       EGL_NO_CONTEXT);
-
-			eglTerminate(glamor_egl->display);
-		}
-		free(glamor_egl);
-	}
-
-	glamor_close_screen(scrn->scrnIndex, scrn->pScreen);
-}
-
 Bool
 glamor_gl_dispatch_init(ScreenPtr screen,
 			struct glamor_gl_dispatch *dispatch,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index ffda04a..2243564 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -123,7 +123,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	return NULL;
 }
 
-static void
+void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
 	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9c2881c..d8168a5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -346,6 +346,7 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_pri
 glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
 				      int w, int h, int depth, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
+void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
commit 97efbd25fed0f86338853d81b974b7f4deb9f1b4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 27 13:22:13 2012 +0000

    Use CLAMP_TO_BORDER in copy_n_to_n so we can sample outside of the source
    
    In order to reduce a composite operation to a source, we need to provide
    Render semantics for the pixel values of samples outside of the source
    pixmap, i.e. they need to be rgba(0, 0, 0, 0). This is provided by using
    the CLAMP_TO_BORDER repeat mode, but only if the texture has an alpha
    channel.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index a39c970..f2d710a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -226,6 +226,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MAG_FILTER,
 					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_WRAP_S,
+					  GL_CLAMP_TO_BORDER);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_WRAP_T,
+					  GL_CLAMP_TO_BORDER);
 
 		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
 						GL_FLOAT, GL_FALSE,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 1e68e65..789c684 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -622,19 +622,21 @@ glamor_composite_with_copy(CARD8 op,
 				      x_source, y_source,
 				      0, 0, x_dest, y_dest, width, height))
 		return TRUE;
-	/* Fallback if we sample outside the source so that we swizzle the
-	 * clear color appropriately. If the source has an alpha channel,
-	 * we could rely on CLAMP_TO_BORDER working as required...
-	 */
-	if (region.extents.x1 + x_source - x_dest < 0)
-		goto cleanup_region;
-	if (region.extents.x2 + x_source - x_dest > source->pDrawable->width)
-		goto cleanup_region;
-
-	if (region.extents.y1 + y_source - y_dest < 0)
-		goto cleanup_region;
-	if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
-		goto cleanup_region;
+
+	if (PICT_FORMAT_A(source->format) == 0) {
+		/* Fallback if we sample outside the source so that we
+		 * swizzle the correct clear color for out-of-bounds texels.
+		 */
+		if (region.extents.x1 + x_source - x_dest < 0)
+			goto cleanup_region;
+		if (region.extents.x2 + x_source - x_dest > source->pDrawable->width)
+			goto cleanup_region;
+
+		if (region.extents.y1 + y_source - y_dest < 0)
+			goto cleanup_region;
+		if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
+			goto cleanup_region;
+	}
 
 	ret = glamor_copy_n_to_n_nf(source->pDrawable,
 				    dest->pDrawable, NULL,
commit 864153bb9eeadb539ed5e9488b829c9f3f8b9482
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 27 13:22:12 2012 +0000

    Do not reduce a composite to a copy if we need to sample outside of the source
    
    In order to maintain Render semantics, samples outside of the source
    should return CLEAR. The copy routines instead are based on the core
    protocol and expects the source rectangle to be wholly contained within
    the drawable and so does no fixup.
    
    Fixes the rendering of GTK icons.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 8d6137d..1e68e65 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -602,7 +602,7 @@ glamor_composite_with_copy(CARD8 op,
 			   INT16 y_dest, CARD16 width, CARD16 height)
 {
 	RegionRec region;
-	int ret;
+	int ret = FALSE;
 
 	if (!source->pDrawable)
 		return FALSE;
@@ -622,14 +622,27 @@ glamor_composite_with_copy(CARD8 op,
 				      x_source, y_source,
 				      0, 0, x_dest, y_dest, width, height))
 		return TRUE;
-	ret = TRUE;
-	if (!glamor_copy_n_to_n_nf(source->pDrawable,
-			dest->pDrawable, NULL,
-	                REGION_RECTS(&region),
-		        REGION_NUM_RECTS(&region),
-			x_source - x_dest, y_source - y_dest,
-			FALSE, FALSE, 0, NULL))
-		ret = FALSE;
+	/* Fallback if we sample outside the source so that we swizzle the
+	 * clear color appropriately. If the source has an alpha channel,
+	 * we could rely on CLAMP_TO_BORDER working as required...
+	 */
+	if (region.extents.x1 + x_source - x_dest < 0)
+		goto cleanup_region;
+	if (region.extents.x2 + x_source - x_dest > source->pDrawable->width)
+		goto cleanup_region;
+
+	if (region.extents.y1 + y_source - y_dest < 0)
+		goto cleanup_region;
+	if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
+		goto cleanup_region;
+
+	ret = glamor_copy_n_to_n_nf(source->pDrawable,
+				    dest->pDrawable, NULL,
+				    REGION_RECTS(&region),
+				    REGION_NUM_RECTS(&region),
+				    x_source - x_dest, y_source - y_dest,
+				    FALSE, FALSE, 0, NULL);
+cleanup_region:
 	REGION_UNINIT(dest->pDrawable->pScreen, &region);
 	return ret;
 }
commit 566cca59e14b223b8dcd045ccc2bbcf08d05b297
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Jan 29 14:14:36 2012 +0800

    glamor-gles2: Fixup the pixmap before read back if it is not readable.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 92c278f..6c50d1b 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -67,7 +67,7 @@ _glamor_get_spans(DrawablePtr drawable,
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
+	    && (!glamor_tex_format_is_readable(format) || !no_revert)) {
 
 		/* XXX prepare whole pixmap is not efficient. */
 		temp_pixmap =
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 1c810b7..e154273 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -685,7 +685,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
+	    && (!glamor_tex_format_is_readable(format) || !no_revert)) {
 		temp_pixmap =
 		    glamor_es2_pixmap_read_prepare(pixmap, &format,
 						   &type, no_alpha,
commit 36ac9b7191a4bbbe4fb25ced9ee27d1e91308a15
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Jan 21 14:41:44 2012 +0800

    glamor-fbo: Tweek the cache bucket calculation.
    
    And also reduce the expire count to 100 which should be
    good enough on x11perf and cairo-trace testing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 75bdf2a..ffda04a 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -6,7 +6,7 @@
 
 #include "glamor_priv.h"
 
-#define GLAMOR_CACHE_EXPIRE_MAX 1000
+#define GLAMOR_CACHE_EXPIRE_MAX 100
 
 #define GLAMOR_CACHE_DEFAULT    0
 #define GLAMOR_CACHE_EXACT_SIZE 1
@@ -51,7 +51,7 @@ static inline unsigned long __fls(unsigned long x)
 
 inline static int cache_wbucket(int size)
 {
-	int order = __fls(size / 256);
+	int order = __fls(size / 32);
 	if (order >= CACHE_BUCKET_WCOUNT)
 		order = CACHE_BUCKET_WCOUNT - 1;
 	return order;
@@ -59,7 +59,7 @@ inline static int cache_wbucket(int size)
 
 inline static int cache_hbucket(int size)
 {
-	int order = __fls(size / 256);
+	int order = __fls(size / 32);
 	if (order >= CACHE_BUCKET_HCOUNT)
 		order = CACHE_BUCKET_HCOUNT - 1;
 	return order;
commit a1de528c56ff1cfd05a04c4ad127456ec00707fd
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Jan 21 13:22:14 2012 +0800

    glamor_create_fbo: Concentrate the fbo size/depth checking.
    
    Concentrate checking the size/depth when creating fbo. Simply
    the pixmap creation and the uploading fbo/texture preparing.
    
    Also slightly change the uploading fbo's preparation. If don't
    need fbo, then a fbo only has valid texture should be enough
    to return.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 51d04cd..80434e9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -139,19 +139,17 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
-	if (!glamor_check_fbo_size(glamor_priv, w, h)
-	    || !glamor_check_fbo_depth(depth)
-	    || usage == GLAMOR_CREATE_PIXMAP_CPU) {
-		/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
-		   If we exceed such limitation, we have to use framebuffer. */
+	if (usage == GLAMOR_CREATE_PIXMAP_CPU || (w == 0 && h == 0))
 		return fbCreatePixmap(screen, w, h, depth, usage);
-	} else
+	else
 		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
 
 	pixmap_priv = calloc(1, sizeof(*pixmap_priv));
 
-	if (!pixmap_priv)
+	if (!pixmap_priv) {
+		fbDestroyPixmap(pixmap);
 		return fbCreatePixmap(screen, w, h, depth, usage);
+	}
 
 	dixSetPrivate(&pixmap->devPrivates,
 		      glamor_pixmap_private_key,
@@ -161,9 +159,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	pixmap_priv->glamor_priv = glamor_priv;
 	pixmap_priv->type = type;
 
-	if (w == 0 || h == 0)
-		return pixmap;
-
 	fbo = glamor_create_fbo(glamor_priv, w, h, depth, usage);
 
 	if (fbo == NULL) {
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index a9399fb..75bdf2a 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -341,6 +341,10 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	GLint tex;
 	int cache_flag;
 
+	if (!glamor_check_fbo_size(glamor_priv, w, h)
+	    || !glamor_check_fbo_depth(depth))
+		return NULL;
+
 	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
 		goto new_fbo;
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 62ca35f..1c810b7 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -436,7 +436,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 static int
 glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 {
-	int flag = 0;
+	int flag;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	GLenum format;
@@ -445,28 +445,29 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-	if (!glamor_check_fbo_size
-	    (glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
-	    || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
-		glamor_fallback
-		    ("upload failed reason: bad size or depth %d x %d @depth %d \n",
-		     pixmap->drawable.width, pixmap->drawable.height,
-		     pixmap->drawable.depth);
-		return -1;
-	}
+	if (!(no_alpha || !no_revert || !glamor_priv->yInverted)) {
 
-	if (!(no_alpha || !no_revert || !glamor_priv->yInverted))
+		if (pixmap_priv && pixmap_priv->fbo)
+			return 0;
 		flag = GLAMOR_CREATE_FBO_NO_FBO;
+	} else {
 
-	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return 0;
+		if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+			return 0;
+		flag = 0;
+	}
 
 	fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 				pixmap->drawable.height,
 				pixmap->drawable.depth,
 				flag);
-	if (fbo == NULL)
+	if (fbo == NULL) {
+		glamor_fallback
+		    ("upload failed, depth %d x %d @depth %d \n",
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     pixmap->drawable.depth);
 		return -1;
+	}
 
 	glamor_pixmap_attach_fbo(pixmap, fbo);
 
commit 1bfe5957117ba5916236caa021124734228e5aa9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 20:38:29 2012 +0800

    glamor-pixmap-upload: Create a uploading fbo with a texture only.
    
    Just an initial implementation and disabled by default.
    When uploading a pixmap to a texture, we don't really want
    to attach the texture to any fbo. So add one fbo type
    which doesn't has a gl FBO attached to it.
    This commit can increase the cairo-trace's performance by
    10-20%. Now the firefox-planet-gnome is 8.3s. SNA is still
    the best, only take 3.5s.
    
    Thanks for Chris to point out the A1 pixmap uploading bug.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 9b6a05e..a9399fb 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -10,6 +10,7 @@
 
 #define GLAMOR_CACHE_DEFAULT    0
 #define GLAMOR_CACHE_EXACT_SIZE 1
+#define GLAMOR_CACHE_TEXTURE	2
 
 /* Loop from the tail to the head. */
 #define list_for_each_entry_reverse(pos, head, member)                  \
@@ -63,7 +64,6 @@ inline static int cache_hbucket(int size)
 		order = CACHE_BUCKET_HCOUNT - 1;
 	return order;
 }
-
 inline static int cache_format(GLenum format)
 {
 	switch (format) {
@@ -85,10 +85,15 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	glamor_pixmap_fbo *fbo_entry;
 	int size;
 
-	cache = &glamor_priv->fbo_cache[cache_format(format)]
-				       [cache_wbucket(w)]
-				       [cache_hbucket(h)];
-	if (flag != GLAMOR_CACHE_EXACT_SIZE) {
+	if (!(flag & GLAMOR_CACHE_TEXTURE))
+		cache = &glamor_priv->fbo_cache[cache_format(format)]
+					       [cache_wbucket(w)]
+					       [cache_hbucket(h)];
+	else
+		cache = &glamor_priv->tex_cache[cache_format(format)]
+					       [cache_wbucket(w)]
+					       [cache_hbucket(h)];
+	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
 		list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
@@ -118,14 +123,39 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	return NULL;
 }
 
+static void
+glamor_purge_fbo(glamor_pixmap_fbo *fbo)
+{
+	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+	if (fbo->fb)
+		dispatch->glDeleteFramebuffers(1, &fbo->fb);
+	if (fbo->tex)
+		dispatch->glDeleteTextures(1, &fbo->tex);
+	if (fbo->pbo)
+		dispatch->glDeleteBuffers(1, &fbo->pbo);
+
+	free(fbo);
+}
+
+
 void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
 	struct list *cache;
 
-	cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
-					    [cache_wbucket(fbo->width)]
-					    [cache_hbucket(fbo->height)];
+	if (fbo->fb == 0) {
+		glamor_purge_fbo(fbo);
+		return;
+	}
+
+	if (fbo->fb)
+		cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
+						    [cache_wbucket(fbo->width)]
+						    [cache_hbucket(fbo->height)];
+	else
+		cache = &fbo->glamor_priv->tex_cache[cache_format(fbo->format)]
+						    [cache_wbucket(fbo->width)]
+						    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
 		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
 	list_add(&fbo->list, cache);
@@ -153,25 +183,12 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 	fbo->format = format;
 	fbo->glamor_priv = glamor_priv;
 
-	glamor_pixmap_ensure_fb(fbo);
+	if (flag != GLAMOR_CREATE_FBO_NO_FBO)
+		glamor_pixmap_ensure_fb(fbo);
 
 	return fbo;
 }
 
-static void
-glamor_purge_fbo(glamor_pixmap_fbo *fbo)
-{
-	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
-	DEBUGF("Purge fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
-	if (fbo->fb)
-		dispatch->glDeleteFramebuffers(1, &fbo->fb);
-	if (fbo->tex)
-		dispatch->glDeleteTextures(1, &fbo->tex);
-	if (fbo->pbo)
-		dispatch->glDeleteBuffers(1, &fbo->pbo);
-
-	free(fbo);
-}
 
 void
 glamor_fbo_expire(glamor_screen_private *glamor_priv)
@@ -195,6 +212,19 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
 						fbo_entry->expire, glamor_priv->tick);
 					glamor_purge_fbo(fbo_entry);
 				}
+#if 0
+				cache = &glamor_priv->tex_cache[i][j][k];
+				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
+						empty_cache = FALSE;
+						break;
+					}
+					list_del(&fbo_entry->list);
+					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
+						fbo_entry->expire, glamor_priv->tick);
+					glamor_purge_fbo(fbo_entry);
+				}
+#endif
 			}
 
 }
@@ -211,6 +241,7 @@ glamor_init_pixmap_fbo(ScreenPtr screen)
 			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
 			{
 				list_init(&glamor_priv->fbo_cache[i][j][k]);
+				list_init(&glamor_priv->tex_cache[i][j][k]);
 			}
 }
 
@@ -232,7 +263,13 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
 					list_del(&fbo_entry->list);
 					glamor_purge_fbo(fbo_entry);
 				}
-
+#if 0
+				cache = &glamor_priv->tex_cache[i][j][k];
+				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					list_del(&fbo_entry->list);
+					glamor_purge_fbo(fbo_entry);
+				}
+#endif
 			}
 }
 
@@ -247,6 +284,54 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 }
 
 glamor_pixmap_fbo *
+glamor_create_tex_obj(glamor_screen_private *glamor_priv,
+		      int w, int h, GLenum format, int flag)
+{
+	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_fbo *fbo;
+	int cache_flag = GLAMOR_CACHE_TEXTURE;
+	GLuint tex;
+
+	if (flag == GLAMOR_CREATE_TEXTURE_EXACT_SIZE)
+		cache_flag |= GLAMOR_CACHE_EXACT_SIZE;
+
+	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
+					  format, cache_flag);
+	if (fbo)
+		return fbo;
+	fbo = calloc(1, sizeof(*fbo));
+	if (fbo == NULL)
+		return NULL;
+
+	list_init(&fbo->list);
+
+	dispatch = &glamor_priv->dispatch;
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
+			       GL_UNSIGNED_BYTE, NULL);
+	fbo->tex = tex;
+	fbo->width = w;
+	fbo->height = h;
+	fbo->format = format;
+	fbo->glamor_priv = glamor_priv;
+
+	return fbo;
+}
+
+void
+glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
+{
+	assert(tex_obj->fb == 0);
+	list_del(&tex_obj->list);
+	glamor_pixmap_fbo_cache_put(tex_obj);
+}
+
+glamor_pixmap_fbo *
 glamor_create_fbo(glamor_screen_private *glamor_priv,
 		  int w, int h, int depth, int flag)
 {
@@ -256,6 +341,9 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	GLint tex;
 	int cache_flag;
 
+	if (flag == GLAMOR_CREATE_FBO_NO_FBO)
+		goto new_fbo;
+
 	if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
 		cache_flag = GLAMOR_CACHE_EXACT_SIZE;
 	else
@@ -266,7 +354,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 					  format, cache_flag);
 	if (fbo)
 		return fbo;
-
+new_fbo:
 	dispatch = &glamor_priv->dispatch;
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
@@ -279,7 +367,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 
 	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
 
-	DEBUGF("Creat new fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
 	return fbo;
 }
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 9c9e517..62ca35f 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -436,7 +436,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 static int
 glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 {
-	int need_fbo;
+	int flag = 0;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	GLenum format;
@@ -455,13 +455,16 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 		return -1;
 	}
 
+	if (!(no_alpha || !no_revert || !glamor_priv->yInverted))
+		flag = GLAMOR_CREATE_FBO_NO_FBO;
+
 	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return 0;
 
 	fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
 				pixmap->drawable.height,
 				pixmap->drawable.depth,
-				0);
+				flag);
 	if (fbo == NULL)
 		return -1;
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 66e47c6..9c2881c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -127,6 +127,10 @@ enum glamor_gl_flavor {
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
 #define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
 
+#define GLAMOR_CREATE_FBO_NO_FBO   0x103
+
+#define GLAMOR_CREATE_TEXTURE_EXACT_SIZE 0x104
+
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
 typedef struct {
@@ -176,6 +180,7 @@ typedef struct glamor_screen_private {
 	int max_fbo_size;
 
 	struct list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+	struct list tex_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
 
 	/* glamor_solid */
 	GLint solid_prog;
@@ -251,7 +256,6 @@ typedef union _glamor_pending_op {
  * #pending_op: currently only support pending filling.
  * @container: The corresponding pixmap's pointer.
  **/
-
 typedef struct glamor_pixmap_fbo {
 	struct list list;
 	unsigned int expire;
commit 6fb92e67b3f3dee38d8d440c8ab9f8cc5dcef9bc
Author: Li Peng <peng.li at intel.com>
Date:   Fri Jan 20 16:23:17 2012 +0800

    glamor: check driver support GEM or not
    
    glamor calls DRM_IOCTL_GEM_FLINK to get a name for a buffer object.
    It only works for driver that support GEM, such as intel i915 driver.
    But for pvr driver who doesn't has GEM, we can't do it this way.
    
    According to Chris's comments, we check the has_gem as the following
    method:
    
    Here we just try to flink handle 0. If that fails with ENODEV or
    ENOTTY instead of ENOENT (or EINVAL on older kernels), set has_gem=0.
    
    Signed-off-by: Li Peng <peng.li at intel.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index c273e8a..71121bc 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -89,6 +89,7 @@ struct glamor_egl_screen_private {
 #ifdef GLAMOR_HAS_GBM
 	struct gbm_device *gbm;
 #endif
+	int has_gem;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
@@ -189,6 +190,19 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 }
 
 Bool
+glamor_egl_check_has_gem(int fd)
+{
+	struct drm_gem_flink flink;
+	flink.handle = 0;
+	int err;
+
+	ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
+	if (errno == ENOENT || err == EINVAL)
+		return TRUE;
+	return FALSE;
+}
+
+Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -200,12 +214,16 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 
 	glamor_egl = glamor_egl_get_screen_private(scrn);
 
-	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Couldn't flink pixmap handle\n");
-		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-		exit(1);
-	}
+	if (glamor_egl->has_gem) {
+		if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				   "Couldn't flink pixmap handle\n");
+			glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+			exit(1);
+		}
+	} else
+		name = handle;
+
 	image = _glamor_egl_create_image(glamor_egl,
 					 pixmap->drawable.width,
 					 pixmap->drawable.height,
@@ -312,6 +330,8 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)fd);
 #endif
 
+	glamor_egl->has_gem = glamor_egl_check_has_gem(fd);
+
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
 #else
commit 68789b23e791d81c6987c755a56851961cbb262f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 15:56:25 2012 +0800

    glamor_gles2: Consolidate gles2 pixmap format readable check to one function.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 086ec4b..377783c 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -78,7 +78,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
 		/* XXX prepare whole pixmap is not efficient. */
 		temp_pixmap =
 		    glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index be81fbb..92c278f 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -66,7 +66,9 @@ _glamor_get_spans(DrawablePtr drawable,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	glamor_validate_pixmap(pixmap);
 
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
+
 		/* XXX prepare whole pixmap is not efficient. */
 		temp_pixmap =
 		    glamor_es2_pixmap_read_prepare(pixmap, &format,
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 2020e21..9c9e517 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -681,15 +681,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	glamor_validate_pixmap(pixmap);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    &&
-	    ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA)
-	     || no_revert != 1)) {
-
+	    && (glamor_tex_format_is_readable(format) || !no_revert)) {
 		temp_pixmap =
 		    glamor_es2_pixmap_read_prepare(pixmap, &format,
 						   &type, no_alpha,
 						   no_revert);
-
 	}
 	switch (access) {
 	case GLAMOR_ACCESS_RO:
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index c7d1c29..b292928 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -603,4 +603,10 @@ inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc)
 	return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
 }
 
+inline static Bool glamor_tex_format_is_readable(GLenum format)
+{
+	return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA));
+
+}
+
 #endif
commit 3373d2c696028a9f2f637430c48b9de1a3776800
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 12:10:06 2012 +0800

    glamor_egl: Add support for the platform doesn't have gbm.
    
    Maybe we should use eglGetDisplayDRM to get display, but current
    PVR's driver is using eglGetDisplay.
    
    Signed-off-by: Peng Li <peng.li at intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 1b18c4c..c273e8a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -46,7 +46,9 @@
 #define EGL_EGLEXT_PROTOTYPES
 #define EGL_DISPLAY_NO_X_MESA
 
+#ifdef GLAMOR_HAS_GBM
 #include <gbm.h>
+#endif
 
 #if GLAMOR_GLES2
 #include <GLES2/gl2.h>
@@ -84,7 +86,9 @@ struct glamor_egl_screen_private {
 	int fd;
 	int front_buffer_handle;
 	int cpp;
+#ifdef GLAMOR_HAS_GBM
 	struct gbm_device *gbm;
+#endif
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
@@ -297,12 +301,16 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 
 	scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
 	glamor_egl->fd = fd;
+#ifdef GLAMOR_HAS_GBM
 	glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
 	if (glamor_egl->gbm == NULL) {
 		ErrorF("couldn't get display device\n");
 		return FALSE;
 	}
 	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
+#else
+	glamor_egl->display = eglGetDisplay((EGLNativeDisplayType)fd);
+#endif
 
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
commit 92671e3ac8cc955379085c143ee8cf8b37e760ec
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 11:58:34 2012 +0800

    glamor_egl: Don't call eglDestroyImageKHR directly.
    
    Some implementation doesn't have it.
    
    Signed-off-by: Peng Li <peng.li at intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 3d581d2..1b18c4c 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -87,6 +87,7 @@ struct glamor_egl_screen_private {
 	struct gbm_device *gbm;
 
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
+	PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
 	struct glamor_gl_dispatch *dispatch;
 };
@@ -235,7 +236,7 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
  			 * a texture. we must call glFlush to make sure the 
  			 * operation on that texture has been done.*/
 			glamor_block_handler(pixmap->drawable.pScreen);
-			eglDestroyImageKHR(glamor_egl->display, image);
+			glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
 		}
 	}
 	glamor_destroy_textured_pixmap(pixmap);
@@ -336,6 +337,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
 	    eglGetProcAddress("eglCreateImageKHR");
 
+	glamor_egl->egl_destroy_image_khr = (PFNEGLDESTROYIMAGEKHRPROC)
+	    eglGetProcAddress("eglDestroyImageKHR");
+
 	glamor_egl->egl_image_target_texture2d_oes =
 	    (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
 	    eglGetProcAddress("glEGLImageTargetTexture2DOES");
commit 125f317d90b69fa4d6f98da9badc1946f0a099ec
Author: Peng Li <peng.li at intel.com>
Date:   Fri Jan 20 11:52:18 2012 +0800

    glamor_gl_dispatch: fix the dispatch initialization on GLES2.
    
    Some gles2 implementation doesn's support get_proc_address.
    And we also need to avoid get those missing functions pointers
    when we are GLES2.
    
    Signed-off-by: Peng Li <peng.li at intel.com>
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index 493c967..da66380 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -1,24 +1,36 @@
 #include "glamor_priv.h"
+#include <dlfcn.h>
 
 #define INIT_FUNC(dst,func_name,get)			\
   dst->func_name = get(#func_name);			\
-  if (dst->func_name == NULL)				\
-    { ErrorF("Failed to get function %s", #func_name);	\
-	goto fail; }
+  if (dst->func_name == NULL) {				\
+    dst->func_name = (void *)dlsym(NULL, #func_name);	\
+    if (dst->func_name == NULL) {			\
+      ErrorF("Failed to get function %s\n", #func_name);\
+      goto fail;					\
+    }							\
+  }							\
 
 _X_EXPORT Bool
 glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 			     int gl_version,
 			     void *(*get_proc_address) (const char *))
 {
+#ifndef GLAMOR_GLES2
 	INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
 	INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
-	INIT_FUNC(dispatch, glViewport, get_proc_address);
 	INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
+	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
+	INIT_FUNC(dispatch, glLogicOp, get_proc_address);
+	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
+	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
+#endif
+	INIT_FUNC(dispatch, glViewport, get_proc_address);
 	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
 	INIT_FUNC(dispatch, glDrawElements, get_proc_address);
 	INIT_FUNC(dispatch, glReadPixels, get_proc_address);
-	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
 	INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
 	INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
 	INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
@@ -34,13 +46,9 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glEnable, get_proc_address);
 	INIT_FUNC(dispatch, glDisable, get_proc_address);
 	INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
-	INIT_FUNC(dispatch, glLogicOp, get_proc_address);
 	INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
 	INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
 	INIT_FUNC(dispatch, glBufferData, get_proc_address);
-	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
-	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
-	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
 	INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
@@ -48,7 +56,6 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
 	INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
 	INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
-	INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
 	INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
 	INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
 	INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
commit 64fef665c9297ddd110b8472943f96b55db120ba
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 10:56:17 2012 +0800

    glamor_render: Add non-Map/Unmap vertex array for GLES.
    
    As some GLES implementations' glMapOES /glUnmapOES is
    not so efficient, we implement the in memory vertex array
    for them.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index eb4d916..8d6137d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -305,29 +305,64 @@ glamor_init_eb(unsigned short *eb, int vert_cnt)
 	}
 }
 
-
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
 	unsigned short *eb;
+	float *vb;
+	int eb_size;
+	int vb_size;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch = &glamor_priv->dispatch;
 	dispatch->glGenBuffers(1, &glamor_priv->vbo);
 	dispatch->glGenBuffers(1, &glamor_priv->ebo);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-	dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2,
-			       NULL, GL_DYNAMIC_DRAW);
-	eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
-	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
-	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-	dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-}
 
+	eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+				       eb_size,
+				       NULL, GL_DYNAMIC_DRAW);
+		eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+	}
+	else {
+		vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
+		if (vb == NULL) {
+			ErrorF("Failed to allocate vb memory.\n");
+			exit(1);
+		}
+		eb = malloc(eb_size);
+	}
+
+	if (eb == NULL) {
+		ErrorF("fatal error, fail to get eb.\n");
+		exit(1);
+	}
+	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
 
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	} else {
+		dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+				       eb_size,
+				       eb, GL_DYNAMIC_DRAW);
+		dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+		dispatch->glBufferData(GL_ARRAY_BUFFER,
+				       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2,
+				       NULL, GL_DYNAMIC_DRAW);
+		dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+		free(eb);
+		glamor_priv->vb = (char*)vb;
+	}
+}
 
 void
 glamor_fini_composite_shaders(ScreenPtr screen)
@@ -350,7 +385,9 @@ glamor_fini_composite_shaders(ScreenPtr screen)
 				if (shader->prog)
 					dispatch->glDeleteProgram(shader->prog);
 			}
-
+	if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+	    && glamor_priv->vb)
+		free(glamor_priv->vb);
 }
 
 
@@ -616,11 +653,12 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-	dispatch->glBufferData(GL_ARRAY_BUFFER,
-			       n_verts * sizeof(float) * 2,
-			       NULL, GL_DYNAMIC_DRAW);
-
-	glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glBufferData(GL_ARRAY_BUFFER,
+				       n_verts * sizeof(float) * 2,
+				       NULL, GL_DYNAMIC_DRAW);
+		glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	}
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -689,7 +727,16 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	if (!glamor_priv->render_nr_verts)
 		return;
-	dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+		dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+	else {
+
+		dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+		dispatch->glBufferData(GL_ARRAY_BUFFER,
+				       glamor_priv->vbo_offset,
+				       glamor_priv->vb, GL_DYNAMIC_DRAW);
+	}
+
 	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 				 GL_UNSIGNED_SHORT, NULL);
 }
@@ -1013,6 +1060,7 @@ glamor_composite_with_shader(CARD8 op,
 
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
+
 	if (!glamor_set_composite_op(screen, op, dest, mask)) {
 		goto fail;
 	}
commit c244969b331e08679be9a9618d75fe5ee9cc9d86
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 10:55:16 2012 +0800

    glamor_init: Should set gl_flavor before sub-module intialization.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6e843f4..51d04cd 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -318,6 +318,12 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
 	glamor_set_debug_level(&glamor_debug_level);
 
+#ifdef GLAMOR_GLES2
+	glamor_priv->gl_flavor = GLAMOR_GL_ES2;
+#else
+	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+#endif
+
 	if (flags & GLAMOR_USE_SCREEN) {
 		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
 						    _glamor_wakeup_handler,
@@ -390,11 +396,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_init_finish_access_shaders(screen);
 	glamor_pixmap_init(screen);
 
-#ifdef GLAMOR_GLES2
-	glamor_priv->gl_flavor = GLAMOR_GL_ES2;
-#else
-	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
-#endif
 	glamor_priv->flags = flags;
 
 	return TRUE;
commit 62e536535168827be76dafb1f5b5e0807c1d5ec9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 10:04:21 2012 +0800

    glamor_composite: Fix one bug when we have too more vertices.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 03f7e32..eb4d916 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1072,7 +1072,7 @@ glamor_composite_with_shader(CARD8 op,
 	}
 
 	nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
-			 (GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) : nrect;
+			 (GLAMOR_COMPOSITE_VBO_VERT_CNT / vert_stride) : nrect;
 
 	while(nrect) {
 		int mrect, rect_processed;
commit 9c6fd931a63fb8a5300014265e4f1cacc746857a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 20 09:59:44 2012 +0800

    glamor-fbo-pool: Enable to reuse different size fbo/texture.
    
    Fixup three special cases, one is in tile and the other is in
    composite. Both cases are due to repeat texture issue. Maybe
    we can refine the shader to recalculate texture coords to
    support partial texture's repeating.
    
    The third is when upload a memory pixmap to texture, as now
    the texture may not have the exact size as the pixmap, we
    should not use the full rect coords.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 9b9d823..6e843f4 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -164,7 +164,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (w == 0 || h == 0)
 		return pixmap;
 
-	fbo = glamor_create_fbo(glamor_priv, w, h, depth, 0);
+	fbo = glamor_create_fbo(glamor_priv, w, h, depth, usage);
 
 	if (fbo == NULL) {
 		fbDestroyPixmap(pixmap);
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 97ba33c..9b6a05e 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -90,7 +90,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 				       [cache_hbucket(h)];
 	if (flag != GLAMOR_CACHE_EXACT_SIZE) {
 		list_for_each_entry(fbo_entry, cache, list) {
-			if (fbo_entry->width == w && fbo_entry->height == h) {
+			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
 				DEBUGF("Request w %d h %d \n", w, h);
 				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
@@ -263,7 +263,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 
 	gl_iformat_for_depth(depth, &format);
 	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
-					  format, GLAMOR_CACHE_EXACT_SIZE);
+					  format, cache_flag);
 	if (fbo)
 		return fbo;
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f001962..2020e21 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -216,7 +216,7 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 int in_restore = 0;
 static void
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				  GLenum type, GLuint tex)
+				  GLenum type, GLuint tex, int sub)
 {
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
@@ -255,12 +255,19 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	} else
 		texels = pixmap->devPrivate.ptr;
 
-	dispatch->glTexImage2D(GL_TEXTURE_2D,
-			       0,
-			       iformat,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height, 0, format, type,
-			       texels);
+	if (sub)
+		dispatch->glTexSubImage2D(GL_TEXTURE_2D,
+				       0,0,0,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height, format, type,
+				       texels);
+	else
+		dispatch->glTexImage2D(GL_TEXTURE_2D,
+				       0,
+				       iformat,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height, 0, format, type,
+				       texels);
 }
 
 
@@ -280,11 +287,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(pixmap->drawable.pScreen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-	static float vertices[8] = { -1, -1,
-		1, -1,
-		1, 1,
-		-1, 1
-	};
+	static float vertices[8];
 	static float texcoords[8] = { 0, 1,
 		1, 1,
 		1, 0,
@@ -296,7 +299,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 		0, 1
 	};
 	float *ptexcoords;
-
+	float dst_xscale, dst_yscale;
 	GLuint tex;
 	int need_flip;
 
@@ -315,16 +318,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	 * to the fbo directly. */
 	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
 		__glamor_upload_pixmap_to_texture(pixmap, format, type,
-						  pixmap_priv->fbo->tex);
+						  pixmap_priv->fbo->tex, 1);
 		return;
 	}
 
-
 	if (need_flip)
 		ptexcoords = texcoords;
 	else
 		ptexcoords = texcoords_inv;
 
+	pixmap_priv_get_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+	glamor_set_normalize_vcoords(dst_xscale,
+				     dst_yscale,
+				     0, 0,
+				     pixmap->drawable.width, pixmap->drawable.height,
+				     glamor_priv->yInverted,
+				     vertices);
+
 	/* Slow path, we need to flip y or wire alpha to 1. */
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
@@ -338,7 +348,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	dispatch->glGenTextures(1, &tex);
 
-	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
+	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex, 0);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 
@@ -791,3 +801,66 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	return TRUE;
 }
+
+/* fixup a fbo to the exact size as the pixmap. */
+Bool
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_pixmap_fbo *old_fbo;
+	glamor_pixmap_fbo *new_fbo = NULL;
+	PixmapPtr scratch = NULL;
+	glamor_pixmap_private *scratch_priv;
+	DrawablePtr drawable;
+	GCPtr gc = NULL;
+	int ret = FALSE;
+
+	drawable = &pixmap_priv->container->drawable;
+
+	if (pixmap_priv->container->drawable.width == pixmap_priv->fbo->width
+	    && pixmap_priv->container->drawable.height == pixmap_priv->fbo->height)
+		return	TRUE;
+
+	old_fbo = pixmap_priv->fbo;
+	glamor_priv = pixmap_priv->glamor_priv;
+
+	if (!old_fbo)
+		return FALSE;
+
+	gc = GetScratchGC(drawable->depth, screen);
+	if (!gc)
+		goto fail;
+
+	scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
+				       drawable->depth,
+				       GLAMOR_CREATE_PIXMAP_FIXUP);
+
+	scratch_priv = glamor_get_pixmap_private(scratch);
+
+	if (!scratch_priv || !scratch_priv->fbo)
+		goto fail;
+
+	ValidateGC(&scratch->drawable, gc);
+	glamor_copy_area(drawable,
+			 &scratch->drawable,
+			 gc, 0, 0,
+			 drawable->width, drawable->height,
+			 0, 0);
+	old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+	new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
+	glamor_pixmap_attach_fbo(pixmap_priv->container, new_fbo);
+	glamor_pixmap_attach_fbo(scratch, old_fbo);
+
+	DEBUGF("old %dx%d type %d\n",
+		drawable->width, drawable->height, pixmap_priv->type);
+	DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
+		old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height);
+	ret = TRUE;
+fail:
+	if (gc)
+		FreeScratchGC(gc);
+	if (scratch)
+		glamor_destroy_pixmap(scratch);
+
+	return ret;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 31f9c93..66e47c6 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -594,6 +594,10 @@ void glamor_destroy_picture(PicturePtr picture);
 enum glamor_pixmap_status
  glamor_upload_picture_to_texture(PicturePtr picture);
 
+/* fixup a fbo to the exact size as the pixmap. */
+Bool
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
+
 void
 glamor_picture_format_fixup(PicturePtr picture,
 			    glamor_pixmap_private * pixmap_priv);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 19ed22e..03f7e32 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -342,7 +342,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
 	dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
 	dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
 
-
 	for(i = 0; i < SHADER_SOURCE_COUNT; i++)
 		for(j = 0; j < SHADER_MASK_COUNT; j++)
 			for(k = 0; k < SHADER_IN_COUNT; k++)
@@ -409,6 +408,33 @@ glamor_set_composite_op(ScreenPtr screen,
 }
 
 static void
+glamor_composite_texture_fixup(ScreenPtr screen,
+			       PicturePtr picture,
+			       glamor_pixmap_private * pixmap_priv)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	Bool has_repeat;
+	int width, height;
+
+	if (picture->repeatType == RepeatNone)
+		has_repeat = FALSE;
+	else
+		has_repeat = TRUE;
+
+	if (has_repeat
+	    && ( (pixmap_priv->container->drawable.width != pixmap_priv->fbo->width)
+		 || (pixmap_priv->container->drawable.height != pixmap_priv->fbo->height))) {
+	/* Currently, we can't support repeat on partial texture, now redirect it
+	 * to an exact size fbo. */
+		DEBUGF("prepare to fixup texture \n");
+		if (!glamor_fixup_pixmap_priv(screen, pixmap_priv))
+			ErrorF("Failed to fixup a unmatch size of repeat picture. \n");
+	}
+}
+
+static void
 glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv)
@@ -979,6 +1005,12 @@ glamor_composite_with_shader(CARD8 op,
 		}
 	}
 #endif
+
+	if (key.source != SHADER_SOURCE_SOLID)
+		glamor_composite_texture_fixup(screen, source, source_pixmap_priv);
+	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID)
+		glamor_composite_texture_fixup(screen, mask, mask_pixmap_priv);
+
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
 	if (!glamor_set_composite_op(screen, op, dest, mask)) {
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 7e0e6ac..4ff4fa1 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -127,8 +127,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
 	    || ((tile_y != 0)
 		&& (tile_y + height > tile->drawable.height))) {
+		/* XXX We can recreate a new pixmap here to avoid partial tiling. */
 		goto fail;
 	}
+
 	if (glamor_priv->tile_prog == 0) {
 		glamor_fallback("Tiling unsupported\n");
 		goto fail;
@@ -148,6 +150,15 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		glamor_fallback("unsupported planemask %lx\n", planemask);
 		goto fail;
 	}
+
+	if (src_pixmap_priv->fbo->width != tile->drawable.width
+	    || src_pixmap_priv->fbo->height != tile->drawable.height) {
+		if (!glamor_fixup_pixmap_priv(screen, src_pixmap_priv)) {
+			glamor_fallback("Failed to create a fixup pixmap for partial tiling. \n");
+			goto fail;
+		}
+	}
+
 	if (alu != GXcopy) {
 		glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
 		glamor_validate_pixmap(tile);
commit c7e79d6acff5abd7a327d5f4d6698ae5d7583834
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jan 19 20:47:55 2012 +0800

    glamor-fbo-pool: Implement fbo cache mechanism.
    
    We classify the cache according to the texture's format/width/height.
    As openGL doesn't allow us to change a texture's format/width/height
    after the internal texture object is already allocated, we can't
    just calculate the size and then according ths size to put the
    fbo to an bucket which is just like SNA does. We can only put
    the fbo to the corresponding format/width/height bucket.
    
    This commit only support the exact size match. The following patch
    will remove this restriction, just need to handle the repeat/tile
    case when the size is not exactly match.
    
    Should use fls instead of ffs when decide the width/height bucket,
    thanks for Chris to point this out.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 29f827c..9b9d823 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -210,8 +210,10 @@ glamor_block_handler(ScreenPtr screen)
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
+	glamor_priv->tick++;
 	dispatch->glFlush();
 	dispatch->glFinish();
+	glamor_fbo_expire(glamor_priv);
 }
 
 static void
@@ -381,6 +383,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	ps->DestroyPicture = glamor_destroy_picture;
 	glamor_init_composite_shaders(screen);
 #endif
+	glamor_init_pixmap_fbo(screen);
 	glamor_init_solid_shader(screen);
 	glamor_init_tile_shader(screen);
 	glamor_init_putimage_shaders(screen);
@@ -392,6 +395,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #else
 	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
 #endif
+	glamor_priv->flags = flags;
 
 	return TRUE;
 
@@ -402,26 +406,54 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	return FALSE;
 }
 
+static void
+glamor_release_screen_priv(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+
+	glamor_priv = glamor_get_screen_private(screen);
+#ifdef RENDER
+	glamor_fini_composite_shaders(screen);
+#endif
+	glamor_fini_pixmap_fbo(screen);
+	glamor_fini_solid_shader(screen);
+	glamor_fini_tile_shader(screen);
+	glamor_fini_putimage_shaders(screen);
+	glamor_fini_finish_access_shaders(screen);
+	glamor_pixmap_fini(screen);
+	free(glamor_priv);
+
+	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
+		      NULL);
+}
+
 Bool
 glamor_close_screen(int idx, ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
+	glamor_screen_private *glamor_priv;
+	int flags;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	flags = glamor_priv->flags;
 #ifdef RENDER
 	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
 	glamor_glyphs_fini(screen);
-	screen->CloseScreen = glamor_priv->saved_procs.close_screen;
-	screen->CreateGC = glamor_priv->saved_procs.create_gc;
-	screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
-	screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
-	screen->GetSpans = glamor_priv->saved_procs.get_spans;
-	screen->ChangeWindowAttributes =
-	    glamor_priv->saved_procs.change_window_attributes;
-	screen->CopyWindow = glamor_priv->saved_procs.copy_window;
-	screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+	if (flags & GLAMOR_USE_SCREEN) {
+
+		screen->CloseScreen = glamor_priv->saved_procs.close_screen;
+		screen->CreateGC = glamor_priv->saved_procs.create_gc;
+		screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+		screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+		screen->GetSpans = glamor_priv->saved_procs.get_spans;
+		screen->ChangeWindowAttributes =
+		    glamor_priv->saved_procs.change_window_attributes;
+		screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+		screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+	}
 #ifdef RENDER
-	if (ps) {
+	if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
+
 		ps->Composite = glamor_priv->saved_procs.composite;
 		ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
 		ps->Glyphs = glamor_priv->saved_procs.glyphs;
@@ -429,13 +461,15 @@ glamor_close_screen(int idx, ScreenPtr screen)
 		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
 	}
 #endif
-	if (glamor_priv->vb)
-		free(glamor_priv->vb);
-	free(glamor_priv);
-	return screen->CloseScreen(idx, screen);
+	glamor_release_screen_priv(screen);
 
+	if (flags & GLAMOR_USE_SCREEN)
+		return screen->CloseScreen(idx, screen);
+	else
+		return TRUE;
 }
 
+
 void
 glamor_fini(ScreenPtr screen)
 {
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 51061f3..fe15700 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -42,7 +42,7 @@
 #endif				/* GLAMOR_H */
 
 /* @GLAMOR_INVERTED_Y_AXIS:
- * set 1 means the GL env's origin (0,0) is at top-left. 
+ * set 1 means the GL env's origin (0,0) is at top-left.
  * EGL/DRM platform is an example need to set this bit.
  * glx platform's origin is at bottom-left thus need to
  * clear this bit.*/
@@ -54,7 +54,7 @@
  * create/destroy pixmap and handle the gc ops. need to
  * set this bit. Standalone glamor DDX driver need to set
  * this bit.
- * Otherwise, need to clear this bit, as the intel video 
+ * Otherwise, need to clear this bit, as the intel video
  * driver with glamor enabled.
  * */
 #define GLAMOR_USE_SCREEN		2
@@ -97,12 +97,24 @@ typedef enum  glamor_pixmap_type {
  *
  * This function initializes necessary internal data structure
  * for glamor. And before calling into this function, the OpenGL
- * environment should be ready. Should be called before any real 
- * glamor rendering or texture allocation functions. 
+ * environment should be ready. Should be called before any real
+ * glamor rendering or texture allocation functions.
  */
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 
+/* This function is used to free the glamor private screen's
+ * resources. If the DDX driver is not set GLAMOR_USE_SCREEN,
+ * then, DDX need to call this function at proper stage, if
+ * it is the xorg DDX driver,then it should be called at free
+ * screen stage not the close screen stage. The reason is after
+ * call to this function, the xorg DDX may need to destroy the
+ * screen pixmap which must be a glamor pixmap and requires
+ * the internal data structure still exist at that time.
+ * Otherwise, the glamor internal structure will not be freed.*/
+extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen);
+
+
 /* Let glamor to know the screen's fbo. The low level
  * driver should already assign a tex
  * to this pixmap through the set_pixmap_texture. */
@@ -133,7 +145,7 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
  * @scrn: Current screen info pointer.
  * @fd:   Current drm fd.
  *
- * This function creates and intialize EGL contexts. 
+ * This function creates and intialize EGL contexts.
  * Should be called from DDX's preInit function.
  * Return TRUE if success, otherwise return FALSE.
  * */
@@ -165,7 +177,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
 /*
  * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
  * 				       a BO handle.
- * 
+ *
  * @pixmap: The pixmap need to be processed.
  * @handle: The BO's handle attached to this pixmap at DDX layer.
  * @stride: Stride in bytes for this pixmap.
@@ -188,24 +200,24 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 
 extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
-/* Glamor rendering/drawing functions with XXX_nf. 
+/* Glamor rendering/drawing functions with XXX_nf.
  * nf means no fallback within glamor internal if possible. If glamor
  * fail to accelerate the operation, glamor will return a false, and the
  * caller need to implement fallback method. Return a true means the
  * rendering request get done successfully. */
 extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
 					   GCPtr gc,
-					   int n, DDXPointPtr points, 
+					   int n, DDXPointPtr points,
 					   int *widths, int sorted);
 
 extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
-					       GCPtr gc, 
-					       int nrect, 
+					       GCPtr gc,
+					       int nrect,
 					       xRectangle * prect);
 
-extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable, 
+extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
 					  GCPtr gc, int depth, int x, int y,
-		 	 		  int w, int h, int left_pad, 
+					  int w, int h, int left_pad,
 					  int image_format, char *bits);
 
 extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
@@ -216,7 +228,7 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
 					    int dx,
 					    int dy,
 					    Bool reverse,
-					    Bool upsidedown, Pixel bitplane, 
+					    Bool upsidedown, Pixel bitplane,
 					    void *closure);
 
 extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
@@ -227,12 +239,12 @@ extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
 					  INT16 y_source,
 					  INT16 x_mask,
 					  INT16 y_mask,
-					  INT16 x_dest, INT16 y_dest, 
+					  INT16 x_dest, INT16 y_dest,
 					  CARD16 width, CARD16 height);
 
 extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
 					   PicturePtr src, PicturePtr dst,
-					   PictFormatPtr mask_format, 
+					   PictFormatPtr mask_format,
 					   INT16 x_src, INT16 y_src,
 					   int ntrap, xTrapezoid * traps);
 
@@ -241,14 +253,14 @@ extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
 				       PicturePtr dst,
 				       PictFormatPtr mask_format,
 				       INT16 x_src,
-				       INT16 y_src, int nlist, 
+				       INT16 y_src, int nlist,
 				       GlyphListPtr list, GlyphPtr * glyphs);
 
 extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
 					  PicturePtr pSrc,
 					  PicturePtr pDst,
 					  PictFormatPtr maskFormat,
-					  INT16 xSrc, INT16 ySrc, 
+					  INT16 xSrc, INT16 ySrc,
 					  int ntris, xTriangle * tris);
 
 
@@ -270,7 +282,7 @@ extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, i
 					  unsigned int format, unsigned long planeMask, char *d);
 
 extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
-					  INT16 x_off, 
+					  INT16 x_off,
 					  INT16 y_off, int ntrap, xTrap * traps);
 
 extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f6f9e83..395e912 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -114,9 +114,8 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
 	const char *vs_source =
 	    "attribute vec4 v_position;\n"
 	    "attribute vec4 v_texcoord0;\n"
@@ -174,25 +173,23 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
 	GLint sampler_uniform_location;
 
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
 	glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
 	glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
 
-	vs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
+	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
 				     vs_source);
-	fs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
 				     fs_source);
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
 				 vs_prog);
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
 				 fs_prog);
 
-	avs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
+	avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
 				     vs_source);
-	set_alpha_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+	set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
 				     set_alpha_source);
 	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
 				 avs_prog);
@@ -255,6 +252,20 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 }
 
 void
+glamor_fini_finish_access_shaders(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
+	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
+	dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
+}
+
+
+
+void
 glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 1b57b46..3d581d2 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -77,7 +77,6 @@ glamor_identify(int flags)
 struct glamor_egl_screen_private {
 	EGLDisplay display;
 	EGLContext context;
-	EGLImageKHR root;
 	EGLint major, minor;
 
 	CreateScreenResourcesProcPtr CreateScreenResources;
@@ -250,10 +249,6 @@ glamor_egl_close_screen(ScreenPtr screen)
 	    glamor_egl_get_screen_private(scrn);
 	glamor_fini(screen);
 
-	eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
-
-	glamor_egl->root = EGL_NO_IMAGE_KHR;
-
 	return TRUE;
 }
 
@@ -402,6 +397,8 @@ glamor_egl_free_screen(int scrnIndex, int flags)
 		}
 		free(glamor_egl);
 	}
+
+	glamor_close_screen(scrn->scrnIndex, scrn->pScreen);
 }
 
 Bool
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index 068d877..97ba33c 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -6,6 +6,132 @@
 
 #include "glamor_priv.h"
 
+#define GLAMOR_CACHE_EXPIRE_MAX 1000
+
+#define GLAMOR_CACHE_DEFAULT    0
+#define GLAMOR_CACHE_EXACT_SIZE 1
+
+/* Loop from the tail to the head. */
+#define list_for_each_entry_reverse(pos, head, member)                  \
+    for (pos = __container_of((head)->prev, pos, member);               \
+         &pos->member != (head);                                        \
+         pos = __container_of(pos->member.prev, pos, member))
+
+
+#define list_for_each_entry_safe_reverse(pos, tmp, head, member)        \
+    for (pos = __container_of((head)->prev, pos, member),               \
+         tmp = __container_of(pos->member.prev, pos, member);           \
+         &pos->member != (head);                                        \
+         pos = tmp, tmp = __container_of(pos->member.prev, tmp, member))
+
+#ifdef __i386__
+static inline unsigned long __fls(unsigned long x)
+{
+        asm("bsr %1,%0"
+            : "=r" (x)
+            : "rm" (x));
+        return x;
+}
+#else
+static inline unsigned long __fls(unsigned long x)
+{
+   int n;
+
+   if (x == 0) return(0);
+   n = 0;
+   if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
+   if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
+   if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
+   if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
+   if (x <= 0x7FFFFFFF) {n = n + 1;}
+   return 31 - n;
+}
+#endif
+
+inline static int cache_wbucket(int size)
+{
+	int order = __fls(size / 256);
+	if (order >= CACHE_BUCKET_WCOUNT)
+		order = CACHE_BUCKET_WCOUNT - 1;
+	return order;
+}
+
+inline static int cache_hbucket(int size)
+{
+	int order = __fls(size / 256);
+	if (order >= CACHE_BUCKET_HCOUNT)
+		order = CACHE_BUCKET_HCOUNT - 1;
+	return order;
+}
+
+inline static int cache_format(GLenum format)
+{
+	switch (format) {
+#if 0
+	case GL_ALPHA:
+		return 1;
+#endif
+	case GL_RGBA:
+	default:
+		return 0;
+	}
+}
+
+glamor_pixmap_fbo *
+glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
+			    int w, int h, GLenum format, int flag)
+{
+	struct list *cache;
+	glamor_pixmap_fbo *fbo_entry;
+	int size;
+
+	cache = &glamor_priv->fbo_cache[cache_format(format)]
+				       [cache_wbucket(w)]
+				       [cache_hbucket(h)];
+	if (flag != GLAMOR_CACHE_EXACT_SIZE) {
+		list_for_each_entry(fbo_entry, cache, list) {
+			if (fbo_entry->width == w && fbo_entry->height == h) {
+
+				DEBUGF("Request w %d h %d \n", w, h);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+					fbo_entry, fbo_entry->width, fbo_entry->height,
+					fbo_entry->fb, fbo_entry->tex);
+				list_del(&fbo_entry->list);
+				return fbo_entry;
+			}
+		}
+	}
+	else {
+		list_for_each_entry(fbo_entry, cache, list) {
+			if (fbo_entry->width == w && fbo_entry->height == h) {
+
+				DEBUGF("Request w %d h %d \n", w, h);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+					fbo_entry, fbo_entry->width, fbo_entry->height,
+					fbo_entry->fb, fbo_entry->tex);
+				list_del(&fbo_entry->list);
+				return fbo_entry;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+void
+glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
+{
+	struct list *cache;
+
+	cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
+					    [cache_wbucket(fbo->width)]
+					    [cache_hbucket(fbo->height)];
+	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
+		fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
+	list_add(&fbo->list, cache);
+	fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+}
+
 glamor_pixmap_fbo *
 glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 		  int w, int h, int depth, GLint tex, int flag)
@@ -18,6 +144,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 	if (fbo == NULL)
 		return NULL;
 
+	list_init(&fbo->list);
 	gl_iformat_for_depth(depth, &format);
 
 	fbo->tex = tex;
@@ -31,13 +158,11 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
 	return fbo;
 }
 
-/* Make sure already detached from any pixmap. */
-void
-glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+static void
+glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
 	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
-
-	DEBUGF("Destroy fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
+	DEBUGF("Purge fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
 	if (fbo->fb)
 		dispatch->glDeleteFramebuffers(1, &fbo->fb);
 	if (fbo->tex)
@@ -48,6 +173,79 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
 	free(fbo);
 }
 
+void
+glamor_fbo_expire(glamor_screen_private *glamor_priv)
+{
+	struct list *cache;
+	glamor_pixmap_fbo *fbo_entry, *tmp;
+	int i,j,k;
+	int empty_cache = TRUE;
+
+	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
+		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
+				cache = &glamor_priv->fbo_cache[i][j][k];
+				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
+						empty_cache = FALSE;
+						break;
+					}
+					list_del(&fbo_entry->list);
+					DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
+						fbo_entry->expire, glamor_priv->tick);
+					glamor_purge_fbo(fbo_entry);
+				}
+			}
+
+}
+
+void
+glamor_init_pixmap_fbo(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	int i,j,k;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
+		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
+			{
+				list_init(&glamor_priv->fbo_cache[i][j][k]);
+			}
+}
+
+void
+glamor_fini_pixmap_fbo(ScreenPtr screen)
+{
+	struct list *cache;
+	glamor_screen_private *glamor_priv;
+	glamor_pixmap_fbo *fbo_entry, *tmp;
+	int i,j,k;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	for(i = 0; i < CACHE_FORMAT_COUNT; i++)
+		for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
+			for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
+			{
+				cache = &glamor_priv->fbo_cache[i][j][k];
+				list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
+					list_del(&fbo_entry->list);
+					glamor_purge_fbo(fbo_entry);
+				}
+
+			}
+}
+
+void
+glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+{
+	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+
+	list_del(&fbo->list);
+	glamor_pixmap_fbo_cache_put(fbo);
+
+}
+
 glamor_pixmap_fbo *
 glamor_create_fbo(glamor_screen_private *glamor_priv,
 		  int w, int h, int depth, int flag)
@@ -56,8 +254,19 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 	glamor_pixmap_fbo *fbo;
 	GLenum format;
 	GLint tex;
+	int cache_flag;
+
+	if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
+		cache_flag = GLAMOR_CACHE_EXACT_SIZE;
+	else
+		cache_flag = 0;
 
 	gl_iformat_for_depth(depth, &format);
+	fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
+					  format, GLAMOR_CACHE_EXACT_SIZE);
+	if (fbo)
+		return fbo;
+
 	dispatch = &glamor_priv->dispatch;
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
@@ -69,8 +278,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
 			       GL_UNSIGNED_BYTE, NULL);
 
 	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
-	DEBUGF("Creat fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
 
+	DEBUGF("Creat new fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
 	return fbo;
 }
 
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index da8097a..df97ad0 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -101,9 +101,8 @@ glamor_fill(DrawablePtr drawable,
 void
 glamor_init_solid_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
 	const char *solid_vs =
 	    "attribute vec4 v_position;"
 	    "void main()\n" "{\n" "       gl_Position = v_position;\n"
@@ -113,12 +112,12 @@ glamor_init_solid_shader(ScreenPtr screen)
 	    "void main()\n" "{\n" "	gl_FragColor = color;\n" "}\n";
 	GLint fs_prog, vs_prog;
 
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
 	glamor_priv->solid_prog = dispatch->glCreateProgram();
-	vs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
-	fs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-				     solid_fs);
+	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
+	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+					   solid_fs);
 	dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
 	dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
 
@@ -131,6 +130,17 @@ glamor_init_solid_shader(ScreenPtr screen)
 					   "color");
 }
 
+void
+glamor_fini_solid_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
+	dispatch->glDeleteProgram(glamor_priv->solid_prog);
+}
+
 Bool
 glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	     unsigned char alu, unsigned long planemask,
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index f8516b4..493c967 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -61,6 +61,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
 	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
+	INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
 	INIT_FUNC(dispatch, glCreateShader, get_proc_address);
 	INIT_FUNC(dispatch, glCompileShader, get_proc_address);
 	INIT_FUNC(dispatch, glAttachShader, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index a8a699b..024de26 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -97,6 +97,7 @@ typedef struct glamor_gl_dispatch {
 	void (*glUniform4fv) (GLint location, GLsizei count,
 			      const GLfloat * value);
 	 GLuint(*glCreateProgram) (void);
+	 GLuint(*glDeleteProgram) (GLuint);
 	 GLuint(*glCreateShader) (GLenum type);
 	void (*glCompileShader) (GLuint shader);
 	void (*glAttachShader) (GLuint program, GLuint shader);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 7c76496..f001962 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -63,12 +63,18 @@ glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
 void
 glamor_pixmap_init(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
+	glamor_screen_private *glamor_priv;
+
+	glamor_priv = glamor_get_screen_private(screen);
 	glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
 }
 
 void
+glamor_pixmap_fini(ScreenPtr screen)
+{
+}
+
+void
 glamor_validate_pixmap(PixmapPtr pixmap)
 {
 	glamor_pixmap_validate_function_t validate_op;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b4c3b74..31f9c93 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -159,18 +159,24 @@ struct glamor_saved_procs {
 	UnrealizeGlyphProcPtr unrealize_glyph;
 };
 
-#define CACHE_FORMAT_COUNT 2
-#define CACHE_BUCKET_WCOUNT 16
-#define CACHE_BUCKET_HCOUNT 16
+#define CACHE_FORMAT_COUNT 1
+#define CACHE_BUCKET_WCOUNT 4
+#define CACHE_BUCKET_HCOUNT 4
+
+#define GLAMOR_TICK_AFTER(t0, t1) 	\
+	(((int)(t1) - (int)(t0)) < 0)
 
 typedef struct glamor_screen_private {
 	struct glamor_gl_dispatch dispatch;
 	int yInverted;
+	unsigned int tick;
 	enum glamor_gl_flavor gl_flavor;
 	int has_pack_invert;
 	int has_fbo_blit;
 	int max_fbo_size;
 
+	struct list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
+
 	/* glamor_solid */
 	GLint solid_prog;
 	GLint solid_color_uniform_location;
@@ -207,6 +213,7 @@ typedef struct glamor_screen_private {
 	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
 	int delayed_fallback_pending;
 	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
+	int flags;
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -246,6 +253,8 @@ typedef union _glamor_pending_op {
  **/
 
 typedef struct glamor_pixmap_fbo {
+	struct list list;
+	unsigned int expire;
 	unsigned char pbo_valid;
 	GLuint tex;
 	GLuint fb;
@@ -321,8 +330,6 @@ extern int glamor_debug_level;
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
-Bool glamor_close_screen(int idx, ScreenPtr screen);
-
 PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 			       unsigned int usage);
 
@@ -336,15 +343,15 @@ glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
 				      int w, int h, int depth, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
 
+void glamor_init_pixmap_fbo(ScreenPtr screen);
+void glamor_fini_pixmap_fbo(ScreenPtr screen);
 Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
+void glamor_fbo_expire(glamor_screen_private *glamor_priv);
+void glamor_init_pixmap_fbo(ScreenPtr screen);
+void glamor_fini_pixmap_fbo(ScreenPtr screen);
 
 Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
 
-#define GLAMOR_CACHE_GET_DEFAULT    0
-#define GLAMOR_CACHE_GET_EAXCT_SIZE 1
-#define GLAMOR_CACHE_GET_UPLOAD	    2
-
-
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
@@ -366,6 +373,7 @@ void glamor_finish_access_window(WindowPtr window);
 Bool glamor_prepare_access_gc(GCPtr gc);
 void glamor_finish_access_gc(GCPtr gc);
 void glamor_init_finish_access_shaders(ScreenPtr screen);
+void glamor_fini_finish_access_shaders(ScreenPtr screen);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
 				int *x, int *y);
@@ -427,6 +435,7 @@ void glamor_fill_spans(DrawablePtr drawable,
 		       int n, DDXPointPtr points, int *widths, int sorted);
 
 void glamor_init_solid_shader(ScreenPtr screen);
+void glamor_fini_solid_shader(ScreenPtr screen);
 
 /* glamor_getspans.c */
 void
@@ -468,6 +477,7 @@ void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits);
 void glamor_init_putimage_shaders(ScreenPtr screen);
+void glamor_fini_putimage_shaders(ScreenPtr screen);
 
 /* glamor_render.c */
 void glamor_composite(CARD8 op,
@@ -484,6 +494,7 @@ void glamor_trapezoids(CARD8 op,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		       int ntrap, xTrapezoid * traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
+void glamor_fini_composite_shaders(ScreenPtr screen);
 void glamor_composite_glyph_rects(CARD8 op,
 				  PicturePtr src, PicturePtr mask,
 				  PicturePtr dst, int nrect,
@@ -501,6 +512,7 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 unsigned char alu, unsigned long planemask,
 		 int tile_x, int tile_y);
 void glamor_init_tile_shader(ScreenPtr screen);
+void glamor_fini_tile_shader(ScreenPtr screen);
 
 /* glamor_triangles.c */
 void
@@ -514,6 +526,7 @@ glamor_triangles(CARD8 op,
 /* glamor_pixmap.c */
 
 void glamor_pixmap_init(ScreenPtr screen);
+void glamor_pixmap_fini(ScreenPtr screen);
 /** 
  * Download a pixmap's texture to cpu memory. If success,
  * One copy of current pixmap's texture will be put into
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index f285d95..26d5cf7 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -239,6 +239,11 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 }
 #endif
 
+void
+glamor_fini_putimage_shaders(ScreenPtr screen)
+{
+}
+
 
 static Bool 
 _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 99b60c6..19ed22e 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -309,11 +309,12 @@ glamor_init_eb(unsigned short *eb, int vert_cnt)
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
 	unsigned short *eb;
 
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = &glamor_priv->dispatch;
 	dispatch->glGenBuffers(1, &glamor_priv->vbo);
 	dispatch->glGenBuffers(1, &glamor_priv->ebo);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
@@ -326,6 +327,34 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
 }
 
+
+
+void
+glamor_fini_composite_shaders(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+	glamor_composite_shader *shader;
+	int i,j,k;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch = &glamor_priv->dispatch;
+	dispatch->glDeleteBuffers(1, &glamor_priv->vbo);
+	dispatch->glDeleteBuffers(1, &glamor_priv->ebo);
+
+
+	for(i = 0; i < SHADER_SOURCE_COUNT; i++)
+		for(j = 0; j < SHADER_MASK_COUNT; j++)
+			for(k = 0; k < SHADER_IN_COUNT; k++)
+			{
+				shader = &glamor_priv->composite_shader[i][j][k];
+				if (shader->prog)
+					dispatch->glDeleteProgram(shader->prog);
+			}
+
+}
+
+
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
 			CARD8 op, PicturePtr dest, PicturePtr mask)
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 9dadf5e..7e0e6ac 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -39,9 +39,8 @@
 void
 glamor_init_tile_shader(ScreenPtr screen)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
 	const char *tile_vs =
 	    "attribute vec4 v_position;\n"
 	    "attribute vec4 v_texcoord0;\n"
@@ -60,12 +59,12 @@ glamor_init_tile_shader(ScreenPtr screen)
 	GLint fs_prog, vs_prog;
 	GLint sampler_uniform_location;
 
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
 	glamor_priv->tile_prog = dispatch->glCreateProgram();
-	vs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
-	fs_prog =
-	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
-				     tile_fs);
+	vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
+	fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+					   tile_fs);
 	dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
 	dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
 
@@ -84,6 +83,17 @@ glamor_init_tile_shader(ScreenPtr screen)
 	dispatch->glUseProgram(0);
 }
 
+void
+glamor_fini_tile_shader(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch =  &glamor_priv->dispatch;
+	dispatch->glDeleteProgram(glamor_priv->tile_prog);
+}
+
 Bool
 glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	    int x, int y, int width, int height,
commit 2ff41008494e6c5909c058f1f80b4f66617dada1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 18 19:21:36 2012 +0800

    glamor_fbo: Introduce glamor fbo to manage all the fb/tex.
    
    This is the first patch to implement a fbo/tex pool mechanism which
    is like the sna's BO cache list. We firstly need to decopule the
    fbo/tex from each pixmap. The new glamor_pixmap_fbo data
    structure is for that purpose. It's somehow independent to each
    pixmap and can be reused latter by other pixmaps once it's detached
    from the current pixmap.
    
    And this commit also slightly change the way to create a
    memory pixmap. We will not create a pixmap private data structure
    by default, instead we will crete that structure when a memory
    pixmap is attaching a fbo to it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 5c5f7e5..d6105d0 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -44,6 +44,7 @@ libglamor_la_SOURCES = \
 	glamor_picture.c\
 	glamor_window.c\
 	glamor_gl_dispatch.c\
+	glamor_fbo.c\
 	glamor.h
 
 sdk_HEADERS = glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6d7abd5..29f827c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -85,52 +85,41 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_fbo *fbo;
 
 	glamor_priv = glamor_get_screen_private(screen);
 	dispatch  = &glamor_priv->dispatch;
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	if (pixmap_priv == NULL) {
-		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
-		dixSetPrivate(&pixmap->devPrivates,
-			      glamor_pixmap_private_key, pixmap_priv);
-		pixmap_priv->container = pixmap;
-		pixmap_priv->glamor_priv = glamor_priv;
+	if (pixmap_priv->fbo) {
+		fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+		glamor_destroy_fbo(fbo);
 	}
 
-	if (pixmap_priv->fb)
-		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
-
-	if (pixmap_priv->tex)
-		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
+	fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
+					 pixmap->drawable.height,
+					 pixmap->drawable.depth, tex, 0);
 
-	pixmap_priv->tex = tex;
-
-	/* Create a framebuffer object wrapping the texture so that we can render
-	 * to it.
-	 */
-	pixmap_priv->gl_fbo = 1;
-	if (tex != 0) {
-		glamor_pixmap_ensure_fb(pixmap);
-		pixmap_priv->gl_tex = 1;
-	} else {
-		pixmap_priv->fb = 0;
-		pixmap_priv->gl_tex = 0;
+	if (fbo == NULL) {
+		ErrorF("XXX fail to create fbo.\n");
+		return;
 	}
 
-	pixmap->devPrivate.ptr = NULL;
+	glamor_pixmap_attach_fbo(pixmap, fbo);
 }
 
 void
 glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
 {
-	ScreenPtr screen = screen_pixmap->drawable.pScreen;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv;
 
-	glamor_priv = glamor_get_screen_private(screen);
+	glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
 	pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
-	glamor_priv->screen_fbo = pixmap_priv->fb;
+	glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
+
+	pixmap_priv->fbo->width = screen_pixmap->drawable.width;
+	pixmap_priv->fbo->height = screen_pixmap->drawable.height;
 }
 
 PixmapPtr
@@ -138,13 +127,15 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
 {
 	PixmapPtr pixmap;
-	GLenum format;
-	GLuint tex;
 	glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_pixmap_fbo *fbo;
+	int pitch;
+	int flag;
+
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
@@ -153,62 +144,53 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	    || usage == GLAMOR_CREATE_PIXMAP_CPU) {
 		/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
 		   If we exceed such limitation, we have to use framebuffer. */
-		type = GLAMOR_MEMORY;
-		pixmap = fbCreatePixmap(screen, w, h, depth, usage);
+		return fbCreatePixmap(screen, w, h, depth, usage);
 	} else
 		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
 
 	pixmap_priv = calloc(1, sizeof(*pixmap_priv));
-	dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key,
+
+	if (!pixmap_priv)
+		return fbCreatePixmap(screen, w, h, depth, usage);
+
+	dixSetPrivate(&pixmap->devPrivates,
+		      glamor_pixmap_private_key,
 		      pixmap_priv);
+
 	pixmap_priv->container = pixmap;
 	pixmap_priv->glamor_priv = glamor_priv;
-
 	pixmap_priv->type = type;
-	if (w == 0 || h == 0 || type == GLAMOR_MEMORY)
+
+	if (w == 0 || h == 0)
 		return pixmap;
 
-	gl_iformat_for_depth(depth, &format);
-	/* Create the texture used to store the pixmap's data. */
-	dispatch->glGenTextures(1, &tex);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
-			       GL_UNSIGNED_BYTE, NULL);
-
-	glamor_set_pixmap_texture(pixmap, tex);
-
-	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-				   (((w *
-				      pixmap->drawable.
-				      bitsPerPixel + 7) / 8) +
-				    3) & ~3, NULL);
+	fbo = glamor_create_fbo(glamor_priv, w, h, depth, 0);
+
+	if (fbo == NULL) {
+		fbDestroyPixmap(pixmap);
+		free(pixmap_priv);
+		return fbCreatePixmap(screen, w, h, depth, usage);
+	}
+
+	glamor_pixmap_attach_fbo(pixmap, fbo);
 
+	pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
+	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
 	return pixmap;
 }
 
 void
 glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	if (pixmap->refcnt == 1) {
-		glamor_pixmap_private *pixmap_priv =
-		    glamor_get_pixmap_private(pixmap);
+		glamor_pixmap_private *pixmap_priv;
+
+		pixmap_priv = glamor_get_pixmap_private(pixmap);
 		if (pixmap_priv != NULL) {
-			if (pixmap_priv->fb)
-				dispatch->glDeleteFramebuffers(1,
-							       &pixmap_priv->fb);
-			if (pixmap_priv->tex)
-				dispatch->glDeleteTextures(1,
-							   &pixmap_priv->tex);
-			if (pixmap_priv->pbo)
-				dispatch->glDeleteBuffers(1,
-							  &pixmap_priv->pbo);
+			glamor_pixmap_fbo *fbo;
+			fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+			if (fbo)
+				glamor_destroy_fbo(fbo);
 			free(pixmap_priv);
 		}
 	}
@@ -238,6 +220,7 @@ _glamor_block_handler(void *data, OSTimePtr timeout,
 {
 	glamor_gl_dispatch *dispatch = data;
 	dispatch->glFlush();
+	dispatch->glFinish();
 }
 
 static void
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 4310a04..a39c970 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -79,7 +79,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	glamor_validate_pixmap(dst_pixmap);
 
 	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
-				    src_pixmap_priv->fb);
+				    src_pixmap_priv->fbo->fb);
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
@@ -167,7 +167,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		goto fail;
 	}
 
-	if (!src_pixmap_priv->gl_fbo) {
+	if (!src_pixmap_priv || !src_pixmap_priv->gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
 		goto fail;
@@ -175,6 +175,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 		src_status = glamor_upload_pixmap_to_texture(src_pixmap);
 		if (src_status != GLAMOR_UPLOAD_DONE)
 			goto fail;
+
+		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 #endif
 	} else
 		flush_needed = 1;
@@ -199,8 +201,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 
-
-
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
@@ -216,7 +216,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 		dispatch->glActiveTexture(GL_TEXTURE0);
 		dispatch->glBindTexture(GL_TEXTURE_2D,
-					src_pixmap_priv->tex);
+					src_pixmap_priv->fbo->tex);
 #ifndef GLAMOR_GLES2
 		dispatch->glEnable(GL_TEXTURE_2D);
 #endif
@@ -333,7 +333,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
 				   &dst_y_off);
 
-	if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
+	if (src_pixmap_priv->fbo && src_pixmap_priv->fbo->fb == dst_pixmap_priv->fbo->fb) {
 		int x_shift = abs(src_x_off - dx - dst_x_off);
 		int y_shift = abs(src_y_off - dy - dst_y_off);
 		for (i = 0; i < nbox; i++) {
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 8ce2104..f6f9e83 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -49,7 +49,7 @@ glamor_get_drawable_location(const DrawablePtr drawable)
 	    glamor_get_screen_private(drawable->pScreen);
 	if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
 		return 'm';
-	if (pixmap_priv->fb == glamor_priv->screen_fbo)
+	if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
 		return 's';
 	else
 		return 'f';
@@ -271,13 +271,13 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 		glamor_restore_pixmap_to_texture(pixmap);
 	}
 
-	if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
+	if (pixmap_priv->fbo->pbo != 0 && pixmap_priv->fbo->pbo_valid) {
 		assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
 		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-		pixmap_priv->pbo_valid = FALSE;
-		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-		pixmap_priv->pbo = 0;
+		pixmap_priv->fbo->pbo_valid = FALSE;
+		dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
+		pixmap_priv->fbo->pbo = 0;
 	} else {
 		free(pixmap->devPrivate.ptr);
 	}
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index b101749..ac7e698 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -79,5 +79,8 @@ AbortServer(void)
 		     _glamor_priv_->delayed_fallback_string);		\
       _glamor_priv_->delayed_fallback_pending = 0;  } } while(0)
 
+#define DEBUGF(str, ...)
+//#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
+
 
 #endif
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
new file mode 100644
index 0000000..068d877
--- /dev/null
+++ b/glamor/glamor_fbo.c
@@ -0,0 +1,132 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+
+glamor_pixmap_fbo *
+glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+		  int w, int h, int depth, GLint tex, int flag)
+{
+	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_fbo *fbo;
+	GLenum format;
+
+	fbo = calloc(1, sizeof(*fbo));
+	if (fbo == NULL)
+		return NULL;
+
+	gl_iformat_for_depth(depth, &format);
+
+	fbo->tex = tex;
+	fbo->width = w;
+	fbo->height = h;
+	fbo->format = format;
+	fbo->glamor_priv = glamor_priv;
+
+	glamor_pixmap_ensure_fb(fbo);
+
+	return fbo;
+}
+
+/* Make sure already detached from any pixmap. */
+void
+glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+{
+	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+
+	DEBUGF("Destroy fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
+	if (fbo->fb)
+		dispatch->glDeleteFramebuffers(1, &fbo->fb);
+	if (fbo->tex)
+		dispatch->glDeleteTextures(1, &fbo->tex);
+	if (fbo->pbo)
+		dispatch->glDeleteBuffers(1, &fbo->pbo);
+
+	free(fbo);
+}
+
+glamor_pixmap_fbo *
+glamor_create_fbo(glamor_screen_private *glamor_priv,
+		  int w, int h, int depth, int flag)
+{
+	glamor_gl_dispatch *dispatch;
+	glamor_pixmap_fbo *fbo;
+	GLenum format;
+	GLint tex;
+
+	gl_iformat_for_depth(depth, &format);
+	dispatch = &glamor_priv->dispatch;
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
+			       GL_UNSIGNED_BYTE, NULL);
+
+	fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
+	DEBUGF("Creat fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
+
+	return fbo;
+}
+
+glamor_pixmap_fbo *
+glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
+{
+	glamor_pixmap_fbo *fbo;
+
+	if (pixmap_priv == NULL)
+		return NULL;
+
+	fbo = pixmap_priv->fbo;
+	if (fbo == NULL)
+		return NULL;
+
+	pixmap_priv->fbo = NULL;
+	return fbo;
+}
+
+/* The pixmap must not be attached to another fbo. */
+void
+glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
+{
+	glamor_pixmap_private *pixmap_priv;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (pixmap_priv == NULL) {
+		glamor_screen_private *glamor_priv;
+		glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+		pixmap_priv = calloc(1, sizeof(*pixmap_priv));
+		dixSetPrivate(&pixmap->devPrivates,
+			      glamor_pixmap_private_key, pixmap_priv);
+		pixmap_priv->container = pixmap;
+		pixmap_priv->glamor_priv = glamor_priv;
+		pixmap_priv->type = GLAMOR_MEMORY;
+	}
+
+	if (pixmap_priv->fbo)
+		return;
+
+	pixmap_priv->fbo = fbo;
+
+	switch (pixmap_priv->type) {
+	case GLAMOR_TEXTURE_ONLY:
+	case GLAMOR_TEXTURE_DRM:
+		pixmap_priv->gl_fbo = 1;
+		if (fbo->tex != 0)
+			pixmap_priv->gl_tex = 1;
+		else {
+			/* XXX For the Xephyr only, may be broken now.*/
+			pixmap_priv->gl_tex = 0;
+		}
+		pixmap->devPrivate.ptr = NULL;
+		break;
+	default:
+		break;
+	}
+}
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 3ed3c51..7c76496 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -89,7 +89,7 @@ void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
 	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fbo->fb);
 #ifndef GLAMOR_GLES2
 	dispatch->glMatrixMode(GL_PROJECTION);
 	dispatch->glLoadIdentity();
@@ -97,8 +97,8 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 	dispatch->glLoadIdentity();
 #endif
 	dispatch->glViewport(0, 0,
-			     pixmap_priv->container->drawable.width,
-			     pixmap_priv->container->drawable.height);
+			     pixmap_priv->fbo->width,
+			     pixmap_priv->fbo->height);
 
 }
 
@@ -242,10 +242,10 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 	}
 
-	if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
+	if (pixmap_priv->fbo->pbo && pixmap_priv->fbo->pbo_valid) {
 		texels = NULL;
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-				       pixmap_priv->pbo);
+				       pixmap_priv->fbo->pbo);
 	} else
 		texels = pixmap->devPrivate.ptr;
 
@@ -309,7 +309,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	 * to the fbo directly. */
 	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
 		__glamor_upload_pixmap_to_texture(pixmap, format, type,
-						  pixmap_priv->tex);
+						  pixmap_priv->fbo->tex);
 		return;
 	}
 
@@ -363,19 +363,18 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 }
 
 void
-glamor_pixmap_ensure_fb(PixmapPtr pixmap)
+glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
 	int status;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-	if (pixmap_priv->fb == 0)
-		dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
-	assert(pixmap_priv->tex != 0);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
+
+	if (fbo->fb == 0)
+		dispatch->glGenFramebuffers(1, &fbo->fb);
+	assert(fbo->tex != 0);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
 	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
 					 GL_COLOR_ATTACHMENT0,
-					 GL_TEXTURE_2D, pixmap_priv->tex,
+					 GL_TEXTURE_2D, fbo->tex,
 					 0);
 	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
 	if (status != GL_FRAMEBUFFER_COMPLETE) {
@@ -422,11 +421,13 @@ static int
 glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 {
 	int need_fbo;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv;
+	GLenum format;
+	glamor_pixmap_fbo *fbo;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
 	if (!glamor_check_fbo_size
 	    (glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
@@ -441,28 +442,14 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return 0;
 
-	if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
-		need_fbo = 1;
-	else
-		need_fbo = 0;
-
-	if (pixmap_priv->tex == 0)
-		dispatch->glGenTextures(1, &pixmap_priv->tex);
-
-	if (need_fbo) {
-		dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height, 0, GL_RGBA,
-				       GL_UNSIGNED_BYTE, NULL);
-		glamor_pixmap_ensure_fb(pixmap);
-	}
+	fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
+				pixmap->drawable.height,
+				pixmap->drawable.depth,
+				0);
+	if (fbo == NULL)
+		return -1;
+
+	glamor_pixmap_attach_fbo(pixmap, fbo);
 
 	return 0;
 }
@@ -575,7 +562,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 
 	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
-	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
 				  GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
@@ -599,7 +586,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
 	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
 	dispatch->glTexParameteri(GL_TEXTURE_2D,
 				  GL_TEXTURE_MIN_FILTER,
 				  GL_NEAREST);
@@ -726,11 +713,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		}
 
 		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-			if (pixmap_priv->pbo == 0)
+			if (pixmap_priv->fbo->pbo == 0)
 				dispatch->glGenBuffers(1,
-						       &pixmap_priv->pbo);
+						       &pixmap_priv->fbo->pbo);
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->pbo);
+					       pixmap_priv->fbo->pbo);
 			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
 					       stride *
 					       pixmap->drawable.height,
@@ -740,7 +727,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 					       format, type, 0);
 			data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
 						     gl_access);
-			pixmap_priv->pbo_valid = TRUE;
+			pixmap_priv->fbo->pbo_valid = TRUE;
 
 			if (!glamor_priv->yInverted) {
 				assert(glamor_priv->gl_flavor ==
@@ -762,11 +749,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		data = malloc(stride * pixmap->drawable.height);
 		assert(data);
 		if (access != GLAMOR_ACCESS_WO) {
-			if (pixmap_priv->pbo == 0)
+			if (pixmap_priv->fbo->pbo == 0)
 				dispatch->glGenBuffers(1,
-						       &pixmap_priv->pbo);
+						       &pixmap_priv->fbo->pbo);
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->pbo);
+					       pixmap_priv->fbo->pbo);
 			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
 					       stride *
 					       pixmap->drawable.height,
@@ -783,9 +770,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 					       y - 1) * stride, stride);
 			dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
 			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-			pixmap_priv->pbo_valid = FALSE;
-			dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-			pixmap_priv->pbo = 0;
+			pixmap_priv->fbo->pbo_valid = FALSE;
+			dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
+			pixmap_priv->fbo->pbo = 0;
 		}
 	}
 
@@ -798,29 +785,3 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	return TRUE;
 }
-
-
-
-static void
-_glamor_destroy_upload_pixmap(PixmapPtr pixmap)
-{
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
-	assert(pixmap_priv->gl_fbo == 0);
-	if (pixmap_priv->fb)
-		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
-	if (pixmap_priv->tex)
-		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
-	if (pixmap_priv->pbo)
-		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-	pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
-
-}
-
-void
-glamor_destroy_upload_pixmap(PixmapPtr pixmap)
-{
-	_glamor_destroy_upload_pixmap(pixmap);
-}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 90ed6bb..b4c3b74 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -59,6 +59,8 @@
 
 #include "glamor_debug.h"
 
+#include <list.h>
+
 typedef struct glamor_composite_shader {
 	GLuint prog;
 	GLint dest_to_dest_uniform_location;
@@ -123,6 +125,7 @@ enum glamor_gl_flavor {
 };
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
+#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
 
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
@@ -156,6 +159,10 @@ struct glamor_saved_procs {
 	UnrealizeGlyphProcPtr unrealize_glyph;
 };
 
+#define CACHE_FORMAT_COUNT 2
+#define CACHE_BUCKET_WCOUNT 16
+#define CACHE_BUCKET_HCOUNT 16
+
 typedef struct glamor_screen_private {
 	struct glamor_gl_dispatch dispatch;
 	int yInverted;
@@ -238,15 +245,25 @@ typedef union _glamor_pending_op {
  * @container: The corresponding pixmap's pointer.
  **/
 
-typedef struct glamor_pixmap_private {
-	glamor_pixmap_type_t type;
-	unsigned char gl_fbo:1;
-	unsigned char gl_tex:1;
-	unsigned char pbo_valid:1;
-	unsigned char is_picture:1;
+typedef struct glamor_pixmap_fbo {
+	unsigned char pbo_valid;
 	GLuint tex;
 	GLuint fb;
 	GLuint pbo;
+	int width;
+	int height;
+	GLenum format;
+	GLenum type;
+	glamor_screen_private *glamor_priv;
+} glamor_pixmap_fbo;
+
+
+typedef struct glamor_pixmap_private {
+	unsigned char gl_fbo:1;
+	unsigned char is_picture:1;
+	unsigned char gl_tex:1;
+	glamor_pixmap_type_t type;
+	glamor_pixmap_fbo *fbo;
 	PictFormatShort pict_format;
 	glamor_pending_op pending_op;
 	PixmapPtr container;
@@ -311,6 +328,23 @@ PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 
+glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
+void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
+glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
+					       int w, int h, int depth, GLint tex, int flag);
+glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
+				      int w, int h, int depth, int flag);
+void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
+
+Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
+
+Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
+
+#define GLAMOR_CACHE_GET_DEFAULT    0
+#define GLAMOR_CACHE_GET_EAXCT_SIZE 1
+#define GLAMOR_CACHE_GET_UPLOAD	    2
+
+
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
@@ -503,14 +537,14 @@ Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
  **/
 void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
 /**
- * Ensure to have a fbo attached to the pixmap. 
- * If the pixmap already has one fbo then do nothing.
- * Otherwise, it will generate a new fbo, and bind
- * the pixmap's texture to the fbo. 
- * The pixmap must has a valid texture before call this
+ * Ensure to have a fbo has a valid/complete glfbo.
+ * If the fbo already has a valid glfbo then do nothing.
+ * Otherwise, it will generate a new glfbo, and bind
+ * the fbo's texture to the glfbo.
+ * The fbo must has a valid texture before call this
  * API, othersie, it will trigger a assert.
  */
-void glamor_pixmap_ensure_fb(PixmapPtr pixmap);
+void glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6a7057a..99b60c6 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -388,7 +388,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
-	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
 	switch (picture->repeatType) {
 	case RepeatNone:
 #ifndef GLAMOR_GLES2
@@ -923,18 +923,16 @@ glamor_composite_with_shader(CARD8 op,
 
 			mask_status = GLAMOR_NONE;
 		}
-		source_status = glamor_upload_picture_to_texture(source);
 
+		source_status = glamor_upload_picture_to_texture(source);
 		if (source_status != GLAMOR_UPLOAD_DONE) {
 			glamor_fallback
 			    ("Failed to upload source texture.\n");
 			goto fail;
 		}
 	} else {
-
 		if (source_status == GLAMOR_UPLOAD_PENDING) {
-			source_status =
-			    glamor_upload_picture_to_texture(source);
+			source_status = glamor_upload_picture_to_texture(source);
 			if (source_status != GLAMOR_UPLOAD_DONE) {
 				glamor_fallback
 				    ("Failed to upload source texture.\n");
@@ -943,9 +941,7 @@ glamor_composite_with_shader(CARD8 op,
 		}
 
 		if (mask_status == GLAMOR_UPLOAD_PENDING) {
-			mask_status =
-			    glamor_upload_picture_to_texture(mask);
-
+			mask_status = glamor_upload_picture_to_texture(mask);
 			if (mask_status != GLAMOR_UPLOAD_DONE) {
 				glamor_fallback
 				    ("Failed to upload mask texture.\n");
@@ -1208,22 +1204,14 @@ _glamor_composite(CARD8 op,
 	if (source->pDrawable) {
 		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		if (!source_pixmap_priv) {
-			glamor_set_pixmap_type(source_pixmap, GLAMOR_MEMORY);
-			source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-		}
-		if (source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+		if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
 			goto fail;
 	}
 
 	if (mask && mask->pDrawable) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		if (!mask_pixmap_priv) {
-			glamor_set_pixmap_type(mask_pixmap, GLAMOR_MEMORY);
-			mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		}
-		if (mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+		if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
 			goto fail;
 	}
 	if ((!source->pDrawable
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index f5a6e75..9dadf5e 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -156,7 +156,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
 		dispatch->glActiveTexture(GL_TEXTURE0);
 		dispatch->glBindTexture(GL_TEXTURE_2D,
-					src_pixmap_priv->tex);
+					src_pixmap_priv->fbo->tex);
 		dispatch->glTexParameteri(GL_TEXTURE_2D,
 					  GL_TEXTURE_MIN_FILTER,
 					  GL_NEAREST);
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 491a1ca..c7d1c29 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -13,12 +13,11 @@
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
-  do {									\
-    *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width;	\
-    *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height;	\
+   do {									\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
   } while(0)
 
-
 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
 			      + ((float)xFixedFrac(_val_) / 65536.0))
 
commit ca2ddd33a114fe83584b5fa9f73b7534abdb96fa
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 18 17:12:32 2012 +0800

    glamor_set_pixmap_texture/screen_pixmap: Remove useless parameters.
    
    As after we got a texture, no matter the texture is created
    on the glamor_create_pixmap or on the egl layer, we all already
    know the texture's width and height there. We don't need
    to pass them in.
    
    This commit also simply the glamor_egl_create_textured_screen to
    reuse the egl_create_textured_pixmap. And also remove the useless
    root image from the egl private structure. As now the root image
    is bound to the screen image, we don't take care it separately
    here. It will be freed at the screen closing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 74c23c6..6d7abd5 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -78,17 +78,18 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
 	pixmap_priv->type = type;
 }
 
-
 _X_EXPORT void
-glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
+glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	glamor_screen_private *glamor_priv;
+	glamor_gl_dispatch *dispatch;
 
+	glamor_priv = glamor_get_screen_private(screen);
+	dispatch  = &glamor_priv->dispatch;
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
 	if (pixmap_priv == NULL) {
 		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
 		dixSetPrivate(&pixmap->devPrivates,
@@ -117,27 +118,18 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 		pixmap_priv->gl_tex = 0;
 	}
 
-	if (pixmap->devKind == 0)
-		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-					   (((w *
-					      pixmap->drawable.
-					      bitsPerPixel + 7) / 8) +
-					    3) & ~3, NULL);
 	pixmap->devPrivate.ptr = NULL;
 }
 
-/* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */
 void
-glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h,
-				 unsigned int tex)
+glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
 {
-	PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+	ScreenPtr screen = screen_pixmap->drawable.pScreen;
 	glamor_pixmap_private *pixmap_priv;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
+	glamor_screen_private *glamor_priv;
 
-	glamor_set_pixmap_texture(pixmap, w, h, tex);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	glamor_priv = glamor_get_screen_private(screen);
+	pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
 	glamor_priv->screen_fbo = pixmap_priv->fb;
 }
 
@@ -187,7 +179,13 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
 			       GL_UNSIGNED_BYTE, NULL);
 
-	glamor_set_pixmap_texture(pixmap, w, h, tex);
+	glamor_set_pixmap_texture(pixmap, tex);
+
+	screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+				   (((w *
+				      pixmap->drawable.
+				      bitsPerPixel + 7) / 8) +
+				    3) & ~3, NULL);
 
 	return pixmap;
 }
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 1119e37..51061f3 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -102,9 +102,12 @@ typedef enum  glamor_pixmap_type {
  */
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
-extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
-						       int w, int h,
-						       unsigned int tex);
+
+/* Let glamor to know the screen's fbo. The low level
+ * driver should already assign a tex
+ * to this pixmap through the set_pixmap_texture. */
+extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap);
+
 /* @glamor_glyphs_init: Initialize glyphs internal data structures.
  *
  * @pScreen: Current screen pointer.
@@ -115,7 +118,7 @@ extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
  */
 extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
 
-extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
+extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
 						unsigned int tex);
 
 extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 28a48ca..1b57b46 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -59,10 +59,6 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#define GLAMOR_VERSION_MAJOR 0
-#define GLAMOR_VERSION_MINOR 1
-#define GLAMOR_VERSION_PATCH 0
-
 #include "glamor.h"
 #include "glamor_gl_dispatch.h"
 
@@ -169,40 +165,22 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
 	return TRUE;
 }
 
-
 Bool
 glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
-	EGLImageKHR image;
-	GLuint texture;
-
-	if (!glamor_get_flink_name
-	    (glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Couldn't flink front buffer handle\n");
-		return FALSE;
-	}
+	struct glamor_egl_screen_private *glamor_egl;
+	PixmapPtr	screen_pixmap;
 
-	if (glamor_egl->root) {
-		eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
-		glamor_egl->root = EGL_NO_IMAGE_KHR;
-	}
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+	screen_pixmap = screen->GetScreenPixmap(screen);
 
-	image = _glamor_egl_create_image(glamor_egl,
-					 scrn->virtualX,
-					 scrn->virtualY,
-					 stride / 4,
-					 glamor_egl->front_buffer_handle, 32);
-	if (image == EGL_NO_IMAGE_KHR)
+	if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create textured screen.");
 		return FALSE;
+	}
 
-	glamor_create_texture_from_image(glamor_egl, image, &texture);
-	glamor_set_screen_pixmap_texture(screen, scrn->virtualX,
-					 scrn->virtualY, texture);
-	glamor_egl->root = image;
+	glamor_set_screen_pixmap(screen_pixmap);
 	return TRUE;
 }
 
@@ -211,12 +189,13 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl =
-	    glamor_egl_get_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl;
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
 
+	glamor_egl = glamor_egl_get_screen_private(scrn);
+
 	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Couldn't flink pixmap handle\n");
@@ -234,8 +213,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 
 	glamor_create_texture_from_image(glamor_egl, image, &texture);
 	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
-	glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
-				  pixmap->drawable.height, texture);
+	glamor_set_pixmap_texture(pixmap, texture);
 	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
 		      image);
 
commit 15166bba973206dcb98121eb3932660529cfc997
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 18 17:10:26 2012 +0800

    Add debug message for all the uploading path.
    
    The previous message missed the texture restoring path.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f43a90b..3ed3c51 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -298,6 +298,13 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 		return;
 	need_flip = (flip && !glamor_priv->yInverted);
 
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
+			    "Uploading pixmap %p  %dx%d depth%d.\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+
 	/* Try fast path firstly, upload the pixmap to the texture attached
 	 * to the fbo directly. */
 	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
@@ -476,12 +483,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 	}
 	if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
 		return GLAMOR_UPLOAD_FAILED;
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
-			    "Uploading pixmap %p  %dx%d depth%d.\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
 	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
 					 no_revert, 1);
 	return GLAMOR_UPLOAD_DONE;
commit 994a9ff7f58161bf5651f83d810eb77b7718ab00
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 18 17:07:25 2012 +0800

    glamor_create_picture: Fix the format matching method.
    
    We should not simply set a TEXTURE_DRM pixmap to a separated
    texture pixmap. If the format is compatible with current fbo
    then it is just fine to keep it as TEXTURE_DRM type and we
    can safely fallback to DDX layer on it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index a9e3c26..6904dab 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -65,15 +65,21 @@ glamor_create_picture(PicturePtr picture)
  	 * the uploading, we need to know the picture format. */
 		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
 		pixmap_priv = glamor_get_pixmap_private(pixmap);
+	} else {
+		if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+			/* If the picture format is not compatible with glamor fbo format,
+			 * we have to mark this pixmap as a separated texture, and don't
+			 * fallback to DDX layer. */
+			if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
+			    && !glamor_pict_format_is_compatible(picture->format,
+								 pixmap->drawable.depth))
+				glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
+		}
 	}
-	
-	if (pixmap_priv) {
-		pixmap_priv->is_picture = 1;
-		pixmap_priv->pict_format = picture->format;
-		/* XXX Some formats are compatible between glamor and ddx driver*/
-		if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
-			glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
-	}
+
+	pixmap_priv->is_picture = 1;
+	pixmap_priv->pict_format = picture->format;
+
 	return miCreatePicture(picture);
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 49c7e1d..491a1ca 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -232,18 +232,16 @@ gl_iformat_for_depth(int depth, GLenum * format)
 	case 8:
 		*format = GL_ALPHA;
 		break;
-#endif
 	case 24:
 		*format = GL_RGB;
 		break;
+#endif
 	default:
 		*format = GL_RGBA;
 		break;
        }
 }
 
-
-
 static inline CARD32
 format_for_pixmap(PixmapPtr pixmap)
 {
@@ -561,6 +559,21 @@ glamor_get_rgba_from_pixel(CARD32 pixel,
 	return TRUE;
 }
 
+inline static Bool glamor_pict_format_is_compatible(PictFormatShort pict_format, int depth)
+{
+	GLenum iformat;
+
+	gl_iformat_for_depth(depth, &iformat);
+	switch (iformat) {
+		case GL_RGBA:
+			return (pict_format == PICT_a8r8g8b8 || pict_format == PICT_x8r8g8b8);
+		case GL_ALPHA:
+			return (pict_format == PICT_a8);
+		default:
+			return FALSE;
+	}
+}
+
 /* return TRUE if we can access this pixmap at DDX driver. */
 inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
 {
commit 28fcd7cd01edfdf68c370e6c6ad0238d45477b3f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jan 13 11:18:28 2012 +0800

    Rearrange data structure and remove unused fileds.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 8f74daa..74c23c6 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -343,60 +343,60 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 			goto fail;
 		}
 
-		glamor_priv->saved_close_screen = screen->CloseScreen;
+		glamor_priv->saved_procs.close_screen = screen->CloseScreen;
 		screen->CloseScreen = glamor_close_screen;
 
-		glamor_priv->saved_create_gc = screen->CreateGC;
+		glamor_priv->saved_procs.create_gc = screen->CreateGC;
 		screen->CreateGC = glamor_create_gc;
 
-		glamor_priv->saved_create_pixmap = screen->CreatePixmap;
+		glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
 		screen->CreatePixmap = glamor_create_pixmap;
 
-		glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
+		glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
 		screen->DestroyPixmap = glamor_destroy_pixmap;
 
-		glamor_priv->saved_get_spans = screen->GetSpans;
+		glamor_priv->saved_procs.get_spans = screen->GetSpans;
 		screen->GetSpans = glamor_get_spans;
 
-		glamor_priv->saved_get_image = screen->GetImage;
+		glamor_priv->saved_procs.get_image = screen->GetImage;
 		screen->GetImage = glamor_get_image;
 
-		glamor_priv->saved_change_window_attributes =
+		glamor_priv->saved_procs.change_window_attributes =
 		    screen->ChangeWindowAttributes;
 		screen->ChangeWindowAttributes =
 		    glamor_change_window_attributes;
 
-		glamor_priv->saved_copy_window = screen->CopyWindow;
+		glamor_priv->saved_procs.copy_window = screen->CopyWindow;
 		screen->CopyWindow = glamor_copy_window;
 
-		glamor_priv->saved_bitmap_to_region =
+		glamor_priv->saved_procs.bitmap_to_region =
 		    screen->BitmapToRegion;
 		screen->BitmapToRegion = glamor_bitmap_to_region;
 	}
 #ifdef RENDER
 	if (flags & GLAMOR_USE_PICTURE_SCREEN) {
-		glamor_priv->saved_composite = ps->Composite;
+		glamor_priv->saved_procs.composite = ps->Composite;
 		ps->Composite = glamor_composite;
 
-		glamor_priv->saved_trapezoids = ps->Trapezoids;
+		glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
 		ps->Trapezoids = glamor_trapezoids;
 
-		glamor_priv->saved_glyphs = ps->Glyphs;
+		glamor_priv->saved_procs.glyphs = ps->Glyphs;
 		ps->Glyphs = glamor_glyphs;
 
-		glamor_priv->saved_triangles = ps->Triangles;
+		glamor_priv->saved_procs.triangles = ps->Triangles;
 		ps->Triangles = glamor_triangles;
 
-		glamor_priv->saved_addtraps = ps->AddTraps;
+		glamor_priv->saved_procs.addtraps = ps->AddTraps;
 		ps->AddTraps = glamor_add_traps;
 
-		glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
+		glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
 		ps->UnrealizeGlyph = glamor_glyph_unrealize;
 	}
-	glamor_priv->saved_create_picture = ps->CreatePicture;
+	glamor_priv->saved_procs.create_picture = ps->CreatePicture;
 	ps->CreatePicture = glamor_create_picture;
 
-	glamor_priv->saved_destroy_picture = ps->DestroyPicture;
+	glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
 	ps->DestroyPicture = glamor_destroy_picture;
 	glamor_init_composite_shaders(screen);
 #endif
@@ -430,22 +430,22 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
 	glamor_glyphs_fini(screen);
-	screen->CloseScreen = glamor_priv->saved_close_screen;
-	screen->CreateGC = glamor_priv->saved_create_gc;
-	screen->CreatePixmap = glamor_priv->saved_create_pixmap;
-	screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
-	screen->GetSpans = glamor_priv->saved_get_spans;
+	screen->CloseScreen = glamor_priv->saved_procs.close_screen;
+	screen->CreateGC = glamor_priv->saved_procs.create_gc;
+	screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+	screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+	screen->GetSpans = glamor_priv->saved_procs.get_spans;
 	screen->ChangeWindowAttributes =
-	    glamor_priv->saved_change_window_attributes;
-	screen->CopyWindow = glamor_priv->saved_copy_window;
-	screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
+	    glamor_priv->saved_procs.change_window_attributes;
+	screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+	screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
 #ifdef RENDER
 	if (ps) {
-		ps->Composite = glamor_priv->saved_composite;
-		ps->Trapezoids = glamor_priv->saved_trapezoids;
-		ps->Glyphs = glamor_priv->saved_glyphs;
-		ps->Triangles = glamor_priv->saved_triangles;
-		ps->CreatePicture = glamor_priv->saved_create_picture;
+		ps->Composite = glamor_priv->saved_procs.composite;
+		ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
+		ps->Glyphs = glamor_priv->saved_procs.glyphs;
+		ps->Triangles = glamor_priv->saved_procs.triangles;
+		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
 	}
 #endif
 	if (glamor_priv->vb)
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 27c3fe8..a9e3c26 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -4,6 +4,7 @@
 
 #include <stdlib.h>
 
+#include "mipict.h"
 #include "glamor_priv.h"
 
 /* Upload picture to texture.  We may need to flip the y axis or
@@ -73,7 +74,7 @@ glamor_create_picture(PicturePtr picture)
 		if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
 			glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
 	}
-	return glamor_priv->saved_create_picture(picture);
+	return miCreatePicture(picture);
 }
 
 void
@@ -95,7 +96,7 @@ glamor_destroy_picture(PicturePtr picture)
 		pixmap_priv->is_picture = 0;
 		pixmap_priv->pict_format = 0;
 	}
-	glamor_priv->saved_destroy_picture(picture);
+	miDestroyPicture(picture);
 }
 
 void
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f3b0996..90ed6bb 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -124,7 +124,6 @@ enum glamor_gl_flavor {
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
 
-#define GLAMOR_NUM_GLYPH_CACHES 4
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
 typedef struct {
@@ -137,46 +136,57 @@ typedef struct {
 
 #include "glamor_gl_dispatch.h"
 
-typedef struct glamor_screen_private {
-	CloseScreenProcPtr saved_close_screen;
-	CreateGCProcPtr saved_create_gc;
-	CreatePixmapProcPtr saved_create_pixmap;
-	DestroyPixmapProcPtr saved_destroy_pixmap;
-	GetSpansProcPtr saved_get_spans;
-	GetImageProcPtr saved_get_image;
-	CompositeProcPtr saved_composite;
-	TrapezoidsProcPtr saved_trapezoids;
-	GlyphsProcPtr saved_glyphs;
-	ChangeWindowAttributesProcPtr saved_change_window_attributes;
-	CopyWindowProcPtr saved_copy_window;
-	BitmapToRegionProcPtr saved_bitmap_to_region;
-	TrianglesProcPtr saved_triangles;
-	AddTrapsProcPtr saved_addtraps;
-	CreatePictureProcPtr saved_create_picture;
-	DestroyPictureProcPtr saved_destroy_picture;
-	UnrealizeGlyphProcPtr saved_unrealize_glyph;
+struct glamor_saved_procs { 
+	CloseScreenProcPtr close_screen;
+	CreateGCProcPtr create_gc;
+	CreatePixmapProcPtr create_pixmap;
+	DestroyPixmapProcPtr destroy_pixmap;
+	GetSpansProcPtr get_spans;
+	GetImageProcPtr get_image;
+	CompositeProcPtr composite;
+	TrapezoidsProcPtr trapezoids;
+	GlyphsProcPtr glyphs;
+	ChangeWindowAttributesProcPtr change_window_attributes;
+	CopyWindowProcPtr copy_window;
+	BitmapToRegionProcPtr bitmap_to_region;
+	TrianglesProcPtr triangles;
+	AddTrapsProcPtr addtraps;
+	CreatePictureProcPtr create_picture;
+	DestroyPictureProcPtr destroy_picture;
+	UnrealizeGlyphProcPtr unrealize_glyph;
+};
 
+typedef struct glamor_screen_private {
+	struct glamor_gl_dispatch dispatch;
 	int yInverted;
-	int screen_fbo;
+	enum glamor_gl_flavor gl_flavor;
+	int has_pack_invert;
+	int has_fbo_blit;
+	int max_fbo_size;
+
+	/* glamor_solid */
+	GLint solid_prog;
+	GLint solid_color_uniform_location;
+
+	/* vertext/elment_index buffer object for render */
 	GLuint vbo, ebo;
 	int vbo_offset;
 	int vbo_size;
 	char *vb;
 	int vb_stride;
-	enum glamor_gl_flavor gl_flavor;
-	int has_pack_invert;
-	int has_fbo_blit;
-	int max_fbo_size;
+	Bool has_source_coords, has_mask_coords;
+	int render_nr_verts;
+	glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+						[SHADER_MASK_COUNT]
+						[SHADER_IN_COUNT];
+	glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
+	Bool glyph_cache_initialized;
 
-	/* glamor_finishaccess */
+	/* shaders to restore a texture to another texture.*/
 	GLint finish_access_prog[2];
 	GLint finish_access_no_revert[2];
 	GLint finish_access_swap_rb[2];
 
-	/* glamor_solid */
-	GLint solid_prog;
-	GLint solid_color_uniform_location;
-
 	/* glamor_tile */
 	GLint tile_prog;
 
@@ -185,19 +195,11 @@ typedef struct glamor_screen_private {
 	GLint put_image_xybitmap_fg_uniform_location;
 	GLint put_image_xybitmap_bg_uniform_location;
 
-	/* glamor_composite */
-	glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
-	    [SHADER_MASK_COUNT][SHADER_IN_COUNT];
-	Bool has_source_coords, has_mask_coords;
-	int render_nr_verts;
-	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
-	glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
+	int screen_fbo;
+	struct glamor_saved_procs saved_procs;
 	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
 	int delayed_fallback_pending;
-
-	glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
-	Bool glyph_cache_initialized;
-	struct glamor_gl_dispatch dispatch;
+	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -236,7 +238,6 @@ typedef union _glamor_pending_op {
  * @container: The corresponding pixmap's pointer.
  **/
 
-
 typedef struct glamor_pixmap_private {
 	glamor_pixmap_type_t type;
 	unsigned char gl_fbo:1;
commit bdd72da0c525faf2aac38a7a8afa1cd88cd8dc1b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jan 10 17:04:48 2012 +0800

    Release previous textre/fb when bind a new texture to a pixmap.
    
    As we want to support DRI2 drawable which may create a new textured_drm
    to a pre-existing texture_only pixmap, we have to add this logical.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Tested-by: He Junyan<junyan.he at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6ee11f7..8f74daa 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -86,6 +86,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
 	if (pixmap_priv == NULL) {
@@ -96,6 +97,12 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 		pixmap_priv->glamor_priv = glamor_priv;
 	}
 
+	if (pixmap_priv->fb)
+		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
+
+	if (pixmap_priv->tex)
+		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
+
 	pixmap_priv->tex = tex;
 
 	/* Create a framebuffer object wrapping the texture so that we can render
commit d7352d57b9ceb809d47c922ed8c820a44f8a0ee5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jan 10 15:24:36 2012 +0800

    Add glFinish after glFlush.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 3634e70..6ee11f7 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -224,6 +224,7 @@ glamor_block_handler(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	dispatch->glFlush();
+	dispatch->glFinish();
 }
 
 static void
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index 5a47b45..f8516b4 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -27,6 +27,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glBindTexture, get_proc_address);
 	INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
 	INIT_FUNC(dispatch, glFlush, get_proc_address);
+	INIT_FUNC(dispatch, glFinish, get_proc_address);
 	INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
 	INIT_FUNC(dispatch, glGetString, get_proc_address);
 	INIT_FUNC(dispatch, glScissor, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index 8fcb3dc..a8a699b 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -41,6 +41,7 @@ typedef struct glamor_gl_dispatch {
 				 const GLvoid * pixels);
 	/* MISC */
 	void (*glFlush) (void);
+	void (*glFinish) (void);
 	void (*glGetIntegerv) (GLenum pname, GLint * params);
 	const GLubyte *(*glGetString) (GLenum name);
 	void (*glScissor) (GLint x, GLint y, GLsizei width,
commit 8b943ce2030b02bb8d279ce2c284cb5d2910ced6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jan 9 12:50:39 2012 +0800

    Set glamor's initial version to 0.2.0.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
index 5281ff4..4da57af 100644
--- a/glamor/glamor_eglmodule.c
+++ b/glamor/glamor_eglmodule.c
@@ -24,6 +24,10 @@
  * XFree86 Project.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <xorg-server.h>
 
 #include "xf86Module.h"
@@ -34,7 +38,7 @@ static XF86ModuleVersionInfo VersRec = {
 	MODINFOSTRING1,
 	MODINFOSTRING2,
 	XORG_VERSION_CURRENT,
-	1, 0, 0,
+	PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
 	ABI_CLASS_ANSIC,	/* Only need the ansic layer */
 	ABI_ANSIC_VERSION,
 	MOD_CLASS_NONE,
commit 7329414bf2ca9873c04150a1d9386cf37f70b663
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jan 9 07:16:06 2012 +0800

    Silence a compilation warning.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 2f9bc81..27c3fe8 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -13,7 +13,6 @@ enum glamor_pixmap_status
 glamor_upload_picture_to_texture(PicturePtr picture)
 {
 	PixmapPtr pixmap;
-	glamor_pixmap_private *pixmap_priv;
 	assert(picture->pDrawable);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 
commit 069a6d1746ef4c180f48a75e655e5e06e33327b5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jan 9 07:11:26 2012 +0800

    glamor_composite: Allocate VBO on demand.
    
    Use a fixed VBO is not efficient. Some times we may only has less than
    100 verts, and some times we may have larger than 4K verts. We change
    it to allocate VBO buffer dynamically, and this can bring about 10%
    performance gain for both aa10text/rgb10text and some cairo benchmarks.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 29c33b0..6a7057a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -291,16 +291,6 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 #define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
 
 static void
-glamor_reset_composite_vbo(ScreenPtr screen)
-{
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_priv->vbo_offset = 0;
-	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2;
-	glamor_priv->render_nr_verts = 0;
-}
-
-static void
 glamor_init_eb(unsigned short *eb, int vert_cnt)
 {
 	int i, j;
@@ -334,7 +324,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
 	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 	dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-	glamor_reset_composite_vbo(screen);
 }
 
 static Bool
@@ -395,7 +384,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv)
 {
-	unsigned int no_alpha, no_revert, format, type;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
@@ -555,12 +543,17 @@ glamor_composite_with_copy(CARD8 op,
 }
 
 static void
-glamor_setup_composite_vbo(ScreenPtr screen)
+glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
+	glamor_priv->vbo_offset = 0;
+	glamor_priv->vbo_offset = 0;
+	glamor_priv->render_nr_verts = 0;
+	glamor_priv->vbo_size = n_verts * sizeof(float) * 2;
+
 	glamor_priv->vb_stride = 2 * sizeof(float);
 	if (glamor_priv->has_source_coords)
 		glamor_priv->vb_stride += 2 * sizeof(float);
@@ -569,7 +562,7 @@ glamor_setup_composite_vbo(ScreenPtr screen)
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 	dispatch->glBufferData(GL_ARRAY_BUFFER,
-			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2,
+			       n_verts * sizeof(float) * 2,
 			       NULL, GL_DYNAMIC_DRAW);
 
 	glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
@@ -644,7 +637,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
 	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
 				 GL_UNSIGNED_SHORT, NULL);
-	glamor_reset_composite_vbo(screen);
 }
 
 static void
@@ -653,19 +645,6 @@ glamor_emit_composite_rect(ScreenPtr screen,
 			   const float *mask_coords,
 			   const float *dst_coords)
 {
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-	if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
-	    glamor_priv->vbo_size) {
-		glamor_flush_composite_rects(screen);
-	}
-
-	if (glamor_priv->vbo_offset == 0) {
-		glamor_setup_composite_vbo(screen);
-	}
-
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
 				   dst_coords, 0);
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
@@ -676,7 +655,6 @@ glamor_emit_composite_rect(ScreenPtr screen,
 				   dst_coords, 3);
 }
 
-
 int pict_format_combine_tab[][3] = {
 	{PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
 	{PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
@@ -763,10 +741,7 @@ glamor_composite_with_shader(CARD8 op,
 	    1, src_yscale = 1;
 	struct shader_key key;
 	glamor_composite_shader *shader;
-	RegionRec region;
 	float vertices[8], source_texcoords[8], mask_texcoords[8];
-	int i;
-	BoxPtr box;
 	int dest_x_off, dest_y_off;
 	int source_x_off, source_y_off;
 	int mask_x_off, mask_y_off;
@@ -776,6 +751,8 @@ glamor_composite_with_shader(CARD8 op,
 	float src_matrix[9], mask_matrix[9];
 	GLfloat source_solid_color[4], mask_solid_color[4];
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+	int vert_stride = 4;
+	int nrect_max;
 
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
@@ -1025,6 +1002,7 @@ glamor_composite_with_shader(CARD8 op,
 		pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
 				      &src_yscale);
 		glamor_picture_get_matrixf(source, src_matrix);
+		vert_stride += 4;
 	}
 
 	if (glamor_priv->has_mask_coords) {
@@ -1033,72 +1011,89 @@ glamor_composite_with_shader(CARD8 op,
 		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
 				      &mask_yscale);
 		glamor_picture_get_matrixf(mask, mask_matrix);
+		vert_stride += 4;
 	}
 
-	while (nrect--) {
-		INT16 x_source;
-		INT16 y_source;
-		INT16 x_mask;
-		INT16 y_mask;
-		INT16 x_dest;
-		INT16 y_dest;
-		CARD16 width;
-		CARD16 height;
-
-		x_dest = rects->x_dst + dest_x_off;
-		y_dest = rects->y_dst + dest_y_off;
-		x_source = rects->x_src + source_x_off;;
-		y_source = rects->y_src + source_y_off;
-		x_mask = rects->x_mask + mask_x_off;
-		y_mask = rects->y_mask + mask_y_off;
-		width = rects->width;
-		height = rects->height;
-
-		glamor_set_normalize_vcoords(dst_xscale,
-					     dst_yscale,
-					     x_dest, y_dest,
-					     x_dest + width, y_dest + height,
-					     glamor_priv->yInverted,
-					     vertices);
-
-		if (key.source != SHADER_SOURCE_SOLID) {
-			if (source->transform)
-				glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale,
-									 src_yscale, x_source, y_source,
-									 x_source + width, y_source + height,
-									 glamor_priv->yInverted,
-									 source_texcoords);
-			else
-				glamor_set_normalize_tcoords(src_xscale, src_yscale,
-							     x_source, y_source,
-							     x_source + width, y_source + height,
-							     glamor_priv->yInverted,
-							     source_texcoords);
-		}
+	nrect_max = (vert_stride * nrect) > GLAMOR_COMPOSITE_VBO_VERT_CNT ?
+			 (GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) : nrect;
+
+	while(nrect) {
+		int mrect, rect_processed;
+
+		mrect = nrect > nrect_max ? nrect_max : nrect ;
+		glamor_setup_composite_vbo(screen, mrect * vert_stride);
+		rect_processed = mrect;
+
+		while (mrect--) {
+			INT16 x_source;
+			INT16 y_source;
+			INT16 x_mask;
+			INT16 y_mask;
+			INT16 x_dest;
+			INT16 y_dest;
+			CARD16 width;
+			CARD16 height;
+
+			x_dest = rects->x_dst + dest_x_off;
+			y_dest = rects->y_dst + dest_y_off;
+			x_source = rects->x_src + source_x_off;;
+			y_source = rects->y_src + source_y_off;
+			x_mask = rects->x_mask + mask_x_off;
+			y_mask = rects->y_mask + mask_y_off;
+			width = rects->width;
+			height = rects->height;
+
+			glamor_set_normalize_vcoords(dst_xscale,
+						     dst_yscale,
+						     x_dest, y_dest,
+						     x_dest + width, y_dest + height,
+						     glamor_priv->yInverted,
+						     vertices);
+
+			if (key.source != SHADER_SOURCE_SOLID) {
+				if (source->transform)
+					glamor_set_transformed_normalize_tcoords
+						(src_matrix, src_xscale,
+						 src_yscale, x_source, y_source,
+						 x_source + width, y_source + height,
+						 glamor_priv->yInverted,
+						 source_texcoords);
+				else
+					glamor_set_normalize_tcoords
+						(src_xscale, src_yscale,
+						 x_source, y_source,
+						 x_source + width, y_source + height,
+						 glamor_priv->yInverted,
+						 source_texcoords);
+			}
 
-		if (key.mask != SHADER_MASK_NONE
-		    && key.mask != SHADER_MASK_SOLID) {
-			if (mask->transform)
-				glamor_set_transformed_normalize_tcoords(mask_matrix,
-									 mask_xscale,
-									 mask_yscale, x_mask, y_mask,
-									 x_mask + width, y_mask + height,
-									 glamor_priv->yInverted,
-									 mask_texcoords);
-			else
-				glamor_set_normalize_tcoords(mask_xscale,
-							     mask_yscale, x_mask, y_mask,
-							     x_mask + width, y_mask + height,
-							     glamor_priv->yInverted,
-							     mask_texcoords);
+			if (key.mask != SHADER_MASK_NONE
+			    && key.mask != SHADER_MASK_SOLID) {
+				if (mask->transform)
+					glamor_set_transformed_normalize_tcoords
+						(mask_matrix,
+						 mask_xscale,
+						 mask_yscale, x_mask, y_mask,
+						 x_mask + width, y_mask + height,
+						 glamor_priv->yInverted,
+						 mask_texcoords);
+				else
+					glamor_set_normalize_tcoords
+						(mask_xscale,
+						 mask_yscale, x_mask, y_mask,
+						 x_mask + width, y_mask + height,
+						 glamor_priv->yInverted,
+						 mask_texcoords);
+			}
+			glamor_emit_composite_rect(screen,
+						   source_texcoords,
+						   mask_texcoords,
+						   vertices);
+			rects++;
 		}
-		glamor_emit_composite_rect(screen,
-					   source_texcoords,
-					   mask_texcoords,
-					   vertices);
-		rects++;
+		glamor_flush_composite_rects(screen);
+		nrect -= rect_processed;
 	}
-	glamor_flush_composite_rects(screen);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
 	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -1380,7 +1375,6 @@ _glamor_composite(CARD8 op,
 		goto done;
 	}
 
-fallback:
 	glamor_fallback
 	    ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
 	     source, source->pDrawable,
commit 42a0261cb3065200887f81816b1bc3850593da4c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jan 9 05:03:08 2012 +0800

    glamor_getimage: Add the optimization path of getImage.
    
    This optimization will only call glReadPixels once. It should get
    some performance gain. But it seems it even get worse performance
    at SNB, disable it by default.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
index 7a9280b..086ec4b 100644
--- a/glamor/glamor_getimage.c
+++ b/glamor/glamor_getimage.c
@@ -34,11 +34,88 @@
 
 
 static Bool
-_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+_glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 		  unsigned int format, unsigned long planeMask, char *d,
 		  Bool fallback)
 {
-	miGetImage(pDrawable, x, y, w, h, format, planeMask, d);
+	PixmapPtr pixmap;
+	struct glamor_pixmap_private *pixmap_priv;
+	struct glamor_screen_private *glamor_priv;
+	int x_off, y_off;
+	GLenum tex_format, tex_type;
+	int no_alpha, no_revert;
+	PixmapPtr temp_pixmap = NULL;
+	glamor_gl_dispatch * dispatch;
+
+	goto fall_back;
+	if (format != ZPixmap)
+		goto fall_back;
+
+	pixmap = glamor_get_drawable_pixmap(drawable);
+	if (!glamor_set_planemask(pixmap, planeMask)) {
+		glamor_fallback
+		    ("Failedto set planemask  in glamor_solid.\n");
+		goto fall_back;
+	}
+	glamor_priv = glamor_get_screen_private(drawable->pScreen);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	dispatch = &glamor_priv->dispatch;
+
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		goto fall_back;
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &tex_format,
+						   &tex_type,
+						   &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("unknown depth. %d \n", drawable->depth);
+		goto fall_back;
+	}
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	glamor_validate_pixmap(pixmap);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		/* XXX prepare whole pixmap is not efficient. */
+		temp_pixmap =
+		    glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
+						   &tex_type, no_alpha,
+						   no_revert);
+		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	}
+
+	int row_length = PixmapBytePad(w, drawable->depth);
+	row_length = (row_length * 8) / drawable->bitsPerPixel;
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+	} else {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+	}
+
+	if (glamor_priv->yInverted)
+		dispatch->glReadPixels(x + x_off,
+				       y + y_off,
+				       w, h,
+				       tex_format,
+				       tex_type, d);
+	else
+		dispatch->glReadPixels(x + x_off,
+				       pixmap->drawable.height - 1 - (y + y_off),
+				       w,
+				       h,
+				       tex_format,
+				       tex_type, d);
+	if (temp_pixmap)
+		glamor_destroy_pixmap(temp_pixmap);
+	return TRUE;
+
+fall_back:
+	miGetImage(drawable, x, y, w, h, format, planeMask, d);
 	return TRUE;
 }
 
commit 96085017c8da96e6d882c87b69186f5aba20131d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Jan 9 05:01:48 2012 +0800

    Consolidate the choose of internal texture format to one function.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index bbcf942..3634e70 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -169,20 +169,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	if (w == 0 || h == 0 || type == GLAMOR_MEMORY)
 		return pixmap;
 
-	switch (depth) {
-#if 0
-	case 8:
-		format = GL_ALPHA;
-		break;
-#endif
-	case 24:
-		format = GL_RGB;
-		break;
-	default:
-		format = GL_RGBA;
-		break;
-	}
-
+	gl_iformat_for_depth(depth, &format);
 	/* Create the texture used to store the pixmap's data. */
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 884dd83..f43a90b 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -221,23 +221,10 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	void *texels;
 	GLenum iformat;
 
-	switch (pixmap->drawable.depth) {
-#if 0
-	case 8:
-		iformat = GL_ALPHA;
-		break;
-#endif
-	case 24:
-		iformat = GL_RGB;
-		break;
-	default:
-		iformat = GL_RGBA;
-		break;
-	}
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
 		iformat = format;
-	}
+	else
+		gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
 
 	stride = pixmap->devKind;
 	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index dfb7711..49c7e1d 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -224,6 +224,26 @@ format_for_depth(int depth)
 	}
 }
 
+static inline void
+gl_iformat_for_depth(int depth, GLenum * format)
+{
+	switch (depth) {
+#if 0
+	case 8:
+		*format = GL_ALPHA;
+		break;
+#endif
+	case 24:
+		*format = GL_RGB;
+		break;
+	default:
+		*format = GL_RGBA;
+		break;
+       }
+}
+
+
+
 static inline CARD32
 format_for_pixmap(PixmapPtr pixmap)
 {
commit a74596be0e7e02b43fb0db844b71b68f384ab599
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Jan 8 08:50:41 2012 +0800

    Set filter to GL_NEAREST by default.
    
    This is the fastest filter and let's use it by default.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index b56afc0..884dd83 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -243,6 +243,10 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
 		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
@@ -584,6 +588,13 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
 	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+
 	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
 			       source->drawable.width,
 			       source->drawable.height, 0, *format, *type,
@@ -601,6 +612,12 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+				  GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
 
 	glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index f4b174d..f285d95 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -313,6 +313,10 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
 
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
 		iformat = format;
@@ -323,10 +327,6 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
 			       w, h, 0, format, type, bits);
 
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
 
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
commit 4cd07871a417b15b0382c07fecec497e93697a5d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Jan 8 08:45:08 2012 +0800

    glamor-composite: Use glDrawElements to reduce the count of vertices.
    
    To split a rectangle (0,1,2,3) to two separated triangles need to feed
    6 vertices, (0,1,2) and (0,2,3). use glDrawElements can reuse the shared
    vertices.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index 788562c..5a47b45 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -16,6 +16,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glViewport, get_proc_address);
 	INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
 	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
+	INIT_FUNC(dispatch, glDrawElements, get_proc_address);
 	INIT_FUNC(dispatch, glReadPixels, get_proc_address);
 	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
 	INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
@@ -37,6 +38,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
 	INIT_FUNC(dispatch, glBufferData, get_proc_address);
 	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glMapBufferRange, get_proc_address);
 	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index 5f1831a..8fcb3dc 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -10,6 +10,9 @@ typedef struct glamor_gl_dispatch {
 	/* Vertex Array */
 	void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
 
+	/* Elements Array*/
+	void (*glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid * indices);
+
 	/* Raster functions */
 	void (*glReadPixels) (GLint x, GLint y,
 			      GLsizei width, GLsizei height,
@@ -55,7 +58,8 @@ typedef struct glamor_gl_dispatch {
 	void (*glBufferData) (GLenum target, GLsizeiptr size,
 			      const GLvoid * data, GLenum usage);
 	GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
-	 GLboolean(*glUnmapBuffer) (GLenum target);
+	GLvoid *(*glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+	GLboolean(*glUnmapBuffer) (GLenum target);
 	void (*glBindBuffer) (GLenum target, GLuint buffer);
 	void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 08db631..f3b0996 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -158,7 +158,7 @@ typedef struct glamor_screen_private {
 
 	int yInverted;
 	int screen_fbo;
-	GLuint vbo;
+	GLuint vbo, ebo;
 	int vbo_offset;
 	int vbo_size;
 	char *vb;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 4f09bbf..29c33b0 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -288,7 +288,7 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 	return shader;
 }
 
-#define GLAMOR_COMPOSITE_VBO_SIZE 8192
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
 
 static void
 glamor_reset_composite_vbo(ScreenPtr screen)
@@ -296,18 +296,44 @@ glamor_reset_composite_vbo(ScreenPtr screen)
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_priv->vbo_offset = 0;
-	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE;
+	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2;
 	glamor_priv->render_nr_verts = 0;
 }
 
+static void
+glamor_init_eb(unsigned short *eb, int vert_cnt)
+{
+	int i, j;
+	for(i = 0, j = 0; j < vert_cnt; i += 6, j += 4)
+	{
+		eb[i] = j;
+		eb[i + 1] = j + 1;
+		eb[i + 2] = j + 2;
+		eb[i + 3] = j;
+		eb[i + 4] = j + 2;
+		eb[i + 5] = j + 3;
+	}
+}
+
 
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
-	glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE);
-	assert(glamor_priv->vb != NULL);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	unsigned short *eb;
+
+	dispatch->glGenBuffers(1, &glamor_priv->vbo);
+	dispatch->glGenBuffers(1, &glamor_priv->ebo);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
+	dispatch->glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2,
+			       NULL, GL_DYNAMIC_DRAW);
+	eb = dispatch->glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+	glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
 	glamor_reset_composite_vbo(screen);
 }
 
@@ -542,6 +568,12 @@ glamor_setup_composite_vbo(ScreenPtr screen)
 		glamor_priv->vb_stride += 2 * sizeof(float);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+	dispatch->glBufferData(GL_ARRAY_BUFFER,
+			       GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2,
+			       NULL, GL_DYNAMIC_DRAW);
+
+	glamor_priv->vb = dispatch->glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, glamor_priv->vb_stride,
@@ -609,11 +641,9 @@ glamor_flush_composite_rects(ScreenPtr screen)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	if (!glamor_priv->render_nr_verts)
 		return;
-	dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
-			       glamor_priv->vb, GL_STREAM_DRAW);
-
-	dispatch->glDrawArrays(GL_TRIANGLES, 0,
-			       glamor_priv->render_nr_verts);
+	dispatch->glUnmapBuffer(GL_ARRAY_BUFFER);
+	dispatch->glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
+				 GL_UNSIGNED_SHORT, NULL);
 	glamor_reset_composite_vbo(screen);
 }
 
@@ -627,15 +657,12 @@ glamor_emit_composite_rect(ScreenPtr screen,
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
-	if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
+	if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
 	    glamor_priv->vbo_size) {
 		glamor_flush_composite_rects(screen);
 	}
 
 	if (glamor_priv->vbo_offset == 0) {
-		if (glamor_priv->vbo == 0)
-			dispatch->glGenBuffers(1, &glamor_priv->vbo);
-
 		glamor_setup_composite_vbo(screen);
 	}
 
@@ -646,10 +673,6 @@ glamor_emit_composite_rect(ScreenPtr screen,
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
 				   dst_coords, 2);
 	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 0);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
-				   dst_coords, 2);
-	glamor_emit_composite_vert(screen, src_coords, mask_coords,
 				   dst_coords, 3);
 }
 
@@ -969,7 +992,6 @@ glamor_composite_with_shader(CARD8 op,
 
 	dispatch->glUseProgram(shader->prog);
 
-
 	if (key.source == SHADER_SOURCE_SOLID) {
 		glamor_set_composite_solid(dispatch, source_solid_color,
 					   shader->source_uniform_location);
@@ -1079,6 +1101,7 @@ glamor_composite_with_shader(CARD8 op,
 	glamor_flush_composite_rects(screen);
 
 	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
commit 9dafd6fce547a6824c1de98d4309f8f2197ebbd0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Jan 8 01:14:12 2012 +0800

    glamor-composite: Optimize the computation of composite region.
    
    Computing the composite region at the composite_with_shader is very
    inefficient. As when we call to here from the glamor_glyph's temproary
    picture, we don't need to compute this region at all. So we move this
    computing out from this function and do that at the glamor_composite
    function. This can get about 5% performance gain for aa10text/rgb10text.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 487171c..4f09bbf 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1023,98 +1023,57 @@ glamor_composite_with_shader(CARD8 op,
 		CARD16 width;
 		CARD16 height;
 
-		x_dest = rects->x_dst;
-		y_dest = rects->y_dst;
-		x_source = rects->x_src;
-		y_source = rects->y_src;
-		x_mask = rects->x_mask;
-		y_mask = rects->y_mask;
+		x_dest = rects->x_dst + dest_x_off;
+		y_dest = rects->y_dst + dest_y_off;
+		x_source = rects->x_src + source_x_off;;
+		y_source = rects->y_src + source_y_off;
+		x_mask = rects->x_mask + mask_x_off;
+		y_mask = rects->y_mask + mask_y_off;
 		width = rects->width;
 		height = rects->height;
 
-		x_dest += dest->pDrawable->x;
-		y_dest += dest->pDrawable->y;
-		if (source->pDrawable) {
-			x_source += source->pDrawable->x;
-			y_source += source->pDrawable->y;
-		}
-		if (mask && mask->pDrawable) {
-			x_mask += mask->pDrawable->x;
-			y_mask += mask->pDrawable->y;
-		}
-
-		if (!miComputeCompositeRegion(&region,
-					      source, mask, dest,
-					      x_source, y_source,
-					      x_mask, y_mask,
-					      x_dest, y_dest, width,
-					      height))
-			continue;
-
-		x_source += source_x_off;
-		y_source += source_y_off;
-		x_mask += mask_x_off;
-		y_mask += mask_y_off;
-
-		box = REGION_RECTS(&region);
-		for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-			int vx1 = box[i].x1 + dest_x_off;
-			int vx2 = box[i].x2 + dest_x_off;
-			int vy1 = box[i].y1 + dest_y_off;
-			int vy2 = box[i].y2 + dest_y_off;
-			glamor_set_normalize_vcoords(dst_xscale,
-						     dst_yscale, vx1,
-						     vy1, vx2, vy2,
-						     glamor_priv->yInverted,
-						     vertices);
-
-			if (key.source != SHADER_SOURCE_SOLID) {
-				int tx1 = box[i].x1 + x_source - x_dest;
-				int ty1 = box[i].y1 + y_source - y_dest;
-				int tx2 = box[i].x2 + x_source - x_dest;
-				int ty2 = box[i].y2 + y_source - y_dest;
-				if (source->transform)
-					glamor_set_transformed_normalize_tcoords
-					    (src_matrix, src_xscale,
-					     src_yscale, tx1, ty1,
-					     tx2, ty2,
-					     glamor_priv->yInverted,
-					     source_texcoords);
-				else
-					glamor_set_normalize_tcoords
-					    (src_xscale, src_yscale,
-					     tx1, ty1, tx2, ty2,
+		glamor_set_normalize_vcoords(dst_xscale,
+					     dst_yscale,
+					     x_dest, y_dest,
+					     x_dest + width, y_dest + height,
 					     glamor_priv->yInverted,
-					     source_texcoords);
-			}
+					     vertices);
+
+		if (key.source != SHADER_SOURCE_SOLID) {
+			if (source->transform)
+				glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale,
+									 src_yscale, x_source, y_source,
+									 x_source + width, y_source + height,
+									 glamor_priv->yInverted,
+									 source_texcoords);
+			else
+				glamor_set_normalize_tcoords(src_xscale, src_yscale,
+							     x_source, y_source,
+							     x_source + width, y_source + height,
+							     glamor_priv->yInverted,
+							     source_texcoords);
+		}
 
-			if (key.mask != SHADER_MASK_NONE
-			    && key.mask != SHADER_MASK_SOLID) {
-				float tx1 = box[i].x1 + x_mask - x_dest;
-				float ty1 = box[i].y1 + y_mask - y_dest;
-				float tx2 = box[i].x2 + x_mask - x_dest;
-				float ty2 = box[i].y2 + y_mask - y_dest;
-				if (mask->transform)
-					glamor_set_transformed_normalize_tcoords
-					    (mask_matrix,
-					     mask_xscale,
-					     mask_yscale, tx1, ty1,
-					     tx2, ty2,
-					     glamor_priv->yInverted,
-					     mask_texcoords);
-				else
-					glamor_set_normalize_tcoords
-					    (mask_xscale,
-					     mask_yscale, tx1, ty1,
-					     tx2, ty2,
-					     glamor_priv->yInverted,
-					     mask_texcoords);
-			}
-			glamor_emit_composite_rect(screen,
-						   source_texcoords,
-						   mask_texcoords,
-						   vertices);
+		if (key.mask != SHADER_MASK_NONE
+		    && key.mask != SHADER_MASK_SOLID) {
+			if (mask->transform)
+				glamor_set_transformed_normalize_tcoords(mask_matrix,
+									 mask_xscale,
+									 mask_yscale, x_mask, y_mask,
+									 x_mask + width, y_mask + height,
+									 glamor_priv->yInverted,
+									 mask_texcoords);
+			else
+				glamor_set_normalize_tcoords(mask_xscale,
+							     mask_yscale, x_mask, y_mask,
+							     x_mask + width, y_mask + height,
+							     glamor_priv->yInverted,
+							     mask_texcoords);
 		}
+		glamor_emit_composite_rect(screen,
+					   source_texcoords,
+					   mask_texcoords,
+					   vertices);
 		rects++;
 	}
 	glamor_flush_composite_rects(screen);
@@ -1123,7 +1082,6 @@ glamor_composite_with_shader(CARD8 op,
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-	REGION_UNINIT(dst->pDrawable->pScreen, &region);
 	dispatch->glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
 	dispatch->glActiveTexture(GL_TEXTURE0);
@@ -1207,11 +1165,16 @@ _glamor_composite(CARD8 op,
 	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
 	PicturePtr temp_src = source, temp_mask = mask;
 	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
-	glamor_composite_rect_t rect;
+	glamor_composite_rect_t rect[10];
+	glamor_composite_rect_t *prect = rect;
+	int prect_size = ARRAY_SIZE(rect);
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	Bool ret = TRUE;
+	RegionRec region;
+	BoxPtr box;
+	int nbox, i, ok;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
@@ -1325,16 +1288,59 @@ _glamor_composite(CARD8 op,
 					       height))
 			goto done;
 	}
-	rect.x_src = x_temp_src;
-	rect.y_src = y_temp_src;
-	rect.x_mask = x_temp_mask;
-	rect.y_mask = y_temp_mask;
-	rect.x_dst = x_dest;
-	rect.y_dst = y_dest;
-	rect.width = width;
-	rect.height = height;
-	if (glamor_composite_with_shader
-	    (op, temp_src, temp_mask, dest, 1, &rect))
+	x_dest += dest->pDrawable->x;
+	y_dest += dest->pDrawable->y;
+	if (temp_src->pDrawable) {
+		x_temp_src += temp_src->pDrawable->x;
+		y_temp_src += temp_src->pDrawable->y;
+	}
+	if (temp_mask && temp_mask->pDrawable) {
+		x_temp_mask += temp_mask->pDrawable->x;
+		y_temp_mask += temp_mask->pDrawable->y;
+	}
+	if (!miComputeCompositeRegion(&region,
+				      temp_src, temp_mask, dest,
+				      x_temp_src, y_temp_src,
+				      x_temp_mask, y_temp_mask,
+				      x_dest, y_dest, width,
+				      height))
+		goto done;
+
+	box = REGION_RECTS(&region);
+	nbox = REGION_NUM_RECTS(&region);
+
+	if (nbox > ARRAY_SIZE(rect)) {
+		prect = calloc(nbox, sizeof(*prect));
+		if (prect)
+			prect_size = nbox;
+		else {
+			prect = rect;
+			prect_size = ARRAY_SIZE(rect);
+		}
+	}
+	while(nbox) {
+		int box_cnt;
+		box_cnt = nbox > prect_size ? prect_size : nbox;
+		for (i = 0; i < box_cnt; i++) {
+			prect[i].x_src = box[i].x1 + x_temp_src - x_dest;
+			prect[i].y_src = box[i].y1 + y_temp_src - y_dest;
+			prect[i].x_mask = box[i].x1 + x_temp_mask - x_dest;
+			prect[i].y_mask = box[i].y1 + y_temp_mask - y_dest;
+			prect[i].x_dst = box[i].x1;
+			prect[i].y_dst = box[i].y1;
+			prect[i].width = box[i].x2 - box[i].x1;
+			prect[i].height = box[i].y2 - box[i].y1;
+		}
+		ok = glamor_composite_with_shader(op, temp_src, temp_mask,
+						  dest, box_cnt, prect);
+		if (!ok)
+			break;
+		nbox -= box_cnt;
+		box += box_cnt;
+	}
+
+	REGION_UNINIT(dest->pDrawable->pScreen, &region);
+	if (ok)
 		goto done;
 
       fail:
@@ -1391,6 +1397,8 @@ fallback:
 		FreePicture(temp_src, 0);
 	if (temp_mask != mask)
 		FreePicture(temp_mask, 0);
+	if (prect != rect)
+		free(prect);
 	return ret;
 }
 
commit 2511a00cdd576512f5d7f45707a4a725df2f4618
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jan 5 14:26:01 2012 +0800

    Fixed a configure bug.
    
    Should check the enable-glamor-gles2 before use the variable.
    And should include the config.h as the GLAMOR_GLES2 macro is
    defined there.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 7eca5ad..28a48ca 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -27,6 +27,10 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4bd169b..08db631 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -27,6 +27,10 @@
 #ifndef GLAMOR_PRIV_H
 #define GLAMOR_PRIV_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #include <xorg-config.h>
commit a65e1c736aaa1bb2440a83c42c0410d9d9b58007
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 4 14:40:24 2012 +0800

    Reduce the double check of pixmap's private pointer.
    
    As we now add the checking to the Macro, we don't need to check
    the pointer outside the Macro.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 049979a..4310a04 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -317,7 +317,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
 
-	if (!dst_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_fallback("dest pixmap %p has no fbo. \n",
 				dst_pixmap);
 		goto fail;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f865ece..8ce2104 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -264,7 +264,7 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
-	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return;
 
 	if (access_mode != GLAMOR_ACCESS_RO) {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index d36313a..da8097a 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -149,7 +149,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	GLfloat color[4];
 	float vertices[8];
 	GLfloat xscale, yscale;
-	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("dest %p has no fbo.\n", pixmap);
 		goto fail;
 	}
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 4d4108d..be81fbb 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -50,7 +50,7 @@ _glamor_get_spans(DrawablePtr drawable,
 	uint8_t *readpixels_dst = (uint8_t *) dst;
 	int x_off, y_off;
 
-	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
 		goto fail;
 	}
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 9559d17..b56afc0 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -646,7 +646,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	screen = pixmap->drawable.pScreen;
-	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return TRUE;
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 7967e25..f4b174d 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -265,7 +265,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		goto fail;
 	}
 
-	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("has no fbo.\n");
 		goto fail;
 	}
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 4a2a438..487171c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -754,7 +754,7 @@ glamor_composite_with_shader(CARD8 op,
 	GLfloat source_solid_color[4], mask_solid_color[4];
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
-	if (!dest_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
 	}
@@ -1220,7 +1220,7 @@ _glamor_composite(CARD8 op,
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
-	if (!dest_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		goto fail;
 	}
 
commit e1789893e5fe07fdbd8f21b7fa8a15f6db066592
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 4 14:37:37 2012 +0800

    get_spans: Check whether have a valid fbo before check format.
    
    If a pixmap is a pure in-memory pixmap, we do not need to
    check its format. Format checking has more overhead than
    checking FBO, so we change to check fbo firtly.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 360ca37..26e774b 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -37,6 +37,7 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 Bool fallback)
 {
 	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_pixmap_private *dest_pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
@@ -47,6 +48,12 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	BoxRec *pbox;
 	int x_off, y_off;
 
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		glamor_fallback("pixmap has no fbo.\n");
+		goto fail;
+	}
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
 		glamor_fallback("ES2 fallback.\n");
 		goto fail;
@@ -61,9 +68,7 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	}
 
 
-	if (glamor_set_destination_pixmap(dest_pixmap))
-		goto fail;
-
+	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
 	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 		goto fail;
commit 057f52a04d47e6ca5f6dead9c1bc71765d4c7ae8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 4 14:34:39 2012 +0800

    Track all picture's drawable pict format.
    
    Even if a picture's pixmap is a pure in memory pixmap, we still need
    to track its format. The reason is we may need to upload this drawable
    to texture thus we need to know its real picture format.
    
    As to the MACRO to check whether a pixmap is a picture, we should
    check whether the priv is non-NULL before we touch its field.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 940c9d7..2f9bc81 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -58,6 +58,14 @@ glamor_create_picture(PicturePtr picture)
 	    glamor_get_screen_private(picture->pDrawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (!pixmap_priv) {
+	/* We must create a pixmap priv to track the picture format even
+ 	 * if the pixmap is a pure in memory pixmap. The reason is that
+ 	 * we may need to upload this pixmap to a texture on the fly. During
+ 	 * the uploading, we need to know the picture format. */
+		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
+		pixmap_priv = glamor_get_pixmap_private(pixmap);
+	}
 	
 	if (pixmap_priv) {
 		pixmap_priv->is_picture = 1;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 9eea70e..dfb7711 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -175,7 +175,7 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
                                          || _depth_ == 32)
 
 
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv->is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
 #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == 1)
 
 #define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
commit 8a4758a358e56b1db481607ff3f7e9375238e5d8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jan 4 13:11:52 2012 +0800

    Need to check pixmap priv before touch its field.
    
    As now the pixmap may be allocated by DDX and doesn't have a
    valid pixmap private field. We must check pixmap private
    pointer before touch its field value. If a pixmap doesn't
    have a non-NULL private pointer, it doesn't have a valid
    FBO.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 4d47f57..9eea70e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -176,7 +176,7 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 
 
 #define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv->is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv && pixmap_priv->gl_fbo == 1)
 
 #define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
 	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
commit 9264335347da641b2626a6b9f56aa05ab313239e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Dec 31 19:29:17 2011 +0800

    Added more drawing functions.
    
    As we want to take over all the possible GC ops from the DDX
    layer, we need to add all the missed functions.
    This commit also fixed one bug at polylines.
    We simply drop the bugy optimized code now, as it did not
    consider of clip info.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 17a3e77..5c5f7e5 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -37,6 +37,9 @@ libglamor_la_SOURCES = \
 	glamor_triangles.c\
 	glamor_addtraps.c\
 	glamor_getimage.c\
+	glamor_copyplane.c\
+	glamor_glyphblt.c\
+	glamor_polyops.c\
 	glamor_pixmap.c\
 	glamor_picture.c\
 	glamor_window.c\
diff --git a/glamor/glamor.h b/glamor/glamor.h
index fc8c152..1119e37 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -270,3 +270,30 @@ extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
 					  INT16 x_off, 
 					  INT16 y_off, int ntrap, xTrap * traps);
 
+extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+					   int srcx, int srcy, int w, int h, int dstx, int dsty,
+					   unsigned long bitPlane, RegionPtr *pRegion);
+
+extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
+						int x, int y, unsigned int nglyph,
+						CharInfoPtr * ppci, pointer pglyphBase);
+
+extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
+					       int x, int y, unsigned int nglyph,
+					       CharInfoPtr * ppci, pointer pglyphBase);
+
+extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
+					    DrawablePtr pDrawable, int w, int h, int x, int y);
+
+extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+					   DDXPointPtr ppt);
+
+extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+					     xSegment *pSeg);
+
+extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+					  DDXPointPtr ppt);
+
+extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
+					   DDXPointPtr points);
+
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
new file mode 100644
index 0000000..288d7ed
--- /dev/null
+++ b/glamor/glamor_copyplane.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+static Bool
+_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+		   int srcx, int srcy, int w, int h, int dstx, int dsty,
+		   unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_gc(pGC)
+	    && glamor_ddx_fallback_check_pixmap(pSrc)
+	    && glamor_ddx_fallback_check_pixmap(pDst))
+		goto fail;
+	glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
+	glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
+	*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
+			  dstx, dsty, bitPlane);
+	glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
+	glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
+	return TRUE;
+
+ fail:
+	return FALSE;
+}
+
+RegionPtr
+glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+		  int srcx, int srcy, int w, int h, int dstx, int dsty,
+		  unsigned long bitPlane)
+{
+	RegionPtr ret;
+	_glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
+			   dstx, dsty, bitPlane, &ret, TRUE);
+	return ret;
+}
+
+Bool
+glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+		     int srcx, int srcy, int w, int h, int dstx, int dsty,
+		     unsigned long bitPlane, RegionPtr *pRegion)
+{
+	return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
+				  dstx, dsty, bitPlane, pRegion, FALSE);
+}
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 9a1b770..f865ece 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -344,10 +344,10 @@ GCOps glamor_gc_ops = {
 	.SetSpans = glamor_set_spans,
 	.PutImage = glamor_put_image,
 	.CopyArea = glamor_copy_area,
-	.CopyPlane = miCopyPlane,
-	.PolyPoint = miPolyPoint,
+	.CopyPlane = glamor_copy_plane,
+	.PolyPoint = glamor_poly_point,
 	.Polylines = glamor_poly_lines,
-	.PolySegment = miPolySegment,
+	.PolySegment = glamor_poly_segment,
 	.PolyRectangle = miPolyRectangle,
 	.PolyArc = miPolyArc,
 	.FillPolygon = miFillPolygon,
@@ -357,9 +357,9 @@ GCOps glamor_gc_ops = {
 	.PolyText16 = miPolyText16,
 	.ImageText8 = miImageText8,
 	.ImageText16 = miImageText16,
-	.ImageGlyphBlt = miImageGlyphBlt,
-	.PolyGlyphBlt = miPolyGlyphBlt,
-	.PushPixels = miPushPixels,
+	.ImageGlyphBlt = glamor_image_glyph_blt, //miImageGlyphBlt,
+	.PolyGlyphBlt = glamor_poly_glyph_blt, //miPolyGlyphBlt,
+	.PushPixels = glamor_push_pixels, //miPushPixels,
 };
 
 /**
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
new file mode 100644
index 0000000..c9a35a0
--- /dev/null
+++ b/glamor/glamor_glyphblt.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+static Bool
+_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_pixmap(pDrawable)
+	    && glamor_ddx_fallback_check_gc(pGC))
+		goto fail;
+	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+	glamor_prepare_access_gc(pGC);
+	fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	glamor_finish_access_gc(pGC);
+	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	return TRUE;
+ fail:
+	return FALSE;
+}
+
+void
+glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase)
+{
+	_glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE);
+}
+
+Bool
+glamor_image_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase)
+{
+	return _glamor_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE);
+}
+
+static Bool
+_glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_pixmap(pDrawable)
+	    && glamor_ddx_fallback_check_gc(pGC))
+		goto fail;
+	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+	glamor_prepare_access_gc(pGC);
+	fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	glamor_finish_access_gc(pGC);
+	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	return TRUE;
+ fail:
+	return FALSE;
+}
+
+void
+glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase)
+{
+	_glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, TRUE);
+}
+
+Bool
+glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase)
+{
+	return _glamor_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase, FALSE);
+}
+
+static Bool
+_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
+		    DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_pixmap(pDrawable)
+	    && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
+	    && glamor_ddx_fallback_check_gc(pGC))
+		goto fail;
+	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+	glamor_prepare_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
+	glamor_prepare_access_gc(pGC);
+	fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
+	glamor_finish_access_gc(pGC);
+	glamor_finish_access(&pBitmap->drawable, GLAMOR_ACCESS_RO);
+	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	return TRUE;
+ fail:
+	return FALSE;
+}
+
+void
+glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
+		   DrawablePtr pDrawable, int w, int h, int x, int y)
+{
+	_glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE);
+}
+
+Bool
+glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
+		      DrawablePtr pDrawable, int w, int h, int x, int y)
+{
+	return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE);
+}
+
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 62401f5..0217e8f 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -42,26 +42,19 @@
  * horizontal or vertical lines (rectangles), and uses existing rectangle fill
  * acceleration if so.
  */
-void
-glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		  DDXPointPtr points)
+static Bool
+_glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		   DDXPointPtr points, Bool fallback)
 {
 	xRectangle *rects;
 	int x1, x2, y1, y2;
 	int i;
-	int x_min = MAXSHORT;
-	int x_max = MINSHORT;
-	int y_min = MAXSHORT;
-	int y_max = MINSHORT;
-	DrawablePtr temp_dest;
-	PixmapPtr temp_pixmap;
-	GCPtr temp_gc = NULL;
 	/* Don't try to do wide lines or non-solid fill style. */
 	if (gc->lineWidth != 0) {
 		/* This ends up in miSetSpans, which is accelerated as well as we
 		 * can hope X wide lines will be.
 		 */
-		goto fail;
+		goto wide_line;
 	}
 	if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) {
 		glamor_fallback
@@ -107,69 +100,40 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	}
 	gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
 	free(rects);
-	return;
+	return TRUE;
 
       fail:
-	for (i = 0; i < n; i++) {
-		if (x_min > points[i].x)
-			x_min = points[i].x;
-		if (x_max < points[i].x)
-			x_max = points[i].x;
-
-		if (y_min > points[i].y)
-			y_min = points[i].y;
-		if (y_max < points[i].y)
-			y_max = points[i].y;
-	}
-
-	temp_pixmap = glamor_create_pixmap(drawable->pScreen,
-					   x_max - x_min + 1,
-					   y_max - y_min + 1,
-					   drawable->depth, 0);
-	if (temp_pixmap) {
-		temp_dest = &temp_pixmap->drawable;
-		temp_gc =
-		    GetScratchGC(temp_dest->depth, temp_dest->pScreen);
-		ValidateGC(temp_dest, temp_gc);
-		for (i = 0; i < n; i++) {
-			points[i].x -= x_min;
-			points[i].y -= y_min;
-		}
-		(void) glamor_copy_area(drawable,
-					temp_dest,
-					temp_gc,
-					x_min, y_min,
-					x_max - x_min + 1,
-					y_max - y_min + 1, 0, 0);
-
-	} else
-		temp_dest = drawable;
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(drawable)
+	    && glamor_ddx_fallback_check_gc(gc))
+		return FALSE;
 
 	if (gc->lineWidth == 0) {
-		if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 			if (glamor_prepare_access_gc(gc)) {
-				fbPolyLine(temp_dest, gc, mode, n, points);
+				fbPolyLine(drawable, gc, mode, n, points);
 				glamor_finish_access_gc(gc);
 			}
-			glamor_finish_access(temp_dest, GLAMOR_ACCESS_RW);
+			glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 		}
 	} else {
+wide_line:
 		/* fb calls mi functions in the lineWidth != 0 case. */
 		fbPolyLine(drawable, gc, mode, n, points);
 	}
-	if (temp_dest != drawable) {
-		(void) glamor_copy_area(temp_dest,
-					drawable,
-					temp_gc,
-					0, 0,
-					x_max - x_min + 1,
-					y_max - y_min + 1, x_min, y_min);
-		glamor_destroy_pixmap(temp_pixmap);
-		for (i = 0; i < n; i++) {
-			points[i].x += x_min;
-			points[i].y += y_min;
-		}
+	return TRUE;
+}
 
-		FreeScratchGC(temp_gc);
-	}
+void
+glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		  DDXPointPtr points)
+{
+	_glamor_poly_lines(drawable, gc, mode, n, points, TRUE);
+}
+
+Bool
+glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		     DDXPointPtr points)
+{
+	return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE);
 }
diff --git a/glamor/glamor_polyops.c b/glamor/glamor_polyops.c
new file mode 100644
index 0000000..6188bb2
--- /dev/null
+++ b/glamor/glamor_polyops.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+static Bool
+_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		   DDXPointPtr ppt, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_gc(pGC)
+	    && glamor_ddx_fallback_check_pixmap(pDrawable))
+		goto fail;
+	glamor_prepare_access_gc(pGC);
+	glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+	fbPolyPoint(pDrawable, pGC, mode, npt, ppt);
+	glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+	glamor_finish_access_gc(pGC);
+	return TRUE;
+
+fail:
+	return FALSE;
+}
+
+void
+glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		  DDXPointPtr ppt)
+{
+	_glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE);
+}
+
+Bool
+glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		     DDXPointPtr ppt)
+{
+	return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE);
+}
+
+static Bool
+_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+		     xSegment *pSeg, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_gc(pGC)
+	    && glamor_ddx_fallback_check_pixmap(pDrawable))
+		goto fail;
+	/* For lineWidth is not zero, fb calls to mi functions. */
+	if (pGC->lineWidth == 0) {
+		glamor_prepare_access_gc(pGC);
+		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+		fbPolySegment(pDrawable, pGC, nseg, pSeg);
+		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+		glamor_finish_access_gc(pGC);
+	} else
+	fbPolySegment(pDrawable, pGC, nseg, pSeg);
+
+	return TRUE;
+
+fail:
+	return FALSE;
+}
+
+void
+glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+		    xSegment *pSeg)
+{
+	_glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE);
+}
+
+Bool
+glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+		     xSegment *pSeg)
+{
+	return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
+}
+
+static Bool
+_glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		  DDXPointPtr ppt, Bool fallback)
+{
+	if (!fallback 
+	    && glamor_ddx_fallback_check_gc(pGC)
+	    && glamor_ddx_fallback_check_pixmap(pDrawable))
+		goto fail;
+	/* For lineWidth is not zero, fb calls to mi functions. */
+	if (pGC->lineWidth == 0) {
+		glamor_prepare_access_gc(pGC);
+		glamor_prepare_access(pDrawable, GLAMOR_ACCESS_RW);
+		fbPolyLine(pDrawable, pGC, mode, npt, ppt);
+		glamor_finish_access(pDrawable, GLAMOR_ACCESS_RW);
+		glamor_finish_access_gc(pGC);
+	} else
+	fbPolyLine(pDrawable, pGC, mode, npt, ppt);
+
+	return TRUE;
+
+fail:
+	return FALSE;
+}
+
+void
+glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		 DDXPointPtr ppt)
+{
+	_glamor_poly_line(pDrawable, pGC, mode, npt, ppt, TRUE);
+}
+
+Bool
+glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		    DDXPointPtr ppt)
+{
+	return _glamor_poly_line(pDrawable, pGC, mode, npt, ppt, FALSE);
+}
+
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 72d7867..4bd169b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -550,12 +550,42 @@ void
 glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
 		 unsigned int format, unsigned long planeMask, char *d);
 
-
 void
 glamor_add_traps(PicturePtr pPicture,
 		 INT16 x_off, 
 		 INT16 y_off, int ntrap, xTrap * traps);
 
+RegionPtr
+glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+		  int srcx, int srcy, int w, int h, int dstx, int dsty,
+		  unsigned long bitPlane);
+
+void
+glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase);
+
+void
+glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
+                    int x, int y, unsigned int nglyph,
+                    CharInfoPtr * ppci, pointer pglyphBase);
+
+void
+glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
+		   DrawablePtr pDrawable, int w, int h, int x, int y);
+
+void
+glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		  DDXPointPtr ppt);
+
+void
+glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+		    xSegment *pSeg);
+
+void
+glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+		 DDXPointPtr ppt);
+
 #include"glamor_utils.h"
 
 /* Dynamic pixmap upload to texture if needed. 
commit d42eb04c29d015fb1e4ed4e9ded4c0dd8bc7dc3c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Dec 31 19:27:33 2011 +0800

    Remove useless output messages.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index bd5192c..f5a6e75 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -117,7 +117,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
 	    || ((tile_y != 0)
 		&& (tile_y + height > tile->drawable.height))) {
-		ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
 		goto fail;
 	}
 	if (glamor_priv->tile_prog == 0) {
commit fbccc4bbbc84a5459010d3238a00a0dd49111eec
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Dec 31 19:20:10 2011 +0800

    Fixed a rendering bug at fillspans.
    
    We should not change the points coords when loop for the clip
    rects. Change to use another variable to store the clipped
    coords and keep the original coords. This bug cause some
    XTS failures. Now fix it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 94cb81e..97c4403 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -55,19 +55,19 @@ _glamor_fill_spans(DrawablePtr drawable,
 		nbox = REGION_NUM_RECTS(pClip);
 		pbox = REGION_RECTS(pClip);
 		while (nbox--) {
-			if (pbox->y1 > y || pbox->y2 <= y)
-				continue;
+			int real_x1 = x1, real_x2 = x2;
 
-			if (x1 < pbox->x1)
-				x1 = pbox->x1;
+			if (real_x1 < pbox->x1)
+				real_x1 = pbox->x1;
 
-			if (x2 > pbox->x2)
-				x2 = pbox->x2;
+			if (real_x2 > pbox->x2)
+				real_x2 = pbox->x2;
 
-			if (x2 <= x1)
-				continue;
-			if (!glamor_fill(drawable, gc, x1, y, x2 - x1, 1, fallback))
-				goto fail;
+			if (real_x2 > real_x1 && pbox->y1 <= y && pbox->y2 > y) {
+				if (!glamor_fill(drawable, gc, real_x1, y, 
+						 real_x2 - real_x1, 1, fallback))
+					goto fail;
+			}
 			pbox++;
 		}
 	}
commit 70b6341538cc11f074b02f9dd97d387418245d77
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sat Dec 31 19:14:06 2011 +0800

    Fixed a bug at putImage.
    
    fbPutImage wants the input drawable is the target drawable rather
    than the backing pixmap. This bug cause some XTS failures, now
    fix it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index f69e719..7967e25 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -403,7 +403,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
-		fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h,
+		fbPutImage(drawable, gc, depth, x, y, w, h,
 			   left_pad, image_format, bits);
 		glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RW);
 	}
commit 27c4c0457dac307500859ca7a14a1e58465d5e0b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Dec 27 16:44:17 2011 +0800

    Remove the assertion which is not safe sometimes.
    
    The original version assumes that each drawable pixmap should
    have a valid private pixmap pointer. But this is not true after
    we create this libglamor. As the DDX layer may create a pure
    software drawable pixmap which doesn't have a private pixmap
    pointer.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index a021109..940c9d7 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -16,9 +16,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
 	glamor_pixmap_private *pixmap_priv;
 	assert(picture->pDrawable);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-	pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-	assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1);
 	return glamor_upload_pixmap_to_texture(pixmap);
 }
 
@@ -65,8 +63,7 @@ glamor_create_picture(PicturePtr picture)
 		pixmap_priv->is_picture = 1;
 		pixmap_priv->pict_format = picture->format;
 		/* XXX Some formats are compatible between glamor and ddx driver*/
-		if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
-		    /*&& pixmap_priv->pict_format != PICT_b8g8r8a8*/)
+		if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
 			glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
 	}
 	return glamor_priv->saved_create_picture(picture);
commit c65dc686228262894e0afc9fbe9fe6635d420e2f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Dec 27 16:42:32 2011 +0800

    Export glamor_validate_gc to DDX.
    
    This is also a function which may direct access pixmaps which
    may be a glamor only pixmap and DDX doesn't know how to access
    it. We have to export this API to DDX driver and let the DDX
    driver use it to do the validation.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index a15cdc4..fc8c152 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -183,6 +183,8 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
 #endif
 
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
+
+extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
 /* Glamor rendering/drawing functions with XXX_nf. 
  * nf means no fallback within glamor internal if possible. If glamor
  * fail to accelerate the operation, glamor will return a false, and the
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 54e110a..9a1b770 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -366,7 +366,7 @@ GCOps glamor_gc_ops = {
  * uxa_validate_gc() sets the ops to glamor's implementations, which may be
  * accelerated or may sync the card and fall back to fb.
  */
-static void
+void
 glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
 	/* fbValidateGC will do direct access to pixmaps if the tiling has changed.
commit f2809745fb641239be5b0281eac569c5b371e55e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 23 16:21:44 2011 +0800

    Flush gl operations when destroy an textured image.
    
    Before destroy an image which was attached to a texture.
    we must call glFlush to make sure the operation on that
    texture has been done.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 1450abb..7eca5ad 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -249,8 +249,13 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 	if (pixmap->refcnt == 1) {
 		image = dixLookupPrivate(&pixmap->devPrivates,
 					 glamor_egl_pixmap_private_key);
-		if (image != EGL_NO_IMAGE_KHR && image != NULL)
+		if (image != EGL_NO_IMAGE_KHR && image != NULL) {
+			/* Before destroy an image which was attached to 
+ 			 * a texture. we must call glFlush to make sure the 
+ 			 * operation on that texture has been done.*/
+			glamor_block_handler(pixmap->drawable.pScreen);
 			eglDestroyImageKHR(glamor_egl->display, image);
+		}
 	}
 	glamor_destroy_textured_pixmap(pixmap);
 }
commit b36d264ec98440707ed3a94fab430e23d4a1582a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 23 16:19:39 2011 +0800

    Add a new API glamor_create_gc.
    
    As at ValidateGC stage, it may need to touch the pixmap directly, for
    example the tile pixmap. We must export this interface to DDX driver
    and let the DDX driver to route the processing to us. As this pixmap
    may be a texture only pixmap, and DDX don't know how to handle it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 4c01623..a15cdc4 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -182,6 +182,7 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
 
 #endif
 
+extern _X_EXPORT int glamor_create_gc(GCPtr gc);
 /* Glamor rendering/drawing functions with XXX_nf. 
  * nf means no fallback within glamor internal if possible. If glamor
  * fail to accelerate the operation, glamor will return a false, and the
commit 3ba546b6998bf1c5d68ff0083017f804ffc48a93
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 23 16:18:22 2011 +0800

    Code cleanup.
    
    Remove useless code, and after a fbCreatePixmap, we
    do not need to modify its header there.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 630df4f..bbcf942 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -156,17 +156,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		   If we exceed such limitation, we have to use framebuffer. */
 		type = GLAMOR_MEMORY;
 		pixmap = fbCreatePixmap(screen, w, h, depth, usage);
-		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-					   (((w *
-					      pixmap->
-					      drawable.bitsPerPixel +
-					      7) / 8) + 3) & ~3, NULL);
-#if 0
-		if (usage != GLAMOR_CREATE_PIXMAP_CPU)
-			glamor_fallback("choose cpu memory for pixmap %p ,"
-					" %d x %d depth %d\n", pixmap, w,
-					h, depth);
-#endif
 	} else
 		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
 
commit 2583620c6cd6a6fedeb7082b526f2751eb6f75b4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 23 14:23:56 2011 +0800

    Remove useless egl functions.
    
    We only need to create image fron external name rather
    than use drm_image_mesa to create drm image, so remove
    them.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 7cc52c8..1450abb 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -87,8 +87,6 @@ struct glamor_egl_screen_private {
 	int cpp;
 	struct gbm_device *gbm;
 
-	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
-	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
 	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
 	struct glamor_gl_dispatch *dispatch;
@@ -353,8 +351,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
 #endif
 
-	glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
-	    eglGetProcAddress("eglExportDRMImageMESA");
 	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
 	    eglGetProcAddress("eglCreateImageKHR");
 
@@ -363,7 +359,6 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	    eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
 	if (!glamor_egl->egl_create_image_khr
-	    || !glamor_egl->egl_export_drm_image_mesa
 	    || !glamor_egl->egl_image_target_texture2d_oes) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglGetProcAddress() failed\n");
commit 7285f2e836c56c31a42b8c18a7ebd0e8a7d78fa1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 16 20:15:33 2011 +0800

    Make sure the devPrivate.ptr of a textured pixmap is NULL.
    
    Just in case when wrongly fallback to DDX layer and cause
    random memory corruption. Pointed out by Chris.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 3693683..630df4f 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -116,6 +116,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 					      pixmap->drawable.
 					      bitsPerPixel + 7) / 8) +
 					    3) & ~3, NULL);
+	pixmap->devPrivate.ptr = NULL;
 }
 
 /* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */
commit 5769d8603ddef6a8023f12bba1d3d3cde83e82d4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 16 15:04:33 2011 +0800

    Export glamor_create_texture to DDX driver.
    
    If DDX failed to create textured pixmap from its BO's handle,
    it can turn to call this API to create a brand new glamor
    rather than fallback to pure in memory pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index eace128..4c01623 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -90,12 +90,29 @@ typedef enum  glamor_pixmap_type {
 } glamor_pixmap_type_t;
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
-
+/* @glamor_init: Initialize glamor internal data structure.
+ *
+ * @screen: Current screen pointer.
+ * @flags:  Please refer the flags description above.
+ *
+ * This function initializes necessary internal data structure
+ * for glamor. And before calling into this function, the OpenGL
+ * environment should be ready. Should be called before any real 
+ * glamor rendering or texture allocation functions. 
+ */
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
 						       int w, int h,
 						       unsigned int tex);
+/* @glamor_glyphs_init: Initialize glyphs internal data structures.
+ *
+ * @pScreen: Current screen pointer.
+ *
+ * This function must be called after the glamor_init and the texture
+ * can be allocated. An example is to call it when create the screen
+ * resources at DDX layer.
+ */
 extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
 
 extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
@@ -104,21 +121,65 @@ extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
 extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type);
 extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
+extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+						unsigned int usage);
 
 #ifdef GLAMOR_FOR_XORG
+/* @glamor_egl_init: Initialize EGL environment.
+ *
+ * @scrn: Current screen info pointer.
+ * @fd:   Current drm fd.
+ *
+ * This function creates and intialize EGL contexts. 
+ * Should be called from DDX's preInit function.
+ * Return TRUE if success, otherwise return FALSE.
+ * */
 extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
+
+/* @glamor_egl_init_textured_pixmap: Initialization for textured pixmap allocation.
+ *
+ * @screen: Current screen pointer.
+ *
+ * This function must be called before any textured pixmap's creation including
+ * the screen pixmap. Could be called from DDX's screenInit function after the calling
+ * to glamor_init..
+ */
+extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
+
+/* @glamor_egl_create_textured_screen: Create textured screen pixmap.
+ *
+ * @screen: screen pointer to be processed.
+ * @handle: screen pixmap's BO handle.
+ * @stride: screen pixmap's stride in bytes.
+ *
+ * This function is similar with the create_textured_pixmap. As the
+ * screen pixmap is a special, we handle it separately in this function.
+ */
 extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
 							int handle,
 							int stride);
+
+/*
+ * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
+ * 				       a BO handle.
+ * 
+ * @pixmap: The pixmap need to be processed.
+ * @handle: The BO's handle attached to this pixmap at DDX layer.
+ * @stride: Stride in bytes for this pixmap.
+ *
+ * This function try to create a texture from the handle and attach
+ * the texture to the pixmap , thus glamor can render to this pixmap
+ * as well. Return true if successful, otherwise return FALSE.
+ */
 extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
 							int handle,
 							int stride);
 
+extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
+
 extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen);
 extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
 
-extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
-extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
 
 /* Glamor rendering/drawing functions with XXX_nf. 
commit 3f5d53b33978bdb848dd605a19d3fb4ea5f259e0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 16 15:02:54 2011 +0800

    Correct the logic of glamor_egl_create_textured_pixmap.
    
    Discussed with Chris and found the previous logic is not
    good. Now change it in this commit, this API will just
    try to create a textured pixmap from the handle provided
    by DDX driver, if failed simply return FALSE without touch
    the pixmap. And the DDX driver can choose how to do next
    step.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a157000..7cc52c8 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -204,10 +204,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 	return TRUE;
 }
 
-/*
- * This function will be called from the dri buffer allocation.
- * It is somehow very familiar with the create textured screen.
- */
 Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
@@ -218,8 +214,6 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
-	int ret;
-	glamor_pixmap_type_t type;
 
 	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -233,42 +227,17 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 					 ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
 					 name,
 					 pixmap->drawable.depth);
-	if (image == EGL_NO_IMAGE_KHR) {
-		GLenum format;
-		/* we have to create separated texture here. The reason is, if
- 		 * a DRM-buffer-only pixmap exist, and given a texture only
- 		 * pixmap as a source, then we will don't know how to render it
- 		 * within glamor, and we even can't find a good way to fallback
- 		 * to DDX driver, as DDX driver don't understand a texture only
- 		 * pixmap. */
-		type = GLAMOR_SEPARATE_TEXTURE;
-		if (pixmap->drawable.depth == 24) 
-			format = GL_RGB;
-		else
-			format = GL_RGBA;
-		glamor_egl->dispatch->glGenTextures(1, &texture);
-		glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, texture);
-		glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-						      GL_NEAREST);
-		glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-						      GL_NEAREST);
-		glamor_egl->dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, pixmap->drawable.width, 
-						   pixmap->drawable.height, 0, format,
-						   GL_UNSIGNED_BYTE, NULL);
-		ret = FALSE;
-	} else {
-		type = GLAMOR_TEXTURE_DRM;
-		glamor_create_texture_from_image(glamor_egl, image, &texture);
-		ret = TRUE;
-	}
+	if (image == EGL_NO_IMAGE_KHR) 
+		return FALSE;
 
-	glamor_set_pixmap_type(pixmap, type);
+	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
 				  pixmap->drawable.height, texture);
 	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
 		      image);
 
-	return ret;
+	return TRUE;
 }
 
 void
@@ -327,7 +296,6 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
 	return FALSE;
 }
 
-
 Bool
 glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
@@ -347,20 +315,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 		    xf86AllocateScrnInfoPrivateIndex();
 
 	scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
-
 	glamor_egl->fd = fd;
-
-	glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
-
-	if (glamor_egl->display == EGL_NO_DISPLAY) {
-		glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
-		if (glamor_egl->gbm == NULL) {
-			ErrorF("couldn't get display device\n");
-			return FALSE;
-		}
+	glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
+	if (glamor_egl->gbm == NULL) {
+		ErrorF("couldn't get display device\n");
+		return FALSE;
 	}
-
 	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
+
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
 #else
commit 8c7fcefb965bfdaaf0576347da20155d0415caa5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Dec 13 22:48:34 2011 +0800

    glamor-for-ddx: Exports all rendering/drawing functions.
    
    This commit exports all the rest rendering/drawing functions
    to the DDX drivers. And introduce some new pixmap type. For
    a pixmap which has a separated texture, we never fallback
    it to the DDX layer.
    
    This commit also adds the following new functions:
    glamor_composite_rects, glamor_get_image_nf which are needed
    by UXA framework. Just a simple wrapper function of miXXX.
    Will consider to optimize them next few weeks.
    
    This commit also Fixed a glyphs rendering bug pointed by Chris.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index a382eb5..17a3e77 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -34,11 +34,13 @@ libglamor_la_SOURCES = \
 	glamor_setspans.c \
 	glamor_render.c \
 	glamor_tile.c \
-        glamor_triangles.c\
-        glamor_pixmap.c\
-        glamor_picture.c\
+	glamor_triangles.c\
+	glamor_addtraps.c\
+	glamor_getimage.c\
+	glamor_pixmap.c\
+	glamor_picture.c\
 	glamor_window.c\
-        glamor_gl_dispatch.c\
+	glamor_gl_dispatch.c\
 	glamor.h
 
 sdk_HEADERS = glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 41afd33..3693683 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -374,7 +374,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		screen->GetSpans = glamor_get_spans;
 
 		glamor_priv->saved_get_image = screen->GetImage;
-		screen->GetImage = miGetImage;
+		screen->GetImage = glamor_get_image;
 
 		glamor_priv->saved_change_window_attributes =
 		    screen->ChangeWindowAttributes;
@@ -402,6 +402,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		glamor_priv->saved_triangles = ps->Triangles;
 		ps->Triangles = glamor_triangles;
 
+		glamor_priv->saved_addtraps = ps->AddTraps;
+		ps->AddTraps = glamor_add_traps;
+
 		glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
 		ps->UnrealizeGlyph = glamor_glyph_unrealize;
 	}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 6febb59..eace128 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -41,9 +41,30 @@
 
 #endif				/* GLAMOR_H */
 
+/* @GLAMOR_INVERTED_Y_AXIS:
+ * set 1 means the GL env's origin (0,0) is at top-left. 
+ * EGL/DRM platform is an example need to set this bit.
+ * glx platform's origin is at bottom-left thus need to
+ * clear this bit.*/
 
 #define GLAMOR_INVERTED_Y_AXIS  	1
+
+/* @GLAMOR_USE_SCREEN:
+ * If want to let glamor to do everything including the
+ * create/destroy pixmap and handle the gc ops. need to
+ * set this bit. Standalone glamor DDX driver need to set
+ * this bit.
+ * Otherwise, need to clear this bit, as the intel video 
+ * driver with glamor enabled.
+ * */
 #define GLAMOR_USE_SCREEN		2
+/* @GLAMOR_USE_PICTURE_SCREEN:
+ * If want to let glamor to do all the composition related
+ * things, need to set this bit. Just as standalone glamor
+ * DDX driver.
+ * Otherwise, need to clear this bit, as the intel video
+ * driver with glamor enabled.
+ */
 #define GLAMOR_USE_PICTURE_SCREEN 	4
 
 #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
@@ -54,12 +75,16 @@
  * glamor_pixmap_type : glamor pixmap's type.
  * @MEMORY: pixmap is in memory.
  * @TEXTURE_DRM: pixmap is in a texture created from a DRM buffer.
+ * @SEPARATE_TEXTURE: The texture is created from a DRM buffer, but
+ * 		      the format is incompatible, so this type of pixmap
+ * 		      will never fallback to DDX layer.
  * @DRM_ONLY: pixmap is in a external DRM buffer.
  * @TEXTURE_ONLY: pixmap is in an internal texture.
  */
 typedef enum  glamor_pixmap_type {
 	GLAMOR_MEMORY,
 	GLAMOR_TEXTURE_DRM,
+	GLAMOR_SEPARATE_TEXTURE,
 	GLAMOR_DRM_ONLY,
 	GLAMOR_TEXTURE_ONLY
 } glamor_pixmap_type_t;
@@ -96,6 +121,11 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
 extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
 
+/* Glamor rendering/drawing functions with XXX_nf. 
+ * nf means no fallback within glamor internal if possible. If glamor
+ * fail to accelerate the operation, glamor will return a false, and the
+ * caller need to implement fallback method. Return a true means the
+ * rendering request get done successfully. */
 extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
 					   GCPtr gc,
 					   int n, DDXPointPtr points, 
@@ -157,4 +187,22 @@ extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
 
 extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 
+extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
+					  DDXPointPtr points, int *widths, int n, int sorted);
+
+extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
+					  DDXPointPtr points, int *widths, int count, char *dst);
+
+extern _X_EXPORT Bool glamor_composite_rects_nf (CARD8         op,
+						 PicturePtr    pDst,
+						 xRenderColor  *color,
+						 int           nRect,
+						 xRectangle    *rects);
+
+extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h,
+					  unsigned int format, unsigned long planeMask, char *d);
+
+extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
+					  INT16 x_off, 
+					  INT16 y_off, int ntrap, xTrap * traps);
 
diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c
new file mode 100644
index 0000000..28775e5
--- /dev/null
+++ b/glamor/glamor_addtraps.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+static Bool
+_glamor_add_traps(PicturePtr pPicture,
+		  INT16 x_off, 
+		  INT16 y_off, int ntrap, xTrap * traps,
+		  Bool fallback)
+{
+	if (!fallback
+	    && ( !pPicture->pDrawable 
+		 || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
+		return FALSE;
+
+	if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
+		fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
+		glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW);
+	}
+
+	return TRUE;
+}
+
+void
+glamor_add_traps(PicturePtr pPicture,
+		 INT16 x_off, 
+		 INT16 y_off, int ntrap, xTrap * traps)
+{
+	_glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
+}
+
+Bool
+glamor_add_traps_nf(PicturePtr pPicture,
+		    INT16 x_off, 
+		    INT16 y_off, int ntrap, xTrap * traps)
+{
+	return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
+}
+
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 625647d..049979a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -317,15 +317,17 @@ _glamor_copy_n_to_n(DrawablePtr src,
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
 
-	if (!dst_pixmap_priv || !src_pixmap_priv)
-		goto fail;
-
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+	if (!dst_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_fallback("dest pixmap %p has no fbo. \n",
 				dst_pixmap);
 		goto fail;
 	}
 
+	if (!src_pixmap_priv) {
+		glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
+		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	}
+
 	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
 				   &src_y_off);
 	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
@@ -398,7 +400,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
 
       fail:
 	
-	if (!fallback) {
+	if (!fallback 
+	    && glamor_ddx_fallback_check_pixmap(src)
+	    && glamor_ddx_fallback_check_pixmap(dst)) {
 		ret = FALSE;
 		goto done;
 	} 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index b66d358..a157000 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -65,8 +65,7 @@
 static const char glamor_name[] = "glamor";
 
 static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
-DevPrivateKey glamor_egl_pixmap_private_key =
-    &glamor_egl_pixmap_private_key_index;
+DevPrivateKey glamor_egl_pixmap_private_key = &glamor_egl_pixmap_private_key_index;
 
 static void
 glamor_identify(int flags)
@@ -121,8 +120,6 @@ _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
 		    EGL_DRM_BUFFER_USE_SCANOUT_MESA,
 		EGL_NONE
 	};
-
-
 	attribs[1] = width;
 	attribs[3] = height;
 	attribs[5] = stride;
@@ -221,14 +218,15 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
+	int ret;
+	glamor_pixmap_type_t type;
 
 	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Couldn't flink pixmap handle\n");
-		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
-		return FALSE;
+		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
+		exit(1);
 	}
-
 	image = _glamor_egl_create_image(glamor_egl,
 					 pixmap->drawable.width,
 					 pixmap->drawable.height,
@@ -236,18 +234,41 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 					 name,
 					 pixmap->drawable.depth);
 	if (image == EGL_NO_IMAGE_KHR) {
-		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
-		return FALSE;
+		GLenum format;
+		/* we have to create separated texture here. The reason is, if
+ 		 * a DRM-buffer-only pixmap exist, and given a texture only
+ 		 * pixmap as a source, then we will don't know how to render it
+ 		 * within glamor, and we even can't find a good way to fallback
+ 		 * to DDX driver, as DDX driver don't understand a texture only
+ 		 * pixmap. */
+		type = GLAMOR_SEPARATE_TEXTURE;
+		if (pixmap->drawable.depth == 24) 
+			format = GL_RGB;
+		else
+			format = GL_RGBA;
+		glamor_egl->dispatch->glGenTextures(1, &texture);
+		glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, texture);
+		glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+						      GL_NEAREST);
+		glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+						      GL_NEAREST);
+		glamor_egl->dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, pixmap->drawable.width, 
+						   pixmap->drawable.height, 0, format,
+						   GL_UNSIGNED_BYTE, NULL);
+		ret = FALSE;
+	} else {
+		type = GLAMOR_TEXTURE_DRM;
+		glamor_create_texture_from_image(glamor_egl, image, &texture);
+		ret = TRUE;
 	}
 
-	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_pixmap_type(pixmap, type);
 	glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
 				  pixmap->drawable.height, texture);
-
-	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
 		      image);
-	return TRUE;
+
+	return ret;
 }
 
 void
@@ -261,7 +282,7 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 	if (pixmap->refcnt == 1) {
 		image = dixLookupPrivate(&pixmap->devPrivates,
 					 glamor_egl_pixmap_private_key);
-		if (image != EGL_NO_IMAGE_KHR)
+		if (image != EGL_NO_IMAGE_KHR && image != NULL)
 			eglDestroyImageKHR(glamor_egl->display, image);
 	}
 	glamor_destroy_textured_pixmap(pixmap);
@@ -357,10 +378,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
 
 #define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
-        if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
-               ErrorF("EGL_" #EXT "required.\n");  \
-               return FALSE;  \
-        }
+	if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
+		ErrorF("EGL_" #EXT "required.\n");  \
+		return FALSE;  \
+	}
 
 	GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
 	GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 10baeb3..d36313a 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -82,7 +82,12 @@ glamor_fill(DrawablePtr drawable,
 	return TRUE;
 
       fail:
-	if (!fallback) return FALSE;
+	if (!fallback) {
+		if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
+		   && glamor_ddx_fallback_check_gc(gc))
+		return FALSE;
+	}
+
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		if (glamor_prepare_access_gc(gc)) {
 			fbFill(drawable, gc, x, y, width, height);
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index bbe0985..94cb81e 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -74,7 +74,10 @@ _glamor_fill_spans(DrawablePtr drawable,
 	return TRUE;
 
       fail:
-	if (!fallback) return FALSE;
+	if (!fallback 
+	    && glamor_ddx_fallback_check_pixmap(drawable)
+	    && glamor_ddx_fallback_check_gc(gc))
+		return FALSE;
 	glamor_fallback("to %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
new file mode 100644
index 0000000..7a9280b
--- /dev/null
+++ b/glamor/glamor_getimage.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+
+static Bool
+_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+		  unsigned int format, unsigned long planeMask, char *d,
+		  Bool fallback)
+{
+	miGetImage(pDrawable, x, y, w, h, format, planeMask, d);
+	return TRUE;
+}
+
+void
+glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+		 unsigned int format, unsigned long planeMask, char *d)
+{
+	_glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE);
+	return;
+}
+
+Bool
+glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h,
+		    unsigned int format, unsigned long planeMask, char *d)
+{
+	return _glamor_get_image(pDrawable, x, y, w, 
+				 h, format, planeMask, d, FALSE);
+}
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 1fa4b4c..4d4108d 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -31,10 +31,11 @@
 
 #include "glamor_priv.h"
 
-void
-glamor_get_spans(DrawablePtr drawable,
-		 int wmax,
-		 DDXPointPtr points, int *widths, int count, char *dst)
+static Bool 
+_glamor_get_spans(DrawablePtr drawable,
+		  int wmax,
+		  DDXPointPtr points, int *widths, int count, char *dst,
+		  Bool fallback)
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	GLenum format, type;
@@ -49,7 +50,7 @@ glamor_get_spans(DrawablePtr drawable,
 	uint8_t *readpixels_dst = (uint8_t *) dst;
 	int x_off, y_off;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("pixmap has no fbo.\n");
 		goto fail;
 	}
@@ -94,14 +95,39 @@ glamor_get_spans(DrawablePtr drawable,
 	}
 	if (temp_pixmap)
 		glamor_destroy_pixmap(temp_pixmap);
-	return;
+	return TRUE;
 
       fail:
+
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(drawable))
+		return FALSE; 
 	glamor_fallback("from %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
 		fbGetSpans(drawable, wmax, points, widths, count, dst);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
 	}
+	return TRUE;
 }
 
+void
+glamor_get_spans(DrawablePtr drawable,
+		 int wmax,
+		 DDXPointPtr points, int *widths, int count, char *dst)
+{
+	_glamor_get_spans(drawable, wmax, points, 
+			  widths, count, dst, TRUE);
+}
+
+Bool
+glamor_get_spans_nf(DrawablePtr drawable,
+		    int wmax,
+		    DDXPointPtr points, int *widths, int count, char *dst)
+{
+	return _glamor_get_spans(drawable, wmax, points, 
+				 widths, count, dst, FALSE);
+}
+
+
+
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index d61d74b..33e06f1 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -184,7 +184,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 					CPComponentAlpha, &component_alpha,
 					serverClient, &error);
 
-		glamor_destroy_pixmap(pixmap);
+		pScreen->DestroyPixmap(pixmap);
 		if (!picture)
 			goto bail;
 
@@ -239,12 +239,57 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 	ValidateGC(&pCachePixmap->drawable, gc);
 
 	scratch = pGlyphPixmap;
+	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
+		scratch = glamor_create_pixmap(screen,
+					       glyph->info.width,
+					       glyph->info.height,
+					       pCachePixmap->
+					       drawable.depth, 0);
+		if (scratch) {
+			if (pGlyphPixmap->drawable.depth !=
+			    pCachePixmap->drawable.depth) {
+				PicturePtr picture;
+				int error;
+
+				picture =
+				    CreatePicture(0,
+						  &scratch->drawable,
+						  PictureMatchFormat
+						  (screen,
+						   pCachePixmap->
+						   drawable.depth,
+						   cache->picture->format),
+						  0, NULL, serverClient,
+						  &error);
+				if (picture) {
+					ValidatePicture(picture);
+					glamor_composite(PictOpSrc,
+						      pGlyphPicture,
+						      NULL, picture,
+						      0, 0, 0, 0, 0,
+						      0,
+						      glyph->info.width,
+						      glyph->info.height);
+					FreePicture(picture, 0);
+				}
+			} else {
+				glamor_copy_area(&pGlyphPixmap->drawable,
+						 &scratch->drawable,
+						 gc, 0, 0,
+						 glyph->info.width,
+						 glyph->info.height, 0, 0);
+			}
+		} else {
+			scratch = pGlyphPixmap;
+		}
+	}
+
 	(*gc->ops->CopyArea)(&scratch->drawable, &pCachePixmap->drawable, gc,
 			     0, 0, glyph->info.width, glyph->info.height, x,
 			     y);
 
 	if (scratch != pGlyphPixmap)
-		glamor_destroy_pixmap(scratch);
+		screen->DestroyPixmap(scratch);
 
 	FreeScratchGC(gc);
 }
@@ -581,8 +626,8 @@ static void
 glamor_glyphs_flush_mask(PicturePtr mask, glamor_glyph_buffer_t * buffer)
 {
 #ifdef RENDER
-	glamor_composite_rects(PictOpAdd, buffer->source, NULL, mask,
-			       buffer->count, buffer->rects);
+	glamor_composite_glyph_rects(PictOpAdd, buffer->source, NULL, mask,
+				     buffer->count, buffer->rects);
 #endif
 	buffer->count = 0;
 	buffer->source = NULL;
@@ -638,7 +683,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			     mask_format, CPComponentAlpha,
 			     &component_alpha, serverClient, &error);
 	if (!mask) {
-		glamor_destroy_pixmap(mask_pixmap);
+		screen->DestroyPixmap(mask_pixmap);
 		return;
 	}
 	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
@@ -695,7 +740,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			 x_src + x - x_dst,
 			 y_src + y - y_dst, 0, 0, x, y, width, height);
 	FreePicture(mask, 0);
-	glamor_destroy_pixmap(mask_pixmap);
+	screen->DestroyPixmap(mask_pixmap);
 }
 
 static void
@@ -714,7 +759,7 @@ glamor_glyphs_flush_dst(CARD8 op,
 		rect->y_src = y_src + rect->y_dst - y_dst;
 	}
 
-	glamor_composite_rects(op, src, buffer->source, dst,
+	glamor_composite_glyph_rects(op, src, buffer->source, dst,
 			       buffer->count, &buffer->rects[0]);
 
 	buffer->count = 0;
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 3b5d568..a021109 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -42,7 +42,7 @@ glamor_finish_access_picture(PicturePtr picture, glamor_access_t access)
 }
 
 /* 
- * We should already has drawable attached to it, if it has one.
+ * We should already have drawable attached to it, if it has one.
  * Then set the attached pixmap to is_picture format, and set
  * the pict format.
  * */
@@ -64,6 +64,10 @@ glamor_create_picture(PicturePtr picture)
 	if (pixmap_priv) {
 		pixmap_priv->is_picture = 1;
 		pixmap_priv->pict_format = picture->format;
+		/* XXX Some formats are compatible between glamor and ddx driver*/
+		if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
+		    /*&& pixmap_priv->pict_format != PICT_b8g8r8a8*/)
+			glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
 	}
 	return glamor_priv->saved_create_picture(picture);
 }
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 8a691bb..32afd09 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -94,7 +94,12 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 	return TRUE;
 
       fail:
-	if (!fallback) return FALSE;
+
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(drawable)
+	    && glamor_ddx_fallback_check_gc(gc))
+		return FALSE;
+
 	glamor_fallback(" to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b969008..72d7867 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -147,6 +147,7 @@ typedef struct glamor_screen_private {
 	CopyWindowProcPtr saved_copy_window;
 	BitmapToRegionProcPtr saved_bitmap_to_region;
 	TrianglesProcPtr saved_triangles;
+	AddTrapsProcPtr saved_addtraps;
 	CreatePictureProcPtr saved_create_picture;
 	DestroyPictureProcPtr saved_destroy_picture;
 	UnrealizeGlyphProcPtr saved_unrealize_glyph;
@@ -444,10 +445,16 @@ void glamor_trapezoids(CARD8 op,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		       int ntrap, xTrapezoid * traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
-void glamor_composite_rects(CARD8 op,
-			    PicturePtr src, PicturePtr mask,
-			    PicturePtr dst, int nrect,
-			    glamor_composite_rect_t * rects);
+void glamor_composite_glyph_rects(CARD8 op,
+				  PicturePtr src, PicturePtr mask,
+				  PicturePtr dst, int nrect,
+				  glamor_composite_rect_t * rects);
+void glamor_composite_rects (CARD8         op,
+			     PicturePtr    pDst,
+			     xRenderColor  *color,
+			     int           nRect,
+			     xRectangle    *rects);
+
 
 /* glamor_tile.c */
 Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
@@ -536,10 +543,19 @@ enum glamor_pixmap_status
  glamor_upload_picture_to_texture(PicturePtr picture);
 
 void
-
 glamor_picture_format_fixup(PicturePtr picture,
 			    glamor_pixmap_private * pixmap_priv);
 
+void
+glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+		 unsigned int format, unsigned long planeMask, char *d);
+
+
+void
+glamor_add_traps(PicturePtr pPicture,
+		 INT16 x_off, 
+		 INT16 y_off, int ntrap, xTrap * traps);
+
 #include"glamor_utils.h"
 
 /* Dynamic pixmap upload to texture if needed. 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 6101850..f69e719 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -395,7 +395,11 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
       fail:
 	glamor_set_planemask(pixmap, ~0);
-	if (!fallback) return FALSE;
+
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
+		return FALSE;
+
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f219c29..4a2a438 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1155,7 +1155,6 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	PicturePtr dst;
 	int error;
 	PictFormatShort format;
-
 	if (!source->pDrawable)
 		format = PICT_a8r8g8b8;
 	else
@@ -1176,7 +1175,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 					       PIXMAN_FORMAT_DEPTH(format),
 					       format),
 			    0, 0, serverClient, &error);
-	screen->DestroyPixmap(pixmap);
+	glamor_destroy_pixmap(pixmap);
 	if (!dst)
 		return NULL;
 
@@ -1226,18 +1225,24 @@ _glamor_composite(CARD8 op,
 	}
 
 	if (source->pDrawable) {
-		source_pixmap =
-		    glamor_get_drawable_pixmap(source->pDrawable);
-		source_pixmap_priv =
-		    glamor_get_pixmap_private(source_pixmap);
-		if (!source_pixmap_priv || source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		if (!source_pixmap_priv) {
+			glamor_set_pixmap_type(source_pixmap, GLAMOR_MEMORY);
+			source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+		}
+		if (source_pixmap_priv->type == GLAMOR_DRM_ONLY)
 			goto fail;
 	}
 
 	if (mask && mask->pDrawable) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		if (!mask_pixmap_priv || mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+		if (!mask_pixmap_priv) {
+			glamor_set_pixmap_type(mask_pixmap, GLAMOR_MEMORY);
+			mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		}
+		if (mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
 			goto fail;
 	}
 	if ((!source->pDrawable
@@ -1336,10 +1341,17 @@ _glamor_composite(CARD8 op,
 
 	dispatch->glUseProgram(0);
 	dispatch->glDisable(GL_BLEND);
-	if (!fallback) {
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
+	    && (!source_pixmap 
+		|| glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
+	    && (!mask_pixmap
+		|| glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
 		ret = FALSE;
 		goto done;
 	}
+
+fallback:
 	glamor_fallback
 	    ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
 	     source, source->pDrawable,
@@ -1564,9 +1576,9 @@ glamor_trapezoids_nf(CARD8 op,
 
 
 void
-glamor_composite_rects(CARD8 op,
-		       PicturePtr src, PicturePtr mask, PicturePtr dst,
-		       int nrect, glamor_composite_rect_t * rects)
+glamor_composite_glyph_rects(CARD8 op,
+			     PicturePtr src, PicturePtr mask, PicturePtr dst,
+			     int nrect, glamor_composite_rect_t * rects)
 {
 	int n;
 	glamor_composite_rect_t *r;
@@ -1592,4 +1604,38 @@ glamor_composite_rects(CARD8 op,
 	}
 }
 
+static Bool
+_glamor_composite_rects (CARD8         op,
+			      PicturePtr    pDst,
+			      xRenderColor  *color,
+			      int           nRect,
+			      xRectangle    *rects,
+			      Bool	    fallback)
+{
+	miCompositeRects(op, pDst, color, nRect, rects);
+	return TRUE;
+}
+
+void
+glamor_composite_rects (CARD8         op,
+			PicturePtr    pDst,
+			xRenderColor  *color,
+			int           nRect,
+			xRectangle    *rects)
+{
+	_glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
+}
+
+Bool
+glamor_composite_rects_nf (CARD8         op,
+			   PicturePtr    pDst,
+			   xRenderColor  *color,
+			   int           nRect,
+			   xRectangle    *rects)
+{
+	return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
+}
+
+
+
 #endif				/* RENDER */
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 4d6fe96..360ca37 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -31,9 +31,10 @@
 
 #include "glamor_priv.h"
 
-void
-glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		 DDXPointPtr points, int *widths, int n, int sorted)
+static Bool
+_glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+		 DDXPointPtr points, int *widths, int n, int sorted,
+		 Bool fallback)
 {
 	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_screen_private *glamor_priv =
@@ -94,13 +95,32 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	glamor_set_planemask(dest_pixmap, ~0);
 	glamor_set_alu(dispatch, GXcopy);
 	dispatch->glDisable(GL_SCISSOR_TEST);
-	return;
+	return TRUE;
       fail:
-
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(drawable))
+		return FALSE;
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		fbSetSpans(drawable, gc, src, points, widths, n, sorted);
 		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
+	return TRUE;
+}
+
+void
+glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+		    DDXPointPtr points, int *widths, int n, int sorted)
+{
+	_glamor_set_spans(drawable, gc, src, points, 
+			     widths, n, sorted, TRUE);
+}
+
+Bool
+glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
+		    DDXPointPtr points, int *widths, int n, int sorted)
+{
+	return _glamor_set_spans(drawable, gc, src, points, 
+				    widths, n, sorted, FALSE);
 }
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index 1ea7fd6..208ac77 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -39,20 +39,23 @@ _glamor_triangles(CARD8 op,
 		 PictFormatPtr maskFormat,
 		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris, Bool fallback)
 {
-	if (!fallback)
+	if (!fallback
+	    && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
+	    && (!pSrc->pDrawable
+		|| glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
 		return FALSE;
-	if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
-		if (pSrc->pDrawable == NULL ||
-		    glamor_prepare_access(pSrc->pDrawable,
-					  GLAMOR_ACCESS_RO)) {
+
+	if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access_picture(pSrc,
+						  GLAMOR_ACCESS_RO)) {
 
 			fbTriangles(op, pSrc, pDst, maskFormat, xSrc,
 				    ySrc, ntris, tris);
+
+			glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO);
 		}
-		if (pSrc->pDrawable != NULL)
-			glamor_finish_access(pSrc->pDrawable, GLAMOR_ACCESS_RO);
 
-		glamor_finish_access(pDst->pDrawable, GLAMOR_ACCESS_RW);
+		glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 265d9ed..4d47f57 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -541,9 +541,34 @@ glamor_get_rgba_from_pixel(CARD32 pixel,
 	return TRUE;
 }
 
+/* return TRUE if we can access this pixmap at DDX driver. */
+inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
+{
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+	return (!pixmap_priv 
+		|| (pixmap_priv->type == GLAMOR_TEXTURE_DRM
+		    || pixmap_priv->type == GLAMOR_MEMORY
+		    || pixmap_priv->type == GLAMOR_DRM_ONLY));
+}
 
-
-
-
+inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc)
+{
+	PixmapPtr pixmap;
+	if (!gc)
+		return TRUE;
+        switch (gc->fillStyle) {
+        case FillStippled:
+        case FillOpaqueStippled:
+                pixmap = gc->stipple;
+                break;
+        case FillTiled:
+                pixmap = gc->tile.pixmap;
+                break;
+	default:
+		pixmap = NULL;
+        }
+	return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
+}
 
 #endif
commit f7539d9bff0a65b9430dcae8745bf5d4409a9f04
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Dec 12 09:58:03 2011 +0800

    Enable texture dynamic uploading.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 423e2fc..b969008 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -549,7 +549,7 @@ glamor_picture_format_fixup(PicturePtr picture,
  * fallback the whole process to cpu. Most of the time,
  * this will increase performance obviously. */
 
-//#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 //#define GLAMOR_DELAYED_FILLING
 
 
commit 2d0ea392ec574efb96ac7a04ee72ba580417ba1e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Dec 12 09:49:06 2011 +0800

    Call screen's method to create pixmap.
    
    As we may need to fallback to DDX's rendering path
    during the glyphs, we have to call screen's create pixmap
    method to create pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 30d9e58..d61d74b 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -172,7 +172,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 			goto bail;
 
 		/* Now allocate the pixmap and picture */
-		pixmap = glamor_create_pixmap(pScreen,
+		pixmap = pScreen->CreatePixmap(pScreen,
 					      CACHE_PICTURE_SIZE,
 					      CACHE_PICTURE_SIZE, depth,
 					      0);
@@ -628,7 +628,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			mask_format = a8Format;
 	}
 
-	mask_pixmap = glamor_create_pixmap(screen, width, height,
+	mask_pixmap = screen->CreatePixmap(screen, width, height,
 					   mask_format->depth,
 					   CREATE_PIXMAP_USAGE_SCRATCH);
 	if (!mask_pixmap)
commit 47e86eea563601c4e1e356f7267b935fcdd542f7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Dec 12 09:48:04 2011 +0800

    Fallback if the pixmap is drm only.
    
    Glamor can't do anything with a drm only pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f522fd6..f219c29 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -517,7 +517,6 @@ glamor_composite_with_copy(CARD8 op,
 				      0, 0, x_dest, y_dest, width, height))
 		return TRUE;
 	ret = TRUE;
-	ErrorF("width %d height %d \n", width, height);
 	if (!glamor_copy_n_to_n_nf(source->pDrawable,
 			dest->pDrawable, NULL,
 	                REGION_RECTS(&region),
@@ -946,6 +945,7 @@ glamor_composite_with_shader(CARD8 op,
 		if (mask_status == GLAMOR_UPLOAD_PENDING) {
 			mask_status =
 			    glamor_upload_picture_to_texture(mask);
+
 			if (mask_status != GLAMOR_UPLOAD_DONE) {
 				glamor_fallback
 				    ("Failed to upload mask texture.\n");
@@ -1230,13 +1230,15 @@ _glamor_composite(CARD8 op,
 		    glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv =
 		    glamor_get_pixmap_private(source_pixmap);
-		if (!source_pixmap_priv) goto fail;
+		if (!source_pixmap_priv || source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+			goto fail;
 	}
 
 	if (mask && mask->pDrawable) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-		if (!mask_pixmap_priv) goto fail;
+		if (!mask_pixmap_priv || mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+			goto fail;
 	}
 	if ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
commit e3d16c9ebdffe8e5793ee253cf9f72b884b42805
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Dec 12 07:09:03 2011 +0800

    Classfy glamor pixmap to different types.
    
    During the integration with intel driver, we introduce two
    new type of pixmap, one is TEXTURE_DRM, the other is DRM_ONLY.
    TEXTURE_DRM means we create a texture bind to the DRM buffer
    successfully. And then the texture and the external BO is
    consistent. DRM_ONLY means that we failed to create a texture
    from the external DRM BO. We need to handle those different
    types carefully, so we have to track them in the data structure.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c1718bf..41afd33 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -61,6 +61,25 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 }
 
 _X_EXPORT void
+glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
+{
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv == NULL) {
+		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
+		dixSetPrivate(&pixmap->devPrivates,
+			      glamor_pixmap_private_key, pixmap_priv);
+		pixmap_priv->container = pixmap;
+		pixmap_priv->glamor_priv = glamor_priv;
+	}
+	pixmap_priv->type = type;
+}
+
+
+_X_EXPORT void
 glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -114,9 +133,6 @@ glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h,
 	glamor_priv->screen_fbo = pixmap_priv->fb;
 }
 
-#define GLAMOR_PIXMAP_MEMORY 0
-#define GLAMOR_PIXMAP_TEXTURE 1
-
 PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
@@ -124,7 +140,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	PixmapPtr pixmap;
 	GLenum format;
 	GLuint tex;
-	int type = GLAMOR_PIXMAP_TEXTURE;
+	glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
 	glamor_pixmap_private *pixmap_priv;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
@@ -137,7 +153,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	    || usage == GLAMOR_CREATE_PIXMAP_CPU) {
 		/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
 		   If we exceed such limitation, we have to use framebuffer. */
-		type = GLAMOR_PIXMAP_MEMORY;
+		type = GLAMOR_MEMORY;
 		pixmap = fbCreatePixmap(screen, w, h, depth, usage);
 		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
 					   (((w *
@@ -159,9 +175,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	pixmap_priv->container = pixmap;
 	pixmap_priv->glamor_priv = glamor_priv;
 
-	if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) {
+	pixmap_priv->type = type;
+	if (w == 0 || h == 0 || type == GLAMOR_MEMORY)
 		return pixmap;
-	}
 
 	switch (depth) {
 #if 0
@@ -188,6 +204,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 			       GL_UNSIGNED_BYTE, NULL);
 
 	glamor_set_pixmap_texture(pixmap, w, h, tex);
+
 	return pixmap;
 }
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index fd056e9..6febb59 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -50,6 +50,20 @@
 				 | GLAMOR_USE_SCREEN 			\
                                  | GLAMOR_USE_PICTURE_SCREEN)
 
+/*
+ * glamor_pixmap_type : glamor pixmap's type.
+ * @MEMORY: pixmap is in memory.
+ * @TEXTURE_DRM: pixmap is in a texture created from a DRM buffer.
+ * @DRM_ONLY: pixmap is in a external DRM buffer.
+ * @TEXTURE_ONLY: pixmap is in an internal texture.
+ */
+typedef enum  glamor_pixmap_type {
+	GLAMOR_MEMORY,
+	GLAMOR_TEXTURE_DRM,
+	GLAMOR_DRM_ONLY,
+	GLAMOR_TEXTURE_ONLY
+} glamor_pixmap_type_t;
+
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
 
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
@@ -58,9 +72,11 @@ extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
 						       int w, int h,
 						       unsigned int tex);
 extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
-void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
-			       unsigned int tex);
 
+extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
+						unsigned int tex);
+
+extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type);
 extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index ce8e6be..b66d358 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -30,7 +30,8 @@
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
-#include <xorg-server.h>
+#define GLAMOR_FOR_XORG
+#include "xorg-server.h"
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -54,15 +55,13 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#define GLAMOR_FOR_XORG
-
-#include <glamor.h>
-#include "glamor_gl_dispatch.h"
-
 #define GLAMOR_VERSION_MAJOR 0
 #define GLAMOR_VERSION_MINOR 1
 #define GLAMOR_VERSION_PATCH 0
 
+#include "glamor.h"
+#include "glamor_gl_dispatch.h"
+
 static const char glamor_name[] = "glamor";
 
 static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
@@ -127,7 +126,7 @@ _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
 	attribs[1] = width;
 	attribs[3] = height;
 	attribs[5] = stride;
-	if (depth != 32)
+	if (depth != 32 && depth != 24)
 		return EGL_NO_IMAGE_KHR;
 	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
 						 glamor_egl->context,
@@ -226,6 +225,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Couldn't flink pixmap handle\n");
+		glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
 		return FALSE;
 	}
 
@@ -236,12 +236,15 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 					 name,
 					 pixmap->drawable.depth);
 	if (image == EGL_NO_IMAGE_KHR) {
+		glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
 		return FALSE;
 	}
 
 	glamor_create_texture_from_image(glamor_egl, image, &texture);
 	glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
 				  pixmap->drawable.height, texture);
+
+	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
 		      image);
 	return TRUE;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8d4181e..423e2fc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -233,6 +233,7 @@ typedef union _glamor_pending_op {
 
 
 typedef struct glamor_pixmap_private {
+	glamor_pixmap_type_t type;
 	unsigned char gl_fbo:1;
 	unsigned char gl_tex:1;
 	unsigned char pbo_valid:1;
commit 36d424feaeec765d131c015df77d24db1a36fc38
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Dec 12 06:56:36 2011 +0800

    Call glamor_create_pixmap directly in glamor rendering path.
    
    When glamor is rendering pixmaps, and needs to create some
    temporary pixmap, it's better to use glamor version create
    pixmap directly. As if goes to external DDX's create pixmap,
    it may create a external DRM buffer which is not necessary.
    All the case within glamor scope is to create a texture only
    pixmap or a in memory pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 482a074..c1718bf 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -114,14 +114,10 @@ glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h,
 	glamor_priv->screen_fbo = pixmap_priv->fb;
 }
 
-
-
 #define GLAMOR_PIXMAP_MEMORY 0
 #define GLAMOR_PIXMAP_TEXTURE 1
 
-
-
-static PixmapPtr
+PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
 {
@@ -163,8 +159,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	pixmap_priv->container = pixmap;
 	pixmap_priv->glamor_priv = glamor_priv;
 
-	if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
+	if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) {
 		return pixmap;
+	}
 
 	switch (depth) {
 #if 0
@@ -218,7 +215,7 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 	}
 }
 
-static Bool
+Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
 	glamor_destroy_textured_pixmap(pixmap);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 98da98a..625647d 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -360,13 +360,13 @@ _glamor_copy_n_to_n(DrawablePtr src,
 			      src_pixmap->drawable.width *
 			      src_pixmap->drawable.height))) {
 
-		temp_pixmap = (*screen->CreatePixmap) (screen,
-						       bound.x2 - bound.x1,
-						       bound.y2 - bound.y1,
-						       src_pixmap->
-						       drawable.depth,
-						       overlaped ? 0 :
-						       GLAMOR_CREATE_PIXMAP_CPU);
+		temp_pixmap = glamor_create_pixmap(screen,
+						   bound.x2 - bound.x1,
+						   bound.y2 - bound.y1,
+						   src_pixmap->
+						   drawable.depth,
+						   overlaped ? 0 :
+						   GLAMOR_CREATE_PIXMAP_CPU);
 		if (!temp_pixmap)
 			goto fail;
 		glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
@@ -430,9 +430,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
       done:
 	glamor_clear_delayed_fallbacks(src->pScreen);
 	glamor_clear_delayed_fallbacks(dst->pScreen);
-	if (temp_src != src) {
-		(*screen->DestroyPixmap) (temp_pixmap);
-	}
+	if (temp_src != src)
+		glamor_destroy_pixmap(temp_pixmap);
 	return ret;
 }
 
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index fc0d90b..1fa4b4c 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -93,7 +93,7 @@ glamor_get_spans(DrawablePtr drawable,
 		    PixmapBytePad(widths[i], drawable->depth);
 	}
 	if (temp_pixmap)
-		pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
+		glamor_destroy_pixmap(temp_pixmap);
 	return;
 
       fail:
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 96e4c57..30d9e58 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -172,10 +172,10 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 			goto bail;
 
 		/* Now allocate the pixmap and picture */
-		pixmap = pScreen->CreatePixmap(pScreen,
-					       CACHE_PICTURE_SIZE,
-					       CACHE_PICTURE_SIZE, depth,
-					       0);
+		pixmap = glamor_create_pixmap(pScreen,
+					      CACHE_PICTURE_SIZE,
+					      CACHE_PICTURE_SIZE, depth,
+					      0);
 		if (!pixmap)
 			goto bail;
 
@@ -184,7 +184,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
 					CPComponentAlpha, &component_alpha,
 					serverClient, &error);
 
-		pScreen->DestroyPixmap(pixmap);
+		glamor_destroy_pixmap(pixmap);
 		if (!picture)
 			goto bail;
 
@@ -244,7 +244,7 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 			     y);
 
 	if (scratch != pGlyphPixmap)
-		screen->DestroyPixmap(scratch);
+		glamor_destroy_pixmap(scratch);
 
 	FreeScratchGC(gc);
 }
@@ -628,7 +628,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			mask_format = a8Format;
 	}
 
-	mask_pixmap = screen->CreatePixmap(screen, width, height,
+	mask_pixmap = glamor_create_pixmap(screen, width, height,
 					   mask_format->depth,
 					   CREATE_PIXMAP_USAGE_SCRATCH);
 	if (!mask_pixmap)
@@ -638,7 +638,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			     mask_format, CPComponentAlpha,
 			     &component_alpha, serverClient, &error);
 	if (!mask) {
-		screen->DestroyPixmap(mask_pixmap);
+		glamor_destroy_pixmap(mask_pixmap);
 		return;
 	}
 	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
@@ -695,7 +695,7 @@ glamor_glyphs_via_mask(CARD8 op,
 			 x_src + x - x_dst,
 			 y_src + y - y_dst, 0, 0, x, y, width, height);
 	FreePicture(mask, 0);
-	screen->DestroyPixmap(mask_pixmap);
+	glamor_destroy_pixmap(mask_pixmap);
 }
 
 static void
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 6f44aab..9559d17 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -576,10 +576,10 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	}
 
 
-	temp_pixmap = (*screen->CreatePixmap) (screen,
-					       source->drawable.width,
-					       source->drawable.height,
-					       source->drawable.depth, 0);
+	temp_pixmap = glamor_create_pixmap (screen,
+					    source->drawable.width,
+					    source->drawable.height,
+					    source->drawable.depth, 0);
 
 	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
@@ -658,7 +658,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		return FALSE;
 	}
 
-	pixmap_priv->access_mode = access;
 	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
 			    "Downloading pixmap %p  %dx%d depth%d\n",
 			    pixmap,
@@ -789,9 +788,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
       done:
 	pixmap->devPrivate.ptr = data;
 
-	if (temp_pixmap) {
-		(*screen->DestroyPixmap) (temp_pixmap);
-	}
+	if (temp_pixmap)
+		glamor_destroy_pixmap(temp_pixmap);
 
 	return TRUE;
 }
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 2bb36c7..62401f5 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -122,10 +122,10 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 			y_max = points[i].y;
 	}
 
-	temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
-						      x_max - x_min + 1,
-						      y_max - y_min + 1,
-						      drawable->depth, 0);
+	temp_pixmap = glamor_create_pixmap(drawable->pScreen,
+					   x_max - x_min + 1,
+					   y_max - y_min + 1,
+					   drawable->depth, 0);
 	if (temp_pixmap) {
 		temp_dest = &temp_pixmap->drawable;
 		temp_gc =
@@ -164,7 +164,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 					0, 0,
 					x_max - x_min + 1,
 					y_max - y_min + 1, x_min, y_min);
-		drawable->pScreen->DestroyPixmap(temp_pixmap);
+		glamor_destroy_pixmap(temp_pixmap);
 		for (i = 0; i < n; i++) {
 			points[i].x += x_min;
 			points[i].y += y_min;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1a462e2..8d4181e 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -231,6 +231,7 @@ typedef union _glamor_pending_op {
  * @container: The corresponding pixmap's pointer.
  **/
 
+
 typedef struct glamor_pixmap_private {
 	unsigned char gl_fbo:1;
 	unsigned char gl_tex:1;
@@ -298,6 +299,10 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
 Bool glamor_close_screen(int idx, ScreenPtr screen);
 
+PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+			       unsigned int usage);
+
+Bool glamor_destroy_pixmap(PixmapPtr pixmap);
 
 /* glamor_copyarea.c */
 RegionPtr
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index fa42532..f522fd6 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1161,7 +1161,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	else
 		format = source->format;
 
-	pixmap = screen->CreatePixmap(screen,
+	pixmap = glamor_create_pixmap(screen,
 				      width,
 				      height,
 				      PIXMAN_FORMAT_DEPTH(format),
@@ -1442,7 +1442,7 @@ glamor_create_mask_picture(ScreenPtr screen,
 			return 0;
 	}
 
-	pixmap = screen->CreatePixmap(screen, 0, 0,
+	pixmap = glamor_create_pixmap(screen, 0, 0,
 				      pict_format->depth,
 				      GLAMOR_CREATE_PIXMAP_CPU);
 	if (!pixmap)
commit 10ad332dedad2df13212dcd198d947a2f5c76862
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Dec 11 08:06:13 2011 +0800

    Remove garbage file.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.indent.c b/glamor/glamor_pixmap.indent.c
deleted file mode 100644
index f02acc7..0000000
--- a/glamor/glamor_pixmap.indent.c
+++ /dev/null
@@ -1,821 +0,0 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "glamor_priv.h"
-/**
- * Sets the offsets to add to coordinates to make them address the same bits in
- * the backing drawable. These coordinates are nonzero only for redirected
- * windows.
- */
-void
-glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
-			   int *x, int *y)
-{
-#ifdef COMPOSITE
-	if (drawable->type == DRAWABLE_WINDOW) {
-		*x = -pixmap->screen_x;
-		*y = -pixmap->screen_y;
-		return;
-	}
-#endif
-
-	*x = 0;
-	*y = 0;
-}
-
-
-static void
-_glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
-				glamor_pixmap_private * pixmap_priv)
-{
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-	GLfloat vertices[8];
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(glamor_priv->solid_prog);
-	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
-			       1, pixmap_priv->pending_op.fill.color4fv);
-	vertices[0] = -1;
-	vertices[1] = -1;
-	vertices[2] = 1;
-	vertices[3] = -1;
-	vertices[4] = 1;
-	vertices[5] = 1;
-	vertices[6] = -1;
-	vertices[7] = 1;
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glUseProgram(0);
-	pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
-}
-
-
-glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
-	NULL,
-	_glamor_pixmap_validate_filling
-};
-
-void
-glamor_pixmap_init(ScreenPtr screen)
-{
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
-}
-
-void
-glamor_validate_pixmap(PixmapPtr pixmap)
-{
-	glamor_pixmap_validate_function_t validate_op;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-
-	validate_op =
-	    glamor_priv->pixmap_validate_funcs[pixmap_priv->
-					       pending_op.type];
-	if (validate_op) {
-		(*validate_op) (glamor_priv, pixmap_priv);
-	}
-}
-
-void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
-{
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-#ifndef GLAMOR_GLES2
-	dispatch->glMatrixMode(GL_PROJECTION);
-	dispatch->glLoadIdentity();
-	dispatch->glMatrixMode(GL_MODELVIEW);
-	dispatch->glLoadIdentity();
-#endif
-	dispatch->glViewport(0, 0,
-			     pixmap_priv->container->drawable.width,
-			     pixmap_priv->container->drawable.height);
-
-}
-
-int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
-{
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return -1;
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	return 0;
-}
-
-int
-glamor_set_destination_pixmap(PixmapPtr pixmap)
-{
-	int err;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-
-	err = glamor_set_destination_pixmap_priv(pixmap_priv);
-	return err;
-}
-
-Bool
-glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
-{
-	if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
-		return GL_TRUE;
-	}
-
-	glamor_fallback("unsupported planemask %lx\n", planemask);
-	return GL_FALSE;
-}
-
-
-
-void
-glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
-{
-#ifndef GLAMOR_GLES2
-	if (alu == GXcopy) {
-		dispatch->glDisable(GL_COLOR_LOGIC_OP);
-		return;
-	}
-	dispatch->glEnable(GL_COLOR_LOGIC_OP);
-	switch (alu) {
-	case GXclear:
-		dispatch->glLogicOp(GL_CLEAR);
-		break;
-	case GXand:
-		dispatch->glLogicOp(GL_AND);
-		break;
-	case GXandReverse:
-		dispatch->glLogicOp(GL_AND_REVERSE);
-		break;
-	case GXandInverted:
-		dispatch->glLogicOp(GL_AND_INVERTED);
-		break;
-	case GXnoop:
-		dispatch->glLogicOp(GL_NOOP);
-		break;
-	case GXxor:
-		dispatch->glLogicOp(GL_XOR);
-		break;
-	case GXor:
-		dispatch->glLogicOp(GL_OR);
-		break;
-	case GXnor:
-		dispatch->glLogicOp(GL_NOR);
-		break;
-	case GXequiv:
-		dispatch->glLogicOp(GL_EQUIV);
-		break;
-	case GXinvert:
-		dispatch->glLogicOp(GL_INVERT);
-		break;
-	case GXorReverse:
-		dispatch->glLogicOp(GL_OR_REVERSE);
-		break;
-	case GXcopyInverted:
-		dispatch->glLogicOp(GL_COPY_INVERTED);
-		break;
-	case GXorInverted:
-		dispatch->glLogicOp(GL_OR_INVERTED);
-		break;
-	case GXnand:
-		dispatch->glLogicOp(GL_NAND);
-		break;
-	case GXset:
-		dispatch->glLogicOp(GL_SET);
-		break;
-	default:
-		FatalError("unknown logic op\n");
-	}
-#else
-	if (alu != GXcopy)
-		ErrorF("unsupported alu %x \n", alu);
-#endif
-}
-
-
-
-
-/**
- * Upload pixmap to a specified texture.
- * This texture may not be the one attached to it.
- **/
-int in_restore = 0;
-static void
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				  GLenum type, GLuint tex)
-{
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-	unsigned int stride, row_length;
-	void *texels;
-	GLenum iformat;
-
-	switch (pixmap->drawable.depth) {
-#if 0
-	case 8:
-		iformat = GL_ALPHA;
-		break;
-#endif
-	case 24:
-		iformat = GL_RGB;
-		break;
-	default:
-		iformat = GL_RGBA;
-		break;
-	}
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		iformat = format;
-	}
-
-	stride = pixmap->devKind;
-	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-	} else {
-		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-	}
-
-	if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
-		texels = NULL;
-		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-				       pixmap_priv->pbo);
-	} else
-		texels = pixmap->devPrivate.ptr;
-
-	dispatch->glTexImage2D(GL_TEXTURE_2D,
-			       0,
-			       iformat,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height, 0, format, type,
-			       texels);
-}
-
-
-/* 
- * Load texture from the pixmap's data pointer and then
- * draw the texture to the fbo, and flip the y axis.
- * */
-
-static void
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
-				 GLenum type, int no_alpha, int no_revert,
-				 int flip)
-{
-
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-	static float vertices[8] = { -1, -1,
-		1, -1,
-		1, 1,
-		-1, 1
-	};
-	static float texcoords[8] = { 0, 1,
-		1, 1,
-		1, 0,
-		0, 0
-	};
-	static float texcoords_inv[8] = { 0, 0,
-		1, 0,
-		1, 1,
-		0, 1
-	};
-	float *ptexcoords;
-
-	GLuint tex;
-	int need_flip;
-	need_flip = (flip && !glamor_priv->yInverted);
-
-	/* Try fast path firstly, upload the pixmap to the texture attached
-	 * to the fbo directly. */
-	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
-		__glamor_upload_pixmap_to_texture(pixmap, format, type,
-						  pixmap_priv->tex);
-		return;
-	}
-
-
-	if (need_flip)
-		ptexcoords = texcoords;
-	else
-		ptexcoords = texcoords_inv;
-
-	/* Slow path, we need to flip y or wire alpha to 1. */
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					ptexcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	dispatch->glGenTextures(1, &tex);
-
-	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-#ifndef GLAMOR_GLES2
-	dispatch->glEnable(GL_TEXTURE_2D);
-#endif
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-	dispatch->glUniform1i(glamor_priv->
-			      finish_access_no_revert[no_alpha],
-			      no_revert);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      0);
-
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-#ifndef GLAMOR_GLES2
-	dispatch->glDisable(GL_TEXTURE_2D);
-#endif
-	dispatch->glUseProgram(0);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glDeleteTextures(1, &tex);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
-void
-glamor_pixmap_ensure_fb(PixmapPtr pixmap)
-{
-	int status;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
-	if (pixmap_priv->fb == 0)
-		dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
-	assert(pixmap_priv->tex != 0);
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
-					 GL_COLOR_ATTACHMENT0,
-					 GL_TEXTURE_2D, pixmap_priv->tex,
-					 0);
-	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
-	if (status != GL_FRAMEBUFFER_COMPLETE) {
-		const char *str;
-		switch (status) {
-		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-			str = "incomplete attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-			str = "incomplete/missing attachment";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-			str = "incomplete draw buffer";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-			str = "incomplete read buffer";
-			break;
-		case GL_FRAMEBUFFER_UNSUPPORTED:
-			str = "unsupported";
-			break;
-		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-			str = "incomplete multiple";
-			break;
-		default:
-			str = "unknown error";
-			break;
-		}
-
-		LogMessageVerb(X_INFO, 0,
-			       "destination is framebuffer incomplete: %s [%#x]\n",
-			       str, status);
-		assert(0);
-	}
-}
-
-/*  
- * Prepare to upload a pixmap to texture memory.
- * no_alpha equals 1 means the format needs to wire alpha to 1.
- * Two condtion need to setup a fbo for a pixmap
- * 1. !yInverted, we need to do flip if we are not yInverted.
- * 2. no_alpha != 0, we need to wire the alpha.
- * */
-static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
-{
-	int need_fbo;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-	if (!glamor_check_fbo_size
-	    (glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
-	    || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
-		glamor_fallback
-		    ("upload failed reason: bad size or depth %d x %d @depth %d \n",
-		     pixmap->drawable.width, pixmap->drawable.height,
-		     pixmap->drawable.depth);
-		return -1;
-	}
-
-	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return 0;
-
-	if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
-		need_fbo = 1;
-	else
-		need_fbo = 0;
-
-	if (pixmap_priv->tex == 0)
-		dispatch->glGenTextures(1, &pixmap_priv->tex);
-
-	if (need_fbo) {
-		dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MIN_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexParameteri(GL_TEXTURE_2D,
-					  GL_TEXTURE_MAG_FILTER,
-					  GL_NEAREST);
-		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height, 0, GL_RGBA,
-				       GL_UNSIGNED_BYTE, NULL);
-		glamor_pixmap_ensure_fb(pixmap);
-	}
-
-	return 0;
-}
-
-enum glamor_pixmap_status
-glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
-{
-	GLenum format, type;
-	int no_alpha, no_revert;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &no_revert)) {
-		glamor_fallback("Unknown pixmap depth %d.\n",
-				pixmap->drawable.depth);
-		return GLAMOR_UPLOAD_FAILED;
-	}
-	if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
-		return GLAMOR_UPLOAD_FAILED;
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
-			    "Uploading pixmap %p  %dx%d depth%d.\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
-	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 no_revert, 1);
-	return GLAMOR_UPLOAD_DONE;
-}
-
-#if 0
-enum glamor_pixmap_status
-glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
-{
-	enum glamor_pixmap_status upload_status;
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-
-	assert(pixmap_priv->pbo_valid == 0);
-	assert(pixmap->devPrivate.ptr == NULL);
-	pixmap->devPrivate.ptr = data;
-	upload_status = glamor_upload_pixmap_to_texture(pixmap);
-	pixmap->devPrivate.ptr = NULL;
-	return upload_status;
-}
-#endif
-
-void
-glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
-{
-	GLenum format, type;
-	int no_alpha, no_revert;
-
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &no_revert)) {
-		ErrorF("Unknown pixmap depth %d.\n",
-		       pixmap->drawable.depth);
-		assert(0);
-	}
-
-	in_restore = 1;
-	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
-					 no_revert, 1);
-	in_restore = 0;
-}
-
-/* 
- * as gles2 only support a very small set of color format and
- * type when do glReadPixel,  
- * Before we use glReadPixels to get back a textured pixmap, 
- * Use shader to convert it to a supported format and thus
- * get a new temporary pixmap returned.
- * */
-
-PixmapPtr
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
-			       GLenum * type, int no_alpha, int no_revert)
-{
-	glamor_pixmap_private *source_priv;
-	glamor_screen_private *glamor_priv;
-	ScreenPtr screen;
-	PixmapPtr temp_pixmap;
-	glamor_pixmap_private *temp_pixmap_priv;
-	glamor_gl_dispatch *dispatch;
-	static float vertices[8] = { -1, -1,
-		1, -1,
-		1, 1,
-		-1, 1
-	};
-	static float texcoords[8] = { 0, 0,
-		1, 0,
-		1, 1,
-		0, 1
-	};
-
-	int swap_rb = 0;
-
-	screen = source->drawable.pScreen;
-
-	glamor_priv = glamor_get_screen_private(screen);
-	source_priv = glamor_get_pixmap_private(source);
-	dispatch = &glamor_priv->dispatch;
-	if (*format == GL_BGRA) {
-		*format = GL_RGBA;
-		swap_rb = 1;
-	}
-
-
-	temp_pixmap = (*screen->CreatePixmap) (screen,
-					       source->drawable.width,
-					       source->drawable.height,
-					       source->drawable.depth, 0);
-
-	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-
-	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
-			       source->drawable.width,
-			       source->drawable.height, 0, *format, *type,
-			       NULL);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					vertices);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
-					GL_FALSE, 2 * sizeof(float),
-					texcoords);
-	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-	dispatch->glActiveTexture(GL_TEXTURE0);
-	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
-
-	glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
-
-	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-	dispatch->glUniform1i(glamor_priv->
-			      finish_access_no_revert[no_alpha],
-			      no_revert);
-	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
-			      swap_rb);
-
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-	dispatch->glUseProgram(0);
-	return temp_pixmap;
-}
-
-
-/**
- * Move a pixmap to CPU memory.
- * The input data is the pixmap's fbo.
- * The output data is at pixmap->devPrivate.ptr. We always use pbo 
- * to read the fbo and then map it to va. If possible, we will use
- * it directly as devPrivate.ptr.
- * If successfully download a fbo to cpu then return TRUE.
- * Otherwise return FALSE.
- **/
-
-Bool
-glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
-{
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	unsigned int stride, row_length, y;
-	GLenum format, type, gl_access, gl_usage;
-	int no_alpha, no_revert;
-	uint8_t *data = NULL, *read;
-	PixmapPtr temp_pixmap = NULL;
-	ScreenPtr screen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(pixmap->drawable.pScreen);
-	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-	screen = pixmap->drawable.pScreen;
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-		return TRUE;
-	if (glamor_get_tex_format_type_from_pixmap(pixmap,
-						   &format,
-						   &type, &no_alpha,
-						   &no_revert)) {
-		ErrorF("Unknown pixmap depth %d.\n",
-		       pixmap->drawable.depth);
-		assert(0);	// Should never happen.
-		return FALSE;
-	}
-
-	pixmap_priv->access_mode = access;
-	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
-			    "Downloading pixmap %p  %dx%d depth%d\n",
-			    pixmap,
-			    pixmap->drawable.width,
-			    pixmap->drawable.height,
-			    pixmap->drawable.depth);
-
-	stride = pixmap->devKind;
-
-	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-	/* XXX we may don't need to validate it on GPU here,
-	 * we can just validate it on CPU. */
-	glamor_validate_pixmap(pixmap);
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-	    &&
-	    ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA)
-	     || no_revert != 1)) {
-
-		temp_pixmap =
-		    glamor_es2_pixmap_read_prepare(pixmap, &format,
-						   &type, no_alpha,
-						   no_revert);
-
-	}
-	switch (access) {
-	case GLAMOR_ACCESS_RO:
-		gl_access = GL_READ_ONLY;
-		gl_usage = GL_STREAM_READ;
-		break;
-	case GLAMOR_ACCESS_WO:
-		data = malloc(stride * pixmap->drawable.height);
-		goto done;
-		break;
-	case GLAMOR_ACCESS_RW:
-		gl_access = GL_READ_WRITE;
-		gl_usage = GL_DYNAMIC_DRAW;
-		break;
-	default:
-		ErrorF("Glamor: Invalid access code. %d\n", access);
-		assert(0);
-	}
-	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-		data = malloc(stride * pixmap->drawable.height);
-	}
-	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-
-	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
-		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
-	} else {
-		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-		//  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-	}
-	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
-
-		if (!glamor_priv->yInverted) {
-			assert(glamor_priv->gl_flavor ==
-			       GLAMOR_GL_DESKTOP);
-			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
-		}
-
-		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-			if (pixmap_priv->pbo == 0)
-				dispatch->glGenBuffers(1,
-						       &pixmap_priv->pbo);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->pbo);
-			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-					       stride *
-					       pixmap->drawable.height,
-					       NULL, gl_usage);
-			dispatch->glReadPixels(0, 0, row_length,
-					       pixmap->drawable.height,
-					       format, type, 0);
-			data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-						     gl_access);
-			pixmap_priv->pbo_valid = TRUE;
-
-			if (!glamor_priv->yInverted) {
-				assert(glamor_priv->gl_flavor ==
-				       GLAMOR_GL_DESKTOP);
-				dispatch->glPixelStorei
-				    (GL_PACK_INVERT_MESA, 0);
-			}
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-
-		} else {
-			if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
-				type = GL_UNSIGNED_SHORT_5_5_5_1;
-			dispatch->glReadPixels(0, 0,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height,
-					       format, type, data);
-		}
-	} else {
-		data = malloc(stride * pixmap->drawable.height);
-		assert(data);
-		if (access != GLAMOR_ACCESS_WO) {
-			if (pixmap_priv->pbo == 0)
-				dispatch->glGenBuffers(1,
-						       &pixmap_priv->pbo);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
-					       pixmap_priv->pbo);
-			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-					       stride *
-					       pixmap->drawable.height,
-					       NULL, GL_STREAM_READ);
-			dispatch->glReadPixels(0, 0, row_length,
-					       pixmap->drawable.height,
-					       format, type, 0);
-			read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
-						     GL_READ_ONLY);
-
-			for (y = 0; y < pixmap->drawable.height; y++)
-				memcpy(data + y * stride,
-				       read + (pixmap->drawable.height -
-					       y - 1) * stride, stride);
-			dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
-			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-			pixmap_priv->pbo_valid = FALSE;
-			dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-			pixmap_priv->pbo = 0;
-		}
-	}
-
-	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
-      done:
-	pixmap->devPrivate.ptr = data;
-
-	if (temp_pixmap) {
-		(*screen->DestroyPixmap) (temp_pixmap);
-	}
-
-	return TRUE;
-}
-
-
-
-static void
-_glamor_destroy_upload_pixmap(PixmapPtr pixmap)
-{
-	glamor_pixmap_private *pixmap_priv =
-	    glamor_get_pixmap_private(pixmap);
-	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
-	assert(pixmap_priv->gl_fbo == 0);
-	if (pixmap_priv->fb)
-		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
-	if (pixmap_priv->tex)
-		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
-	if (pixmap_priv->pbo)
-		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-	pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
-
-}
-
-void
-glamor_destroy_upload_pixmap(PixmapPtr pixmap)
-{
-	_glamor_destroy_upload_pixmap(pixmap);
-}
commit 92fd83872f5509a2792338b4665dc2b3e1ed68cd
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Sun Dec 11 02:26:15 2011 +0800

    Remove the access mode from private pixmap structure.
    
    Change the finish_access to pass in the access mode, and remove
    the access mode from the pixmap structure. This element should
    not be a pixmap's property.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 38254d6..98da98a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -422,9 +422,9 @@ _glamor_copy_n_to_n(DrawablePtr src,
 				   dx, dy, reverse, upsidedown, bitplane,
 				   closure);
 			if (dst != src)
-				glamor_finish_access(src);
+				glamor_finish_access(src, GLAMOR_ACCESS_RO);
 		}
-		glamor_finish_access(dst);
+		glamor_finish_access(dst, GLAMOR_ACCESS_RW);
 	}
 
       done:
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4c58022..54e110a 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -255,7 +255,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 }
 
 void
-glamor_finish_access(DrawablePtr drawable)
+glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
 {
 	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_pixmap_private *pixmap_priv =
@@ -267,7 +267,7 @@ glamor_finish_access(DrawablePtr drawable)
 	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return;
 
-	if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
+	if (access_mode != GLAMOR_ACCESS_RO) {
 		glamor_restore_pixmap_to_texture(pixmap);
 	}
 
@@ -307,7 +307,8 @@ glamor_prepare_access_gc(GCPtr gc)
 					   GLAMOR_ACCESS_RO)) {
 			if (gc->stipple)
 				glamor_finish_access(&gc->
-						     stipple->drawable);
+						     stipple->drawable, 
+						     GLAMOR_ACCESS_RO);
 			return FALSE;
 		}
 	}
@@ -321,9 +322,9 @@ void
 glamor_finish_access_gc(GCPtr gc)
 {
 	if (gc->fillStyle == FillTiled)
-		glamor_finish_access(&gc->tile.pixmap->drawable);
+		glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO);
 	if (gc->stipple)
-		glamor_finish_access(&gc->stipple->drawable);
+		glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
 }
 
 Bool
@@ -406,7 +407,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 					    (old_tile,
 					     drawable->bitsPerPixel);
 					glamor_finish_access
-					    (&old_tile->drawable);
+					    (&old_tile->drawable, GLAMOR_ACCESS_RO);
 				}
 			}
 			if (new_tile) {
@@ -432,7 +433,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 				     GLAMOR_ACCESS_RW)) {
 					fbPadPixmap(gc->tile.pixmap);
 					glamor_finish_access
-					    (&gc->tile.pixmap->drawable);
+					    (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW);
 				}
 			}
 		}
@@ -449,7 +450,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 		if (glamor_prepare_access
 		    (&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
 			fbValidateGC(gc, changes, drawable);
-			glamor_finish_access(&gc->stipple->drawable);
+			glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW);
 		}
 	} else {
 		fbValidateGC(gc, changes, drawable);
@@ -491,7 +492,7 @@ glamor_bitmap_to_region(PixmapPtr pixmap)
 	if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
 		return NULL;
 	ret = fbPixmapToRegion(pixmap);
-	glamor_finish_access(&pixmap->drawable);
+	glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
 	return ret;
 }
 
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index b20ec5e..10baeb3 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -88,7 +88,7 @@ glamor_fill(DrawablePtr drawable,
 			fbFill(drawable, gc, x, y, width, height);
 			glamor_finish_access_gc(gc);
 		}
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 996f0c5..bbe0985 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -83,7 +83,7 @@ _glamor_fill_spans(DrawablePtr drawable,
 				    sorted);
 			glamor_finish_access_gc(gc);
 		}
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index dff55ba..fc0d90b 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -101,7 +101,7 @@ glamor_get_spans(DrawablePtr drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
 		fbGetSpans(drawable, wmax, points, widths, count, dst);
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
 	}
 }
 
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 68c90eb..3b5d568 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -33,12 +33,12 @@ glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
 }
 
 void
-glamor_finish_access_picture(PicturePtr picture)
+glamor_finish_access_picture(PicturePtr picture, glamor_access_t access)
 {
 	if (!picture || !picture->pDrawable)
 		return;
 
-	glamor_finish_access(picture->pDrawable);
+	glamor_finish_access(picture->pDrawable, access);
 }
 
 /* 
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 44df8a8..8a691bb 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -102,7 +102,7 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
 			fbPolyFillRect(drawable, gc, nrect, prect);
 			glamor_finish_access_gc(gc);
 		}
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 01124bb..2bb36c7 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -151,7 +151,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 				fbPolyLine(temp_dest, gc, mode, n, points);
 				glamor_finish_access_gc(gc);
 			}
-			glamor_finish_access(temp_dest);
+			glamor_finish_access(temp_dest, GLAMOR_ACCESS_RW);
 		}
 	} else {
 		/* fb calls mi functions in the lineWidth != 0 case. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4dfdbc4..1a462e2 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -226,7 +226,6 @@ typedef union _glamor_pending_op {
  * @tex:     attached texture.
  * @fb:      attached fbo.
  * @pbo:     attached pbo.
- * @access_mode: access mode during the prepare/finish pair.
  * @pict_format: the corresponding picture's format.
  * #pending_op: currently only support pending filling.
  * @container: The corresponding pixmap's pointer.
@@ -240,7 +239,6 @@ typedef struct glamor_pixmap_private {
 	GLuint tex;
 	GLuint fb;
 	GLuint pbo;
-	glamor_access_t access_mode;
 	PictFormatShort pict_format;
 	glamor_pending_op pending_op;
 	PixmapPtr container;
@@ -316,7 +314,7 @@ void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
 
 /* glamor_core.c */
 Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
-void glamor_finish_access(DrawablePtr drawable);
+void glamor_finish_access(DrawablePtr drawable, glamor_access_t access);
 Bool glamor_prepare_access_window(WindowPtr window);
 void glamor_finish_access_window(WindowPtr window);
 Bool glamor_prepare_access_gc(GCPtr gc);
@@ -524,7 +522,7 @@ int glamor_create_picture(PicturePtr picture);
 Bool
 glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
 
-void glamor_finish_access_picture(PicturePtr picture);
+void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access);
 
 void glamor_destroy_picture(PicturePtr picture);
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 989f635..6101850 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -234,7 +234,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
 			   bits);
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 }
 #endif
@@ -401,7 +401,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
 		fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h,
 			   left_pad, image_format, bits);
-		glamor_finish_access(&pixmap->drawable);
+		glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e7e5305..fa42532 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1366,11 +1366,11 @@ _glamor_composite(CARD8 op,
 					    x_mask, y_mask, x_dest,
 					    y_dest, width, height);
 				if (mask)
-					glamor_finish_access_picture(mask);
+					glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO);
 			}
-			glamor_finish_access_picture(source);
+			glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
 		}
-		glamor_finish_access_picture(dest);
+		glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
 	}
       done:
 	if (temp_src != source)
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 61163ce..4d6fe96 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -101,6 +101,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		fbSetSpans(drawable, gc, src, points, widths, n, sorted);
-		glamor_finish_access(drawable);
+		glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
 	}
 }
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index b7ddd82..1ea7fd6 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -50,9 +50,9 @@ _glamor_triangles(CARD8 op,
 				    ySrc, ntris, tris);
 		}
 		if (pSrc->pDrawable != NULL)
-			glamor_finish_access(pSrc->pDrawable);
+			glamor_finish_access(pSrc->pDrawable, GLAMOR_ACCESS_RO);
 
-		glamor_finish_access(pDst->pDrawable);
+		glamor_finish_access(pDst->pDrawable, GLAMOR_ACCESS_RW);
 	}
 	return TRUE;
 }
commit d135e879a6c8698bf21ae44a02315f370b961b14
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 9 16:01:45 2011 +0800

    Can't create KHR image if the depth is uncompatible.
    
    Currently, KHR image only support one color format ARGB32.
    For all other format, we have to fail to create corresponding
    image and texture here.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a068e39..ce8e6be 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -108,7 +108,7 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 
 static EGLImageKHR
 _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
-			 int width, int height, int stride, int name)
+			 int width, int height, int stride, int name, int depth)
 {
 	EGLImageKHR image;
 	EGLint attribs[] = {
@@ -126,7 +126,9 @@ _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
 
 	attribs[1] = width;
 	attribs[3] = height;
-	attribs[5] = stride / 4;
+	attribs[5] = stride;
+	if (depth != 32)
+		return EGL_NO_IMAGE_KHR;
 	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
 						 glamor_egl->context,
 						 EGL_DRM_BUFFER_MESA,
@@ -165,6 +167,7 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
 
 	(glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D,
 						      image);
+	glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, 0);
 	return TRUE;
 }
 
@@ -193,8 +196,8 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 	image = _glamor_egl_create_image(glamor_egl,
 					 scrn->virtualX,
 					 scrn->virtualY,
-					 stride,
-					 glamor_egl->front_buffer_handle);
+					 stride / 4,
+					 glamor_egl->front_buffer_handle, 32);
 	if (image == EGL_NO_IMAGE_KHR)
 		return FALSE;
 
@@ -208,8 +211,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 /*
  * This function will be called from the dri buffer allocation.
  * It is somehow very familiar with the create textured screen.
- * XXX the egl image here is not stored at any data structure.
- * Does this cause a leak problem?
  */
 Bool
 glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
@@ -221,19 +222,20 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	EGLImageKHR image;
 	GLuint texture;
 	int name;
+
 	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Couldn't flink pixmap handle\n");
 		return FALSE;
 	}
 
-
 	image = _glamor_egl_create_image(glamor_egl,
 					 pixmap->drawable.width,
-					 pixmap->drawable.height, stride,
-					 name);
+					 pixmap->drawable.height,
+					 ((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
+					 name,
+					 pixmap->drawable.depth);
 	if (image == EGL_NO_IMAGE_KHR) {
-		ErrorF("Failed to create khr image for bo handle %d.\n", handle);
 		return FALSE;
 	}
 
commit b5630663cf9438383166f59cdfc7889571f2cd62
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 9 15:58:19 2011 +0800

    exports more rendering functions to DDX driver.
    
    Exports all necessary rendering functions to DDx drivers, including
    CopyArea, Glyphs, Composite, Triangles, ....
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index ce1a41f..fd056e9 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -90,3 +90,55 @@ extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
 					       int nrect, 
 					       xRectangle * prect);
 
+extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable, 
+					  GCPtr gc, int depth, int x, int y,
+		 	 		  int w, int h, int left_pad, 
+					  int image_format, char *bits);
+
+extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
+					    DrawablePtr dst,
+					    GCPtr gc,
+					    BoxPtr box,
+					    int nbox,
+					    int dx,
+					    int dy,
+					    Bool reverse,
+					    Bool upsidedown, Pixel bitplane, 
+					    void *closure);
+
+extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
+					  PicturePtr source,
+					  PicturePtr mask,
+					  PicturePtr dest,
+					  INT16 x_source,
+					  INT16 y_source,
+					  INT16 x_mask,
+					  INT16 y_mask,
+					  INT16 x_dest, INT16 y_dest, 
+					  CARD16 width, CARD16 height);
+
+extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
+					   PicturePtr src, PicturePtr dst,
+					   PictFormatPtr mask_format, 
+					   INT16 x_src, INT16 y_src,
+					   int ntrap, xTrapezoid * traps);
+
+extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
+				       PicturePtr src,
+				       PicturePtr dst,
+				       PictFormatPtr mask_format,
+				       INT16 x_src,
+				       INT16 y_src, int nlist, 
+				       GlyphListPtr list, GlyphPtr * glyphs);
+
+extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
+					  PicturePtr pSrc,
+					  PicturePtr pDst,
+					  PictFormatPtr maskFormat,
+					  INT16 xSrc, INT16 ySrc, 
+					  int ntris, xTriangle * tris);
+
+
+extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
+
+
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index b49d816..38254d6 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -286,16 +286,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	return FALSE;
 }
 
-void
-glamor_copy_n_to_n(DrawablePtr src,
-		   DrawablePtr dst,
-		   GCPtr gc,
-		   BoxPtr box,
-		   int nbox,
-		   int dx,
-		   int dy,
-		   Bool reverse,
-		   Bool upsidedown, Pixel bitplane, void *closure)
+static Bool 
+_glamor_copy_n_to_n(DrawablePtr src,
+		    DrawablePtr dst,
+		    GCPtr gc,
+		    BoxPtr box,
+		    int nbox,
+		    int dx,
+		    int dy,
+		    Bool reverse,
+		    Bool upsidedown, Pixel bitplane, 
+		    void *closure, Bool fallback)
 {
 	glamor_access_t dst_access;
 	PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
@@ -308,6 +309,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 	int src_x_off, src_y_off, dst_x_off, dst_y_off;
 	int i;
 	int overlaped = 0;
+	Bool ret = TRUE;
 
 	dst_pixmap = glamor_get_drawable_pixmap(dst);
 	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
@@ -315,6 +317,9 @@ glamor_copy_n_to_n(DrawablePtr src,
 	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 	screen = dst_pixmap->drawable.pScreen;
 
+	if (!dst_pixmap_priv || !src_pixmap_priv)
+		goto fail;
+
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
 		glamor_fallback("dest pixmap %p has no fbo. \n",
 				dst_pixmap);
@@ -338,14 +343,12 @@ glamor_copy_n_to_n(DrawablePtr src,
 		}
 	}
 	/* XXX need revisit to handle overlapped area copying. */
-
 #ifndef GLAMOR_GLES2
 	if ((overlaped
 	     || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
 	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
 					   dy)) {
 		goto done;
-		return;
 	}
 #endif
 	glamor_calculate_boxes_bound(&bound, box, nbox);
@@ -394,6 +397,12 @@ glamor_copy_n_to_n(DrawablePtr src,
 
 
       fail:
+	
+	if (!fallback) {
+		ret = FALSE;
+		goto done;
+	} 
+
 	glamor_report_delayed_fallbacks(src->pScreen);
 	glamor_report_delayed_fallbacks(dst->pScreen);
 
@@ -424,6 +433,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 	if (temp_src != src) {
 		(*screen->DestroyPixmap) (temp_pixmap);
 	}
+	return ret;
 }
 
 RegionPtr
@@ -438,3 +448,36 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 	return region;
 }
+
+void
+glamor_copy_n_to_n(DrawablePtr src,
+		   DrawablePtr dst,
+		   GCPtr gc,
+		   BoxPtr box,
+		   int nbox,
+		   int dx,
+		   int dy,
+		   Bool reverse,
+		   Bool upsidedown, Pixel bitplane, 
+		   void *closure)
+{
+	_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, 
+			    dy, reverse, upsidedown, bitplane, closure, TRUE);
+}
+
+Bool
+glamor_copy_n_to_n_nf(DrawablePtr src,
+		   DrawablePtr dst,
+		   GCPtr gc,
+		   BoxPtr box,
+		   int nbox,
+		   int dx,
+		   int dy,
+		   Bool reverse,
+		   Bool upsidedown, Pixel bitplane, 
+		   void *closure)
+{
+	return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, 
+				    dy, reverse, upsidedown, bitplane, closure, FALSE);
+}
+
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 8ba938f..4c58022 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -264,7 +264,7 @@ glamor_finish_access(DrawablePtr drawable)
 	    glamor_get_screen_private(drawable->pScreen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return;
 
 	if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 96f5120..dff55ba 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -104,3 +104,4 @@ glamor_get_spans(DrawablePtr drawable,
 		glamor_finish_access(drawable);
 	}
 }
+
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 335540d..96e4c57 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -239,57 +239,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
 	ValidateGC(&pCachePixmap->drawable, gc);
 
 	scratch = pGlyphPixmap;
-#if 0
-	/* Create a temporary bo to stream the updates to the cache */
-	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth ||
-	    !uxa_pixmap_is_offscreen(scratch)) {
-		scratch = screen->CreatePixmap(screen,
-					       glyph->info.width,
-					       glyph->info.height,
-					       pCachePixmap->
-					       drawable.depth, 0);
-		if (scratch) {
-			if (pGlyphPixmap->drawable.depth !=
-			    pCachePixmap->drawable.depth) {
-				PicturePtr picture;
-				int error;
-
-				picture =
-				    CreatePicture(0,
-						  &scratch->drawable,
-						  PictureMatchFormat
-						  (screen,
-						   pCachePixmap->
-						   drawable.depth,
-						   cache->picture->format),
-						  0, NULL, serverClient,
-						  &error);
-				if (picture) {
-					ValidatePicture(picture);
-					uxa_composite(PictOpSrc,
-						      pGlyphPicture,
-						      NULL, picture,
-						      0, 0, 0, 0, 0,
-						      0,
-						      glyph->info.width,
-						      glyph->info.height);
-					FreePicture(picture, 0);
-				}
-			} else {
-				glamor_copy_area(&pGlyphPixmap->drawable,
-						 &scratch->drawable,
-						 gc, 0, 0,
-						 glyph->info.width,
-						 glyph->info.height, 0, 0);
-			}
-		} else {
-			scratch = pGlyphPixmap;
-		}
-	}
-#endif
-	glamor_copy_area(&scratch->drawable, &pCachePixmap->drawable, gc,
-			 0, 0, glyph->info.width, glyph->info.height, x,
-			 y);
+	(*gc->ops->CopyArea)(&scratch->drawable, &pCachePixmap->drawable, gc,
+			     0, 0, glyph->info.width, glyph->info.height, x,
+			     y);
 
 	if (scratch != pGlyphPixmap)
 		screen->DestroyPixmap(scratch);
@@ -657,6 +609,7 @@ glamor_glyphs_via_mask(CARD8 op,
 	BoxRec extents = { 0, 0, 0, 0 };
 	CARD32 component_alpha;
 	glamor_glyph_buffer_t buffer;
+	xRectangle fill_rect;
 
 	GCPtr gc;
 
@@ -690,7 +643,14 @@ glamor_glyphs_via_mask(CARD8 op,
 	}
 	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
 	ValidateGC(&mask_pixmap->drawable, gc);
-	glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height, TRUE);
+	gc->fillStyle = FillSolid;
+	//glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height, TRUE);
+	fill_rect.x = 0;
+	fill_rect.y = 0;
+	fill_rect.width = width;
+	fill_rect.height = height;
+	gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &fill_rect);
+	
 	FreeScratchGC(gc);
 	x = -extents.x1;
 	y = -extents.y1;
@@ -810,13 +770,14 @@ glamor_glyphs_to_dst(CARD8 op,
 					x_src, y_src, x_dst, y_dst);
 }
 
-void
-glamor_glyphs(CARD8 op,
-	      PicturePtr src,
-	      PicturePtr dst,
-	      PictFormatPtr mask_format,
-	      INT16 x_src,
-	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+static Bool
+_glamor_glyphs(CARD8 op,
+	       PicturePtr src,
+	       PicturePtr dst,
+	       PictFormatPtr mask_format,
+	       INT16 x_src,
+	       INT16 y_src, int nlist, GlyphListPtr list, 
+	       GlyphPtr * glyphs, Bool fallback)
 {
 	/* If we don't have a mask format but all the glyphs have the same format
 	 * and don't intersect, use the glyph format as mask format for the full
@@ -848,4 +809,31 @@ glamor_glyphs(CARD8 op,
 	else
 		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
 				     list, glyphs);
+	return TRUE;
 }
+
+void
+glamor_glyphs(CARD8 op,
+	      PicturePtr src,
+	      PicturePtr dst,
+	      PictFormatPtr mask_format,
+	      INT16 x_src,
+	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+{
+	_glamor_glyphs(op, src, dst, mask_format, x_src, 
+		       y_src, nlist, list, glyphs, TRUE);
+}
+
+Bool
+glamor_glyphs_nf(CARD8 op,
+		 PicturePtr src,
+		 PicturePtr dst,
+		 PictFormatPtr mask_format,
+		 INT16 x_src,
+		 INT16 y_src, int nlist, 
+		 GlyphListPtr list, GlyphPtr * glyphs)
+{
+	return _glamor_glyphs(op, src, dst, mask_format, x_src, 
+			      y_src, nlist, list, glyphs, FALSE);
+}
+
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 9e8d6ec..68c90eb 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -60,10 +60,11 @@ glamor_create_picture(PicturePtr picture)
 	    glamor_get_screen_private(picture->pDrawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	assert(pixmap_priv);
-
-	pixmap_priv->is_picture = 1;
-	pixmap_priv->pict_format = picture->format;
+	
+	if (pixmap_priv) {
+		pixmap_priv->is_picture = 1;
+		pixmap_priv->pict_format = picture->format;
+	}
 	return glamor_priv->saved_create_picture(picture);
 }
 
@@ -81,10 +82,11 @@ glamor_destroy_picture(PicturePtr picture)
 	    glamor_get_screen_private(picture->pDrawable->pScreen);
 	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
 	pixmap_priv = glamor_get_pixmap_private(pixmap);
-	assert(pixmap_priv);
 
-	pixmap_priv->is_picture = 0;
-	pixmap_priv->pict_format = 0;
+	if (pixmap_priv) {
+		pixmap_priv->is_picture = 0;
+		pixmap_priv->pict_format = 0;
+	}
 	glamor_priv->saved_destroy_picture(picture);
 }
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index f02acc7..6f44aab 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -302,6 +302,9 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
 	GLuint tex;
 	int need_flip;
+
+	if (!pixmap_priv)
+		return;
 	need_flip = (flip && !glamor_priv->yInverted);
 
 	/* Try fast path firstly, upload the pixmap to the texture attached
@@ -368,7 +371,6 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
 	glamor_pixmap_private *pixmap_priv =
 	    glamor_get_pixmap_private(pixmap);
 	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
 	if (pixmap_priv->fb == 0)
 		dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
 	assert(pixmap_priv->tex != 0);
@@ -644,7 +646,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	screen = pixmap->drawable.pScreen;
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
 		return TRUE;
 	if (glamor_get_tex_format_type_from_pixmap(pixmap,
 						   &format,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index a40a508..4dfdbc4 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -545,7 +545,7 @@ glamor_picture_format_fixup(PicturePtr picture,
  * fallback the whole process to cpu. Most of the time,
  * this will increase performance obviously. */
 
-#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+//#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 //#define GLAMOR_DELAYED_FILLING
 
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index a8cafed..989f635 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -240,9 +240,9 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 #endif
 
 
-void
-glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int left_pad, int image_format, char *bits)
+static Bool 
+_glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int left_pad, int image_format, char *bits, Bool fallback)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(drawable->pScreen);
@@ -263,10 +263,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (image_format == XYBitmap) {
 		assert(depth == 1);
 		goto fail;
-		return;
 	}
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("has no fbo.\n");
 		goto fail;
 	}
@@ -309,12 +308,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 					pixmap->drawable.bitsPerPixel);
 	} else {
 		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-//      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	}
 
 	dispatch->glGenTextures(1, &tex);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
 	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
 		iformat = format;
 	} else {
@@ -328,10 +327,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 				  GL_NEAREST);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
+
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-
 	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 	dispatch->glUniform1i(glamor_priv->
 			      finish_access_no_revert[no_alpha],
@@ -386,15 +385,17 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	dispatch->glUseProgram(0);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
 	dispatch->glDeleteTextures(1, &tex);
 	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
 		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 	glamor_set_alu(dispatch, GXcopy);
 	glamor_set_planemask(pixmap, ~0);
-	return;
+	return TRUE;
 
       fail:
 	glamor_set_planemask(pixmap, ~0);
+	if (!fallback) return FALSE;
 	glamor_fallback("to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
@@ -402,4 +403,22 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 			   left_pad, image_format, bits);
 		glamor_finish_access(&pixmap->drawable);
 	}
+	return TRUE;
+}
+
+void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int left_pad, int image_format, char *bits)
+{
+	_glamor_put_image(drawable, gc, depth, x, y, w, h, 
+			left_pad, image_format, bits, TRUE);
 }
+
+Bool
+glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int left_pad, int image_format, char *bits)
+{
+	return _glamor_put_image(drawable, gc, depth, x, y, w, h, 
+				left_pad, image_format, bits, FALSE);
+}
+
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 7f52c7b..e7e5305 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -36,8 +36,6 @@
 #include "mipict.h"
 #include "fbpict.h"
 
-//#include "glu3/glu3.h"
-
 struct shader_key {
 	enum shader_source source;
 	enum shader_mask mask;
@@ -371,6 +369,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv)
 {
+	unsigned int no_alpha, no_revert, format, type;
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
@@ -497,6 +496,7 @@ glamor_composite_with_copy(CARD8 op,
 			   INT16 y_dest, CARD16 width, CARD16 height)
 {
 	RegionRec region;
+	int ret;
 
 	if (!source->pDrawable)
 		return FALSE;
@@ -511,21 +511,22 @@ glamor_composite_with_copy(CARD8 op,
 	y_dest += dest->pDrawable->y;
 	x_source += source->pDrawable->x;
 	y_source += source->pDrawable->y;
-
 	if (!miComputeCompositeRegion(&region,
 				      source, NULL, dest,
 				      x_source, y_source,
 				      0, 0, x_dest, y_dest, width, height))
 		return TRUE;
-
-	glamor_copy_n_to_n(source->pDrawable,
-			   dest->pDrawable, NULL,
-			   REGION_RECTS(&region),
-			   REGION_NUM_RECTS(&region),
-			   x_source - x_dest, y_source - y_dest,
-			   FALSE, FALSE, 0, NULL);
+	ret = TRUE;
+	ErrorF("width %d height %d \n", width, height);
+	if (!glamor_copy_n_to_n_nf(source->pDrawable,
+			dest->pDrawable, NULL,
+	                REGION_RECTS(&region),
+		        REGION_NUM_RECTS(&region),
+			x_source - x_dest, y_source - y_dest,
+			FALSE, FALSE, 0, NULL))
+		ret = FALSE;
 	REGION_UNINIT(dest->pDrawable->pScreen, &region);
-	return TRUE;
+	return ret;
 }
 
 static void
@@ -696,7 +697,6 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
 		return FALSE;
 	}
 
-
 	if (src_type == mask_type) {
 		*des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
 		return TRUE;
@@ -753,10 +753,9 @@ glamor_composite_with_shader(CARD8 op,
 	PictFormatShort saved_source_format = 0;
 	float src_matrix[9], mask_matrix[9];
 	GLfloat source_solid_color[4], mask_solid_color[4];
-
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+	if (!dest_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
 	}
@@ -997,8 +996,6 @@ glamor_composite_with_shader(CARD8 op,
 				   &dest_x_off, &dest_y_off);
 	pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
-
-
 	if (glamor_priv->has_source_coords) {
 		glamor_get_drawable_deltas(source->pDrawable,
 					   source_pixmap, &source_x_off,
@@ -1190,16 +1187,17 @@ glamor_convert_gradient_picture(ScreenPtr screen,
 	return dst;
 }
 
-void
-glamor_composite(CARD8 op,
-		 PicturePtr source,
-		 PicturePtr mask,
-		 PicturePtr dest,
-		 INT16 x_source,
-		 INT16 y_source,
-		 INT16 x_mask,
-		 INT16 y_mask,
-		 INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
+static Bool
+_glamor_composite(CARD8 op,
+		  PicturePtr source,
+		  PicturePtr mask,
+		  PicturePtr dest,
+		  INT16 x_source,
+		  INT16 y_source,
+		  INT16 x_mask,
+		  INT16 y_mask,
+		  INT16 x_dest, INT16 y_dest, 
+		  CARD16 width, CARD16 height, Bool fallback)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
 	glamor_pixmap_private *dest_pixmap_priv;
@@ -1214,6 +1212,7 @@ glamor_composite(CARD8 op,
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	Bool ret = TRUE;
 
 	x_temp_src = x_source;
 	y_temp_src = y_source;
@@ -1222,7 +1221,7 @@ glamor_composite(CARD8 op,
 
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	/* Currently. Always fallback to cpu if destination is in CPU memory. */
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+	if (!dest_pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		goto fail;
 	}
 
@@ -1231,13 +1230,14 @@ glamor_composite(CARD8 op,
 		    glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv =
 		    glamor_get_pixmap_private(source_pixmap);
+		if (!source_pixmap_priv) goto fail;
 	}
 
 	if (mask && mask->pDrawable) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		if (!mask_pixmap_priv) goto fail;
 	}
-
 	if ((!source->pDrawable
 	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
 	    || (source->pDrawable
@@ -1311,7 +1311,6 @@ glamor_composite(CARD8 op,
 			goto fail;
 		}
 	}
-
 	if (!mask) {
 		if (glamor_composite_with_copy(op, temp_src, dest,
 					       x_temp_src, y_temp_src,
@@ -1319,7 +1318,6 @@ glamor_composite(CARD8 op,
 					       height))
 			goto done;
 	}
-
 	rect.x_src = x_temp_src;
 	rect.y_src = y_temp_src;
 	rect.x_mask = x_temp_mask;
@@ -1334,6 +1332,12 @@ glamor_composite(CARD8 op,
 
       fail:
 
+	dispatch->glUseProgram(0);
+	dispatch->glDisable(GL_BLEND);
+	if (!fallback) {
+		ret = FALSE;
+		goto done;
+	}
 	glamor_fallback
 	    ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
 	     source, source->pDrawable,
@@ -1349,8 +1353,6 @@ glamor_composite(CARD8 op,
 	     dest->pDrawable->width, dest->pDrawable->height,
 	     glamor_get_picture_location(dest));
 
-	dispatch->glUseProgram(0);
-	dispatch->glDisable(GL_BLEND);
 	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
 		if (glamor_prepare_access_picture
 		    (source, GLAMOR_ACCESS_RO)) {
@@ -1375,8 +1377,45 @@ glamor_composite(CARD8 op,
 		FreePicture(temp_src, 0);
 	if (temp_mask != mask)
 		FreePicture(temp_mask, 0);
+	return ret;
 }
 
+void
+glamor_composite(CARD8 op,
+		 PicturePtr source,
+		 PicturePtr mask,
+		 PicturePtr dest,
+		 INT16 x_source,
+		 INT16 y_source,
+		 INT16 x_mask,
+		 INT16 y_mask,
+		 INT16 x_dest, INT16 y_dest, 
+		 CARD16 width, CARD16 height)
+{
+	_glamor_composite(op, source, mask, dest, x_source, y_source, 
+			  x_mask, y_mask, x_dest, y_dest, width, height,
+			  TRUE);
+}
+
+Bool
+glamor_composite_nf(CARD8 op,
+		    PicturePtr source,
+		    PicturePtr mask,
+		    PicturePtr dest,
+		    INT16 x_source,
+		    INT16 y_source,
+		    INT16 x_mask,
+		    INT16 y_mask,
+		    INT16 x_dest, INT16 y_dest, 
+		    CARD16 width, CARD16 height)
+{
+	return _glamor_composite(op, source, mask, dest, x_source, y_source, 
+				 x_mask, y_mask, x_dest, y_dest, width, height,
+				 FALSE);
+}
+
+
+
 
 /**
  * Creates an appropriate picture to upload our alpha mask into (which
@@ -1418,11 +1457,11 @@ glamor_create_mask_picture(ScreenPtr screen,
  * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
  * accumulation in system memory.
  */
-void
-glamor_trapezoids(CARD8 op,
+static Bool 
+_glamor_trapezoids(CARD8 op,
 		  PicturePtr src, PicturePtr dst,
 		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid * traps)
+		  int ntrap, xTrapezoid * traps, Bool fallback)
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
 	BoxRec bounds;
@@ -1446,13 +1485,13 @@ glamor_trapezoids(CARD8 op,
 		for (; ntrap; ntrap--, traps++)
 			glamor_trapezoids(op, src, dst, mask_format, x_src,
 					  y_src, 1, traps);
-		return;
+		return TRUE;
 	}
 
 	miTrapezoidBounds(ntrap, traps, &bounds);
 
 	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-		return;
+		return TRUE;
 
 	x_dst = traps[0].left.p1.x >> 16;
 	y_dst = traps[0].left.p1.y >> 16;
@@ -1463,13 +1502,13 @@ glamor_trapezoids(CARD8 op,
 	picture = glamor_create_mask_picture(screen, dst, mask_format,
 					     width, height);
 	if (!picture)
-		return;
+		return TRUE;
 
 	image = pixman_image_create_bits(picture->format,
 					 width, height, NULL, stride);
 	if (!image) {
 		FreePicture(picture, 0);
-		return;
+		return TRUE;
 	}
 
 	for (; ntrap; ntrap--, traps++)
@@ -1497,9 +1536,32 @@ glamor_trapezoids(CARD8 op,
 	pixman_image_unref(image);
 
 	FreePicture(picture, 0);
+	return TRUE;
 }
 
 void
+glamor_trapezoids(CARD8 op,
+		  PicturePtr src, PicturePtr dst,
+		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		  int ntrap, xTrapezoid * traps)
+{
+	_glamor_trapezoids(op, src, dst, mask_format, x_src, 
+			   y_src, ntrap, traps, TRUE);
+}
+
+Bool
+glamor_trapezoids_nf(CARD8 op,
+		     PicturePtr src, PicturePtr dst,
+		     PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		     int ntrap, xTrapezoid * traps)
+{
+	return _glamor_trapezoids(op, src, dst, mask_format, x_src, 
+				  y_src, ntrap, traps, FALSE);
+}
+
+
+
+void
 glamor_composite_rects(CARD8 op,
 		       PicturePtr src, PicturePtr mask, PicturePtr dst,
 		       int nrect, glamor_composite_rect_t * rects)
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index 3cbdd55..b7ddd82 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -32,14 +32,15 @@
 
 #include "glamor_priv.h"
 
-void
-glamor_triangles(CARD8 op,
+static Bool
+_glamor_triangles(CARD8 op,
 		 PicturePtr pSrc,
 		 PicturePtr pDst,
 		 PictFormatPtr maskFormat,
-		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris, Bool fallback)
 {
-
+	if (!fallback)
+		return FALSE;
 	if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
 		if (pSrc->pDrawable == NULL ||
 		    glamor_prepare_access(pSrc->pDrawable,
@@ -53,4 +54,28 @@ glamor_triangles(CARD8 op,
 
 		glamor_finish_access(pDst->pDrawable);
 	}
+	return TRUE;
 }
+
+void
+glamor_triangles(CARD8 op,
+		 PicturePtr pSrc,
+		 PicturePtr pDst,
+		 PictFormatPtr maskFormat,
+		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+{
+	_glamor_triangles(op, pSrc, pDst, maskFormat, 
+			  xSrc, ySrc, ntris, tris, TRUE);
+}
+
+Bool
+glamor_triangles_nf(CARD8 op,
+		    PicturePtr pSrc,
+		    PicturePtr pDst,
+		    PictFormatPtr maskFormat,
+		    INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+{
+	return _glamor_triangles(op, pSrc, pDst, maskFormat, 
+				 xSrc, ySrc, ntris, tris, FALSE);
+}
+
commit b5480e64ac4a72bdc31e587ff9e51d67a1a0f11d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Dec 9 14:57:24 2011 +0800

    Override create/destroy picture to track pict format.
    
    When create a piccture, we need to attach a pixmap to it.
    A pixmap only has a depth, which is not sufficant for glamor.
    As in openGL texture only has a few internal formats which
    is not sufficant to represent all the possible picture
    format. So we always transform the picture format to GL_RGBA.
    And when we need to read back the picture, we must know the
    original picture format. So we have to override create
    and destroy picture to track a pixmap's real picture format
    if it is attached to a picture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b660f95..482a074 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -388,16 +388,14 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		glamor_priv->saved_triangles = ps->Triangles;
 		ps->Triangles = glamor_triangles;
 
-		glamor_priv->saved_create_picture = ps->CreatePicture;
-		ps->CreatePicture = glamor_create_picture;
-
-		glamor_priv->saved_destroy_picture = ps->DestroyPicture;
-		ps->DestroyPicture = glamor_destroy_picture;
-
 		glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
 		ps->UnrealizeGlyph = glamor_glyph_unrealize;
 	}
+	glamor_priv->saved_create_picture = ps->CreatePicture;
+	ps->CreatePicture = glamor_create_picture;
 
+	glamor_priv->saved_destroy_picture = ps->DestroyPicture;
+	ps->DestroyPicture = glamor_destroy_picture;
 	glamor_init_composite_shaders(screen);
 #endif
 	glamor_init_solid_shader(screen);
commit 7b2310834d83198fc88b5a5fb062cb1c9ee19ead
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Nov 22 18:28:10 2011 +0800

    Added a missed header file.
    
    Pointed by Chris, we must add xorg-server.h at the top
    of each file before we include any other xorg header files.
    Otherwise, it may cause incorrect XID length.
    
    This commit also fixes one compilation warning in X86_64
    platform.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 9e4804a..a068e39 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -30,6 +30,7 @@
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
+#include <xorg-server.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -129,7 +130,7 @@ _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
 	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
 						 glamor_egl->context,
 						 EGL_DRM_BUFFER_MESA,
-						 (void *) name, attribs);
+						 (void *) (uintptr_t)name, attribs);
 	if (image == EGL_NO_IMAGE_KHR)
 		return EGL_NO_IMAGE_KHR;
 
commit 90eaac96aeb53b3e45b82dc7dd4e98778c8c9343
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Nov 15 20:17:18 2011 +0800

    If caller is not using glamor screen, we can't register
    the block handler.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c96795c..b660f95 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -334,16 +334,16 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
 					    &glamor_priv->max_fbo_size);
 
-	if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
-					    _glamor_wakeup_handler,
-					    (void *)
-					    &glamor_priv->dispatch)) {
-		goto fail;
-	}
-
 	glamor_set_debug_level(&glamor_debug_level);
 
 	if (flags & GLAMOR_USE_SCREEN) {
+		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
+						    _glamor_wakeup_handler,
+						    (void *)
+						    &glamor_priv->dispatch)) {
+			goto fail;
+		}
+
 		glamor_priv->saved_close_screen = screen->CloseScreen;
 		screen->CloseScreen = glamor_close_screen;
 
commit 9ff39e53eb20673d42f42c94adb55bf9a9f1c285
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Nov 15 20:16:16 2011 +0800

    Revert "Disable glamor_tile temporary."
    
    The previous corruption output is caused by GLAMOR/UXA flushing
    issue. Now get fixed.
    
    This reverts commit 0d2d3e4f051e48c3499e1c972e012803a8623526.

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 77f4d0e..bd5192c 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -110,7 +110,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
-	goto fail;
 
 	if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
 		goto fail;
commit 13ab4d59afb824f2a4c03280fffe79c6ba9aa26c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Nov 11 14:55:12 2011 +0800

    Disable glamor_tile temporary.
    
    Enable glamor tile cause corrupted output. Need more investigation.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index bd5192c..77f4d0e 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -110,6 +110,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+	goto fail;
 
 	if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
 		goto fail;
commit 9b6a484df0724d72dd27ad620672e7a762a460df
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Nov 11 10:26:00 2011 +0800

    Add new version glamor_poly_fill_rect without internal fallback.
    
    If need fallback, this new version just returns FALSE without
    doing anything. It's the caller's responsibility to implement
    fallback method.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index e98d7d5..ce1a41f 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -85,4 +85,8 @@ extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
 					   int n, DDXPointPtr points, 
 					   int *widths, int sorted);
 
+extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
+					       GCPtr gc, 
+					       int nrect, 
+					       xRectangle * prect);
 
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 5fc350b..b20ec5e 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -144,7 +144,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	GLfloat color[4];
 	float vertices[8];
 	GLfloat xscale, yscale;
-	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
 		glamor_fallback("dest %p has no fbo.\n", pixmap);
 		goto fail;
 	}
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index eff63b6..44df8a8 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -37,9 +37,9 @@
  * GC PolyFillRect implementation, taken straight from fb_fill.c
  */
 
-void
-glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc, int nrect, xRectangle * prect)
+static Bool
+_glamor_poly_fill_rect(DrawablePtr drawable,
+		      GCPtr gc, int nrect, xRectangle * prect, Bool fallback)
 {
 	int fullX1, fullX2, fullY1, fullY2;
 	int xorg, yorg;
@@ -87,13 +87,14 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 			if (x1 >= x2 || y1 >= y2)
 				continue;
 			if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
-					 y2 - y1, TRUE))
+					 y2 - y1, fallback))
 				goto fail;
 		}
 	}
-	return;
+	return TRUE;
 
       fail:
+	if (!fallback) return FALSE;
 	glamor_fallback(" to %p (%c)\n",
 			drawable, glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
@@ -103,5 +104,20 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 		}
 		glamor_finish_access(drawable);
 	}
-	return;
+	return TRUE;
+}
+
+
+void
+glamor_poly_fill_rect(DrawablePtr drawable,
+		      GCPtr gc, int nrect, xRectangle * prect)
+{
+	_glamor_poly_fill_rect(drawable, gc, nrect, prect, TRUE);
+}
+
+Bool
+glamor_poly_fill_rect_nf(DrawablePtr drawable,
+		         GCPtr gc, int nrect, xRectangle * prect)
+{
+	return _glamor_poly_fill_rect(drawable, gc, nrect, prect, FALSE);
 }
commit ba1b3b53240b5d499791570ba9f598a4e421c719
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Nov 9 16:09:03 2011 +0800

    Add new version glamor_fillspans without internal fallback.
    
    For the purpose of incrementally intergration of existing intel
    driver, for the GC operations we may don't want to use glamor's
    internal fallback which is in general much slower than the
    implementation in intel driver. If the parameter "fallback" is
    false when call the glamor_fillspans, then if glamor found it
    can't accelerate it then it will just return a FALSE rather than
    fallback to a slow path.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index f9da4ad..e98d7d5 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -79,3 +79,10 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
 extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
 extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
+
+extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
+					   GCPtr gc,
+					   int n, DDXPointPtr points, 
+					   int *widths, int sorted);
+
+
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 7a43251..5fc350b 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -34,7 +34,7 @@
 
 Bool
 glamor_fill(DrawablePtr drawable,
-	    GCPtr gc, int x, int y, int width, int height)
+	    GCPtr gc, int x, int y, int width, int height, Bool fallback)
 {
 	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
 	int off_x, off_y;
@@ -80,7 +80,9 @@ glamor_fill(DrawablePtr drawable,
 		break;
 	}
 	return TRUE;
+
       fail:
+	if (!fallback) return FALSE;
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 		if (glamor_prepare_access_gc(gc)) {
 			fbFill(drawable, gc, x, y, width, height);
@@ -89,7 +91,6 @@ glamor_fill(DrawablePtr drawable,
 		glamor_finish_access(drawable);
 	}
 	return TRUE;
-
 }
 
 void
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index a91e6a9..996f0c5 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -30,10 +30,10 @@
  */
 #include "glamor_priv.h"
 
-void
-glamor_fill_spans(DrawablePtr drawable,
+static Bool
+_glamor_fill_spans(DrawablePtr drawable,
 		  GCPtr gc,
-		  int n, DDXPointPtr points, int *widths, int sorted)
+		  int n, DDXPointPtr points, int *widths, int sorted, Bool fallback)
 {
 	DDXPointPtr ppt;
 	int nbox;
@@ -66,12 +66,15 @@ glamor_fill_spans(DrawablePtr drawable,
 
 			if (x2 <= x1)
 				continue;
-			glamor_fill(drawable, gc, x1, y, x2 - x1, 1);
+			if (!glamor_fill(drawable, gc, x1, y, x2 - x1, 1, fallback))
+				goto fail;
 			pbox++;
 		}
 	}
-	return;
+	return TRUE;
+
       fail:
+	if (!fallback) return FALSE;
 	glamor_fallback("to %p (%c)\n", drawable,
 			glamor_get_drawable_location(drawable));
 	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
@@ -82,4 +85,24 @@ glamor_fill_spans(DrawablePtr drawable,
 		}
 		glamor_finish_access(drawable);
 	}
+	return TRUE;
 }
+
+
+void
+glamor_fill_spans(DrawablePtr drawable,
+		  GCPtr gc,
+		  int n, DDXPointPtr points, int *widths, int sorted)
+{
+	_glamor_fill_spans(drawable, gc, n, points, widths, sorted, TRUE);
+}
+
+Bool
+glamor_fill_spans_nf(DrawablePtr drawable,
+		     GCPtr gc,
+		     int n, DDXPointPtr points, int *widths, int sorted)
+{
+	return _glamor_fill_spans(drawable, gc, n, points, widths, sorted, FALSE);
+}
+
+
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 899dd9d..335540d 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -690,7 +690,7 @@ glamor_glyphs_via_mask(CARD8 op,
 	}
 	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
 	ValidateGC(&mask_pixmap->drawable, gc);
-	glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height);
+	glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height, TRUE);
 	FreeScratchGC(gc);
 	x = -extents.x1;
 	y = -extents.y1;
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 762dfc2..eff63b6 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -87,7 +87,7 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 			if (x1 >= x2 || y1 >= y2)
 				continue;
 			if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
-					 y2 - y1))
+					 y2 - y1, TRUE))
 				goto fail;
 		}
 	}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 66c4359..a40a508 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -370,7 +370,7 @@ int glamor_gl_get_version(void);
 
 /* glamor_fill.c */
 Bool glamor_fill(DrawablePtr drawable,
-		 GCPtr gc, int x, int y, int width, int height);
+		 GCPtr gc, int x, int y, int width, int height, Bool fallback);
 Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		  unsigned char alu, unsigned long planemask,
 		  unsigned long fg_pixel);
commit b861aad8e2fcf6fe1fae4f26abb650bb4eb499c6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Nov 2 13:44:50 2011 +0800

    Initial version.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 8712e76..a382eb5 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -1,29 +1,24 @@
-noinst_LTLIBRARIES = libglamor.la
+inst_LTLIBRARIES = libglamor.la
 
 # Override these since glamor doesn't need them and the needed files aren't
 # built (in hw/xfree86/os-support/solaris) until after glamor is built
 SOLARIS_ASM_CFLAGS=""
 
-if XORG
-sdk_HEADERS = glamor.h
-endif
-
 if GLAMOR_GLES2
 libglamor_la_LIBADD = $(GLESV2_LIBS)
 else
 libglamor_la_LIBADD = $(GL_LIBS)
 endif
 
-if XORG
-sdk_HEADERS = glamor.h
-endif
+instdir = $(moduledir)
 
 INCLUDES = \
 	$(XORG_INCS)
 
-
 AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 
+libglamor_la_LDFLAGS = -avoid-version
+
 libglamor_la_SOURCES = \
 	glamor.c \
 	glamor_copyarea.c \
@@ -45,3 +40,17 @@ libglamor_la_SOURCES = \
 	glamor_window.c\
         glamor_gl_dispatch.c\
 	glamor.h
+
+sdk_HEADERS = glamor.h
+
+if EGL
+LIBGLAMOR_EGL = libglamor_egl.la
+module_LTLIBRARIES = $(LIBGLAMOR_EGL) 
+libglamor_egl_la_DEPENDENCIES = libglamor.la
+libglamor_egl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
+#libglamor_egl_la_LIBADD = $(top_builddir)/src/libglamor.la
+libglamor_egl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
+libglamor_egl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
+endif
+
+
diff --git a/glamor/glamor.c b/glamor/glamor.c
index ee83fd3..c96795c 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -53,57 +53,71 @@ DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 PixmapPtr
 glamor_get_drawable_pixmap(DrawablePtr drawable)
 {
-     if (drawable->type == DRAWABLE_WINDOW)
-	return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable);
-     else
-	return (PixmapPtr)drawable;
+	if (drawable->type == DRAWABLE_WINDOW)
+		return drawable->
+		    pScreen->GetWindowPixmap((WindowPtr) drawable);
+	else
+		return (PixmapPtr) drawable;
 }
 
-void
+_X_EXPORT void
 glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_pixmap_private *pixmap_priv;
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    assert(pixmap_priv);
-    pixmap_priv->tex = tex;
-
-    /* Create a framebuffer object wrapping the texture so that we can render
-     * to it.
-     */
-    pixmap_priv->gl_fbo = 1;
-    if (tex != 0) {
-      glamor_pixmap_ensure_fb(pixmap);
-      pixmap_priv->gl_tex = 1;
-    }
-    else {
-      pixmap_priv->fb = 0;
-      pixmap_priv->gl_tex = 0;
-    }
-    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-                              (((w * pixmap->drawable.bitsPerPixel +
-                                 7) / 8) + 3) & ~3,
-                              NULL);
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (pixmap_priv == NULL) {
+		pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
+		dixSetPrivate(&pixmap->devPrivates,
+			      glamor_pixmap_private_key, pixmap_priv);
+		pixmap_priv->container = pixmap;
+		pixmap_priv->glamor_priv = glamor_priv;
+	}
+
+	pixmap_priv->tex = tex;
+
+	/* Create a framebuffer object wrapping the texture so that we can render
+	 * to it.
+	 */
+	pixmap_priv->gl_fbo = 1;
+	if (tex != 0) {
+		glamor_pixmap_ensure_fb(pixmap);
+		pixmap_priv->gl_tex = 1;
+	} else {
+		pixmap_priv->fb = 0;
+		pixmap_priv->gl_tex = 0;
+	}
+
+	if (pixmap->devKind == 0)
+		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+					   (((w *
+					      pixmap->drawable.
+					      bitsPerPixel + 7) / 8) +
+					    3) & ~3, NULL);
 }
 
 /* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */
 void
-glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex)
+glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h,
+				 unsigned int tex)
 {
-  PixmapPtr pixmap = screen->GetScreenPixmap(screen);
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-
-  glamor_set_pixmap_texture(pixmap, w, h, tex);
-  glamor_priv->screen_fbo = pixmap_priv->fb;
-  pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
+	PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+
+	glamor_set_pixmap_texture(pixmap, w, h, tex);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	glamor_priv->screen_fbo = pixmap_priv->fb;
 }
 
 
 
-#define GLAMOR_PIXMAP_MEMORY 0 
-#define GLAMOR_PIXMAP_TEXTURE 1 
+#define GLAMOR_PIXMAP_MEMORY 0
+#define GLAMOR_PIXMAP_TEXTURE 1
 
 
 
@@ -111,113 +125,138 @@ static PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
 {
-    PixmapPtr pixmap;
-    GLenum format;
-    GLuint tex;
-    int type = GLAMOR_PIXMAP_TEXTURE;
-    glamor_pixmap_private *pixmap_priv;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    if (w > 32767 || h > 32767)
-	return NullPixmap;
-
-    if (!glamor_check_fbo_size(glamor_priv, w,h)
-	|| !glamor_check_fbo_depth(depth) 
-	|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
-	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
- 	   If we exceed such limitation, we have to use framebuffer.*/
-      type = GLAMOR_PIXMAP_MEMORY;
-      pixmap = fbCreatePixmap (screen, w, h, depth, usage);
-      screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-                              (((w * pixmap->drawable.bitsPerPixel +
-                                 7) / 8) + 3) & ~3,
-                              NULL);
+	PixmapPtr pixmap;
+	GLenum format;
+	GLuint tex;
+	int type = GLAMOR_PIXMAP_TEXTURE;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	if (w > 32767 || h > 32767)
+		return NullPixmap;
+
+	if (!glamor_check_fbo_size(glamor_priv, w, h)
+	    || !glamor_check_fbo_depth(depth)
+	    || usage == GLAMOR_CREATE_PIXMAP_CPU) {
+		/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
+		   If we exceed such limitation, we have to use framebuffer. */
+		type = GLAMOR_PIXMAP_MEMORY;
+		pixmap = fbCreatePixmap(screen, w, h, depth, usage);
+		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+					   (((w *
+					      pixmap->
+					      drawable.bitsPerPixel +
+					      7) / 8) + 3) & ~3, NULL);
 #if 0
-      if (usage != GLAMOR_CREATE_PIXMAP_CPU)
-	glamor_fallback("choose cpu memory for pixmap %p ,"
-			" %d x %d depth %d\n", pixmap, w, h, depth);
+		if (usage != GLAMOR_CREATE_PIXMAP_CPU)
+			glamor_fallback("choose cpu memory for pixmap %p ,"
+					" %d x %d depth %d\n", pixmap, w,
+					h, depth);
 #endif
-   } else 
-      pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+	} else
+		pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
 
-    if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
-        fbDestroyPixmap(pixmap);
-	ErrorF("Fail to allocate privates for PIXMAP.\n");
-	return NullPixmap;
-    }	 
+	pixmap_priv = calloc(1, sizeof(*pixmap_priv));
+	dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key,
+		      pixmap_priv);
+	pixmap_priv->container = pixmap;
+	pixmap_priv->glamor_priv = glamor_priv;
 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    pixmap_priv->container = pixmap;
-    pixmap_priv->glamor_priv = glamor_priv;
-
-    if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
-	return pixmap;
+	if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
+		return pixmap;
 
-    switch (depth) {
+	switch (depth) {
 #if 0
-    case 8:
-        format = GL_ALPHA;
-        break;
+	case 8:
+		format = GL_ALPHA;
+		break;
 #endif
-    case 24:
-        format = GL_RGB;
-        break; 
-    default:
-        format = GL_RGBA;
-        break;
-    }
-
-    /* Create the texture used to store the pixmap's data. */
-    dispatch->glGenTextures(1, &tex);
-    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-                 format, GL_UNSIGNED_BYTE, NULL);
-
-    glamor_set_pixmap_texture(pixmap, w, h, tex);
-    return pixmap;
+	case 24:
+		format = GL_RGB;
+		break;
+	default:
+		format = GL_RGBA;
+		break;
+	}
+
+	/* Create the texture used to store the pixmap's data. */
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
+			       GL_UNSIGNED_BYTE, NULL);
+
+	glamor_set_pixmap_texture(pixmap, w, h, tex);
+	return pixmap;
+}
+
+void
+glamor_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	if (pixmap->refcnt == 1) {
+		glamor_pixmap_private *pixmap_priv =
+		    glamor_get_pixmap_private(pixmap);
+		if (pixmap_priv != NULL) {
+			if (pixmap_priv->fb)
+				dispatch->glDeleteFramebuffers(1,
+							       &pixmap_priv->fb);
+			if (pixmap_priv->tex)
+				dispatch->glDeleteTextures(1,
+							   &pixmap_priv->tex);
+			if (pixmap_priv->pbo)
+				dispatch->glDeleteBuffers(1,
+							  &pixmap_priv->pbo);
+			free(pixmap_priv);
+		}
+	}
 }
 
 static Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    if (pixmap->refcnt == 1) {
-	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-        if (pixmap_priv->fb)
-	  dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
-        if (pixmap_priv->tex)
-	  dispatch->glDeleteTextures(1, &pixmap_priv->tex);
-        if (pixmap_priv->pbo)
-          dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-        dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
-    }
-
-    return fbDestroyPixmap(pixmap);
+	glamor_destroy_textured_pixmap(pixmap);
+	return fbDestroyPixmap(pixmap);
+}
+
+void
+glamor_block_handler(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	dispatch->glFlush();
 }
 
 static void
-glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
+_glamor_block_handler(void *data, OSTimePtr timeout,
+		      void *last_select_mask)
 {
-    glamor_gl_dispatch *dispatch = data;
-    dispatch->glFlush();
+	glamor_gl_dispatch *dispatch = data;
+	dispatch->glFlush();
 }
 
 static void
-glamor_wakeup_handler(void *data, int result, void *last_select_mask)
+_glamor_wakeup_handler(void *data, int result, void *last_select_mask)
 {
 }
 
-static void 
+static void
 glamor_set_debug_level(int *debug_level)
 {
-  char *debug_level_string;
-  debug_level_string = getenv("GLAMOR_DEBUG");
-  if (debug_level_string && sscanf(debug_level_string, "%d", debug_level) == 1)
-     return;
-  *debug_level = 0;
+	char *debug_level_string;
+	debug_level_string = getenv("GLAMOR_DEBUG");
+	if (debug_level_string
+	    && sscanf(debug_level_string, "%d", debug_level) == 1)
+		return;
+	*debug_level = 0;
 }
 
 int glamor_debug_level;
@@ -226,176 +265,198 @@ int glamor_debug_level;
 Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
 {
-    glamor_screen_private *glamor_priv;
-    int gl_version;
+	glamor_screen_private *glamor_priv;
+	int gl_version;
 
 #ifdef RENDER
-    PictureScreenPtr ps = GetPictureScreenIfSet(screen);
+	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
-    if (flags & ~GLAMOR_VALID_FLAGS) {
-      ErrorF("glamor_init: Invalid flags %x\n", flags);
-      return FALSE;
-    }
-    glamor_priv = calloc(1, sizeof(*glamor_priv));
-    if (glamor_priv == NULL)
-	return FALSE;
-
-    if (flags & GLAMOR_INVERTED_Y_AXIS) {
-	glamor_priv->yInverted = 1;
-    } else
-	glamor_priv->yInverted = 0;
-
-    if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN,
-			   0)) {
-	LogMessage(X_WARNING,
-		   "glamor%d: Failed to allocate screen private\n",
-		   screen->myNum);
-        goto fail;
-    }
-
-    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
-
-    if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP,
-                           sizeof(glamor_pixmap_private))) {
-        LogMessage(X_WARNING,
-                   "glamor%d: Failed to allocate pixmap private\n",
-                   screen->myNum);
-        goto fail;;
-    }
-
-    gl_version = glamor_gl_get_version();
+	if (flags & ~GLAMOR_VALID_FLAGS) {
+		ErrorF("glamor_init: Invalid flags %x\n", flags);
+		return FALSE;
+	}
+	glamor_priv = calloc(1, sizeof(*glamor_priv));
+	if (glamor_priv == NULL)
+		return FALSE;
+
+	if (flags & GLAMOR_INVERTED_Y_AXIS) {
+		glamor_priv->yInverted = 1;
+	} else
+		glamor_priv->yInverted = 0;
+
+	if (!dixRegisterPrivateKey
+	    (glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate screen private\n",
+			   screen->myNum);
+		goto fail;
+	}
+
+	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
+		      glamor_priv);
+
+	if (!dixRegisterPrivateKey
+	    (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate pixmap private\n",
+			   screen->myNum);
+		goto fail;;
+	}
+
+	gl_version = glamor_gl_get_version();
 
 #ifndef GLAMOR_GLES2
-    if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3))  {
-        ErrorF("Require OpenGL version 1.3 or latter.\n");
-        goto fail;
-    }
+	if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
+		ErrorF("Require OpenGL version 1.3 or latter.\n");
+		goto fail;
+	}
 #else
-    if (gl_version < GLAMOR_GL_VERSION_ENCODE(2,0))  {
-        ErrorF("Require Open GLES2.0 or latter.\n");
-        goto fail;
-    }
+	if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
+		ErrorF("Require Open GLES2.0 or latter.\n");
+		goto fail;
+	}
 #endif
 
-    glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version);
+	glamor_gl_dispatch_init(screen, &glamor_priv->dispatch,
+				gl_version);
 
 #ifdef GLAMOR_GLES2
-    if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
-	ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
-	goto fail;
-    }
+	if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
+		ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
+		goto fail;
+	}
 #endif
 
-    glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert");
-    glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit");
-    glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); 
+	glamor_priv->has_pack_invert =
+	    glamor_gl_has_extension("GL_MESA_pack_invert");
+	glamor_priv->has_fbo_blit =
+	    glamor_gl_has_extension("GL_EXT_framebuffer_blit");
+	glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
+					    &glamor_priv->max_fbo_size);
 
-    if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
-					glamor_wakeup_handler,
-					(void*)&glamor_priv->dispatch)) {
-	goto fail;
-    }
+	if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
+					    _glamor_wakeup_handler,
+					    (void *)
+					    &glamor_priv->dispatch)) {
+		goto fail;
+	}
 
-    glamor_set_debug_level(&glamor_debug_level); 
-    glamor_priv->saved_close_screen = screen->CloseScreen;
-    screen->CloseScreen = glamor_close_screen;
+	glamor_set_debug_level(&glamor_debug_level);
 
-    glamor_priv->saved_create_gc = screen->CreateGC;
-    screen->CreateGC = glamor_create_gc;
+	if (flags & GLAMOR_USE_SCREEN) {
+		glamor_priv->saved_close_screen = screen->CloseScreen;
+		screen->CloseScreen = glamor_close_screen;
 
-    glamor_priv->saved_create_pixmap = screen->CreatePixmap;
-    screen->CreatePixmap = glamor_create_pixmap;
+		glamor_priv->saved_create_gc = screen->CreateGC;
+		screen->CreateGC = glamor_create_gc;
 
-    glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
-    screen->DestroyPixmap = glamor_destroy_pixmap;
+		glamor_priv->saved_create_pixmap = screen->CreatePixmap;
+		screen->CreatePixmap = glamor_create_pixmap;
 
-    glamor_priv->saved_get_spans = screen->GetSpans;
-    screen->GetSpans = glamor_get_spans;
+		glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
+		screen->DestroyPixmap = glamor_destroy_pixmap;
 
-    glamor_priv->saved_get_image = screen->GetImage;
-    screen->GetImage = miGetImage;
+		glamor_priv->saved_get_spans = screen->GetSpans;
+		screen->GetSpans = glamor_get_spans;
 
-    glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes;
-    screen->ChangeWindowAttributes = glamor_change_window_attributes;
+		glamor_priv->saved_get_image = screen->GetImage;
+		screen->GetImage = miGetImage;
 
-    glamor_priv->saved_copy_window = screen->CopyWindow;
-    screen->CopyWindow = glamor_copy_window;
+		glamor_priv->saved_change_window_attributes =
+		    screen->ChangeWindowAttributes;
+		screen->ChangeWindowAttributes =
+		    glamor_change_window_attributes;
 
-    glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion;
-    screen->BitmapToRegion = glamor_bitmap_to_region;
+		glamor_priv->saved_copy_window = screen->CopyWindow;
+		screen->CopyWindow = glamor_copy_window;
 
+		glamor_priv->saved_bitmap_to_region =
+		    screen->BitmapToRegion;
+		screen->BitmapToRegion = glamor_bitmap_to_region;
+	}
 #ifdef RENDER
-    glamor_priv->saved_composite = ps->Composite;
-    ps->Composite = glamor_composite;
-    glamor_priv->saved_trapezoids = ps->Trapezoids;
-    ps->Trapezoids = glamor_trapezoids;
-    glamor_priv->saved_glyphs = ps->Glyphs;
-    ps->Glyphs = glamor_glyphs;
-    glamor_priv->saved_triangles = ps->Triangles;
-    ps->Triangles = glamor_triangles;
-    glamor_init_composite_shaders(screen);
-    glamor_priv->saved_create_picture = ps->CreatePicture; 
-    ps->CreatePicture = glamor_create_picture;
-    glamor_priv->saved_destroy_picture = ps->DestroyPicture; 
-    ps->DestroyPicture = glamor_destroy_picture;
-
-    glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
-    ps->UnrealizeGlyph = glamor_glyph_unrealize;
+	if (flags & GLAMOR_USE_PICTURE_SCREEN) {
+		glamor_priv->saved_composite = ps->Composite;
+		ps->Composite = glamor_composite;
+
+		glamor_priv->saved_trapezoids = ps->Trapezoids;
+		ps->Trapezoids = glamor_trapezoids;
+
+		glamor_priv->saved_glyphs = ps->Glyphs;
+		ps->Glyphs = glamor_glyphs;
+
+		glamor_priv->saved_triangles = ps->Triangles;
+		ps->Triangles = glamor_triangles;
+
+		glamor_priv->saved_create_picture = ps->CreatePicture;
+		ps->CreatePicture = glamor_create_picture;
+
+		glamor_priv->saved_destroy_picture = ps->DestroyPicture;
+		ps->DestroyPicture = glamor_destroy_picture;
+
+		glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
+		ps->UnrealizeGlyph = glamor_glyph_unrealize;
+	}
+
+	glamor_init_composite_shaders(screen);
 #endif
-    glamor_init_solid_shader(screen);
-    glamor_init_tile_shader(screen);
-    glamor_init_putimage_shaders(screen);
-    glamor_init_finish_access_shaders(screen);
-    glamor_pixmap_init(screen);
+	glamor_init_solid_shader(screen);
+	glamor_init_tile_shader(screen);
+	glamor_init_putimage_shaders(screen);
+	glamor_init_finish_access_shaders(screen);
+	glamor_pixmap_init(screen);
 
 #ifdef GLAMOR_GLES2
-    glamor_priv->gl_flavor = GLAMOR_GL_ES2;
+	glamor_priv->gl_flavor = GLAMOR_GL_ES2;
 #else
-    glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
 #endif
 
-    return TRUE;
+	return TRUE;
 
-fail:
-    free(glamor_priv);
-    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
-    return FALSE;
+      fail:
+	free(glamor_priv);
+	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
+		      NULL);
+	return FALSE;
 }
 
-Bool 
+Bool
 glamor_close_screen(int idx, ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
 #ifdef RENDER
-    PictureScreenPtr	ps = GetPictureScreenIfSet(screen);
+	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
-    glamor_glyphs_fini(screen);
-    screen->CloseScreen = glamor_priv->saved_close_screen;
-    screen->CreateGC = glamor_priv->saved_create_gc;
-    screen->CreatePixmap = glamor_priv->saved_create_pixmap;
-    screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
-    screen->GetSpans = glamor_priv->saved_get_spans;
-    screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes;
-    screen->CopyWindow = glamor_priv->saved_copy_window;
-    screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
+	glamor_glyphs_fini(screen);
+	screen->CloseScreen = glamor_priv->saved_close_screen;
+	screen->CreateGC = glamor_priv->saved_create_gc;
+	screen->CreatePixmap = glamor_priv->saved_create_pixmap;
+	screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
+	screen->GetSpans = glamor_priv->saved_get_spans;
+	screen->ChangeWindowAttributes =
+	    glamor_priv->saved_change_window_attributes;
+	screen->CopyWindow = glamor_priv->saved_copy_window;
+	screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
 #ifdef RENDER
-    if (ps) {
-	ps->Composite = glamor_priv->saved_composite;
-	ps->Trapezoids = glamor_priv->saved_trapezoids;
-	ps->Glyphs = glamor_priv->saved_glyphs;
-        ps->Triangles = glamor_priv->saved_triangles;
-        ps->CreatePicture = glamor_priv->saved_create_picture;
-    }
+	if (ps) {
+		ps->Composite = glamor_priv->saved_composite;
+		ps->Trapezoids = glamor_priv->saved_trapezoids;
+		ps->Glyphs = glamor_priv->saved_glyphs;
+		ps->Triangles = glamor_priv->saved_triangles;
+		ps->CreatePicture = glamor_priv->saved_create_picture;
+	}
 #endif
-    if (glamor_priv->vb)
-      free(glamor_priv->vb);
-    free(glamor_priv);
-    return screen->CloseScreen(idx, screen);   
-    
+	if (glamor_priv->vb)
+		free(glamor_priv->vb);
+	free(glamor_priv);
+	return screen->CloseScreen(idx, screen);
+
 }
 
 void
 glamor_fini(ScreenPtr screen)
 {
-/* Do nothing currently. */
+	/* Do nothing currently. */
 }
diff --git a/glamor/glamor.h b/glamor/glamor.h
index e8719fb..f9da4ad 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -39,25 +39,43 @@
 #include "fb.h"
 #include "fbpict.h"
 
-#endif /* GLAMOR_H */
+#endif				/* GLAMOR_H */
 
 
-#define GLAMOR_INVERTED_Y_AXIS  1
-#define GLAMOR_HOSTX            2
-#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX)
+#define GLAMOR_INVERTED_Y_AXIS  	1
+#define GLAMOR_USE_SCREEN		2
+#define GLAMOR_USE_PICTURE_SCREEN 	4
+
+#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
+				 | GLAMOR_USE_SCREEN 			\
+                                 | GLAMOR_USE_PICTURE_SCREEN)
 
 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
 
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
-extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
-extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen);
-void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
+extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
+						       int w, int h,
+						       unsigned int tex);
+extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
+void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
+			       unsigned int tex);
+
+extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
+extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 
 #ifdef GLAMOR_FOR_XORG
 extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
-extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
-extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride);
-extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
-extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
+extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
+							int handle,
+							int stride);
+extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
+							int handle,
+							int stride);
+
+extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen);
+extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
+
+extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
+extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
 #endif
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index ec57520..b49d816 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -35,367 +35,406 @@
 static Bool
 glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 			    DrawablePtr dst,
-			    GCPtr gc,
-			    BoxPtr box,
-			    int nbox,
-			    int dx,
-			    int dy)
+			    GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
 {
-    ScreenPtr screen = dst->pScreen;
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-    glamor_pixmap_private *src_pixmap_priv;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
-
-    if (!glamor_priv->has_fbo_blit) {
-	glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
-	return FALSE;
-    }
-    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-
-    if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) 
-      return FALSE;
-
-    if (gc) {
-	if (gc->alu != GXcopy) {
-	    glamor_delayed_fallback(screen, "non-copy ALU\n");
-	    return FALSE;
+	ScreenPtr screen = dst->pScreen;
+	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+	glamor_pixmap_private *src_pixmap_priv;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
+
+	if (!glamor_priv->has_fbo_blit) {
+		glamor_delayed_fallback(screen,
+					"no EXT_framebuffer_blit\n");
+		return FALSE;
 	}
-	if (!glamor_pm_is_solid(dst, gc->planemask)) {
-	    glamor_delayed_fallback(screen, "non-solid planemask\n");
-	    return FALSE;
+	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+
+	if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
+		return FALSE;
+
+	if (gc) {
+		if (gc->alu != GXcopy) {
+			glamor_delayed_fallback(screen, "non-copy ALU\n");
+			return FALSE;
+		}
+		if (!glamor_pm_is_solid(dst, gc->planemask)) {
+			glamor_delayed_fallback(screen,
+						"non-solid planemask\n");
+			return FALSE;
+		}
 	}
-    }
 
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
-        glamor_delayed_fallback(screen, "no src fbo\n");
-        return FALSE;
-    }
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+		glamor_delayed_fallback(screen, "no src fbo\n");
+		return FALSE;
+	}
 
-    if (glamor_set_destination_pixmap(dst_pixmap)) {
-	return FALSE;
-    }
-    glamor_validate_pixmap(dst_pixmap);
-
-    dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
-    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
-    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
-    src_y_off += dy;
-
-    for (i = 0; i < nbox; i++) {
-      if(glamor_priv->yInverted) {
-	dispatch->glBlitFramebuffer((box[i].x1 + dx + src_x_off),
-                             (box[i].y1 + src_y_off),
-			     (box[i].x2 + dx + src_x_off),
-			     (box[i].y2 + src_y_off),
-                             (box[i].x1 + dst_x_off),
-                             (box[i].y1 + dst_y_off),
-			     (box[i].x2 + dst_x_off),
-			     (box[i].y2 + dst_y_off),
-			     GL_COLOR_BUFFER_BIT,
-			     GL_NEAREST);
-       } else {
-	int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
-	int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
-	int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
-	int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
-
-	dispatch->glBlitFramebuffer(box[i].x1 + dx + src_x_off,
-			     flip_src_y1,
-			     box[i].x2 + dx + src_x_off,
-			     flip_src_y2,
-			     box[i].x1 + dst_x_off,
-			     flip_dst_y1,
-			     box[i].x2 + dst_x_off,
-			     flip_dst_y2,
-			     GL_COLOR_BUFFER_BIT,
-			     GL_NEAREST);
+	if (glamor_set_destination_pixmap(dst_pixmap)) {
+		return FALSE;
+	}
+	glamor_validate_pixmap(dst_pixmap);
+
+	dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
+				    src_pixmap_priv->fb);
+	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
+				   &dst_y_off);
+	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+				   &src_y_off);
+	src_y_off += dy;
+
+	for (i = 0; i < nbox; i++) {
+		if (glamor_priv->yInverted) {
+			dispatch->glBlitFramebuffer((box[i].x1 + dx +
+						     src_x_off),
+						    (box[i].y1 +
+						     src_y_off),
+						    (box[i].x2 + dx +
+						     src_x_off),
+						    (box[i].y2 +
+						     src_y_off),
+						    (box[i].x1 +
+						     dst_x_off),
+						    (box[i].y1 +
+						     dst_y_off),
+						    (box[i].x2 +
+						     dst_x_off),
+						    (box[i].y2 +
+						     dst_y_off),
+						    GL_COLOR_BUFFER_BIT,
+						    GL_NEAREST);
+		} else {
+			int flip_dst_y1 =
+			    dst_pixmap->drawable.height - (box[i].y2 +
+							   dst_y_off);
+			int flip_dst_y2 =
+			    dst_pixmap->drawable.height - (box[i].y1 +
+							   dst_y_off);
+			int flip_src_y1 =
+			    src_pixmap->drawable.height - (box[i].y2 +
+							   src_y_off);
+			int flip_src_y2 =
+			    src_pixmap->drawable.height - (box[i].y1 +
+							   src_y_off);
+
+			dispatch->glBlitFramebuffer(box[i].x1 + dx +
+						    src_x_off,
+						    flip_src_y1,
+						    box[i].x2 + dx +
+						    src_x_off,
+						    flip_src_y2,
+						    box[i].x1 +
+						    dst_x_off,
+						    flip_dst_y1,
+						    box[i].x2 +
+						    dst_x_off,
+						    flip_dst_y2,
+						    GL_COLOR_BUFFER_BIT,
+						    GL_NEAREST);
+		}
 	}
-    }
-    return TRUE;
+	return TRUE;
 }
 #endif
 
 static Bool
 glamor_copy_n_to_n_textured(DrawablePtr src,
-			      DrawablePtr dst,
-			      GCPtr gc,
-			      BoxPtr box,
-			      int nbox,
-			      int dx,
-			      int dy
-                              )
+			    DrawablePtr dst,
+			    GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
 {
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(dst->pScreen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-    int i;
-    float vertices[8], texcoords[8];
-    glamor_pixmap_private *src_pixmap_priv;
-    glamor_pixmap_private *dst_pixmap_priv;
-    int src_x_off, src_y_off, dst_x_off, dst_y_off;
-    enum glamor_pixmap_status src_status = GLAMOR_NONE;
-    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-    int flush_needed = 0;
-
-    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
-        glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
-        goto fail;
-    }
-
-    if (!src_pixmap_priv->gl_fbo) {
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(dst->pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+	int i;
+	float vertices[8], texcoords[8];
+	glamor_pixmap_private *src_pixmap_priv;
+	glamor_pixmap_private *dst_pixmap_priv;
+	int src_x_off, src_y_off, dst_x_off, dst_y_off;
+	enum glamor_pixmap_status src_status = GLAMOR_NONE;
+	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+	int flush_needed = 0;
+
+	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+		glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
+		goto fail;
+	}
+
+	if (!src_pixmap_priv->gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-	glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
-	goto fail;
+		glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
+		goto fail;
 #else
-        src_status = glamor_upload_pixmap_to_texture(src_pixmap);
-	if (src_status != GLAMOR_UPLOAD_DONE) 
-	goto fail;
+		src_status = glamor_upload_pixmap_to_texture(src_pixmap);
+		if (src_status != GLAMOR_UPLOAD_DONE)
+			goto fail;
 #endif
-    }
-    else
-      flush_needed = 1;
-
-    if (gc) {
-	glamor_set_alu(dispatch, gc->alu);
-	if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-	  goto fail;
-        if (gc->alu != GXcopy) {
-          glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
-          glamor_validate_pixmap(src_pixmap);
-        }
-    }
+	} else
+		flush_needed = 1;
+
+	if (gc) {
+		glamor_set_alu(dispatch, gc->alu);
+		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+			goto fail;
+		if (gc->alu != GXcopy) {
+			glamor_set_destination_pixmap_priv_nc
+			    (src_pixmap_priv);
+			glamor_validate_pixmap(src_pixmap);
+		}
+	}
 
-    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-    glamor_validate_pixmap(dst_pixmap);
+	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+	glamor_validate_pixmap(dst_pixmap);
 
-    pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+	pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
-    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
+				   &dst_y_off);
 
 
 
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
-                          2 * sizeof(float),
-                          vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-      glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
-      dx += src_x_off;
-      dy += src_y_off;
-      pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+		glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+					   &src_y_off);
+		dx += src_x_off;
+		dy += src_y_off;
+		pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
+				      &src_yscale);
 
-      dispatch->glActiveTexture(GL_TEXTURE0);
-      dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+		dispatch->glActiveTexture(GL_TEXTURE0);
+		dispatch->glBindTexture(GL_TEXTURE_2D,
+					src_pixmap_priv->tex);
 #ifndef GLAMOR_GLES2
-      dispatch->glEnable(GL_TEXTURE_2D);
+		dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- 
-      dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
-                            2 * sizeof(float),
-                            texcoords);
-      dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-      dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-      dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
-      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
- 
-   } 
-    else {
-      GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
-   }
- 
-    for (i = 0; i < nbox; i++) {
-
-      glamor_set_normalize_vcoords(dst_xscale, dst_yscale, 
-				   box[i].x1 + dst_x_off,
-				   box[i].y1 + dst_y_off,
-				   box[i].x2 + dst_x_off,
-				   box[i].y2 + dst_y_off,
-				   glamor_priv->yInverted,
-				   vertices);
-
-      if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
-        glamor_set_normalize_tcoords(src_xscale, src_yscale,
-	  			     box[i].x1 + dx, box[i].y1 + dy,
-				     box[i].x2 + dx, box[i].y2 + dy,
-				     glamor_priv->yInverted,
-				     texcoords);
-
-      dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    }
-
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-      dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+
+		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+						GL_FLOAT, GL_FALSE,
+						2 * sizeof(float),
+						texcoords);
+		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+		dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+		dispatch->
+		    glUniform1i(glamor_priv->finish_access_no_revert[0],
+				1);
+		dispatch->
+		    glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
+
+	} else {
+		GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
+					  src_pixmap_priv);
+	}
+
+	for (i = 0; i < nbox; i++) {
+
+		glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+					     box[i].x1 + dst_x_off,
+					     box[i].y1 + dst_y_off,
+					     box[i].x2 + dst_x_off,
+					     box[i].y2 + dst_y_off,
+					     glamor_priv->yInverted,
+					     vertices);
+
+		if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
+			glamor_set_normalize_tcoords(src_xscale,
+						     src_yscale,
+						     box[i].x1 + dx,
+						     box[i].y1 + dy,
+						     box[i].x2 + dx,
+						     box[i].y2 + dy,
+						     glamor_priv->yInverted,
+						     texcoords);
+
+		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	}
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+		dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-      dispatch->glDisable(GL_TEXTURE_2D);
+		dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-    }
-    dispatch->glUseProgram(0);
-    /* The source texture is bound to a fbo, we have to flush it here. */
-    if (flush_needed) 
-      dispatch->glFlush();
-    return TRUE;
-
-fail:
-    glamor_set_alu(dispatch, GXcopy);
-    glamor_set_planemask(dst_pixmap, ~0);
-    return FALSE;
+	}
+	dispatch->glUseProgram(0);
+	/* The source texture is bound to a fbo, we have to flush it here. */
+	if (flush_needed)
+		dispatch->glFlush();
+	return TRUE;
+
+      fail:
+	glamor_set_alu(dispatch, GXcopy);
+	glamor_set_planemask(dst_pixmap, ~0);
+	return FALSE;
 }
 
 void
 glamor_copy_n_to_n(DrawablePtr src,
-		 DrawablePtr dst,
-		 GCPtr gc,
-		 BoxPtr box,
-		 int nbox,
-		 int		dx,
-		 int		dy,
-		 Bool		reverse,
-		 Bool		upsidedown,
-		 Pixel		bitplane,
-		 void		*closure)
+		   DrawablePtr dst,
+		   GCPtr gc,
+		   BoxPtr box,
+		   int nbox,
+		   int dx,
+		   int dy,
+		   Bool reverse,
+		   Bool upsidedown, Pixel bitplane, void *closure)
 {
-    glamor_access_t dst_access;
-    PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
-    DrawablePtr temp_src = src;
-    glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
-    BoxRec bound;
-    ScreenPtr screen;
-    int temp_dx = dx;
-    int temp_dy = dy;
-    int src_x_off, src_y_off, dst_x_off, dst_y_off;
-    int i;
-    int overlaped = 0;
-    
-    dst_pixmap = glamor_get_drawable_pixmap(dst);
-    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-    src_pixmap = glamor_get_drawable_pixmap(src);
-    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-    screen = dst_pixmap->drawable.pScreen;
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
-      glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap);
-      goto fail;
-    }
-
-    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
-    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
-
-    if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
-      int x_shift = abs(src_x_off - dx - dst_x_off);
-      int y_shift = abs(src_y_off - dy - dst_y_off);
-      for ( i = 0; i < nbox; i++)
-        {
-         if (x_shift < abs(box[i].x2 - box[i].x1) 
-            && y_shift < abs(box[i].y2 - box[i].y1)) {
-           overlaped = 1;
-           break;
-         }
-        }
-    }
-    /* XXX need revisit to handle overlapped area copying. */
+	glamor_access_t dst_access;
+	PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
+	DrawablePtr temp_src = src;
+	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+	BoxRec bound;
+	ScreenPtr screen;
+	int temp_dx = dx;
+	int temp_dy = dy;
+	int src_x_off, src_y_off, dst_x_off, dst_y_off;
+	int i;
+	int overlaped = 0;
+
+	dst_pixmap = glamor_get_drawable_pixmap(dst);
+	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+	src_pixmap = glamor_get_drawable_pixmap(src);
+	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+	screen = dst_pixmap->drawable.pScreen;
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+		glamor_fallback("dest pixmap %p has no fbo. \n",
+				dst_pixmap);
+		goto fail;
+	}
+
+	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
+				   &src_y_off);
+	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
+				   &dst_y_off);
+
+	if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
+		int x_shift = abs(src_x_off - dx - dst_x_off);
+		int y_shift = abs(src_y_off - dy - dst_y_off);
+		for (i = 0; i < nbox; i++) {
+			if (x_shift < abs(box[i].x2 - box[i].x1)
+			    && y_shift < abs(box[i].y2 - box[i].y1)) {
+				overlaped = 1;
+				break;
+			}
+		}
+	}
+	/* XXX need revisit to handle overlapped area copying. */
 
 #ifndef GLAMOR_GLES2
-    if ((overlaped 
-          || !src_pixmap_priv->gl_tex  || !dst_pixmap_priv->gl_tex )
-        && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
-        goto done;
-	return;
-    }
+	if ((overlaped
+	     || !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
+	    && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
+					   dy)) {
+		goto done;
+		return;
+	}
 #endif
-    glamor_calculate_boxes_bound(&bound, box, nbox);
-
-    /*  Overlaped indicate the src and dst are the same pixmap. */
-    if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) 
-	&& ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
-	    * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height))) {
-
-      temp_pixmap = (*screen->CreatePixmap)(screen,
-					 bound.x2 - bound.x1,
-					 bound.y2 - bound.y1,
-					 src_pixmap->drawable.depth,
-					 overlaped ? 0 : GLAMOR_CREATE_PIXMAP_CPU);
-      if (!temp_pixmap)
-	goto fail;
-      glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
-      temp_src = &temp_pixmap->drawable;
-
-      if (overlaped)
-        glamor_copy_n_to_n_textured(src, temp_src, gc, box, nbox, 
-                                    temp_dx + bound.x1, temp_dy + bound.y1); 
-      else
-        fbCopyNtoN(src, temp_src, gc, box, nbox,
-	  	   temp_dx + bound.x1, temp_dy + bound.y1, 
-		   reverse, upsidedown, bitplane,
-		   closure);
-      glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
-      temp_dx = -bound.x1;
-      temp_dy = -bound.y1;
-    }
-    else {
-      temp_dx = dx;
-      temp_dy = dy;
-      temp_src = src;
-    }
-
-    if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
-        goto done;
-    }
-
-    
- fail:
-    glamor_report_delayed_fallbacks(src->pScreen);
-    glamor_report_delayed_fallbacks(dst->pScreen);
-
-    glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
-		    glamor_get_drawable_location(src),
-		    glamor_get_drawable_location(dst));
-
-    if (gc && gc->alu != GXcopy)
-      dst_access = GLAMOR_ACCESS_RW;
-    else
-      dst_access = GLAMOR_ACCESS_WO;
-
-    if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
-	if (dst == src 
-            || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
-	    fbCopyNtoN(src, dst, gc, box, nbox,
-		       dx, dy, reverse, upsidedown, bitplane,
-		       closure);
-            if (dst != src)
-	      glamor_finish_access(src);
+	glamor_calculate_boxes_bound(&bound, box, nbox);
+
+	/*  Overlaped indicate the src and dst are the same pixmap. */
+	if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
+			  && ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
+			      * 4 >
+			      src_pixmap->drawable.width *
+			      src_pixmap->drawable.height))) {
+
+		temp_pixmap = (*screen->CreatePixmap) (screen,
+						       bound.x2 - bound.x1,
+						       bound.y2 - bound.y1,
+						       src_pixmap->
+						       drawable.depth,
+						       overlaped ? 0 :
+						       GLAMOR_CREATE_PIXMAP_CPU);
+		if (!temp_pixmap)
+			goto fail;
+		glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
+		temp_src = &temp_pixmap->drawable;
+
+		if (overlaped)
+			glamor_copy_n_to_n_textured(src, temp_src, gc, box,
+						    nbox,
+						    temp_dx + bound.x1,
+						    temp_dy + bound.y1);
+		else
+			fbCopyNtoN(src, temp_src, gc, box, nbox,
+				   temp_dx + bound.x1, temp_dy + bound.y1,
+				   reverse, upsidedown, bitplane, closure);
+		glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
+		temp_dx = -bound.x1;
+		temp_dy = -bound.y1;
+	} else {
+		temp_dx = dx;
+		temp_dy = dy;
+		temp_src = src;
+	}
+
+	if (glamor_copy_n_to_n_textured
+	    (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
+		goto done;
+	}
+
+
+      fail:
+	glamor_report_delayed_fallbacks(src->pScreen);
+	glamor_report_delayed_fallbacks(dst->pScreen);
+
+	glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
+			glamor_get_drawable_location(src),
+			glamor_get_drawable_location(dst));
+
+	if (gc && gc->alu != GXcopy)
+		dst_access = GLAMOR_ACCESS_RW;
+	else
+		dst_access = GLAMOR_ACCESS_WO;
+
+	if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
+		if (dst == src
+		    || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+			fbCopyNtoN(src, dst, gc, box, nbox,
+				   dx, dy, reverse, upsidedown, bitplane,
+				   closure);
+			if (dst != src)
+				glamor_finish_access(src);
+		}
+		glamor_finish_access(dst);
+	}
+
+      done:
+	glamor_clear_delayed_fallbacks(src->pScreen);
+	glamor_clear_delayed_fallbacks(dst->pScreen);
+	if (temp_src != src) {
+		(*screen->DestroyPixmap) (temp_pixmap);
 	}
-	glamor_finish_access(dst);
-    }
-
-done:
-    glamor_clear_delayed_fallbacks(src->pScreen);
-    glamor_clear_delayed_fallbacks(dst->pScreen);
-    if (temp_src != src) {
-      (*screen->DestroyPixmap)(temp_pixmap);
-    }
 }
 
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-		 int srcx, int srcy, int width, int height, int dstx, int dsty)
+		 int srcx, int srcy, int width, int height, int dstx,
+		 int dsty)
 {
-    RegionPtr region;
-    region = miDoCopy(src, dst, gc,
-		      srcx, srcy, width, height,
-		      dstx, dsty, glamor_copy_n_to_n, 0, NULL);
+	RegionPtr region;
+	region = miDoCopy(src, dst, gc,
+			  srcx, srcy, width, height,
+			  dstx, dsty, glamor_copy_n_to_n, 0, NULL);
 
-    return region;
+	return region;
 }
diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c
index 1e840a9..11b3036 100644
--- a/glamor/glamor_copywindow.c
+++ b/glamor/glamor_copywindow.c
@@ -32,29 +32,31 @@
  * Screen CopyWindow implementation.
  */
 
-void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
-			RegionPtr src_region)
+void
+glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
+		   RegionPtr src_region)
 {
-    RegionRec dst_region;
-    int dx, dy;
-    PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
+	RegionRec dst_region;
+	int dx, dy;
+	PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
 
-    dx = old_origin.x - win->drawable.x;
-    dy = old_origin.y - win->drawable.y;
-    REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
+	dx = old_origin.x - win->drawable.x;
+	dy = old_origin.y - win->drawable.y;
+	REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
 
-    REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
+	REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
 
-    REGION_INTERSECT(win->drawable.pScreen, &dst_region, &win->borderClip,
-		     src_region);
+	REGION_INTERSECT(win->drawable.pScreen, &dst_region,
+			 &win->borderClip, src_region);
 #ifdef COMPOSITE
-    if (pixmap->screen_x || pixmap->screen_y)
-	REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
-			 -pixmap->screen_x, -pixmap->screen_y);
+	if (pixmap->screen_x || pixmap->screen_y)
+		REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
+				 -pixmap->screen_x, -pixmap->screen_y);
 #endif
 
-    miCopyRegion(&pixmap->drawable, &pixmap->drawable,
-		 NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL);
+	miCopyRegion(&pixmap->drawable, &pixmap->drawable,
+		     NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0,
+		     NULL);
 
-    REGION_UNINIT(win->drawable.pScreen, &dst_region);
+	REGION_UNINIT(win->drawable.pScreen, &dst_region);
 }
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 2249ac8..8ba938f 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -42,215 +42,247 @@
 const Bool
 glamor_get_drawable_location(const DrawablePtr drawable)
 {
-  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv =
-    glamor_get_screen_private(drawable->pScreen);
-  if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
-    return 'm';
-  if (pixmap_priv->fb == glamor_priv->screen_fbo)
-    return 's';
-  else
-    return 'f';
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(drawable->pScreen);
+	if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
+		return 'm';
+	if (pixmap_priv->fb == glamor_priv->screen_fbo)
+		return 's';
+	else
+		return 'f';
 }
 
 GLint
-glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source)
+glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
+			 const char *source)
 {
-  GLint ok;
-  GLint prog;
-
-  prog = dispatch->glCreateShader(type);
-  dispatch->glShaderSource(prog, 1, (const GLchar **)&source, NULL);
-  dispatch->glCompileShader(prog);
-  dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
-  if (!ok) {
-    GLchar *info;
-    GLint size;
-
-    dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
-    info = malloc(size);
-
-    dispatch->glGetShaderInfoLog(prog, size, NULL, info);
-    ErrorF("Failed to compile %s: %s\n",
-	   type == GL_FRAGMENT_SHADER ? "FS" : "VS",
-	   info);
-    ErrorF("Program source:\n%s", source);
-    FatalError("GLSL compile failure\n");
-  }
-
-  return prog;
+	GLint ok;
+	GLint prog;
+
+	prog = dispatch->glCreateShader(type);
+	dispatch->glShaderSource(prog, 1, (const GLchar **) &source, NULL);
+	dispatch->glCompileShader(prog);
+	dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+	if (!ok) {
+		GLchar *info;
+		GLint size;
+
+		dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+		info = malloc(size);
+
+		dispatch->glGetShaderInfoLog(prog, size, NULL, info);
+		ErrorF("Failed to compile %s: %s\n",
+		       type == GL_FRAGMENT_SHADER ? "FS" : "VS", info);
+		ErrorF("Program source:\n%s", source);
+		FatalError("GLSL compile failure\n");
+	}
+
+	return prog;
 }
 
 void
-glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog)
+glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog)
 {
-  GLint ok;
-
-  dispatch->glLinkProgram(prog);
-  dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
-  if (!ok) {
-    GLchar *info;
-    GLint size;
-
-    dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
-    info = malloc(size);
-
-    dispatch->glGetProgramInfoLog(prog, size, NULL, info);
-    ErrorF("Failed to link: %s\n",
-	   info);
-    FatalError("GLSL link failure\n");
-  }
+	GLint ok;
+
+	dispatch->glLinkProgram(prog);
+	dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+	if (!ok) {
+		GLchar *info;
+		GLint size;
+
+		dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+		info = malloc(size);
+
+		dispatch->glGetProgramInfoLog(prog, size, NULL, info);
+		ErrorF("Failed to link: %s\n", info);
+		FatalError("GLSL link failure\n");
+	}
 }
 
 
 Bool
 glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
-  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-  return glamor_download_pixmap_to_cpu(pixmap, access);
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	return glamor_download_pixmap_to_cpu(pixmap, access);
 }
 
 void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  const char *vs_source =
-    "attribute vec4 v_position;\n"
-    "attribute vec4 v_texcoord0;\n"
-    "varying vec2 source_texture;\n"
-    "void main()\n"
-    "{\n"
-    "	gl_Position = v_position;\n"
-    "	source_texture = v_texcoord0.xy;\n"
-    "}\n";
-
-  const char *fs_source =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 source_texture;\n"
-    "uniform sampler2D sampler;\n"
-    "uniform int no_revert;\n"
-    "uniform int swap_rb;\n"
-    "void main()\n"
-    "{\n"
-    "   if (no_revert == 1) \n"
-    "    { \n"
-    "     if (swap_rb == 1)   \n"
-    "	  gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
-    "     else \n"
-    "	  gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
-    "    } \n"
-    "   else \n"
-    "    { \n"
-    "     if (swap_rb == 1)   \n"
-    "	    gl_FragColor = texture2D(sampler, source_texture).argb;\n"
-    "     else \n"
-    "	    gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
-    "    } \n"
-    "}\n";
-    
-  const char *set_alpha_source =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 source_texture;\n"
-    "uniform sampler2D sampler;\n"
-    "uniform int no_revert;\n"
-    "uniform int swap_rb;\n"
-    "void main()\n"
-    "{\n"
-    "   if (no_revert == 1) \n"
-    "    { \n"
-    "     if (swap_rb == 1)   \n"
-    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
-    "     else \n"
-    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
-    "    } \n"
-    "   else \n"
-    "    { \n"
-    "     if (swap_rb == 1)   \n"
-    "	  gl_FragColor = vec4(1,  texture2D(sampler, source_texture).rgb);\n"
-    "     else \n"
-    "	  gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
-    "    } \n"
-    "}\n";
-  GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
-  GLint sampler_uniform_location;
-
-  glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
-  glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
-
-  vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
-  fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source);
-  dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-  dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
-
-  avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
-  set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source);
-  dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-  dispatch->glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
-
-  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position");
-  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]);
-
-  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position");
-  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]);
-
-  glamor_priv->finish_access_no_revert[0] = 
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
-
-  glamor_priv->finish_access_swap_rb[0] = 
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
-  sampler_uniform_location =
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
-  dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
-  dispatch->glUniform1i(sampler_uniform_location, 0);
-  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0],1);
-  dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
-  dispatch->glUseProgram(0);
-
-  glamor_priv->finish_access_no_revert[1] = 
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
-  glamor_priv->finish_access_swap_rb[1] = 
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
-  sampler_uniform_location =
-    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
-  dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
-  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1],1);
-  dispatch->glUniform1i(sampler_uniform_location, 0);
-  dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
-  dispatch->glUseProgram(0);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	const char *vs_source =
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord0;\n"
+	    "varying vec2 source_texture;\n"
+	    "void main()\n"
+	    "{\n"
+	    "	gl_Position = v_position;\n"
+	    "	source_texture = v_texcoord0.xy;\n" "}\n";
+
+	const char *fs_source =
+	    GLAMOR_DEFAULT_PRECISION
+	    "varying vec2 source_texture;\n"
+	    "uniform sampler2D sampler;\n"
+	    "uniform int no_revert;\n"
+	    "uniform int swap_rb;\n"
+	    "void main()\n"
+	    "{\n"
+	    "   if (no_revert == 1) \n"
+	    "    { \n"
+	    "     if (swap_rb == 1)   \n"
+	    "	  gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+	    "     else \n"
+	    "	  gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+	    "    } \n"
+	    "   else \n"
+	    "    { \n"
+	    "     if (swap_rb == 1)   \n"
+	    "	    gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+	    "     else \n"
+	    "	    gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+	    "    } \n" "}\n";
+
+	const char *set_alpha_source =
+	    GLAMOR_DEFAULT_PRECISION
+	    "varying vec2 source_texture;\n"
+	    "uniform sampler2D sampler;\n"
+	    "uniform int no_revert;\n"
+	    "uniform int swap_rb;\n"
+	    "void main()\n"
+	    "{\n"
+	    "   if (no_revert == 1) \n"
+	    "    { \n"
+	    "     if (swap_rb == 1)   \n"
+	    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+	    "     else \n"
+	    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+	    "    } \n"
+	    "   else \n"
+	    "    { \n"
+	    "     if (swap_rb == 1)   \n"
+	    "	  gl_FragColor = vec4(1,  texture2D(sampler, source_texture).rgb);\n"
+	    "     else \n"
+	    "	  gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+	    "    } \n" "}\n";
+	GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
+	GLint sampler_uniform_location;
+
+	glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
+	glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
+
+	vs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
+				     vs_source);
+	fs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+				     fs_source);
+	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
+				 vs_prog);
+	dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
+				 fs_prog);
+
+	avs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
+				     vs_source);
+	set_alpha_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+				     set_alpha_source);
+	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
+				 avs_prog);
+	dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
+				 set_alpha_prog);
+
+	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
+				       GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0],
+				       GLAMOR_VERTEX_SOURCE,
+				       "v_texcoord0");
+	glamor_link_glsl_prog(dispatch,
+			      glamor_priv->finish_access_prog[0]);
+
+	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
+				       GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1],
+				       GLAMOR_VERTEX_SOURCE,
+				       "v_texcoord0");
+	glamor_link_glsl_prog(dispatch,
+			      glamor_priv->finish_access_prog[1]);
+
+	glamor_priv->finish_access_no_revert[0] =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
+				 "no_revert");
+
+	glamor_priv->finish_access_swap_rb[0] =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
+				 "swap_rb");
+	sampler_uniform_location =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[0],
+				 "sampler");
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+	dispatch->glUniform1i(sampler_uniform_location, 0);
+	dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
+	dispatch->glUseProgram(0);
+
+	glamor_priv->finish_access_no_revert[1] =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
+				 "no_revert");
+	glamor_priv->finish_access_swap_rb[1] =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
+				 "swap_rb");
+	sampler_uniform_location =
+	    dispatch->
+	    glGetUniformLocation(glamor_priv->finish_access_prog[1],
+				 "sampler");
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
+	dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1], 1);
+	dispatch->glUniform1i(sampler_uniform_location, 0);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
+	dispatch->glUseProgram(0);
 
 }
 
 void
 glamor_finish_access(DrawablePtr drawable)
 {
-  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    
-  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-    return;
-
-  if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
-    glamor_restore_pixmap_to_texture(pixmap);
-  }
-
-  if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
-    assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
-    dispatch->glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
-    pixmap_priv->pbo_valid = FALSE;
-    dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-    pixmap_priv->pbo = 0;
-  } else {
-    free(pixmap->devPrivate.ptr);
-  }
-
-  pixmap->devPrivate.ptr = NULL;
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(drawable->pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return;
+
+	if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
+		glamor_restore_pixmap_to_texture(pixmap);
+	}
+
+	if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
+		assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+		dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+		pixmap_priv->pbo_valid = FALSE;
+		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
+		pixmap_priv->pbo = 0;
+	} else {
+		free(pixmap->devPrivate.ptr);
+	}
+
+	pixmap->devPrivate.ptr = NULL;
 }
 
 
@@ -265,19 +297,21 @@ glamor_finish_access(DrawablePtr drawable)
 Bool
 glamor_prepare_access_gc(GCPtr gc)
 {
-  if (gc->stipple) {
-    if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
-      return FALSE;
-  }
-  if (gc->fillStyle == FillTiled) {
-    if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
-				GLAMOR_ACCESS_RO)) {
-      if (gc->stipple)
-	glamor_finish_access(&gc->stipple->drawable);
-      return FALSE;
-    }
-  }
-  return TRUE;
+	if (gc->stipple) {
+		if (!glamor_prepare_access
+		    (&gc->stipple->drawable, GLAMOR_ACCESS_RO))
+			return FALSE;
+	}
+	if (gc->fillStyle == FillTiled) {
+		if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
+					   GLAMOR_ACCESS_RO)) {
+			if (gc->stipple)
+				glamor_finish_access(&gc->
+						     stipple->drawable);
+			return FALSE;
+		}
+	}
+	return TRUE;
 }
 
 /**
@@ -286,10 +320,10 @@ glamor_prepare_access_gc(GCPtr gc)
 void
 glamor_finish_access_gc(GCPtr gc)
 {
-  if (gc->fillStyle == FillTiled)
-    glamor_finish_access(&gc->tile.pixmap->drawable);
-  if (gc->stipple)
-    glamor_finish_access(&gc->stipple->drawable);
+	if (gc->fillStyle == FillTiled)
+		glamor_finish_access(&gc->tile.pixmap->drawable);
+	if (gc->stipple)
+		glamor_finish_access(&gc->stipple->drawable);
 }
 
 Bool
@@ -299,31 +333,32 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 	       unsigned long fg_pixel, unsigned long bg_pixel,
 	       int stipple_x, int stipple_y)
 {
-  glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
-  return FALSE;
+	glamor_fallback("stubbed out stipple depth %d\n",
+			pixmap->drawable.depth);
+	return FALSE;
 }
 
 GCOps glamor_gc_ops = {
-  .FillSpans = glamor_fill_spans,
-  .SetSpans = glamor_set_spans,
-  .PutImage = glamor_put_image,
-  .CopyArea = glamor_copy_area,
-  .CopyPlane = miCopyPlane,
-  .PolyPoint = miPolyPoint,
-  .Polylines = glamor_poly_lines,
-  .PolySegment = miPolySegment,
-  .PolyRectangle = miPolyRectangle,
-  .PolyArc = miPolyArc,
-  .FillPolygon = miFillPolygon,
-  .PolyFillRect = glamor_poly_fill_rect,
-  .PolyFillArc = miPolyFillArc,
-  .PolyText8 = miPolyText8,
-  .PolyText16 = miPolyText16,
-  .ImageText8 = miImageText8,
-  .ImageText16 = miImageText16,
-  .ImageGlyphBlt = miImageGlyphBlt,
-  .PolyGlyphBlt = miPolyGlyphBlt,
-  .PushPixels = miPushPixels,
+	.FillSpans = glamor_fill_spans,
+	.SetSpans = glamor_set_spans,
+	.PutImage = glamor_put_image,
+	.CopyArea = glamor_copy_area,
+	.CopyPlane = miCopyPlane,
+	.PolyPoint = miPolyPoint,
+	.Polylines = glamor_poly_lines,
+	.PolySegment = miPolySegment,
+	.PolyRectangle = miPolyRectangle,
+	.PolyArc = miPolyArc,
+	.FillPolygon = miFillPolygon,
+	.PolyFillRect = glamor_poly_fill_rect,
+	.PolyFillArc = miPolyFillArc,
+	.PolyText8 = miPolyText8,
+	.PolyText16 = miPolyText16,
+	.ImageText8 = miImageText8,
+	.ImageText16 = miImageText16,
+	.ImageGlyphBlt = miImageGlyphBlt,
+	.PolyGlyphBlt = miPolyGlyphBlt,
+	.PushPixels = miPushPixels,
 };
 
 /**
@@ -333,91 +368,104 @@ GCOps glamor_gc_ops = {
 static void
 glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
-  /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
-   * Preempt fbValidateGC by doing its work and masking the change out, so
-   * that we can do the Prepare/finish_access.
-   */
+	/* fbValidateGC will do direct access to pixmaps if the tiling has changed.
+	 * Preempt fbValidateGC by doing its work and masking the change out, so
+	 * that we can do the Prepare/finish_access.
+	 */
 #ifdef FB_24_32BIT
-  if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
-    gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
-    fbGetRotatedPixmap(gc) = 0;
-  }
-
-  if (gc->fillStyle == FillTiled) {
-    PixmapPtr old_tile, new_tile;
-
-    old_tile = gc->tile.pixmap;
-    if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
-      new_tile = fbGetRotatedPixmap(gc);
-      if (!new_tile ||
-	  new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel)
-	{
-	  if (new_tile)
-	    gc->pScreen->DestroyPixmap(new_tile);
-	  /* fb24_32ReformatTile will do direct access of a newly-
-	   * allocated pixmap.
-	   */
-	  glamor_fallback("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile);
-
-	  if (glamor_prepare_access(&old_tile->drawable,
-				    GLAMOR_ACCESS_RO)) {
-	    new_tile = fb24_32ReformatTile(old_tile,
-					   drawable->bitsPerPixel);
-	    glamor_finish_access(&old_tile->drawable);
-	  }
+	if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
+		gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
+		fbGetRotatedPixmap(gc) = 0;
+	}
+
+	if (gc->fillStyle == FillTiled) {
+		PixmapPtr old_tile, new_tile;
+
+		old_tile = gc->tile.pixmap;
+		if (old_tile->drawable.bitsPerPixel !=
+		    drawable->bitsPerPixel) {
+			new_tile = fbGetRotatedPixmap(gc);
+			if (!new_tile ||
+			    new_tile->drawable.bitsPerPixel !=
+			    drawable->bitsPerPixel) {
+				if (new_tile)
+					gc->pScreen->DestroyPixmap
+					    (new_tile);
+				/* fb24_32ReformatTile will do direct access of a newly-
+				 * allocated pixmap.
+				 */
+				glamor_fallback
+				    ("GC %p tile FB_24_32 transformat %p.\n",
+				     gc, old_tile);
+
+				if (glamor_prepare_access
+				    (&old_tile->drawable,
+				     GLAMOR_ACCESS_RO)) {
+					new_tile =
+					    fb24_32ReformatTile
+					    (old_tile,
+					     drawable->bitsPerPixel);
+					glamor_finish_access
+					    (&old_tile->drawable);
+				}
+			}
+			if (new_tile) {
+				fbGetRotatedPixmap(gc) = old_tile;
+				gc->tile.pixmap = new_tile;
+				changes |= GCTile;
+			}
+		}
 	}
-      if (new_tile) {
-	fbGetRotatedPixmap(gc) = old_tile;
-	gc->tile.pixmap = new_tile;
-	changes |= GCTile;
-      }
-    }
-  }
 #endif
-  if (changes & GCTile) {
-    if (!gc->tileIsPixel) {
-      glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap);
-      if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-         && FbEvenTile(gc->tile.pixmap->drawable.width *
-	  			       drawable->bitsPerPixel))
-        {
-	  glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap);
-	  if (glamor_prepare_access(&gc->tile.pixmap->drawable,
-				  GLAMOR_ACCESS_RW)) {
-	  fbPadPixmap(gc->tile.pixmap);
-	  glamor_finish_access(&gc->tile.pixmap->drawable);
-	  }
-        }
-    }
-    /* Mask out the GCTile change notification, now that we've done FB's
-     * job for it.
-     */
-    changes &= ~GCTile;
-  }
-
-  if (changes & GCStipple && gc->stipple) {
-    /* We can't inline stipple handling like we do for GCTile because
-     * it sets fbgc privates.
-     */
-    if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
-      fbValidateGC(gc, changes, drawable);
-      glamor_finish_access(&gc->stipple->drawable);
-    }
-  } else {
-    fbValidateGC(gc, changes, drawable);
-  }
-
-  gc->ops = &glamor_gc_ops;
+	if (changes & GCTile) {
+		if (!gc->tileIsPixel) {
+			glamor_pixmap_private *pixmap_priv =
+			    glamor_get_pixmap_private(gc->tile.pixmap);
+			if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+			    && FbEvenTile(gc->tile.pixmap->drawable.width *
+					  drawable->bitsPerPixel)) {
+				glamor_fallback
+				    ("GC %p tile changed %p.\n", gc,
+				     gc->tile.pixmap);
+				if (glamor_prepare_access
+				    (&gc->tile.pixmap->drawable,
+				     GLAMOR_ACCESS_RW)) {
+					fbPadPixmap(gc->tile.pixmap);
+					glamor_finish_access
+					    (&gc->tile.pixmap->drawable);
+				}
+			}
+		}
+		/* Mask out the GCTile change notification, now that we've done FB's
+		 * job for it.
+		 */
+		changes &= ~GCTile;
+	}
+
+	if (changes & GCStipple && gc->stipple) {
+		/* We can't inline stipple handling like we do for GCTile because
+		 * it sets fbgc privates.
+		 */
+		if (glamor_prepare_access
+		    (&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
+			fbValidateGC(gc, changes, drawable);
+			glamor_finish_access(&gc->stipple->drawable);
+		}
+	} else {
+		fbValidateGC(gc, changes, drawable);
+	}
+
+	gc->ops = &glamor_gc_ops;
 }
 
 static GCFuncs glamor_gc_funcs = {
-  glamor_validate_gc,
-  miChangeGC,
-  miCopyGC,
-  miDestroyGC,
-  miChangeClip,
-  miDestroyClip,
-  miCopyClip
+	glamor_validate_gc,
+	miChangeGC,
+	miCopyGC,
+	miDestroyGC,
+	miChangeClip,
+	miDestroyClip,
+	miCopyClip
 };
 
 /**
@@ -427,69 +475,68 @@ static GCFuncs glamor_gc_funcs = {
 int
 glamor_create_gc(GCPtr gc)
 {
-  if (!fbCreateGC(gc))
-    return FALSE;
+	if (!fbCreateGC(gc))
+		return FALSE;
 
-  gc->funcs = &glamor_gc_funcs;
+	gc->funcs = &glamor_gc_funcs;
 
-  return TRUE;
+	return TRUE;
 }
 
 RegionPtr
 glamor_bitmap_to_region(PixmapPtr pixmap)
 {
-  RegionPtr ret;
-  glamor_fallback("pixmap %p \n", pixmap);
-  if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
-    return NULL;
-  ret = fbPixmapToRegion(pixmap);
-  glamor_finish_access(&pixmap->drawable);
-  return ret;
+	RegionPtr ret;
+	glamor_fallback("pixmap %p \n", pixmap);
+	if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
+		return NULL;
+	ret = fbPixmapToRegion(pixmap);
+	glamor_finish_access(&pixmap->drawable);
+	return ret;
 }
 
 /* Borrow from cairo. */
 Bool
 glamor_gl_has_extension(char *extension)
 {
-  const char *gl_extensions;
-  char *pext;
-  int  ext_len;
-  ext_len = strlen(extension);
- 
-  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
-  pext = (char*)gl_extensions;
- 
-  if (pext == NULL || extension == NULL)
-    return FALSE;
-
-  while((pext = strstr(pext, extension)) != NULL) {
-    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
-      return TRUE;
-    pext += ext_len;
-  }
-  return FALSE;
+	const char *gl_extensions;
+	char *pext;
+	int ext_len;
+	ext_len = strlen(extension);
+
+	gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
+	pext = (char *) gl_extensions;
+
+	if (pext == NULL || extension == NULL)
+		return FALSE;
+
+	while ((pext = strstr(pext, extension)) != NULL) {
+		if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+			return TRUE;
+		pext += ext_len;
+	}
+	return FALSE;
 }
 
 int
-glamor_gl_get_version (void)
+glamor_gl_get_version(void)
 {
-    int major, minor;
-    const char *version = (const char *) glGetString (GL_VERSION);
-    const char *dot = version == NULL ? NULL : strchr (version, '.');
-    const char *major_start = dot;
-
-    /* Sanity check */
-    if (dot == NULL || dot == version || *(dot + 1) == '\0') {
-        major = 0;
-        minor = 0;
-    } else {
-        /* Find the start of the major version in the string */
-        while (major_start > version && *major_start != ' ')
-            --major_start;
-        major = strtol (major_start, NULL, 10);
-        minor = strtol (dot + 1, NULL, 10);
-    }
-
-    return GLAMOR_GL_VERSION_ENCODE (major, minor);
-}
+	int major, minor;
+	const char *version = (const char *) glGetString(GL_VERSION);
+	const char *dot = version == NULL ? NULL : strchr(version, '.');
+	const char *major_start = dot;
+
+	/* Sanity check */
+	if (dot == NULL || dot == version || *(dot + 1) == '\0') {
+		major = 0;
+		minor = 0;
+	} else {
+		/* Find the start of the major version in the string */
+		while (major_start > version && *major_start != ' ')
+			--major_start;
+		major = strtol(major_start, NULL, 10);
+		minor = strtol(dot + 1, NULL, 10);
+	}
 
+	return GLAMOR_GL_VERSION_ENCODE(major, minor);
+}
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index 48682e8..b101749 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -11,7 +11,8 @@
 #define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD   3
 
 extern void
-AbortServer(void) _X_NORETURN;
+AbortServer(void)
+    _X_NORETURN;
 
 #define GLAMOR_PANIC(_format_, ...)			\
   do {							\
@@ -19,9 +20,9 @@ AbortServer(void) _X_NORETURN;
 		   " at %32s line %d: " _format_ "\n",	\
 		   __FUNCTION__, __LINE__,		\
 		   ##__VA_ARGS__ );			\
-    AbortServer();					\
+    exit(1);                                            \
   } while(0)
-                        
+
 
 
 
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 921023e..9e4804a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -64,10 +64,15 @@
 
 static const char glamor_name[] = "glamor";
 
+static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
+DevPrivateKey glamor_egl_pixmap_private_key =
+    &glamor_egl_pixmap_private_key_index;
+
 static void
 glamor_identify(int flags)
 {
-	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", glamor_name);
+	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n",
+		glamor_name);
 }
 
 struct glamor_egl_screen_private {
@@ -75,51 +80,56 @@ struct glamor_egl_screen_private {
 	EGLContext context;
 	EGLImageKHR root;
 	EGLint major, minor;
-        
+
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
 	int fd;
-        int front_buffer_handle;
+	int front_buffer_handle;
 	int cpp;
-        struct gbm_device *gbm;
+	struct gbm_device *gbm;
 
 	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
-        PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
+	PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
-        struct glamor_gl_dispatch *dispatch;
+	struct glamor_gl_dispatch *dispatch;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
 
-static struct glamor_egl_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn)
+static struct glamor_egl_screen_private
+*
+glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 {
-        return (struct glamor_egl_screen_private *)  scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
+	return (struct glamor_egl_screen_private *)
+	    scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
 
 static EGLImageKHR
-_glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width, int height, int stride, int name)
+_glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
+			 int width, int height, int stride, int name)
 {
 	EGLImageKHR image;
 	EGLint attribs[] = {
-		EGL_WIDTH,	0,
-		EGL_HEIGHT,	0,
-                EGL_DRM_BUFFER_STRIDE_MESA, 0,
-		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
-					EGL_DRM_BUFFER_USE_SCANOUT_MESA,
+		EGL_WIDTH, 0,
+		EGL_HEIGHT, 0,
+		EGL_DRM_BUFFER_STRIDE_MESA, 0,
+		EGL_DRM_BUFFER_FORMAT_MESA,
+		EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+		EGL_DRM_BUFFER_USE_MESA,
+		EGL_DRM_BUFFER_USE_SHARE_MESA |
+		    EGL_DRM_BUFFER_USE_SCANOUT_MESA,
 		EGL_NONE
 	};
 
-         
+
 	attribs[1] = width;
 	attribs[3] = height;
-        attribs[5] = stride / 4;
-        image = glamor_egl->egl_create_image_khr (glamor_egl->display, 
-                                                  glamor_egl->context,
-                                                  EGL_DRM_BUFFER_MESA,
-                                                  (void*)name,
-                                                  attribs);   
+	attribs[5] = stride / 4;
+	image = glamor_egl->egl_create_image_khr(glamor_egl->display,
+						 glamor_egl->context,
+						 EGL_DRM_BUFFER_MESA,
+						 (void *) name, attribs);
 	if (image == EGL_NO_IMAGE_KHR)
 		return EGL_NO_IMAGE_KHR;
 
@@ -130,162 +140,198 @@ _glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width
 static int
 glamor_get_flink_name(int fd, int handle, int *name)
 {
-        struct drm_gem_flink flink;
-        flink.handle = handle;
-        if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) 
-           return FALSE;
-        *name = flink.name;
-        return TRUE;
+	struct drm_gem_flink flink;
+	flink.handle = handle;
+	if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0)
+		return FALSE;
+	*name = flink.name;
+	return TRUE;
 }
 
 static Bool
-glamor_create_texture_from_image(struct glamor_egl_screen_private *glamor_egl, EGLImageKHR image, GLuint *texture)
+glamor_create_texture_from_image(struct glamor_egl_screen_private
+				 *glamor_egl,
+				 EGLImageKHR image, GLuint * texture)
 {
 	glamor_egl->dispatch->glGenTextures(1, texture);
 	glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture);
-	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-	(glamor_egl->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
-        return TRUE;
+	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
+					      GL_TEXTURE_MIN_FILTER,
+					      GL_NEAREST);
+	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D,
+					      GL_TEXTURE_MAG_FILTER,
+					      GL_NEAREST);
+
+	(glamor_egl->egl_image_target_texture2d_oes) (GL_TEXTURE_2D,
+						      image);
+	return TRUE;
 }
 
 
 Bool
-glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride)
+glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
 	EGLImageKHR image;
 	GLuint texture;
 
-        if (!glamor_get_flink_name(glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) {
-          xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-	       "Couldn't flink front buffer handle\n");
-          return FALSE;
-        }
+	if (!glamor_get_flink_name
+	    (glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't flink front buffer handle\n");
+		return FALSE;
+	}
 
-        if (glamor_egl->root) {
-          eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
-	  glamor_egl->root = EGL_NO_IMAGE_KHR;
-        }
- 
-        image = _glamor_create_egl_image( glamor_egl, 
-                                          scrn->virtualX, 
-                                          scrn->virtualY, 
-                                          stride, 
-                                          glamor_egl->front_buffer_handle);
-        if (image == EGL_NO_IMAGE_KHR)
-          return FALSE;
-        
-        glamor_create_texture_from_image(glamor_egl, image, &texture);
-	glamor_set_screen_pixmap_texture(screen, scrn->virtualX, scrn->virtualY, texture);
+	if (glamor_egl->root) {
+		eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
+		glamor_egl->root = EGL_NO_IMAGE_KHR;
+	}
+
+	image = _glamor_egl_create_image(glamor_egl,
+					 scrn->virtualX,
+					 scrn->virtualY,
+					 stride,
+					 glamor_egl->front_buffer_handle);
+	if (image == EGL_NO_IMAGE_KHR)
+		return FALSE;
+
+	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_screen_pixmap_texture(screen, scrn->virtualX,
+					 scrn->virtualY, texture);
 	glamor_egl->root = image;
-        return TRUE;
+	return TRUE;
 }
 
 /*
  * This function will be called from the dri buffer allocation.
- * It is somehow very familiar with the create screen image.
+ * It is somehow very familiar with the create textured screen.
  * XXX the egl image here is not stored at any data structure.
  * Does this cause a leak problem?
  */
 Bool
-glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride)
+glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 {
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
 	EGLImageKHR image;
 	GLuint texture;
-        int name;
-        if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
-          xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-	       "Couldn't flink pixmap handle\n");
-          return FALSE;
-        }
+	int name;
+	if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't flink pixmap handle\n");
+		return FALSE;
+	}
+
 
-        image = _glamor_create_egl_image( glamor_egl, 
-                                          pixmap->drawable.width, 
-                                          pixmap->drawable.height, 
-                                          stride, 
-                                          name);
-        if (image == EGL_NO_IMAGE_KHR)
-          return FALSE;
-
-        glamor_create_texture_from_image(glamor_egl, image, &texture);
-        glamor_set_pixmap_texture(pixmap, pixmap->drawable.width, pixmap->drawable.height, texture);
-        return TRUE;
+	image = _glamor_egl_create_image(glamor_egl,
+					 pixmap->drawable.width,
+					 pixmap->drawable.height, stride,
+					 name);
+	if (image == EGL_NO_IMAGE_KHR) {
+		ErrorF("Failed to create khr image for bo handle %d.\n", handle);
+		return FALSE;
+	}
+
+	glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_pixmap_texture(pixmap, pixmap->drawable.width,
+				  pixmap->drawable.height, texture);
+	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
+		      image);
+	return TRUE;
+}
+
+void
+glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+	EGLImageKHR image;
+	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+
+	if (pixmap->refcnt == 1) {
+		image = dixLookupPrivate(&pixmap->devPrivates,
+					 glamor_egl_pixmap_private_key);
+		if (image != EGL_NO_IMAGE_KHR)
+			eglDestroyImageKHR(glamor_egl->display, image);
+	}
+	glamor_destroy_textured_pixmap(pixmap);
 }
 
 Bool
-glamor_close_egl_screen(ScreenPtr screen)
+glamor_egl_close_screen(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
 	glamor_fini(screen);
 
-        eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
-
+	eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
 
 	glamor_egl->root = EGL_NO_IMAGE_KHR;
 
 	return TRUE;
 }
 
-
-
 static Bool
-glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, char *extension)
+glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
+			 char *extension)
 {
-  const char *egl_extensions;
-  char *pext;
-  int  ext_len;
-  ext_len = strlen(extension);
- 
-  egl_extensions = (const char*)eglQueryString(glamor_egl->display, EGL_EXTENSIONS);
-  pext = (char*)egl_extensions;
- 
-  if (pext == NULL || extension == NULL)
-    return FALSE;
-  while((pext = strstr(pext, extension)) != NULL) {
-    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
-      return TRUE;
-    pext += ext_len;
-  }
-  return FALSE;
+	const char *egl_extensions;
+	char *pext;
+	int ext_len;
+	ext_len = strlen(extension);
+
+	egl_extensions =
+	    (const char *) eglQueryString(glamor_egl->display,
+					  EGL_EXTENSIONS);
+	pext = (char *) egl_extensions;
+
+	if (pext == NULL || extension == NULL)
+		return FALSE;
+	while ((pext = strstr(pext, extension)) != NULL) {
+		if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+			return TRUE;
+		pext += ext_len;
+	}
+	return FALSE;
 }
 
 
-Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
+Bool
+glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
 	struct glamor_egl_screen_private *glamor_egl;
 	const char *version;
-        EGLint config_attribs[] = {
+	EGLint config_attribs[] = {
 #ifdef GLAMOR_GLES2
-          EGL_CONTEXT_CLIENT_VERSION, 2, 
+		EGL_CONTEXT_CLIENT_VERSION, 2,
 #endif
-          EGL_NONE
-        };
+		EGL_NONE
+	};
 
-        glamor_identify(0);
-        glamor_egl = calloc(sizeof(*glamor_egl), 1);
-        if (xf86GlamorEGLPrivateIndex == -1) 
-           xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex();      
+	glamor_identify(0);
+	glamor_egl = calloc(sizeof(*glamor_egl), 1);
+	if (xf86GlamorEGLPrivateIndex == -1)
+		xf86GlamorEGLPrivateIndex =
+		    xf86AllocateScrnInfoPrivateIndex();
 
-        scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
+	scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
 
-        glamor_egl->fd = fd;
+	glamor_egl->fd = fd;
 
-        glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
+	glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
 
-        if (glamor_egl->display == EGL_NO_DISPLAY) {
-          glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
-          if (glamor_egl->gbm == NULL) {
-            ErrorF("couldn't get display device\n");
-            return FALSE;
-          }
-        }
+	if (glamor_egl->display == EGL_NO_DISPLAY) {
+		glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
+		if (glamor_egl->gbm == NULL) {
+			ErrorF("couldn't get display device\n");
+			return FALSE;
+		}
+	}
 
 	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
 #ifndef GLAMOR_GLES2
@@ -293,7 +339,9 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
 #else
 	eglBindAPI(EGL_OPENGL_ES_API);
 #endif
-	if (!eglInitialize(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) {
+	if (!eglInitialize
+	    (glamor_egl->display, &glamor_egl->major, &glamor_egl->minor))
+	{
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglInitialize() failed\n");
 		return FALSE;
@@ -306,34 +354,36 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
         if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
                ErrorF("EGL_" #EXT "required.\n");  \
                return FALSE;  \
-        } 
+        }
 
-        GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
+	GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
+	GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
 #ifdef GLAMOR_GLES2
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
+	GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
 #else
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
+	GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
 #endif
 
 	glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
-                                            eglGetProcAddress("eglExportDRMImageMESA");
-        glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
-                                       eglGetProcAddress("eglCreateImageKHR");
+	    eglGetProcAddress("eglExportDRMImageMESA");
+	glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
+	    eglGetProcAddress("eglCreateImageKHR");
 
-	glamor_egl->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
-                                                 eglGetProcAddress("glEGLImageTargetTexture2DOES");
+	glamor_egl->egl_image_target_texture2d_oes =
+	    (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
+	    eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
-	if (!glamor_egl->egl_create_image_khr 
-            || !glamor_egl->egl_export_drm_image_mesa
-            || !glamor_egl->egl_image_target_texture2d_oes) {
+	if (!glamor_egl->egl_create_image_khr
+	    || !glamor_egl->egl_export_drm_image_mesa
+	    || !glamor_egl->egl_image_target_texture2d_oes) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglGetProcAddress() failed\n");
 		return FALSE;
 	}
 
 	glamor_egl->context = eglCreateContext(glamor_egl->display,
-					   NULL, EGL_NO_CONTEXT, config_attribs);
+					       NULL, EGL_NO_CONTEXT,
+					       config_attribs);
 	if (glamor_egl->context == EGL_NO_CONTEXT) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to create EGL context\n");
@@ -341,44 +391,59 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
 	}
 
 	if (!eglMakeCurrent(glamor_egl->display,
-			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
+			    EGL_NO_SURFACE, EGL_NO_SURFACE,
+			    glamor_egl->context)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to make EGL context current\n");
 		return FALSE;
 	}
 
-        
+	return TRUE;
+}
 
-        return TRUE;
+Bool
+glamor_egl_init_textured_pixmap(ScreenPtr screen)
+{
+	if (!dixRegisterPrivateKey
+	    (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate egl pixmap private\n",
+			   screen->myNum);
+		return FALSE;
+	}
+	return TRUE;
 }
 
 void
-glamor_free_egl_screen(int scrnIndex, int flags)
+glamor_egl_free_screen(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
-
-	if (glamor_egl != NULL)
-	{
-	  if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
-            eglMakeCurrent(glamor_egl->display,
-                         EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-	    eglTerminate(glamor_egl->display);
-          }
-	  free(glamor_egl);
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+
+	if (glamor_egl != NULL) {
+		if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
+			eglMakeCurrent(glamor_egl->display,
+				       EGL_NO_SURFACE, EGL_NO_SURFACE,
+				       EGL_NO_CONTEXT);
+
+			eglTerminate(glamor_egl->display);
+		}
+		free(glamor_egl);
 	}
 }
 
-/* egl version. */
-
 Bool
-glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
+glamor_gl_dispatch_init(ScreenPtr screen,
+			struct glamor_gl_dispatch *dispatch,
+			int gl_version)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
-        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
-          return FALSE;
-        glamor_egl->dispatch = dispatch; 
-        return TRUE;
+	struct glamor_egl_screen_private *glamor_egl =
+	    glamor_egl_get_screen_private(scrn);
+	if (!glamor_gl_dispatch_init_impl
+	    (dispatch, gl_version, (get_proc_address_t)eglGetProcAddress))
+		return FALSE;
+	glamor_egl->dispatch = dispatch;
+	return TRUE;
 }
diff --git a/glamor/glamor_eglmodule.c b/glamor/glamor_eglmodule.c
new file mode 100644
index 0000000..5281ff4
--- /dev/null
+++ b/glamor/glamor_eglmodule.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc.  All Rights Reserved.
+ *
+ * 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
+ * XFREE86 PROJECT 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.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+ */
+
+#include <xorg-server.h>
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo VersRec = {
+	"glamor_egl",
+	MODULEVENDORSTRING,
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XORG_VERSION_CURRENT,
+	1, 0, 0,
+	ABI_CLASS_ANSIC,	/* Only need the ansic layer */
+	ABI_ANSIC_VERSION,
+	MOD_CLASS_NONE,
+	{0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
+};
+
+_X_EXPORT XF86ModuleData glamor_eglModuleData = { &VersRec, NULL, NULL };
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 7254167..7a43251 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -32,174 +32,167 @@
  * GC fill implementation, based loosely on fb_fill.c
  */
 
-void
+Bool
 glamor_fill(DrawablePtr drawable,
-	    GCPtr gc,
-	    int x,
-	    int y,
-	    int width,
-	    int height)
+	    GCPtr gc, int x, int y, int width, int height)
 {
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
-    int off_x, off_y;
-
-    glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
-
-    switch (gc->fillStyle) {
-    case FillSolid:
-	if (!glamor_solid(dst_pixmap,
-                         x + off_x,
-                         y + off_y,
-		         width,
-		         height,
-		         gc->alu,
-		         gc->planemask,
-		         gc->fgPixel))
-	goto fail;
-	break;
-    case FillStippled:
-    case FillOpaqueStippled:
-	if (!glamor_stipple(dst_pixmap,
-		       gc->stipple,
-		       x + off_x,
-		       y + off_y,
-		       width,
-		       height,
-		       gc->alu,
-		       gc->planemask,
-		       gc->fgPixel,
-		       gc->bgPixel,
-		       gc->patOrg.x,
-		       gc->patOrg.y))
-	goto fail;
-        return;
-	break;
-    case FillTiled:
-	if (!glamor_tile(dst_pixmap,
-		    gc->tile.pixmap,
-		    x + off_x,
-		    y + off_y,
-		    width,
-		    height,
-		    gc->alu,
-		    gc->planemask,
-		    drawable->x + x + off_x - gc->patOrg.x,
-		    drawable->y + y + off_y - gc->patOrg.y))
-	goto fail;
-	break;
-    }
-    return;
-fail:
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	if (glamor_prepare_access_gc(gc)) {
-            fbFill(drawable, gc, x, y, width, height);
-	    glamor_finish_access_gc(gc);
+	PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
+	int off_x, off_y;
+
+	glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
+
+	switch (gc->fillStyle) {
+	case FillSolid:
+		if (!glamor_solid(dst_pixmap,
+				  x + off_x,
+				  y + off_y,
+				  width, height, gc->alu, gc->planemask,
+				  gc->fgPixel))
+			goto fail;
+		break;
+	case FillStippled:
+	case FillOpaqueStippled:
+		if (!glamor_stipple(dst_pixmap,
+				    gc->stipple,
+				    x + off_x,
+				    y + off_y,
+				    width,
+				    height,
+				    gc->alu,
+				    gc->planemask,
+				    gc->fgPixel,
+				    gc->bgPixel, gc->patOrg.x,
+				    gc->patOrg.y))
+			goto fail;
+		break;
+	case FillTiled:
+		if (!glamor_tile(dst_pixmap,
+				 gc->tile.pixmap,
+				 x + off_x,
+				 y + off_y,
+				 width,
+				 height,
+				 gc->alu,
+				 gc->planemask,
+				 drawable->x + x + off_x - gc->patOrg.x,
+				 drawable->y + y + off_y - gc->patOrg.y))
+			goto fail;
+		break;
+	}
+	return TRUE;
+      fail:
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access_gc(gc)) {
+			fbFill(drawable, gc, x, y, width, height);
+			glamor_finish_access_gc(gc);
+		}
+		glamor_finish_access(drawable);
 	}
-	glamor_finish_access(drawable);
-    }
-return;
+	return TRUE;
 
 }
 
 void
 glamor_init_solid_shader(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    const char *solid_vs =
-        "attribute vec4 v_position;"
-	"void main()\n"
-	"{\n"
-        "       gl_Position = v_position;\n"
-	"}\n";
-    const char *solid_fs =
-        GLAMOR_DEFAULT_PRECISION
-	"uniform vec4 color;\n"
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = color;\n"
-	"}\n";
-    GLint fs_prog, vs_prog;
-
-    glamor_priv->solid_prog = dispatch->glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs);
-    dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
-    
-    dispatch->glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position");
-    glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
-
-    glamor_priv->solid_color_uniform_location =
-	dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color");
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	const char *solid_vs =
+	    "attribute vec4 v_position;"
+	    "void main()\n" "{\n" "       gl_Position = v_position;\n"
+	    "}\n";
+	const char *solid_fs =
+	    GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
+	    "void main()\n" "{\n" "	gl_FragColor = color;\n" "}\n";
+	GLint fs_prog, vs_prog;
+
+	glamor_priv->solid_prog = dispatch->glCreateProgram();
+	vs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
+	fs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+				     solid_fs);
+	dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
+	dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
+
+	dispatch->glBindAttribLocation(glamor_priv->solid_prog,
+				       GLAMOR_VERTEX_POS, "v_position");
+	glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
+
+	glamor_priv->solid_color_uniform_location =
+	    dispatch->glGetUniformLocation(glamor_priv->solid_prog,
+					   "color");
 }
 
 Bool
 glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	     unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
+	     unsigned char alu, unsigned long planemask,
+	     unsigned long fg_pixel)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    int x1 = x;
-    int x2 = x + width;
-    int y1 = y;
-    int y2 = y + height;
-    GLfloat color[4];
-    float vertices[8];
-    GLfloat xscale, yscale;
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-        glamor_fallback("dest %p has no fbo.\n", pixmap);
-	goto fail;
-    }
-    glamor_set_alu(dispatch, alu);
-    if (!glamor_set_planemask(pixmap, planemask)) {
-      glamor_fallback("Failedto set planemask  in glamor_solid.\n");
-      goto fail;
-    } 
-
-    glamor_get_rgba_from_pixel(fg_pixel, 
-                              &color[0], 
-                              &color[1], 
-                              &color[2], 
-                              &color[3],
-                              format_for_pixmap(pixmap));
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	int x1 = x;
+	int x2 = x + width;
+	int y1 = y;
+	int y2 = y + height;
+	GLfloat color[4];
+	float vertices[8];
+	GLfloat xscale, yscale;
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+		glamor_fallback("dest %p has no fbo.\n", pixmap);
+		goto fail;
+	}
+	glamor_set_alu(dispatch, alu);
+	if (!glamor_set_planemask(pixmap, planemask)) {
+		glamor_fallback
+		    ("Failedto set planemask  in glamor_solid.\n");
+		goto fail;
+	}
+
+	glamor_get_rgba_from_pixel(fg_pixel,
+				   &color[0],
+				   &color[1],
+				   &color[2],
+				   &color[3], format_for_pixmap(pixmap));
 #ifdef GLAMOR_DELAYED_FILLING
-    if (x == 0 && y == 0 
-        && width == pixmap->drawable.width 
-        && height == pixmap->drawable.height 
-        && pixmap_priv->fb != glamor_priv->screen_fbo ) {
-      pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
-      memcpy(&pixmap_priv->pending_op.fill.color4fv,
-	     color, 4*sizeof(GLfloat));
-      pixmap_priv->pending_op.fill.colori = fg_pixel;
-      return TRUE;
-    }
+	if (x == 0 && y == 0
+	    && width == pixmap->drawable.width
+	    && height == pixmap->drawable.height
+	    && pixmap_priv->fb != glamor_priv->screen_fbo) {
+		pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
+		memcpy(&pixmap_priv->pending_op.fill.color4fv,
+		       color, 4 * sizeof(GLfloat));
+		pixmap_priv->pending_op.fill.colori = fg_pixel;
+		return TRUE;
+	}
 #endif
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-    glamor_validate_pixmap(pixmap);
-
-    dispatch->glUseProgram(glamor_priv->solid_prog);
- 
-    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
-
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                          2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
-    glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
-				 glamor_priv->yInverted,
-				 vertices);
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(0);
-    return TRUE;
-fail:
-    glamor_set_alu(dispatch, GXcopy);
-    glamor_set_planemask(pixmap, ~0);
-    return FALSE;
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	glamor_validate_pixmap(pixmap);
+
+	dispatch->glUseProgram(glamor_priv->solid_prog);
+
+	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
+			       1, color);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
+	glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
+				     glamor_priv->yInverted, vertices);
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	return TRUE;
+      fail:
+	glamor_set_alu(dispatch, GXcopy);
+	glamor_set_planemask(pixmap, ~0);
+	return FALSE;
 }
-
-
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 9a97da2..a91e6a9 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -32,58 +32,54 @@
 
 void
 glamor_fill_spans(DrawablePtr drawable,
-		  GCPtr	gc,
-		  int n,
-		  DDXPointPtr points,
-		  int *widths,
-		  int sorted)
+		  GCPtr gc,
+		  int n, DDXPointPtr points, int *widths, int sorted)
 {
-    DDXPointPtr ppt;
-    int nbox;
-    BoxPtr pbox;
-    int x1, x2, y;
-    RegionPtr pClip = fbGetCompositeClip(gc);
+	DDXPointPtr ppt;
+	int nbox;
+	BoxPtr pbox;
+	int x1, x2, y;
+	RegionPtr pClip = fbGetCompositeClip(gc);
 
-    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) 
-	goto fail;
+	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
+		goto fail;
 
 	ppt = points;
-        while (n--) {
-                x1 = ppt->x;
-                y = ppt->y;
-                x2 = x1 + (int)*widths;
-                ppt++;
-                widths++;
+	while (n--) {
+		x1 = ppt->x;
+		y = ppt->y;
+		x2 = x1 + (int) *widths;
+		ppt++;
+		widths++;
 
-                nbox = REGION_NUM_RECTS(pClip);
-                pbox = REGION_RECTS(pClip);
-                while (nbox--) {
-                        if (pbox->y1 > y || pbox->y2 <= y)
-                                continue;
+		nbox = REGION_NUM_RECTS(pClip);
+		pbox = REGION_RECTS(pClip);
+		while (nbox--) {
+			if (pbox->y1 > y || pbox->y2 <= y)
+				continue;
 
-                        if (x1 < pbox->x1)
-                                x1 = pbox->x1;
+			if (x1 < pbox->x1)
+				x1 = pbox->x1;
 
-                        if (x2 > pbox->x2)
-                                x2 = pbox->x2;
+			if (x2 > pbox->x2)
+				x2 = pbox->x2;
 
-                        if (x2 <= x1)
-                                continue;
-                        glamor_fill (drawable,gc,
-                                     x1, y,
-                                     x2 - x1 ,  1);
-                        pbox++;
-                }
-        }
-    return;
-fail:
-    glamor_fallback("to %p (%c)\n", drawable,
-		    glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	if (glamor_prepare_access_gc(gc)) {
-	    fbFillSpans(drawable, gc, n, points, widths, sorted);
-	    glamor_finish_access_gc(gc);
+			if (x2 <= x1)
+				continue;
+			glamor_fill(drawable, gc, x1, y, x2 - x1, 1);
+			pbox++;
+		}
+	}
+	return;
+      fail:
+	glamor_fallback("to %p (%c)\n", drawable,
+			glamor_get_drawable_location(drawable));
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access_gc(gc)) {
+			fbFillSpans(drawable, gc, n, points, widths,
+				    sorted);
+			glamor_finish_access_gc(gc);
+		}
+		glamor_finish_access(drawable);
 	}
-	glamor_finish_access(drawable);
-    }
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 224af1b..96f5120 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -34,77 +34,73 @@
 void
 glamor_get_spans(DrawablePtr drawable,
 		 int wmax,
-		 DDXPointPtr points,
-		 int *widths,
-		 int count,
-		 char *dst)
+		 DDXPointPtr points, int *widths, int count, char *dst)
 {
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    GLenum format, type;
-    int no_alpha, no_revert;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    PixmapPtr temp_pixmap = NULL;
-    int i;
-    uint8_t *readpixels_dst = (uint8_t *)dst;
-    int x_off, y_off;
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	GLenum format, type;
+	int no_alpha, no_revert;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(drawable->pScreen);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	PixmapPtr temp_pixmap = NULL;
+	int i;
+	uint8_t *readpixels_dst = (uint8_t *) dst;
+	int x_off, y_off;
 
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-        glamor_fallback("pixmap has no fbo.\n");
-	goto fail;
-    }
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+		glamor_fallback("pixmap has no fbo.\n");
+		goto fail;
+	}
 
-    if (glamor_get_tex_format_type_from_pixmap(pixmap,
-                                               &format, 
-                                               &type, 
-                                               &no_alpha,
-                                               &no_revert
-                                               )) {
-      glamor_fallback("unknown depth. %d \n", 
-                     drawable->depth);
-      goto fail;
-    }
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("unknown depth. %d \n", drawable->depth);
+		goto fail;
+	}
 
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-    glamor_validate_pixmap(pixmap);
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	glamor_validate_pixmap(pixmap);
 
-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-    /* XXX prepare whole pixmap is not efficient. */
-      temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, 
-                                                   &type, no_alpha, no_revert);
-      pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-      glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-    }
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		/* XXX prepare whole pixmap is not efficient. */
+		temp_pixmap =
+		    glamor_es2_pixmap_read_prepare(pixmap, &format,
+						   &type, no_alpha,
+						   no_revert);
+		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	}
 
-    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-    for (i = 0; i < count; i++) {
-      if (glamor_priv->yInverted) {
-	dispatch->glReadPixels(points[i].x + x_off,
-		     (points[i].y + y_off),
-		     widths[i],
-		     1,
-		     format, type,
-		     readpixels_dst);
- 	} else {
-	dispatch->glReadPixels(points[i].x + x_off,
-		     pixmap->drawable.height - 1 - (points[i].y + y_off),
-		     widths[i],
-		     1,
-		     format, type,
-		     readpixels_dst);
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+	for (i = 0; i < count; i++) {
+		if (glamor_priv->yInverted) {
+			dispatch->glReadPixels(points[i].x + x_off,
+					       (points[i].y + y_off),
+					       widths[i], 1, format,
+					       type, readpixels_dst);
+		} else {
+			dispatch->glReadPixels(points[i].x + x_off,
+					       pixmap->drawable.height -
+					       1 - (points[i].y + y_off),
+					       widths[i], 1, format,
+					       type, readpixels_dst);
+		}
+		readpixels_dst +=
+		    PixmapBytePad(widths[i], drawable->depth);
 	}
-       readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
-    }
-    if (temp_pixmap) 
-     pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
-    return;
+	if (temp_pixmap)
+		pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
+	return;
 
-fail:
-    glamor_fallback("from %p (%c)\n", drawable,
-		    glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
-	fbGetSpans(drawable, wmax, points, widths, count, dst);
-	glamor_finish_access(drawable);
-    }
+      fail:
+	glamor_fallback("from %p (%c)\n", drawable,
+			glamor_get_drawable_location(drawable));
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
+		fbGetSpans(drawable, wmax, points, widths, count, dst);
+		glamor_finish_access(drawable);
+	}
 }
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
index 8232624..788562c 100644
--- a/glamor/glamor_gl_dispatch.c
+++ b/glamor/glamor_gl_dispatch.c
@@ -3,71 +3,71 @@
 #define INIT_FUNC(dst,func_name,get)			\
   dst->func_name = get(#func_name);			\
   if (dst->func_name == NULL)				\
-    { ErrorF("Failed to get fun %s", #func_name);	\
+    { ErrorF("Failed to get function %s", #func_name);	\
 	goto fail; }
 
-Bool
-glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, 
-                             int gl_version, 
-                             void *(*get_proc_address)(const char*))
+_X_EXPORT Bool
+glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
+			     int gl_version,
+			     void *(*get_proc_address) (const char *))
 {
-  INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
-  INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
-  INIT_FUNC(dispatch, glViewport, get_proc_address);
-  INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
-  INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
-  INIT_FUNC(dispatch, glReadPixels, get_proc_address);
-  INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
-  INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
-  INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
-  INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
-  INIT_FUNC(dispatch, glGenTextures, get_proc_address);
-  INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
-  INIT_FUNC(dispatch, glBindTexture, get_proc_address);
-  INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
-  INIT_FUNC(dispatch, glFlush, get_proc_address);
-  INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
-  INIT_FUNC(dispatch, glGetString, get_proc_address);
-  INIT_FUNC(dispatch, glScissor, get_proc_address);
-  INIT_FUNC(dispatch, glEnable, get_proc_address);
-  INIT_FUNC(dispatch, glDisable, get_proc_address);
-  INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
-  INIT_FUNC(dispatch, glLogicOp, get_proc_address);
-  INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
-  INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
-  INIT_FUNC(dispatch, glBufferData, get_proc_address);
-  INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
-  INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
-  INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
-  INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
-  INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
-  INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
-  INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
-  INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
-  INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
-  INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
-  INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
-  INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
-  INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
-  INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
-  INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
-  INIT_FUNC(dispatch, glShaderSource, get_proc_address);
+	INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
+	INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
+	INIT_FUNC(dispatch, glViewport, get_proc_address);
+	INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
+	INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
+	INIT_FUNC(dispatch, glReadPixels, get_proc_address);
+	INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
+	INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
+	INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
+	INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
+	INIT_FUNC(dispatch, glGenTextures, get_proc_address);
+	INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
+	INIT_FUNC(dispatch, glBindTexture, get_proc_address);
+	INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
+	INIT_FUNC(dispatch, glFlush, get_proc_address);
+	INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
+	INIT_FUNC(dispatch, glGetString, get_proc_address);
+	INIT_FUNC(dispatch, glScissor, get_proc_address);
+	INIT_FUNC(dispatch, glEnable, get_proc_address);
+	INIT_FUNC(dispatch, glDisable, get_proc_address);
+	INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
+	INIT_FUNC(dispatch, glLogicOp, get_proc_address);
+	INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
+	INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
+	INIT_FUNC(dispatch, glBufferData, get_proc_address);
+	INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
+	INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
+	INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
+	INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
+	INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
+	INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
+	INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
+	INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
+	INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
+	INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
+	INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
+	INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
+	INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
+	INIT_FUNC(dispatch, glShaderSource, get_proc_address);
 
-  INIT_FUNC(dispatch, glUseProgram, get_proc_address);
-  INIT_FUNC(dispatch, glUniform1i, get_proc_address);
-  INIT_FUNC(dispatch, glUniform4f, get_proc_address);
-  INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
-  INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
-  INIT_FUNC(dispatch, glCreateShader, get_proc_address);
-  INIT_FUNC(dispatch, glCompileShader, get_proc_address);
-  INIT_FUNC(dispatch, glAttachShader, get_proc_address);
-  INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
-  INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
-  INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
-  INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
-  INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
+	INIT_FUNC(dispatch, glUseProgram, get_proc_address);
+	INIT_FUNC(dispatch, glUniform1i, get_proc_address);
+	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
+	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
+	INIT_FUNC(dispatch, glCreateShader, get_proc_address);
+	INIT_FUNC(dispatch, glCompileShader, get_proc_address);
+	INIT_FUNC(dispatch, glAttachShader, get_proc_address);
+	INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
+	INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
+	INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
+	INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
+	INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
 
-  return TRUE;
-fail:
-  return FALSE;
+	return TRUE;
+      fail:
+	return FALSE;
 }
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
index c519667..5f1831a 100644
--- a/glamor/glamor_gl_dispatch.h
+++ b/glamor/glamor_gl_dispatch.h
@@ -1,101 +1,123 @@
 typedef struct glamor_gl_dispatch {
-  /* Transformation functions */
-  void (*glMatrixMode)(GLenum mode);
-  void (*glLoadIdentity)(void);
-  void (*glViewport)( GLint x, GLint y,
-                      GLsizei width, GLsizei height );
-  /* Drawing functions */ 
-  void (*glRasterPos2i)( GLint x, GLint y );
-
-  /* Vertex Array */
-  void (*glDrawArrays)( GLenum mode, GLint first, GLsizei count );
-
-  /* Raster functions */
-  void (*glReadPixels)( GLint x, GLint y,
-                        GLsizei width, GLsizei height,
-                        GLenum format, GLenum type,
-                        GLvoid *pixels );
-
-  void (*glDrawPixels)( GLsizei width, GLsizei height,
-                        GLenum format, GLenum type,
-                        const GLvoid *pixels );
-  void (*glPixelStorei)( GLenum pname, GLint param ); 
-  /* Texture Mapping */
-
-  void (*glTexParameteri)( GLenum target, GLenum pname, GLint param );
-  void (*glTexImage2D)( GLenum target, GLint level,
-                        GLint internalFormat,
-                        GLsizei width, GLsizei height,
-                        GLint border, GLenum format, GLenum type,
-                        const GLvoid *pixels );
-  /* 1.1 */
-  void (*glGenTextures)( GLsizei n, GLuint *textures );
-  void (*glDeleteTextures)( GLsizei n, const GLuint *textures);
-  void (*glBindTexture)( GLenum target, GLuint texture );                                                                                                                         
-  void (*glTexSubImage2D)( GLenum target, GLint level,
-                           GLint xoffset, GLint yoffset,
-                           GLsizei width, GLsizei height,
-                           GLenum format, GLenum type,
-                           const GLvoid *pixels );
-  /* MISC */
-  void (*glFlush)( void );
-  void (*glGetIntegerv)( GLenum pname, GLint *params );
-  const GLubyte * (*glGetString)( GLenum name );
-  void (*glScissor)( GLint x, GLint y, GLsizei width, GLsizei height);
-  void (*glEnable)( GLenum cap );
-  void (*glDisable)( GLenum cap );
-  void (*glBlendFunc)( GLenum sfactor, GLenum dfactor );
-  void (*glLogicOp)( GLenum opcode );
-
-  /* 1.3 */
-  void (*glActiveTexture)( GLenum texture );
-
-  /* GL Extentions */
-  void (*glGenBuffers) (GLsizei n, GLuint *buffers);
-  void (*glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
-  GLvoid* (*glMapBuffer) (GLenum target, GLenum access);
-  GLboolean (*glUnmapBuffer) (GLenum target);
-  void (*glBindBuffer) (GLenum target, GLuint buffer);
-  void (*glDeleteBuffers) (GLsizei n, const GLuint *buffers);        
-
-  void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-  void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
-  void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers);
-  void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers);          
-  GLenum (*glCheckFramebufferStatus) (GLenum target);
-  void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-
-  void (*glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
-  void (*glDisableVertexAttribArray) (GLuint index);
-  void (*glEnableVertexAttribArray) (GLuint index);
-  void (*glBindAttribLocation) (GLuint program, GLuint index, const GLchar *name);
-
-  void (*glLinkProgram) (GLuint program);
-  void (*glShaderSource) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
-  void (*glUseProgram) (GLuint program);
-  void (*glUniform1i) (GLint location, GLint v0);
-  void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
-  void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat *value);
-  GLuint (*glCreateProgram) (void);
-  GLuint (*glCreateShader) (GLenum type);
-  void (*glCompileShader) (GLuint shader);
-  void (*glAttachShader) (GLuint program, GLuint shader);
-  void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint *params);
-  void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
-  void (*glGetProgramiv) (GLuint program, GLenum pname, GLint *params);
-  void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
-  GLint (*glGetUniformLocation) (GLuint program, const GLchar *name);
-
-}glamor_gl_dispatch;
-
-Bool
+	/* Transformation functions */
+	void (*glMatrixMode) (GLenum mode);
+	void (*glLoadIdentity) (void);
+	void (*glViewport) (GLint x, GLint y, GLsizei width,
+			    GLsizei height);
+	/* Drawing functions */
+	void (*glRasterPos2i) (GLint x, GLint y);
+
+	/* Vertex Array */
+	void (*glDrawArrays) (GLenum mode, GLint first, GLsizei count);
+
+	/* Raster functions */
+	void (*glReadPixels) (GLint x, GLint y,
+			      GLsizei width, GLsizei height,
+			      GLenum format, GLenum type, GLvoid * pixels);
+
+	void (*glDrawPixels) (GLsizei width, GLsizei height,
+			      GLenum format, GLenum type,
+			      const GLvoid * pixels);
+	void (*glPixelStorei) (GLenum pname, GLint param);
+	/* Texture Mapping */
+
+	void (*glTexParameteri) (GLenum target, GLenum pname, GLint param);
+	void (*glTexImage2D) (GLenum target, GLint level,
+			      GLint internalFormat,
+			      GLsizei width, GLsizei height,
+			      GLint border, GLenum format, GLenum type,
+			      const GLvoid * pixels);
+	/* 1.1 */
+	void (*glGenTextures) (GLsizei n, GLuint * textures);
+	void (*glDeleteTextures) (GLsizei n, const GLuint * textures);
+	void (*glBindTexture) (GLenum target, GLuint texture);
+	void (*glTexSubImage2D) (GLenum target, GLint level,
+				 GLint xoffset, GLint yoffset,
+				 GLsizei width, GLsizei height,
+				 GLenum format, GLenum type,
+				 const GLvoid * pixels);
+	/* MISC */
+	void (*glFlush) (void);
+	void (*glGetIntegerv) (GLenum pname, GLint * params);
+	const GLubyte *(*glGetString) (GLenum name);
+	void (*glScissor) (GLint x, GLint y, GLsizei width,
+			   GLsizei height);
+	void (*glEnable) (GLenum cap);
+	void (*glDisable) (GLenum cap);
+	void (*glBlendFunc) (GLenum sfactor, GLenum dfactor);
+	void (*glLogicOp) (GLenum opcode);
+
+	/* 1.3 */
+	void (*glActiveTexture) (GLenum texture);
+
+	/* GL Extentions */
+	void (*glGenBuffers) (GLsizei n, GLuint * buffers);
+	void (*glBufferData) (GLenum target, GLsizeiptr size,
+			      const GLvoid * data, GLenum usage);
+	GLvoid *(*glMapBuffer) (GLenum target, GLenum access);
+	 GLboolean(*glUnmapBuffer) (GLenum target);
+	void (*glBindBuffer) (GLenum target, GLuint buffer);
+	void (*glDeleteBuffers) (GLsizei n, const GLuint * buffers);
+
+	void (*glFramebufferTexture2D) (GLenum target, GLenum attachment,
+					GLenum textarget, GLuint texture,
+					GLint level);
+	void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
+	void (*glDeleteFramebuffers) (GLsizei n,
+				      const GLuint * framebuffers);
+	void (*glGenFramebuffers) (GLsizei n, GLuint * framebuffers);
+	 GLenum(*glCheckFramebufferStatus) (GLenum target);
+	void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1,
+				   GLint srcY1, GLint dstX0, GLint dstY0,
+				   GLint dstX1, GLint dstY1,
+				   GLbitfield mask, GLenum filter);
+
+	void (*glVertexAttribPointer) (GLuint index, GLint size,
+				       GLenum type, GLboolean normalized,
+				       GLsizei stride,
+				       const GLvoid * pointer);
+	void (*glDisableVertexAttribArray) (GLuint index);
+	void (*glEnableVertexAttribArray) (GLuint index);
+	void (*glBindAttribLocation) (GLuint program, GLuint index,
+				      const GLchar * name);
+
+	void (*glLinkProgram) (GLuint program);
+	void (*glShaderSource) (GLuint shader, GLsizei count,
+				const GLchar * *string,
+				const GLint * length);
+	void (*glUseProgram) (GLuint program);
+	void (*glUniform1i) (GLint location, GLint v0);
+	void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
+			     GLfloat v2, GLfloat v3);
+	void (*glUniform4fv) (GLint location, GLsizei count,
+			      const GLfloat * value);
+	 GLuint(*glCreateProgram) (void);
+	 GLuint(*glCreateShader) (GLenum type);
+	void (*glCompileShader) (GLuint shader);
+	void (*glAttachShader) (GLuint program, GLuint shader);
+	void (*glGetShaderiv) (GLuint shader, GLenum pname,
+			       GLint * params);
+	void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
+				    GLsizei * length, GLchar * infoLog);
+	void (*glGetProgramiv) (GLuint program, GLenum pname,
+				GLint * params);
+	void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize,
+				     GLsizei * length, GLchar * infoLog);
+	 GLint(*glGetUniformLocation) (GLuint program,
+				       const GLchar * name);
+
+} glamor_gl_dispatch;
+
+
+typedef void *(*get_proc_address_t) (const char *);
+
+_X_EXPORT Bool
 glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-                             int gl_version,
-                             void *(*get_proc_address)(const char*));
-
-
-Bool
-glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version);
-
+			     int gl_version,
+			     get_proc_address_t get_proc_address);
 
 
+_X_EXPORT Bool
+glamor_gl_dispatch_init(ScreenPtr screen,
+			struct glamor_gl_dispatch *dispatch,
+			int gl_version);
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index af6ec71..899dd9d 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -66,28 +66,27 @@
  */
 #define GLYPH_BUFFER_SIZE 1024
 
-#define CACHE_PICTURE_SIZE  1024 
+#define CACHE_PICTURE_SIZE  1024
 #define GLYPH_MIN_SIZE 8
 #define GLYPH_MAX_SIZE 64
 #define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
 
 typedef struct {
-    PicturePtr source;
-    glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE];
-    int count;
+	PicturePtr source;
+	glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE];
+	int count;
 } glamor_glyph_buffer_t;
 
-struct glamor_glyph
-{
-  glamor_glyph_cache_t *cache;
-  uint16_t x, y;
-  uint16_t size, pos;
+struct glamor_glyph {
+	glamor_glyph_cache_t *cache;
+	uint16_t x, y;
+	uint16_t size, pos;
 };
 
 typedef enum {
-    GLAMOR_GLYPH_SUCCESS,	/* Glyph added to render buffer */
-    GLAMOR_GLYPH_FAIL,		/* out of memory, etc */
-    GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
+	GLAMOR_GLYPH_SUCCESS,	/* Glyph added to render buffer */
+	GLAMOR_GLYPH_FAIL,	/* out of memory, etc */
+	GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
 } glamor_glyph_cache_result_t;
 
 
@@ -96,44 +95,43 @@ typedef enum {
 static DevPrivateKeyRec glamor_glyph_key;
 
 static inline struct glamor_glyph *
-glamor_glyph_get_private (GlyphPtr glyph)
+glamor_glyph_get_private(GlyphPtr glyph)
 {
-  return dixGetPrivate (&glyph->devPrivates, &glamor_glyph_key);
+	return dixGetPrivate(&glyph->devPrivates, &glamor_glyph_key);
 }
 
 static inline void
-glamor_glyph_set_private (GlyphPtr glyph, struct glamor_glyph *priv)
+glamor_glyph_set_private(GlyphPtr glyph, struct glamor_glyph *priv)
 {
-  dixSetPrivate (&glyph->devPrivates, &glamor_glyph_key, priv);
+	dixSetPrivate(&glyph->devPrivates, &glamor_glyph_key, priv);
 }
 
 
 static void
-glamor_unrealize_glyph_caches (ScreenPtr pScreen)
+glamor_unrealize_glyph_caches(ScreenPtr pScreen)
 {
-  glamor_screen_private *glamor = glamor_get_screen_private (pScreen);
-  int i;
+	glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
+	int i;
 
-  if (!glamor->glyph_cache_initialized)
-    return;
+	if (!glamor->glyph_cache_initialized)
+		return;
 
-  for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++)
-    {
-      glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
+	for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) {
+		glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
 
-      if (cache->picture)
-	FreePicture (cache->picture, 0);
+		if (cache->picture)
+			FreePicture(cache->picture, 0);
 
-      if (cache->glyphs)
-	free (cache->glyphs);
-    }
-  glamor->glyph_cache_initialized = FALSE;
+		if (cache->glyphs)
+			free(cache->glyphs);
+	}
+	glamor->glyph_cache_initialized = FALSE;
 }
 
 void
-glamor_glyphs_fini (ScreenPtr pScreen)
+glamor_glyphs_fini(ScreenPtr pScreen)
 {
-  glamor_unrealize_glyph_caches (pScreen);
+	glamor_unrealize_glyph_caches(pScreen);
 }
 
 /* All caches for a single format share a single pixmap for glyph storage,
@@ -146,220 +144,219 @@ glamor_glyphs_fini (ScreenPtr pScreen)
  * rest of the allocated structures for all caches with the given format.
  */
 static Bool
-glamor_realize_glyph_caches (ScreenPtr pScreen)
+glamor_realize_glyph_caches(ScreenPtr pScreen)
 {
-  glamor_screen_private *glamor = glamor_get_screen_private (pScreen);
-  unsigned int formats[] = {
-    PIXMAN_a8,
-    PIXMAN_a8r8g8b8,
-  };
-  int i;
-
-  if (glamor->glyph_cache_initialized)
-    return TRUE;
-
-  glamor->glyph_cache_initialized = TRUE;
-  memset (glamor->glyphCaches, 0, sizeof (glamor->glyphCaches));
-
-  for (i = 0; i < sizeof (formats) / sizeof (formats[0]); i++)
-    {
-      glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
-      PixmapPtr pixmap;
-      PicturePtr picture;
-      CARD32 component_alpha;
-      int depth = PIXMAN_FORMAT_DEPTH (formats[i]);
-      int error;
-      PictFormatPtr pPictFormat =
-	PictureMatchFormat (pScreen, depth, formats[i]);
-      if (!pPictFormat)
-	goto bail;
-
-      /* Now allocate the pixmap and picture */
-      pixmap = pScreen->CreatePixmap (pScreen,
-				      CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
-				      depth, 0);
-      if (!pixmap)
-	goto bail;
-
-      component_alpha = NeedsComponent (pPictFormat->format);
-      picture = CreatePicture (0, &pixmap->drawable, pPictFormat,
-			       CPComponentAlpha, &component_alpha,
-			       serverClient, &error);
-
-      pScreen->DestroyPixmap (pixmap);
-      if (!picture)
-	goto bail;
-
-      ValidatePicture (picture);
-
-      cache->picture = picture;
-      cache->glyphs = calloc (sizeof (GlyphPtr), GLYPH_CACHE_SIZE);
-      if (!cache->glyphs)
-	goto bail;
-
-      cache->evict = rand () % GLYPH_CACHE_SIZE;
-    }
-  assert (i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
-
-  return TRUE;
-
-bail:
-  glamor_unrealize_glyph_caches (pScreen);
-  return FALSE;
+	glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
+	unsigned int formats[] = {
+		PIXMAN_a8,
+		PIXMAN_a8r8g8b8,
+	};
+	int i;
+
+	if (glamor->glyph_cache_initialized)
+		return TRUE;
+
+	glamor->glyph_cache_initialized = TRUE;
+	memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
+
+	for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+		glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
+		PixmapPtr pixmap;
+		PicturePtr picture;
+		CARD32 component_alpha;
+		int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
+		int error;
+		PictFormatPtr pPictFormat =
+		    PictureMatchFormat(pScreen, depth, formats[i]);
+		if (!pPictFormat)
+			goto bail;
+
+		/* Now allocate the pixmap and picture */
+		pixmap = pScreen->CreatePixmap(pScreen,
+					       CACHE_PICTURE_SIZE,
+					       CACHE_PICTURE_SIZE, depth,
+					       0);
+		if (!pixmap)
+			goto bail;
+
+		component_alpha = NeedsComponent(pPictFormat->format);
+		picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
+					CPComponentAlpha, &component_alpha,
+					serverClient, &error);
+
+		pScreen->DestroyPixmap(pixmap);
+		if (!picture)
+			goto bail;
+
+		ValidatePicture(picture);
+
+		cache->picture = picture;
+		cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
+		if (!cache->glyphs)
+			goto bail;
+
+		cache->evict = rand() % GLYPH_CACHE_SIZE;
+	}
+	assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
+
+	return TRUE;
+
+      bail:
+	glamor_unrealize_glyph_caches(pScreen);
+	return FALSE;
 }
 
 
 Bool
-glamor_glyphs_init (ScreenPtr pScreen)
+glamor_glyphs_init(ScreenPtr pScreen)
 {
-  if (!dixRegisterPrivateKey (&glamor_glyph_key, PRIVATE_GLYPH, 0))
-    return FALSE;
+	if (!dixRegisterPrivateKey(&glamor_glyph_key, PRIVATE_GLYPH, 0))
+		return FALSE;
 
-  /* Skip pixmap creation if we don't intend to use it. */
+	/* Skip pixmap creation if we don't intend to use it. */
 
-  return glamor_realize_glyph_caches (pScreen);
+	return glamor_realize_glyph_caches(pScreen);
 }
 
 /* The most efficient thing to way to upload the glyph to the screen
  * is to use CopyArea; glamor pixmaps are always offscreen.
  */
 static void
-glamor_glyph_cache_upload_glyph (ScreenPtr screen,
-				 glamor_glyph_cache_t * cache,
-				 GlyphPtr glyph, int x, int y)
+glamor_glyph_cache_upload_glyph(ScreenPtr screen,
+				glamor_glyph_cache_t * cache,
+				GlyphPtr glyph, int x, int y)
 {
-  PicturePtr pGlyphPicture = GlyphPicture (glyph)[screen->myNum];
-  PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
-  PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
-  PixmapPtr scratch;
-  GCPtr gc;
+	PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
+	PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
+	PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
+	PixmapPtr scratch;
+	GCPtr gc;
 
-  gc = GetScratchGC (pCachePixmap->drawable.depth, screen);
-  if (!gc)
-    return;
+	gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
+	if (!gc)
+		return;
 
-  ValidateGC (&pCachePixmap->drawable, gc);
+	ValidateGC(&pCachePixmap->drawable, gc);
 
-  scratch = pGlyphPixmap;
+	scratch = pGlyphPixmap;
 #if 0
-  /* Create a temporary bo to stream the updates to the cache */
-  if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth ||
-      !uxa_pixmap_is_offscreen (scratch))
-    {
-      scratch = screen->CreatePixmap (screen,
-				      glyph->info.width,
-				      glyph->info.height,
-				      pCachePixmap->drawable.depth, 0);
-      if (scratch)
-	{
-	  if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth)
-	    {
-	      PicturePtr picture;
-	      int error;
-
-	      picture = CreatePicture (0, &scratch->drawable,
-				       PictureMatchFormat (screen,
-							   pCachePixmap->
-							   drawable.depth,
-							   cache->picture->
-							   format), 0, NULL,
-				       serverClient, &error);
-	      if (picture)
-		{
-		  ValidatePicture (picture);
-		  uxa_composite (PictOpSrc, pGlyphPicture, NULL, picture,
-				 0, 0,
-				 0, 0,
-				 0, 0, glyph->info.width, glyph->info.height);
-		  FreePicture (picture, 0);
+	/* Create a temporary bo to stream the updates to the cache */
+	if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth ||
+	    !uxa_pixmap_is_offscreen(scratch)) {
+		scratch = screen->CreatePixmap(screen,
+					       glyph->info.width,
+					       glyph->info.height,
+					       pCachePixmap->
+					       drawable.depth, 0);
+		if (scratch) {
+			if (pGlyphPixmap->drawable.depth !=
+			    pCachePixmap->drawable.depth) {
+				PicturePtr picture;
+				int error;
+
+				picture =
+				    CreatePicture(0,
+						  &scratch->drawable,
+						  PictureMatchFormat
+						  (screen,
+						   pCachePixmap->
+						   drawable.depth,
+						   cache->picture->format),
+						  0, NULL, serverClient,
+						  &error);
+				if (picture) {
+					ValidatePicture(picture);
+					uxa_composite(PictOpSrc,
+						      pGlyphPicture,
+						      NULL, picture,
+						      0, 0, 0, 0, 0,
+						      0,
+						      glyph->info.width,
+						      glyph->info.height);
+					FreePicture(picture, 0);
+				}
+			} else {
+				glamor_copy_area(&pGlyphPixmap->drawable,
+						 &scratch->drawable,
+						 gc, 0, 0,
+						 glyph->info.width,
+						 glyph->info.height, 0, 0);
+			}
+		} else {
+			scratch = pGlyphPixmap;
 		}
-	    }
-	  else
-	    {
-	      glamor_copy_area (&pGlyphPixmap->drawable,
-				&scratch->drawable,
-				gc,
-				0, 0,
-				glyph->info.width, glyph->info.height, 0, 0);
-	    }
 	}
-      else
-	{
-	  scratch = pGlyphPixmap;
-	}
-    }
 #endif
-  glamor_copy_area (&scratch->drawable, &pCachePixmap->drawable, gc,
-		    0, 0, glyph->info.width, glyph->info.height, x, y);
+	glamor_copy_area(&scratch->drawable, &pCachePixmap->drawable, gc,
+			 0, 0, glyph->info.width, glyph->info.height, x,
+			 y);
 
-  if (scratch != pGlyphPixmap)
-    screen->DestroyPixmap (scratch);
+	if (scratch != pGlyphPixmap)
+		screen->DestroyPixmap(scratch);
 
-  FreeScratchGC (gc);
+	FreeScratchGC(gc);
 }
 
 
 void
-glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph)
+glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
 {
-  struct glamor_glyph *priv;
+	struct glamor_glyph *priv;
 
-  /* Use Lookup in case we have not attached to this glyph. */
-  priv = dixLookupPrivate (&glyph->devPrivates, &glamor_glyph_key);
-  if (priv == NULL)
-    return;
+	/* Use Lookup in case we have not attached to this glyph. */
+	priv = dixLookupPrivate(&glyph->devPrivates, &glamor_glyph_key);
+	if (priv == NULL)
+		return;
 
-  priv->cache->glyphs[priv->pos] = NULL;
+	priv->cache->glyphs[priv->pos] = NULL;
 
-  glamor_glyph_set_private (glyph, NULL);
-  free (priv);
+	glamor_glyph_set_private(glyph, NULL);
+	free(priv);
 }
 
 /* Cut and paste from render/glyph.c - probably should export it instead */
 static void
-glamor_glyph_extents (int nlist,
-		      GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
+glamor_glyph_extents(int nlist,
+		     GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
 {
-  int x1, x2, y1, y2;
-  int x, y, n;
-
-  x1 = y1 = MAXSHORT;
-  x2 = y2 = MINSHORT;
-  x = y = 0;
-  while (nlist--)
-    {
-      x += list->xOff;
-      y += list->yOff;
-      n = list->len;
-      list++;
-      while (n--)
-	{
-	  GlyphPtr glyph = *glyphs++;
-	  int v;
-
-	  v = x - glyph->info.x;
-	  if (v < x1)
-	    x1 = v;
-	  v += glyph->info.width;
-	  if (v > x2)
-	    x2 = v;
-
-	  v = y - glyph->info.y;
-	  if (v < y1)
-	    y1 = v;
-	  v += glyph->info.height;
-	  if (v > y2)
-	    y2 = v;
-
-	  x += glyph->info.xOff;
-	  y += glyph->info.yOff;
+	int x1, x2, y1, y2;
+	int x, y, n;
+
+	x1 = y1 = MAXSHORT;
+	x2 = y2 = MINSHORT;
+	x = y = 0;
+	while (nlist--) {
+		x += list->xOff;
+		y += list->yOff;
+		n = list->len;
+		list++;
+		while (n--) {
+			GlyphPtr glyph = *glyphs++;
+			int v;
+
+			v = x - glyph->info.x;
+			if (v < x1)
+				x1 = v;
+			v += glyph->info.width;
+			if (v > x2)
+				x2 = v;
+
+			v = y - glyph->info.y;
+			if (v < y1)
+				y1 = v;
+			v += glyph->info.height;
+			if (v > y2)
+				y2 = v;
+
+			x += glyph->info.xOff;
+			y += glyph->info.yOff;
+		}
 	}
-    }
 
-  extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
-  extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
-  extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
-  extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
+	extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
+	extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
+	extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
+	extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
 }
 
 /**
@@ -367,494 +364,488 @@ glamor_glyph_extents (int nlist,
  * bounding box, which appears to be good enough to catch most cases at least.
  */
 static Bool
-glamor_glyphs_intersect (int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-  int x1, x2, y1, y2;
-  int n;
-  int x, y;
-  BoxRec extents;
-  Bool first = TRUE;
-
-  x = 0;
-  y = 0;
-  extents.x1 = 0;
-  extents.y1 = 0;
-  extents.x2 = 0;
-  extents.y2 = 0;
-  while (nlist--)
-    {
-      x += list->xOff;
-      y += list->yOff;
-      n = list->len;
-      list++;
-      while (n--)
-	{
-	  GlyphPtr glyph = *glyphs++;
-
-	  if (glyph->info.width == 0 || glyph->info.height == 0)
-	    {
-	      x += glyph->info.xOff;
-	      y += glyph->info.yOff;
-	      continue;
-	    }
-
-	  x1 = x - glyph->info.x;
-	  if (x1 < MINSHORT)
-	    x1 = MINSHORT;
-	  y1 = y - glyph->info.y;
-	  if (y1 < MINSHORT)
-	    y1 = MINSHORT;
-	  x2 = x1 + glyph->info.width;
-	  if (x2 > MAXSHORT)
-	    x2 = MAXSHORT;
-	  y2 = y1 + glyph->info.height;
-	  if (y2 > MAXSHORT)
-	    y2 = MAXSHORT;
-
-	  if (first)
-	    {
-	      extents.x1 = x1;
-	      extents.y1 = y1;
-	      extents.x2 = x2;
-	      extents.y2 = y2;
-	      first = FALSE;
-	    }
-	  else
-	    {
-	      if (x1 < extents.x2 && x2 > extents.x1 &&
-		  y1 < extents.y2 && y2 > extents.y1)
-		{
-		  return TRUE;
+	int x1, x2, y1, y2;
+	int n;
+	int x, y;
+	BoxRec extents;
+	Bool first = TRUE;
+
+	x = 0;
+	y = 0;
+	extents.x1 = 0;
+	extents.y1 = 0;
+	extents.x2 = 0;
+	extents.y2 = 0;
+	while (nlist--) {
+		x += list->xOff;
+		y += list->yOff;
+		n = list->len;
+		list++;
+		while (n--) {
+			GlyphPtr glyph = *glyphs++;
+
+			if (glyph->info.width == 0
+			    || glyph->info.height == 0) {
+				x += glyph->info.xOff;
+				y += glyph->info.yOff;
+				continue;
+			}
+
+			x1 = x - glyph->info.x;
+			if (x1 < MINSHORT)
+				x1 = MINSHORT;
+			y1 = y - glyph->info.y;
+			if (y1 < MINSHORT)
+				y1 = MINSHORT;
+			x2 = x1 + glyph->info.width;
+			if (x2 > MAXSHORT)
+				x2 = MAXSHORT;
+			y2 = y1 + glyph->info.height;
+			if (y2 > MAXSHORT)
+				y2 = MAXSHORT;
+
+			if (first) {
+				extents.x1 = x1;
+				extents.y1 = y1;
+				extents.x2 = x2;
+				extents.y2 = y2;
+				first = FALSE;
+			} else {
+				if (x1 < extents.x2 && x2 > extents.x1
+				    && y1 < extents.y2
+				    && y2 > extents.y1) {
+					return TRUE;
+				}
+
+				if (x1 < extents.x1)
+					extents.x1 = x1;
+				if (x2 > extents.x2)
+					extents.x2 = x2;
+				if (y1 < extents.y1)
+					extents.y1 = y1;
+				if (y2 > extents.y2)
+					extents.y2 = y2;
+			}
+			x += glyph->info.xOff;
+			y += glyph->info.yOff;
 		}
-
-	      if (x1 < extents.x1)
-		extents.x1 = x1;
-	      if (x2 > extents.x2)
-		extents.x2 = x2;
-	      if (y1 < extents.y1)
-		extents.y1 = y1;
-	      if (y2 > extents.y2)
-		extents.y2 = y2;
-	    }
-	  x += glyph->info.xOff;
-	  y += glyph->info.yOff;
 	}
-    }
 
-  return FALSE;
+	return FALSE;
 }
 
 
 static inline unsigned int
-glamor_glyph_size_to_count (int size)
+glamor_glyph_size_to_count(int size)
 {
-  size /= GLYPH_MIN_SIZE;
-  return size * size;
+	size /= GLYPH_MIN_SIZE;
+	return size * size;
 }
 
 static inline unsigned int
-glamor_glyph_count_to_mask (int count)
+glamor_glyph_count_to_mask(int count)
 {
-  return ~(count - 1);
+	return ~(count - 1);
 }
 
 static inline unsigned int
-glamor_glyph_size_to_mask (int size)
+glamor_glyph_size_to_mask(int size)
 {
-  return glamor_glyph_count_to_mask (glamor_glyph_size_to_count (size));
+	return
+	    glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size));
 }
 
 static PicturePtr
-glamor_glyph_cache (ScreenPtr screen, GlyphPtr glyph, int *out_x, int *out_y)
+glamor_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x,
+		   int *out_y)
 {
-  glamor_screen_private *glamor = glamor_get_screen_private (screen);
-  PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum];
-  glamor_glyph_cache_t *cache =
-    &glamor->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0];
-  struct glamor_glyph *priv = NULL;
-  int size, mask, pos, s;
-
-  if (glyph->info.width > GLYPH_MAX_SIZE
-      || glyph->info.height > GLYPH_MAX_SIZE)
-    return NULL;
-
-  for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
-    if (glyph->info.width <= size && glyph->info.height <= size)
-      break;
-
-  s = glamor_glyph_size_to_count (size);
-  mask = glamor_glyph_count_to_mask (s);
-  pos = (cache->count + s - 1) & mask;
-  if (pos < GLYPH_CACHE_SIZE)
-    {
-      cache->count = pos + s;
-    }
-  else
-    {
-      for (s = size; s <= GLYPH_MAX_SIZE; s *= 2)
-	{
-	  int i = cache->evict & glamor_glyph_size_to_mask (s);
-	  GlyphPtr evicted = cache->glyphs[i];
-	  if (evicted == NULL)
-	    continue;
-
-	  priv = glamor_glyph_get_private (evicted);
-	  if (priv->size >= s)
-	    {
-	      cache->glyphs[i] = NULL;
-	      glamor_glyph_set_private (evicted, NULL);
-	      pos = cache->evict & glamor_glyph_size_to_mask (size);
-	    }
-	  else
-	    priv = NULL;
-	  break;
-	}
-      if (priv == NULL)
-	{
-	  int count = glamor_glyph_size_to_count (size);
-	  mask = glamor_glyph_count_to_mask (count);
-	  pos = cache->evict & mask;
-	  for (s = 0; s < count; s++)
-	    {
-	      GlyphPtr evicted = cache->glyphs[pos + s];
-	      if (evicted != NULL)
-		{
-		  if (priv != NULL)
-		    free (priv);
-
-		  priv = glamor_glyph_get_private (evicted);
-		  glamor_glyph_set_private (evicted, NULL);
-		  cache->glyphs[pos + s] = NULL;
+	glamor_screen_private *glamor = glamor_get_screen_private(screen);
+	PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
+	glamor_glyph_cache_t *cache =
+	    &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) !=
+				 0];
+	struct glamor_glyph *priv = NULL;
+	int size, mask, pos, s;
+
+	if (glyph->info.width > GLYPH_MAX_SIZE
+	    || glyph->info.height > GLYPH_MAX_SIZE)
+		return NULL;
+
+	for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
+		if (glyph->info.width <= size
+		    && glyph->info.height <= size)
+			break;
+
+	s = glamor_glyph_size_to_count(size);
+	mask = glamor_glyph_count_to_mask(s);
+	pos = (cache->count + s - 1) & mask;
+	if (pos < GLYPH_CACHE_SIZE) {
+		cache->count = pos + s;
+	} else {
+		for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) {
+			int i =
+			    cache->evict & glamor_glyph_size_to_mask(s);
+			GlyphPtr evicted = cache->glyphs[i];
+			if (evicted == NULL)
+				continue;
+
+			priv = glamor_glyph_get_private(evicted);
+			if (priv->size >= s) {
+				cache->glyphs[i] = NULL;
+				glamor_glyph_set_private(evicted, NULL);
+				pos = cache->evict &
+				    glamor_glyph_size_to_mask(size);
+			} else
+				priv = NULL;
+			break;
 		}
-	    }
+		if (priv == NULL) {
+			int count = glamor_glyph_size_to_count(size);
+			mask = glamor_glyph_count_to_mask(count);
+			pos = cache->evict & mask;
+			for (s = 0; s < count; s++) {
+				GlyphPtr evicted = cache->glyphs[pos + s];
+				if (evicted != NULL) {
+					if (priv != NULL)
+						free(priv);
+
+					priv =
+					    glamor_glyph_get_private
+					    (evicted);
+					glamor_glyph_set_private(evicted,
+								 NULL);
+					cache->glyphs[pos + s] = NULL;
+				}
+			}
+		}
+		/* And pick a new eviction position */
+		cache->evict = rand() % GLYPH_CACHE_SIZE;
+	}
+
+	if (priv == NULL) {
+		priv = malloc(sizeof(struct glamor_glyph));
+		if (priv == NULL)
+			return NULL;
+	}
+
+	glamor_glyph_set_private(glyph, priv);
+	cache->glyphs[pos] = glyph;
+
+	priv->cache = cache;
+	priv->size = size;
+	priv->pos = pos;
+	s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
+		   (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
+	priv->x =
+	    s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
+	priv->y =
+	    (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
+	for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) {
+		if (pos & 1)
+			priv->x += s;
+		if (pos & 2)
+			priv->y += s;
+		pos >>= 2;
 	}
-      /* And pick a new eviction position */
-      cache->evict = rand () % GLYPH_CACHE_SIZE;
-    }
-
-  if (priv == NULL)
-    {
-      priv = malloc (sizeof (struct glamor_glyph));
-      if (priv == NULL)
-	return NULL;
-    }
-
-  glamor_glyph_set_private (glyph, priv);
-  cache->glyphs[pos] = glyph;
-
-  priv->cache = cache;
-  priv->size = size;
-  priv->pos = pos;
-  s =
-    pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
-	   (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
-  priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
-  priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
-  for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2)
-    {
-      if (pos & 1)
-	priv->x += s;
-      if (pos & 2)
-	priv->y += s;
-      pos >>= 2;
-    }
-
-  glamor_glyph_cache_upload_glyph (screen, cache, glyph, priv->x, priv->y);
-
-  *out_x = priv->x;
-  *out_y = priv->y;
-  return cache->picture;
+
+	glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x,
+					priv->y);
+
+	*out_x = priv->x;
+	*out_y = priv->y;
+	return cache->picture;
 }
 
 static glamor_glyph_cache_result_t
-glamor_buffer_glyph (ScreenPtr screen,
-		     glamor_glyph_buffer_t * buffer,
-		     GlyphPtr glyph, int x_glyph, int y_glyph)
+glamor_buffer_glyph(ScreenPtr screen,
+		    glamor_glyph_buffer_t * buffer,
+		    GlyphPtr glyph, int x_glyph, int y_glyph)
 {
-  glamor_screen_private *glamor_screen = glamor_get_screen_private (screen);
-  unsigned int format = (GlyphPicture (glyph)[screen->myNum])->format;
-  glamor_composite_rect_t *rect;
-  PicturePtr source;
-  struct glamor_glyph *priv;
-  int x, y;
-  PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum];
-  glamor_glyph_cache_t *cache; 
-
-  if (PICT_FORMAT_BPP (format) == 1)
-    format = PICT_a8;
-
-  cache = &glamor_screen->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0];
-
-  if (buffer->source && buffer->source != cache->picture)
-    return GLAMOR_GLYPH_NEED_FLUSH;
-
-  if (buffer->count == GLYPH_BUFFER_SIZE)
-    return GLAMOR_GLYPH_NEED_FLUSH;
-
-  priv = glamor_glyph_get_private (glyph);
-
-  if (priv)
-    {
-      rect = &buffer->rects[buffer->count++];
-      rect->x_src = priv->x;
-      rect->y_src = priv->y;
-      if (buffer->source == NULL) buffer->source = priv->cache->picture;
-    }
-  else
-    {
-      source = glamor_glyph_cache (screen, glyph, &x, &y);
-      if (source != NULL)
-	{
-	  rect = &buffer->rects[buffer->count++];
-	  rect->x_src = x;
-	  rect->y_src = y;
-          if (buffer->source == NULL) buffer->source = source;
-	}
-      else
-	{
-	  source = GlyphPicture (glyph)[screen->myNum];
-	  if (buffer->source && buffer->source != source)
-	    return GLAMOR_GLYPH_NEED_FLUSH;
-	  buffer->source = source;
-
-	  rect = &buffer->rects[buffer->count++];
-	  rect->x_src = 0;
-	  rect->y_src = 0;
+	glamor_screen_private *glamor_screen =
+	    glamor_get_screen_private(screen);
+	unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format;
+	glamor_composite_rect_t *rect;
+	PicturePtr source;
+	struct glamor_glyph *priv;
+	int x, y;
+	PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
+	glamor_glyph_cache_t *cache;
+
+	if (PICT_FORMAT_BPP(format) == 1)
+		format = PICT_a8;
+
+	cache =
+	    &glamor_screen->glyphCaches[PICT_FORMAT_RGB
+					(glyph_picture->format) != 0];
+
+	if (buffer->source && buffer->source != cache->picture)
+		return GLAMOR_GLYPH_NEED_FLUSH;
+
+	if (buffer->count == GLYPH_BUFFER_SIZE)
+		return GLAMOR_GLYPH_NEED_FLUSH;
+
+	priv = glamor_glyph_get_private(glyph);
+
+	if (priv) {
+		rect = &buffer->rects[buffer->count++];
+		rect->x_src = priv->x;
+		rect->y_src = priv->y;
+		if (buffer->source == NULL)
+			buffer->source = priv->cache->picture;
+	} else {
+		source = glamor_glyph_cache(screen, glyph, &x, &y);
+		if (source != NULL) {
+			rect = &buffer->rects[buffer->count++];
+			rect->x_src = x;
+			rect->y_src = y;
+			if (buffer->source == NULL)
+				buffer->source = source;
+		} else {
+			source = GlyphPicture(glyph)[screen->myNum];
+			if (buffer->source && buffer->source != source)
+				return GLAMOR_GLYPH_NEED_FLUSH;
+			buffer->source = source;
+
+			rect = &buffer->rects[buffer->count++];
+			rect->x_src = 0;
+			rect->y_src = 0;
+		}
 	}
-    }
 
-  rect->x_dst = x_glyph - glyph->info.x;
-  rect->y_dst = y_glyph - glyph->info.y;
-  rect->width = glyph->info.width;
-  rect->height = glyph->info.height;
+	rect->x_dst = x_glyph - glyph->info.x;
+	rect->y_dst = y_glyph - glyph->info.y;
+	rect->width = glyph->info.width;
+	rect->height = glyph->info.height;
 
-  /* Couldn't find the glyph in the cache, use the glyph picture directly */
+	/* Couldn't find the glyph in the cache, use the glyph picture directly */
 
-  return GLAMOR_GLYPH_SUCCESS;
+	return GLAMOR_GLYPH_SUCCESS;
 }
 
 
 static void
-glamor_glyphs_flush_mask (PicturePtr mask, glamor_glyph_buffer_t * buffer)
+glamor_glyphs_flush_mask(PicturePtr mask, glamor_glyph_buffer_t * buffer)
 {
 #ifdef RENDER
-  glamor_composite_rects (PictOpAdd, buffer->source, NULL, mask,
-			  buffer->count, buffer->rects);
+	glamor_composite_rects(PictOpAdd, buffer->source, NULL, mask,
+			       buffer->count, buffer->rects);
 #endif
-  buffer->count = 0;
-  buffer->source = NULL;
+	buffer->count = 0;
+	buffer->source = NULL;
 }
 
 static void
-glamor_glyphs_via_mask (CARD8 op,
-			PicturePtr src,
-			PicturePtr dst,
-			PictFormatPtr mask_format,
-			INT16 x_src,
-			INT16 y_src,
-			int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs_via_mask(CARD8 op,
+		       PicturePtr src,
+		       PicturePtr dst,
+		       PictFormatPtr mask_format,
+		       INT16 x_src,
+		       INT16 y_src,
+		       int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-  PixmapPtr mask_pixmap = 0;
-  PicturePtr mask;
-  ScreenPtr screen = dst->pDrawable->pScreen;
-  int width = 0, height = 0;
-  int x, y;
-  int x_dst = list->xOff, y_dst = list->yOff;
-  int n;
-  GlyphPtr glyph;
-  int error;
-  BoxRec extents = { 0, 0, 0, 0 };
-  CARD32 component_alpha;
-  glamor_glyph_buffer_t buffer;
-
-  GCPtr gc;
-
-  glamor_glyph_extents (nlist, list, glyphs, &extents);
-
-  if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
-    return;
-  width = extents.x2 - extents.x1;
-  height = extents.y2 - extents.y1;
-
-  if (mask_format->depth == 1)
-    {
-      PictFormatPtr a8Format = PictureMatchFormat (screen, 8, PICT_a8);
-
-      if (a8Format)
-	mask_format = a8Format;
-    }
-
-  mask_pixmap = screen->CreatePixmap (screen, width, height,
-				      mask_format->depth,
-				      CREATE_PIXMAP_USAGE_SCRATCH);
-  if (!mask_pixmap)
-    return;
-  component_alpha = NeedsComponent (mask_format->format);
-  mask = CreatePicture (0, &mask_pixmap->drawable,
-			mask_format, CPComponentAlpha,
-			&component_alpha, serverClient, &error);
-  if (!mask)
-    {
-      screen->DestroyPixmap (mask_pixmap);
-      return;
-    }
-  gc = GetScratchGC (mask_pixmap->drawable.depth, screen);
-  ValidateGC (&mask_pixmap->drawable, gc);
-  glamor_fill (&mask_pixmap->drawable, gc, 0, 0, width, height);
-  FreeScratchGC (gc);
-  x = -extents.x1;
-  y = -extents.y1;
-
-  buffer.count = 0;
-  buffer.source = NULL;
-  while (nlist--)
-    {
-      x += list->xOff;
-      y += list->yOff;
-      n = list->len;
-      while (n--)
-	{
-	  glyph = *glyphs++;
-
-	  if (glyph->info.width > 0 && glyph->info.height > 0 &&
-	      glamor_buffer_glyph (screen, &buffer, glyph, x,
-				   y) == GLAMOR_GLYPH_NEED_FLUSH)
-	    {
-
-	      glamor_glyphs_flush_mask (mask, &buffer);
-
-	      glamor_buffer_glyph (screen, &buffer, glyph, x, y);
-	    }
-
-	  x += glyph->info.xOff;
-	  y += glyph->info.yOff;
+	PixmapPtr mask_pixmap = 0;
+	PicturePtr mask;
+	ScreenPtr screen = dst->pDrawable->pScreen;
+	int width = 0, height = 0;
+	int x, y;
+	int x_dst = list->xOff, y_dst = list->yOff;
+	int n;
+	GlyphPtr glyph;
+	int error;
+	BoxRec extents = { 0, 0, 0, 0 };
+	CARD32 component_alpha;
+	glamor_glyph_buffer_t buffer;
+
+	GCPtr gc;
+
+	glamor_glyph_extents(nlist, list, glyphs, &extents);
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+		return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+
+	if (mask_format->depth == 1) {
+		PictFormatPtr a8Format =
+		    PictureMatchFormat(screen, 8, PICT_a8);
+
+		if (a8Format)
+			mask_format = a8Format;
+	}
+
+	mask_pixmap = screen->CreatePixmap(screen, width, height,
+					   mask_format->depth,
+					   CREATE_PIXMAP_USAGE_SCRATCH);
+	if (!mask_pixmap)
+		return;
+	component_alpha = NeedsComponent(mask_format->format);
+	mask = CreatePicture(0, &mask_pixmap->drawable,
+			     mask_format, CPComponentAlpha,
+			     &component_alpha, serverClient, &error);
+	if (!mask) {
+		screen->DestroyPixmap(mask_pixmap);
+		return;
 	}
-      list++;
-    }
-
-  if (buffer.count)
-      glamor_glyphs_flush_mask (mask, &buffer);
-
-  x = extents.x1;
-  y = extents.y1;
-  CompositePicture (op,
-		    src,
-		    mask,
-		    dst,
-		    x_src + x - x_dst,
-		    y_src + y - y_dst, 0, 0, x, y, width, height);
-  FreePicture (mask, 0);
-  screen->DestroyPixmap (mask_pixmap);
+	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
+	ValidateGC(&mask_pixmap->drawable, gc);
+	glamor_fill(&mask_pixmap->drawable, gc, 0, 0, width, height);
+	FreeScratchGC(gc);
+	x = -extents.x1;
+	y = -extents.y1;
+
+	buffer.count = 0;
+	buffer.source = NULL;
+	while (nlist--) {
+		x += list->xOff;
+		y += list->yOff;
+		n = list->len;
+		while (n--) {
+			glyph = *glyphs++;
+
+			if (glyph->info.width > 0
+			    && glyph->info.height > 0
+			    && glamor_buffer_glyph(screen, &buffer,
+						   glyph, x,
+						   y) ==
+			    GLAMOR_GLYPH_NEED_FLUSH) {
+
+				glamor_glyphs_flush_mask(mask, &buffer);
+
+				glamor_buffer_glyph(screen, &buffer,
+						    glyph, x, y);
+			}
+
+			x += glyph->info.xOff;
+			y += glyph->info.yOff;
+		}
+		list++;
+	}
+
+	if (buffer.count)
+		glamor_glyphs_flush_mask(mask, &buffer);
+
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture(op,
+			 src,
+			 mask,
+			 dst,
+			 x_src + x - x_dst,
+			 y_src + y - y_dst, 0, 0, x, y, width, height);
+	FreePicture(mask, 0);
+	screen->DestroyPixmap(mask_pixmap);
 }
 
 static void
-glamor_glyphs_flush_dst (CARD8 op,
-			 PicturePtr src,
-			 PicturePtr dst,
-			 glamor_glyph_buffer_t * buffer,
-			 INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
+glamor_glyphs_flush_dst(CARD8 op,
+			PicturePtr src,
+			PicturePtr dst,
+			glamor_glyph_buffer_t * buffer,
+			INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
 {
-  int i;
-  glamor_composite_rect_t *rect = &buffer->rects[0];
-  for (i = 0; i < buffer->count; i++, rect++)
-    {
-      rect->x_mask = rect->x_src;
-      rect->y_mask = rect->y_src;
-      rect->x_src = x_src + rect->x_dst - x_dst;
-      rect->y_src = y_src + rect->y_dst - y_dst;
-    }
-
-  glamor_composite_rects (op, src, buffer->source, dst,
-			  buffer->count, &buffer->rects[0]);
-
-  buffer->count = 0;
-  buffer->source = NULL;
+	int i;
+	glamor_composite_rect_t *rect = &buffer->rects[0];
+	for (i = 0; i < buffer->count; i++, rect++) {
+		rect->x_mask = rect->x_src;
+		rect->y_mask = rect->y_src;
+		rect->x_src = x_src + rect->x_dst - x_dst;
+		rect->y_src = y_src + rect->y_dst - y_dst;
+	}
+
+	glamor_composite_rects(op, src, buffer->source, dst,
+			       buffer->count, &buffer->rects[0]);
+
+	buffer->count = 0;
+	buffer->source = NULL;
 }
 
 static void
-glamor_glyphs_to_dst (CARD8 op,
-		      PicturePtr src,
-		      PicturePtr dst,
-		      INT16 x_src,
-		      INT16 y_src,
-		      int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs_to_dst(CARD8 op,
+		     PicturePtr src,
+		     PicturePtr dst,
+		     INT16 x_src,
+		     INT16 y_src,
+		     int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-  ScreenPtr screen = dst->pDrawable->pScreen;
-  int x = 0, y = 0;
-  int x_dst = list->xOff, y_dst = list->yOff;
-  int n;
-  GlyphPtr glyph;
-  glamor_glyph_buffer_t buffer;
-
-  buffer.count = 0;
-  buffer.source = NULL;
-  while (nlist--)
-    {
-      x += list->xOff;
-      y += list->yOff;
-      n = list->len;
-      while (n--)
-	{
-	  glyph = *glyphs++;
-
-	  if (glyph->info.width > 0 && glyph->info.height > 0 &&
-	      glamor_buffer_glyph (screen, &buffer, glyph, x,
-				   y) == GLAMOR_GLYPH_NEED_FLUSH)
-	    {
-	      glamor_glyphs_flush_dst (op, src, dst,
-				       &buffer, x_src, y_src, x_dst, y_dst);
-	      glamor_buffer_glyph (screen, &buffer, glyph, x, y);
-	    }
-
-	  x += glyph->info.xOff;
-	  y += glyph->info.yOff;
+	ScreenPtr screen = dst->pDrawable->pScreen;
+	int x = 0, y = 0;
+	int x_dst = list->xOff, y_dst = list->yOff;
+	int n;
+	GlyphPtr glyph;
+	glamor_glyph_buffer_t buffer;
+
+	buffer.count = 0;
+	buffer.source = NULL;
+	while (nlist--) {
+		x += list->xOff;
+		y += list->yOff;
+		n = list->len;
+		while (n--) {
+			glyph = *glyphs++;
+
+			if (glyph->info.width > 0
+			    && glyph->info.height > 0
+			    && glamor_buffer_glyph(screen, &buffer,
+						   glyph, x,
+						   y) ==
+			    GLAMOR_GLYPH_NEED_FLUSH) {
+				glamor_glyphs_flush_dst(op, src, dst,
+							&buffer, x_src,
+							y_src, x_dst,
+							y_dst);
+				glamor_buffer_glyph(screen, &buffer,
+						    glyph, x, y);
+			}
+
+			x += glyph->info.xOff;
+			y += glyph->info.yOff;
+		}
+		list++;
 	}
-      list++;
-    }
 
-  if (buffer.count)
-      glamor_glyphs_flush_dst (op, src, dst, &buffer,
-			       x_src, y_src, x_dst, y_dst);
+	if (buffer.count)
+		glamor_glyphs_flush_dst(op, src, dst, &buffer,
+					x_src, y_src, x_dst, y_dst);
 }
 
 void
-glamor_glyphs (CARD8 op,
-	       PicturePtr src,
-	       PicturePtr dst,
-	       PictFormatPtr mask_format,
-	       INT16 x_src,
-	       INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs(CARD8 op,
+	      PicturePtr src,
+	      PicturePtr dst,
+	      PictFormatPtr mask_format,
+	      INT16 x_src,
+	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-  /* If we don't have a mask format but all the glyphs have the same format
-   * and don't intersect, use the glyph format as mask format for the full
-   * benefits of the glyph cache.
-   */
-  if (!mask_format)
-    {
-      Bool same_format = TRUE;
-      int i;
-
-      mask_format = list[0].format;
-
-      for (i = 0; i < nlist; i++)
-	{
-	  if (mask_format->format != list[i].format->format)
-	    {
-	      same_format = FALSE;
-	      break;
-	    }
-	}
+	/* If we don't have a mask format but all the glyphs have the same format
+	 * and don't intersect, use the glyph format as mask format for the full
+	 * benefits of the glyph cache.
+	 */
+	if (!mask_format) {
+		Bool same_format = TRUE;
+		int i;
+
+		mask_format = list[0].format;
+
+		for (i = 0; i < nlist; i++) {
+			if (mask_format->format != list[i].format->format) {
+				same_format = FALSE;
+				break;
+			}
+		}
 
-      if (!same_format || (mask_format->depth != 1 &&
-			   glamor_glyphs_intersect (nlist, list, glyphs)))
-	{
-	  mask_format = NULL;
+		if (!same_format || (mask_format->depth != 1 &&
+				     glamor_glyphs_intersect(nlist, list,
+							     glyphs))) {
+			mask_format = NULL;
+		}
 	}
-    }
 
-  if (mask_format)
-    glamor_glyphs_via_mask (op, src, dst, mask_format,
-			    x_src, y_src, nlist, list, glyphs);
-  else
-    glamor_glyphs_to_dst (op, src, dst, x_src, y_src, nlist, list, glyphs);
+	if (mask_format)
+		glamor_glyphs_via_mask(op, src, dst, mask_format,
+				       x_src, y_src, nlist, list, glyphs);
+	else
+		glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
+				     list, glyphs);
 }
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index c94c07c..9e8d6ec 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -9,36 +9,36 @@
 /* Upload picture to texture.  We may need to flip the y axis or
  * wire alpha to 1. So we may conditional create fbo for the picture.
  * */
-enum glamor_pixmap_status 
+enum glamor_pixmap_status
 glamor_upload_picture_to_texture(PicturePtr picture)
 {
-  PixmapPtr pixmap;
-  glamor_pixmap_private *pixmap_priv;
-  assert(picture->pDrawable);
-  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-  assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1);
-  return glamor_upload_pixmap_to_texture(pixmap);
+	PixmapPtr pixmap;
+	glamor_pixmap_private *pixmap_priv;
+	assert(picture->pDrawable);
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1);
+	return glamor_upload_pixmap_to_texture(pixmap);
 }
 
 
 Bool
 glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
 {
-  if (!picture || !picture->pDrawable)
-    return TRUE;
-    
-  return glamor_prepare_access(picture->pDrawable, access);
+	if (!picture || !picture->pDrawable)
+		return TRUE;
+
+	return glamor_prepare_access(picture->pDrawable, access);
 }
 
 void
 glamor_finish_access_picture(PicturePtr picture)
 {
-  if (!picture || !picture->pDrawable)
-    return;
-    
-  glamor_finish_access(picture->pDrawable);
+	if (!picture || !picture->pDrawable)
+		return;
+
+	glamor_finish_access(picture->pDrawable);
 }
 
 /* 
@@ -49,45 +49,48 @@ glamor_finish_access_picture(PicturePtr picture)
 int
 glamor_create_picture(PicturePtr picture)
 {
-  PixmapPtr pixmap;
-  glamor_pixmap_private *pixmap_priv;
-  glamor_screen_private *glamor_priv;
-
-  if (!picture || !picture->pDrawable)
-    return 0;
-
-  glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
-  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  assert(pixmap_priv);
-
-  pixmap_priv->is_picture = 1;
-  pixmap_priv->pict_format = picture->format;
-  return glamor_priv->saved_create_picture(picture);
+	PixmapPtr pixmap;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv;
+
+	if (!picture || !picture->pDrawable)
+		return 0;
+
+	glamor_priv =
+	    glamor_get_screen_private(picture->pDrawable->pScreen);
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	assert(pixmap_priv);
+
+	pixmap_priv->is_picture = 1;
+	pixmap_priv->pict_format = picture->format;
+	return glamor_priv->saved_create_picture(picture);
 }
 
 void
 glamor_destroy_picture(PicturePtr picture)
 {
-  PixmapPtr pixmap;
-  glamor_pixmap_private *pixmap_priv;
-  glamor_screen_private *glamor_priv;
-
-  if (!picture || !picture->pDrawable)
-    return;
-
-  glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
-  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  assert(pixmap_priv);
-
-  pixmap_priv->is_picture = 0;
-  pixmap_priv->pict_format = 0;
-  glamor_priv->saved_destroy_picture(picture);
+	PixmapPtr pixmap;
+	glamor_pixmap_private *pixmap_priv;
+	glamor_screen_private *glamor_priv;
+
+	if (!picture || !picture->pDrawable)
+		return;
+
+	glamor_priv =
+	    glamor_get_screen_private(picture->pDrawable->pScreen);
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	assert(pixmap_priv);
+
+	pixmap_priv->is_picture = 0;
+	pixmap_priv->pict_format = 0;
+	glamor_priv->saved_destroy_picture(picture);
 }
 
-void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv)
+void
+glamor_picture_format_fixup(PicturePtr picture,
+			    glamor_pixmap_private * pixmap_priv)
 {
-  pixmap_priv->pict_format = picture->format;
+	pixmap_priv->pict_format = picture->format;
 }
-
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 28ad57a..f02acc7 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -15,118 +15,123 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
 			   int *x, int *y)
 {
 #ifdef COMPOSITE
-  if (drawable->type == DRAWABLE_WINDOW) {
-    *x = -pixmap->screen_x;
-    *y = -pixmap->screen_y;
-    return;
-  }
+	if (drawable->type == DRAWABLE_WINDOW) {
+		*x = -pixmap->screen_x;
+		*y = -pixmap->screen_y;
+		return;
+	}
 #endif
 
-  *x = 0;
-  *y = 0;
+	*x = 0;
+	*y = 0;
 }
 
 
-static void 
-_glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, 
-				 glamor_pixmap_private *pixmap_priv)
+static void
+_glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
+				glamor_pixmap_private * pixmap_priv)
 {
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    GLfloat vertices[8];
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                          2 * sizeof(float), vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(glamor_priv->solid_prog);
-    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 
-      1, pixmap_priv->pending_op.fill.color4fv);
-    vertices[0] = -1;
-    vertices[1] = -1;
-    vertices[2] = 1;
-    vertices[3] = -1;
-    vertices[4] = 1;
-    vertices[5] = 1;
-    vertices[6] = -1;
-    vertices[7] = 1;
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(0);
-    pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	GLfloat vertices[8];
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(glamor_priv->solid_prog);
+	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
+			       1, pixmap_priv->pending_op.fill.color4fv);
+	vertices[0] = -1;
+	vertices[1] = -1;
+	vertices[2] = 1;
+	vertices[3] = -1;
+	vertices[4] = 1;
+	vertices[5] = 1;
+	vertices[6] = -1;
+	vertices[7] = 1;
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
 
 
 glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
-  NULL,
-  _glamor_pixmap_validate_filling
+	NULL,
+	_glamor_pixmap_validate_filling
 };
 
 void
 glamor_pixmap_init(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
 }
 
 void
 glamor_validate_pixmap(PixmapPtr pixmap)
 {
-  glamor_pixmap_validate_function_t validate_op;
-  glamor_screen_private *glamor_priv =
-    glamor_get_screen_private(pixmap->drawable.pScreen);
-  glamor_pixmap_private *pixmap_priv = 
-    glamor_get_pixmap_private(pixmap);
-
-  validate_op = glamor_priv->pixmap_validate_funcs[pixmap_priv->pending_op.type];
-  if (validate_op) { 
-    (*validate_op)(glamor_priv, pixmap_priv);
-  }
+	glamor_pixmap_validate_function_t validate_op;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+
+	validate_op =
+	    glamor_priv->pixmap_validate_funcs[pixmap_priv->
+					       pending_op.type];
+	if (validate_op) {
+		(*validate_op) (glamor_priv, pixmap_priv);
+	}
 }
 
 void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
 {
-  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
 #ifndef GLAMOR_GLES2
-  dispatch->glMatrixMode(GL_PROJECTION);
-  dispatch->glLoadIdentity();
-  dispatch->glMatrixMode(GL_MODELVIEW);
-  dispatch->glLoadIdentity();                                        
+	dispatch->glMatrixMode(GL_PROJECTION);
+	dispatch->glLoadIdentity();
+	dispatch->glMatrixMode(GL_MODELVIEW);
+	dispatch->glLoadIdentity();
 #endif
-  dispatch->glViewport(0, 0,
-	     pixmap_priv->container->drawable.width,
-	     pixmap_priv->container->drawable.height);
+	dispatch->glViewport(0, 0,
+			     pixmap_priv->container->drawable.width,
+			     pixmap_priv->container->drawable.height);
 
 }
 
 int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
 {
-  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-    return -1;
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return -1;
 
-  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-  return 0;
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	return 0;
 }
 
 int
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
-  int err;
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+	int err;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
 
-  err = glamor_set_destination_pixmap_priv(pixmap_priv);
-  return err;
+	err = glamor_set_destination_pixmap_priv(pixmap_priv);
+	return err;
 }
 
 Bool
 glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 {
-  if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
-    return GL_TRUE;
-  }
+	if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+		return GL_TRUE;
+	}
 
-  glamor_fallback("unsupported planemask %lx\n", planemask);
-  return GL_FALSE;
+	glamor_fallback("unsupported planemask %lx\n", planemask);
+	return GL_FALSE;
 }
 
 
@@ -135,63 +140,63 @@ void
 glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 {
 #ifndef GLAMOR_GLES2
-  if (alu == GXcopy) {
-    dispatch->glDisable(GL_COLOR_LOGIC_OP);
-    return;
-  }
-  dispatch->glEnable(GL_COLOR_LOGIC_OP);
-  switch (alu) {
-  case GXclear:
-    dispatch->glLogicOp(GL_CLEAR);
-    break;
-  case GXand:
-    dispatch->glLogicOp(GL_AND);
-    break;
-  case GXandReverse:
-    dispatch->glLogicOp(GL_AND_REVERSE);
-    break;
-  case GXandInverted:
-    dispatch->glLogicOp(GL_AND_INVERTED);
-    break;
-  case GXnoop:
-    dispatch->glLogicOp(GL_NOOP);
-    break;
-  case GXxor:
-    dispatch->glLogicOp(GL_XOR);
-    break;
-  case GXor:
-    dispatch->glLogicOp(GL_OR);
-    break;
-  case GXnor:
-    dispatch->glLogicOp(GL_NOR);
-    break;
-  case GXequiv:
-    dispatch->glLogicOp(GL_EQUIV);
-    break;
-  case GXinvert:
-    dispatch->glLogicOp(GL_INVERT);
-    break;
-  case GXorReverse:
-    dispatch->glLogicOp(GL_OR_REVERSE);
-    break;
-  case GXcopyInverted:
-    dispatch->glLogicOp(GL_COPY_INVERTED);
-    break;
-  case GXorInverted:
-    dispatch->glLogicOp(GL_OR_INVERTED);
-    break;
-  case GXnand:
-    dispatch->glLogicOp(GL_NAND);
-    break;
-  case GXset:
-    dispatch->glLogicOp(GL_SET);
-    break;
-  default:
-    FatalError("unknown logic op\n");
-  }
+	if (alu == GXcopy) {
+		dispatch->glDisable(GL_COLOR_LOGIC_OP);
+		return;
+	}
+	dispatch->glEnable(GL_COLOR_LOGIC_OP);
+	switch (alu) {
+	case GXclear:
+		dispatch->glLogicOp(GL_CLEAR);
+		break;
+	case GXand:
+		dispatch->glLogicOp(GL_AND);
+		break;
+	case GXandReverse:
+		dispatch->glLogicOp(GL_AND_REVERSE);
+		break;
+	case GXandInverted:
+		dispatch->glLogicOp(GL_AND_INVERTED);
+		break;
+	case GXnoop:
+		dispatch->glLogicOp(GL_NOOP);
+		break;
+	case GXxor:
+		dispatch->glLogicOp(GL_XOR);
+		break;
+	case GXor:
+		dispatch->glLogicOp(GL_OR);
+		break;
+	case GXnor:
+		dispatch->glLogicOp(GL_NOR);
+		break;
+	case GXequiv:
+		dispatch->glLogicOp(GL_EQUIV);
+		break;
+	case GXinvert:
+		dispatch->glLogicOp(GL_INVERT);
+		break;
+	case GXorReverse:
+		dispatch->glLogicOp(GL_OR_REVERSE);
+		break;
+	case GXcopyInverted:
+		dispatch->glLogicOp(GL_COPY_INVERTED);
+		break;
+	case GXorInverted:
+		dispatch->glLogicOp(GL_OR_INVERTED);
+		break;
+	case GXnand:
+		dispatch->glLogicOp(GL_NAND);
+		break;
+	case GXset:
+		dispatch->glLogicOp(GL_SET);
+		break;
+	default:
+		FatalError("unknown logic op\n");
+	}
 #else
- if (alu != GXcopy)
-  ErrorF("unsupported alu %x \n", alu);
+	if (alu != GXcopy)
+		ErrorF("unsupported alu %x \n", alu);
 #endif
 }
 
@@ -203,60 +208,62 @@ glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
  * This texture may not be the one attached to it.
  **/
 int in_restore = 0;
-static void 
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex)
+static void
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
+				  GLenum type, GLuint tex)
 {
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  unsigned int stride, row_length;
-  void *texels;
-  GLenum iformat;
-
-  switch (pixmap->drawable.depth) {
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	unsigned int stride, row_length;
+	void *texels;
+	GLenum iformat;
+
+	switch (pixmap->drawable.depth) {
 #if 0
-    case 8:
-        iformat = GL_ALPHA;
-        break;
+	case 8:
+		iformat = GL_ALPHA;
+		break;
 #endif
-    case 24:
-        iformat = GL_RGB;
-        break; 
-    default:
-        iformat = GL_RGBA;
-        break;
-    }
-
-  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-    iformat = format;
-  }
-
-  stride = pixmap->devKind;
-  row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-
-  dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
-  if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-  } 
-  else {
-    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-  }
-
-  if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
-    texels = NULL;
-    dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
-  }
-  else
-    texels = pixmap->devPrivate.ptr;
-
-  dispatch->glTexImage2D(GL_TEXTURE_2D, 
-	       0, 
-	       iformat,
-	       pixmap->drawable.width, 
-	       pixmap->drawable.height, 0,
-	       format, type, texels);
+	case 24:
+		iformat = GL_RGB;
+		break;
+	default:
+		iformat = GL_RGBA;
+		break;
+	}
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		iformat = format;
+	}
+
+	stride = pixmap->devKind;
+	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+	} else {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	}
+
+	if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
+		texels = NULL;
+		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
+				       pixmap_priv->pbo);
+	} else
+		texels = pixmap->devPrivate.ptr;
+
+	dispatch->glTexImage2D(GL_TEXTURE_2D,
+			       0,
+			       iformat,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height, 0, format, type,
+			       texels);
 }
 
 
@@ -266,118 +273,142 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
  * */
 
 static void
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, 
-                                 GLenum type, int no_alpha, int no_revert, 
-                                 int flip)
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
+				 GLenum type, int no_alpha, int no_revert,
+				 int flip)
 {
 
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv =
-    glamor_get_screen_private(pixmap->drawable.pScreen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  static float vertices[8] = {-1, -1,
-			      1, -1,
-			      1,  1,
-			      -1,  1};
-  static float texcoords[8] = {0, 1,
-			       1, 1,
-			       1, 0,
-			       0, 0};
-  static float texcoords_inv[8] = {0, 0,
-				   1, 0,
-				   1, 1,
-				   0, 1};
-  float *ptexcoords;
-
-  GLuint tex;
-  int need_flip;
-  need_flip = (flip && !glamor_priv->yInverted);
-
-  /* Try fast path firstly, upload the pixmap to the texture attached
-   * to the fbo directly. */
-  if (no_alpha == 0 && no_revert == 1 && !need_flip) {
-    __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex);
-    return;
-  }
-
-
-  if (need_flip)
-    ptexcoords = texcoords;
-  else
-    ptexcoords = texcoords_inv;
-
-  /* Slow path, we need to flip y or wire alpha to 1. */
-  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        vertices);
-  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        ptexcoords);
-  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-  dispatch->glGenTextures(1, &tex);
-
-  __glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
-  dispatch->glActiveTexture(GL_TEXTURE0);
-  dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
-  dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	static float vertices[8] = { -1, -1,
+		1, -1,
+		1, 1,
+		-1, 1
+	};
+	static float texcoords[8] = { 0, 1,
+		1, 1,
+		1, 0,
+		0, 0
+	};
+	static float texcoords_inv[8] = { 0, 0,
+		1, 0,
+		1, 1,
+		0, 1
+	};
+	float *ptexcoords;
+
+	GLuint tex;
+	int need_flip;
+	need_flip = (flip && !glamor_priv->yInverted);
+
+	/* Try fast path firstly, upload the pixmap to the texture attached
+	 * to the fbo directly. */
+	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
+		__glamor_upload_pixmap_to_texture(pixmap, format, type,
+						  pixmap_priv->tex);
+		return;
+	}
+
+
+	if (need_flip)
+		ptexcoords = texcoords;
+	else
+		ptexcoords = texcoords_inv;
+
+	/* Slow path, we need to flip y or wire alpha to 1. */
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					ptexcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	dispatch->glGenTextures(1, &tex);
+
+	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
 #ifndef GLAMOR_GLES2
-  dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-  dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0);
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUniform1i(glamor_priv->
+			      finish_access_no_revert[no_alpha],
+			      no_revert);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+			      0);
 
-  dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 #ifndef GLAMOR_GLES2
-  dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-  dispatch->glUseProgram(0);
-  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-  dispatch->glDeleteTextures(1, &tex);
-  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+	dispatch->glUseProgram(0);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDeleteTextures(1, &tex);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
 void
 glamor_pixmap_ensure_fb(PixmapPtr pixmap)
 {
-  int status;
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
-  if (pixmap_priv->fb == 0)
-    dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
-  assert(pixmap_priv->tex != 0);
-  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-  dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
-                         GL_COLOR_ATTACHMENT0,
-			 GL_TEXTURE_2D,
-			 pixmap_priv->tex,
-			 0);
-    status = dispatch->glCheckFramebufferStatus (GL_FRAMEBUFFER);
-    if (status != GL_FRAMEBUFFER_COMPLETE) {
-        const char *str;
-        switch (status) {
-        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str= "incomplete attachment"; break;
-        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str= "incomplete/missing attachment"; break;
-        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str= "incomplete draw buffer"; break;
-        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str= "incomplete read buffer"; break;
-        case GL_FRAMEBUFFER_UNSUPPORTED: str= "unsupported"; break;
-        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str= "incomplete multiple"; break;
-        default: str = "unknown error"; break;
-        }
-
-        LogMessageVerb(X_INFO, 0,
-                 "destination is framebuffer incomplete: %s [%#x]\n",
-                 str, status);
-        assert(0);
-    }
+	int status;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+
+	if (pixmap_priv->fb == 0)
+		dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
+	assert(pixmap_priv->tex != 0);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
+					 GL_COLOR_ATTACHMENT0,
+					 GL_TEXTURE_2D, pixmap_priv->tex,
+					 0);
+	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+	if (status != GL_FRAMEBUFFER_COMPLETE) {
+		const char *str;
+		switch (status) {
+		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+			str = "incomplete attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+			str = "incomplete/missing attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+			str = "incomplete draw buffer";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+			str = "incomplete read buffer";
+			break;
+		case GL_FRAMEBUFFER_UNSUPPORTED:
+			str = "unsupported";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+			str = "incomplete multiple";
+			break;
+		default:
+			str = "unknown error";
+			break;
+		}
+
+		LogMessageVerb(X_INFO, 0,
+			       "destination is framebuffer incomplete: %s [%#x]\n",
+			       str, status);
+		assert(0);
+	}
 }
 
 /*  
@@ -390,102 +421,115 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
 static int
 glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 {
-  int need_fbo;
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-  if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) 
-      || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
-    glamor_fallback("upload failed reason: bad size or depth %d x %d @depth %d \n",
-		    pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth);
-    return -1;
-  }
-
-  if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 
-    return 0; 
-
-  if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
-    need_fbo = 1;
-  else
-    need_fbo = 0;
-
-  if (pixmap_priv->tex == 0) 
-    dispatch->glGenTextures(1, &pixmap_priv->tex);
-
-  if (need_fbo) {
-    dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
-		 pixmap->drawable.height, 0,
-		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-    glamor_pixmap_ensure_fb(pixmap);
-  }
- 
-  return 0;
+	int need_fbo;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	if (!glamor_check_fbo_size
+	    (glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
+	    || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
+		glamor_fallback
+		    ("upload failed reason: bad size or depth %d x %d @depth %d \n",
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     pixmap->drawable.depth);
+		return -1;
+	}
+
+	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return 0;
+
+	if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
+		need_fbo = 1;
+	else
+		need_fbo = 0;
+
+	if (pixmap_priv->tex == 0)
+		dispatch->glGenTextures(1, &pixmap_priv->tex);
+
+	if (need_fbo) {
+		dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height, 0, GL_RGBA,
+				       GL_UNSIGNED_BYTE, NULL);
+		glamor_pixmap_ensure_fb(pixmap);
+	}
+
+	return 0;
 }
- 
-enum glamor_pixmap_status 
+
+enum glamor_pixmap_status
 glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 {
-  GLenum format, type;
-  int no_alpha, no_revert;
-
-  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
-					     &format, 
-					     &type, 
-					     &no_alpha,
-                                             &no_revert)) {
-    glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
-    return GLAMOR_UPLOAD_FAILED;
-  }
-  if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
-    return GLAMOR_UPLOAD_FAILED;
-  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
-		      "Uploading pixmap %p  %dx%d depth%d.\n", 
-		      pixmap, 
-		      pixmap->drawable.width, 
-		      pixmap->drawable.height,
-		      pixmap->drawable.depth);
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1);
-  return GLAMOR_UPLOAD_DONE;
+	GLenum format, type;
+	int no_alpha, no_revert;
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("Unknown pixmap depth %d.\n",
+				pixmap->drawable.depth);
+		return GLAMOR_UPLOAD_FAILED;
+	}
+	if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
+		return GLAMOR_UPLOAD_FAILED;
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
+			    "Uploading pixmap %p  %dx%d depth%d.\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					 no_revert, 1);
+	return GLAMOR_UPLOAD_DONE;
 }
 
 #if 0
-enum glamor_pixmap_status 
+enum glamor_pixmap_status
 glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
 {
-  enum glamor_pixmap_status upload_status;
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-  assert(pixmap_priv->pbo_valid == 0);
-  assert(pixmap->devPrivate.ptr == NULL);
-  pixmap->devPrivate.ptr = data;
-  upload_status = glamor_upload_pixmap_to_texture(pixmap);
-  pixmap->devPrivate.ptr = NULL;
-  return upload_status;
+	enum glamor_pixmap_status upload_status;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+
+	assert(pixmap_priv->pbo_valid == 0);
+	assert(pixmap->devPrivate.ptr == NULL);
+	pixmap->devPrivate.ptr = data;
+	upload_status = glamor_upload_pixmap_to_texture(pixmap);
+	pixmap->devPrivate.ptr = NULL;
+	return upload_status;
 }
 #endif
 
 void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
-  GLenum format, type;
-  int no_alpha, no_revert;
-
-  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
-					     &format, 
-					     &type, 
-					     &no_alpha, 
-                                             &no_revert)) {
-    ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
-    assert(0);
-  }
-
-  in_restore = 1;
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1);
-  in_restore = 0;
+	GLenum format, type;
+	int no_alpha, no_revert;
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		ErrorF("Unknown pixmap depth %d.\n",
+		       pixmap->drawable.depth);
+		assert(0);
+	}
+
+	in_restore = 1;
+	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					 no_revert, 1);
+	in_restore = 0;
 }
 
 /* 
@@ -497,77 +541,82 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
  * */
 
 PixmapPtr
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, 
-                               GLenum *type, int no_alpha, int no_revert)
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
+			       GLenum * type, int no_alpha, int no_revert)
 {
-    glamor_pixmap_private *source_priv;
-    glamor_screen_private *glamor_priv;
-    ScreenPtr screen;
-    PixmapPtr temp_pixmap;
-    glamor_pixmap_private *temp_pixmap_priv;
-    glamor_gl_dispatch *dispatch;
-    static float vertices[8] = {-1, -1,
-			      1, -1,
-			      1,  1,
-			      -1,  1};
-    static float texcoords[8] = {0, 0,
-				   1, 0,
-				   1, 1,
-				   0, 1};
-
-    int swap_rb = 0;
-
-    screen = source->drawable.pScreen;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    source_priv = glamor_get_pixmap_private(source);
-    dispatch = &glamor_priv->dispatch;
-    if (*format == GL_BGRA) {
-      *format = GL_RGBA;
-      swap_rb = 1;
-    }
-
-
-    temp_pixmap = (*screen->CreatePixmap)(screen,
-			                  source->drawable.width,
-					  source->drawable.height,
-					  source->drawable.depth,
-					  0);
-
-    temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-
-    dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, 
-		 source->drawable.height, 0,
-		 *format, *type, NULL);
-    
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
-
-    glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
-
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
-
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glUseProgram(0);
-    return temp_pixmap; 
+	glamor_pixmap_private *source_priv;
+	glamor_screen_private *glamor_priv;
+	ScreenPtr screen;
+	PixmapPtr temp_pixmap;
+	glamor_pixmap_private *temp_pixmap_priv;
+	glamor_gl_dispatch *dispatch;
+	static float vertices[8] = { -1, -1,
+		1, -1,
+		1, 1,
+		-1, 1
+	};
+	static float texcoords[8] = { 0, 0,
+		1, 0,
+		1, 1,
+		0, 1
+	};
+
+	int swap_rb = 0;
+
+	screen = source->drawable.pScreen;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	source_priv = glamor_get_pixmap_private(source);
+	dispatch = &glamor_priv->dispatch;
+	if (*format == GL_BGRA) {
+		*format = GL_RGBA;
+		swap_rb = 1;
+	}
+
+
+	temp_pixmap = (*screen->CreatePixmap) (screen,
+					       source->drawable.width,
+					       source->drawable.height,
+					       source->drawable.depth, 0);
+
+	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+
+	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
+			       source->drawable.width,
+			       source->drawable.height, 0, *format, *type,
+			       NULL);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					texcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+
+	glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
+
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUniform1i(glamor_priv->
+			      finish_access_no_revert[no_alpha],
+			      no_revert);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+			      swap_rb);
+
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	return temp_pixmap;
 }
- 
+
 
 /**
  * Move a pixmap to CPU memory.
@@ -579,174 +628,194 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
  * Otherwise return FALSE.
  **/
 
-Bool 
+Bool
 glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 {
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  unsigned int stride, row_length, y;
-  GLenum format, type, gl_access, gl_usage;
-  int no_alpha, no_revert;
-  uint8_t *data = NULL, *read;
-  PixmapPtr temp_pixmap = NULL;
-  ScreenPtr screen;
-  glamor_screen_private *glamor_priv =
-    glamor_get_screen_private(pixmap->drawable.pScreen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  
-  screen = pixmap->drawable.pScreen;
-  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-    return TRUE;
-  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
-					     &format,
-					     &type, 
-					     &no_alpha,
-                                             &no_revert)) {
-    ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
-    assert(0);  // Should never happen.
-    return FALSE;
-  }
-
-  pixmap_priv->access_mode = access;
-  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
-		      "Downloading pixmap %p  %dx%d depth%d\n", 
-		      pixmap, 
-		      pixmap->drawable.width, 
-		      pixmap->drawable.height,
-		      pixmap->drawable.depth);
-
-  stride = pixmap->devKind;
-
-  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-  /* XXX we may don't need to validate it on GPU here,
-   * we can just validate it on CPU. */
-  glamor_validate_pixmap(pixmap); 
- 
-  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
-    && ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA) || no_revert != 1)) {
-    
-    temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, &type, no_alpha, no_revert);
-
-  } 
- switch (access) {
-  case GLAMOR_ACCESS_RO:
-    gl_access = GL_READ_ONLY;
-    gl_usage = GL_STREAM_READ;
-    break;
-  case GLAMOR_ACCESS_WO:
-    data = malloc(stride * pixmap->drawable.height);
-    goto done;
-    break;
-  case GLAMOR_ACCESS_RW:
-    gl_access = GL_READ_WRITE;
-    gl_usage = GL_DYNAMIC_DRAW;
-    break;
-  default:
-    ErrorF("Glamor: Invalid access code. %d\n", access);
-    assert(0);
-  }
-  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-    data = malloc(stride * pixmap->drawable.height);
-  }
-  row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-
-  if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
-  }
-  else {
-    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-  //  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-  }
-  if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
-
-    if (!glamor_priv->yInverted) {
-      assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); 
-      dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
-    }
-    
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-    if (pixmap_priv->pbo == 0)
-      dispatch->glGenBuffers (1, &pixmap_priv->pbo);
-    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
-    dispatch->glBufferData (GL_PIXEL_PACK_BUFFER,
-		     stride * pixmap->drawable.height,
-		     NULL, gl_usage);
-    dispatch->glReadPixels (0, 0,
-                    row_length, pixmap->drawable.height,
-                    format, type, 0);
-    data = dispatch->glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
-    pixmap_priv->pbo_valid = TRUE;
-
-    if (!glamor_priv->yInverted) {
-      assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-      dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
-    }
-    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
-
-    } else {
-    if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
-      type = GL_UNSIGNED_SHORT_5_5_5_1;
-    dispatch->glReadPixels (0, 0,
-                    pixmap->drawable.width, pixmap->drawable.height,
-                    format, type, data);
-    }
-  } else {
-    data = malloc(stride * pixmap->drawable.height);
-    assert(data);
-    if (access != GLAMOR_ACCESS_WO) {
-      if (pixmap_priv->pbo == 0)
-	dispatch->glGenBuffers(1, &pixmap_priv->pbo);
-      dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
-      dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
-		      stride * pixmap->drawable.height,
-		      NULL, GL_STREAM_READ);
-      dispatch->glReadPixels (0, 0, row_length, pixmap->drawable.height,
-		    format, type, 0);
-      read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
-	  
-      for (y = 0; y < pixmap->drawable.height; y++)
-	memcpy(data + y * stride,
-	       read + (pixmap->drawable.height - y - 1) * stride, stride);
-      dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
-      dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-      pixmap_priv->pbo_valid = FALSE;
-      dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-      pixmap_priv->pbo = 0;
-    }
-  }
-
-  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
-done:
-  pixmap->devPrivate.ptr = data;
-
-  if (temp_pixmap) { 
-      (*screen->DestroyPixmap)(temp_pixmap);
-  }
-
-  return TRUE;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	unsigned int stride, row_length, y;
+	GLenum format, type, gl_access, gl_usage;
+	int no_alpha, no_revert;
+	uint8_t *data = NULL, *read;
+	PixmapPtr temp_pixmap = NULL;
+	ScreenPtr screen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	screen = pixmap->drawable.pScreen;
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return TRUE;
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		ErrorF("Unknown pixmap depth %d.\n",
+		       pixmap->drawable.depth);
+		assert(0);	// Should never happen.
+		return FALSE;
+	}
+
+	pixmap_priv->access_mode = access;
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+			    "Downloading pixmap %p  %dx%d depth%d\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+
+	stride = pixmap->devKind;
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	/* XXX we may don't need to validate it on GPU here,
+	 * we can just validate it on CPU. */
+	glamor_validate_pixmap(pixmap);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    &&
+	    ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA)
+	     || no_revert != 1)) {
+
+		temp_pixmap =
+		    glamor_es2_pixmap_read_prepare(pixmap, &format,
+						   &type, no_alpha,
+						   no_revert);
+
+	}
+	switch (access) {
+	case GLAMOR_ACCESS_RO:
+		gl_access = GL_READ_ONLY;
+		gl_usage = GL_STREAM_READ;
+		break;
+	case GLAMOR_ACCESS_WO:
+		data = malloc(stride * pixmap->drawable.height);
+		goto done;
+		break;
+	case GLAMOR_ACCESS_RW:
+		gl_access = GL_READ_WRITE;
+		gl_usage = GL_DYNAMIC_DRAW;
+		break;
+	default:
+		ErrorF("Glamor: Invalid access code. %d\n", access);
+		assert(0);
+	}
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		data = malloc(stride * pixmap->drawable.height);
+	}
+	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+	} else {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+		//  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+	}
+	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
+
+		if (!glamor_priv->yInverted) {
+			assert(glamor_priv->gl_flavor ==
+			       GLAMOR_GL_DESKTOP);
+			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
+		}
+
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+			if (pixmap_priv->pbo == 0)
+				dispatch->glGenBuffers(1,
+						       &pixmap_priv->pbo);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
+					       pixmap_priv->pbo);
+			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+					       stride *
+					       pixmap->drawable.height,
+					       NULL, gl_usage);
+			dispatch->glReadPixels(0, 0, row_length,
+					       pixmap->drawable.height,
+					       format, type, 0);
+			data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+						     gl_access);
+			pixmap_priv->pbo_valid = TRUE;
+
+			if (!glamor_priv->yInverted) {
+				assert(glamor_priv->gl_flavor ==
+				       GLAMOR_GL_DESKTOP);
+				dispatch->glPixelStorei
+				    (GL_PACK_INVERT_MESA, 0);
+			}
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+		} else {
+			if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
+				type = GL_UNSIGNED_SHORT_5_5_5_1;
+			dispatch->glReadPixels(0, 0,
+					       pixmap->drawable.width,
+					       pixmap->drawable.height,
+					       format, type, data);
+		}
+	} else {
+		data = malloc(stride * pixmap->drawable.height);
+		assert(data);
+		if (access != GLAMOR_ACCESS_WO) {
+			if (pixmap_priv->pbo == 0)
+				dispatch->glGenBuffers(1,
+						       &pixmap_priv->pbo);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
+					       pixmap_priv->pbo);
+			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+					       stride *
+					       pixmap->drawable.height,
+					       NULL, GL_STREAM_READ);
+			dispatch->glReadPixels(0, 0, row_length,
+					       pixmap->drawable.height,
+					       format, type, 0);
+			read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+						     GL_READ_ONLY);
+
+			for (y = 0; y < pixmap->drawable.height; y++)
+				memcpy(data + y * stride,
+				       read + (pixmap->drawable.height -
+					       y - 1) * stride, stride);
+			dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+			pixmap_priv->pbo_valid = FALSE;
+			dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
+			pixmap_priv->pbo = 0;
+		}
+	}
+
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+      done:
+	pixmap->devPrivate.ptr = data;
+
+	if (temp_pixmap) {
+		(*screen->DestroyPixmap) (temp_pixmap);
+	}
+
+	return TRUE;
 }
 
 
 
-static void 
+static void
 _glamor_destroy_upload_pixmap(PixmapPtr pixmap)
 {
-  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
-
-  assert(pixmap_priv->gl_fbo == 0);
-  if (pixmap_priv->fb)
-    dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
-  if (pixmap_priv->tex)
-    dispatch->glDeleteTextures(1, &pixmap_priv->tex);
-  if (pixmap_priv->pbo)
-    dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
-  pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+
+	assert(pixmap_priv->gl_fbo == 0);
+	if (pixmap_priv->fb)
+		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
+	if (pixmap_priv->tex)
+		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
+	if (pixmap_priv->pbo)
+		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
+	pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
 
 }
 
-void glamor_destroy_upload_pixmap(PixmapPtr pixmap)
+void
+glamor_destroy_upload_pixmap(PixmapPtr pixmap)
 {
-  _glamor_destroy_upload_pixmap(pixmap);
+	_glamor_destroy_upload_pixmap(pixmap);
 }
-
diff --git a/glamor/glamor_pixmap.indent.c b/glamor/glamor_pixmap.indent.c
new file mode 100644
index 0000000..f02acc7
--- /dev/null
+++ b/glamor/glamor_pixmap.indent.c
@@ -0,0 +1,821 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+/**
+ * Sets the offsets to add to coordinates to make them address the same bits in
+ * the backing drawable. These coordinates are nonzero only for redirected
+ * windows.
+ */
+void
+glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
+			   int *x, int *y)
+{
+#ifdef COMPOSITE
+	if (drawable->type == DRAWABLE_WINDOW) {
+		*x = -pixmap->screen_x;
+		*y = -pixmap->screen_y;
+		return;
+	}
+#endif
+
+	*x = 0;
+	*y = 0;
+}
+
+
+static void
+_glamor_pixmap_validate_filling(glamor_screen_private * glamor_priv,
+				glamor_pixmap_private * pixmap_priv)
+{
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	GLfloat vertices[8];
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(glamor_priv->solid_prog);
+	dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
+			       1, pixmap_priv->pending_op.fill.color4fv);
+	vertices[0] = -1;
+	vertices[1] = -1;
+	vertices[2] = 1;
+	vertices[3] = -1;
+	vertices[4] = 1;
+	vertices[5] = 1;
+	vertices[6] = -1;
+	vertices[7] = 1;
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
+}
+
+
+glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
+	NULL,
+	_glamor_pixmap_validate_filling
+};
+
+void
+glamor_pixmap_init(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
+}
+
+void
+glamor_validate_pixmap(PixmapPtr pixmap)
+{
+	glamor_pixmap_validate_function_t validate_op;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+
+	validate_op =
+	    glamor_priv->pixmap_validate_funcs[pixmap_priv->
+					       pending_op.type];
+	if (validate_op) {
+		(*validate_op) (glamor_priv, pixmap_priv);
+	}
+}
+
+void
+glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
+{
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+#ifndef GLAMOR_GLES2
+	dispatch->glMatrixMode(GL_PROJECTION);
+	dispatch->glLoadIdentity();
+	dispatch->glMatrixMode(GL_MODELVIEW);
+	dispatch->glLoadIdentity();
+#endif
+	dispatch->glViewport(0, 0,
+			     pixmap_priv->container->drawable.width,
+			     pixmap_priv->container->drawable.height);
+
+}
+
+int
+glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
+{
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return -1;
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	return 0;
+}
+
+int
+glamor_set_destination_pixmap(PixmapPtr pixmap)
+{
+	int err;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+
+	err = glamor_set_destination_pixmap_priv(pixmap_priv);
+	return err;
+}
+
+Bool
+glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
+{
+	if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+		return GL_TRUE;
+	}
+
+	glamor_fallback("unsupported planemask %lx\n", planemask);
+	return GL_FALSE;
+}
+
+
+
+void
+glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
+{
+#ifndef GLAMOR_GLES2
+	if (alu == GXcopy) {
+		dispatch->glDisable(GL_COLOR_LOGIC_OP);
+		return;
+	}
+	dispatch->glEnable(GL_COLOR_LOGIC_OP);
+	switch (alu) {
+	case GXclear:
+		dispatch->glLogicOp(GL_CLEAR);
+		break;
+	case GXand:
+		dispatch->glLogicOp(GL_AND);
+		break;
+	case GXandReverse:
+		dispatch->glLogicOp(GL_AND_REVERSE);
+		break;
+	case GXandInverted:
+		dispatch->glLogicOp(GL_AND_INVERTED);
+		break;
+	case GXnoop:
+		dispatch->glLogicOp(GL_NOOP);
+		break;
+	case GXxor:
+		dispatch->glLogicOp(GL_XOR);
+		break;
+	case GXor:
+		dispatch->glLogicOp(GL_OR);
+		break;
+	case GXnor:
+		dispatch->glLogicOp(GL_NOR);
+		break;
+	case GXequiv:
+		dispatch->glLogicOp(GL_EQUIV);
+		break;
+	case GXinvert:
+		dispatch->glLogicOp(GL_INVERT);
+		break;
+	case GXorReverse:
+		dispatch->glLogicOp(GL_OR_REVERSE);
+		break;
+	case GXcopyInverted:
+		dispatch->glLogicOp(GL_COPY_INVERTED);
+		break;
+	case GXorInverted:
+		dispatch->glLogicOp(GL_OR_INVERTED);
+		break;
+	case GXnand:
+		dispatch->glLogicOp(GL_NAND);
+		break;
+	case GXset:
+		dispatch->glLogicOp(GL_SET);
+		break;
+	default:
+		FatalError("unknown logic op\n");
+	}
+#else
+	if (alu != GXcopy)
+		ErrorF("unsupported alu %x \n", alu);
+#endif
+}
+
+
+
+
+/**
+ * Upload pixmap to a specified texture.
+ * This texture may not be the one attached to it.
+ **/
+int in_restore = 0;
+static void
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
+				  GLenum type, GLuint tex)
+{
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	unsigned int stride, row_length;
+	void *texels;
+	GLenum iformat;
+
+	switch (pixmap->drawable.depth) {
+#if 0
+	case 8:
+		iformat = GL_ALPHA;
+		break;
+#endif
+	case 24:
+		iformat = GL_RGB;
+		break;
+	default:
+		iformat = GL_RGBA;
+		break;
+	}
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		iformat = format;
+	}
+
+	stride = pixmap->devKind;
+	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+	} else {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	}
+
+	if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
+		texels = NULL;
+		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
+				       pixmap_priv->pbo);
+	} else
+		texels = pixmap->devPrivate.ptr;
+
+	dispatch->glTexImage2D(GL_TEXTURE_2D,
+			       0,
+			       iformat,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height, 0, format, type,
+			       texels);
+}
+
+
+/* 
+ * Load texture from the pixmap's data pointer and then
+ * draw the texture to the fbo, and flip the y axis.
+ * */
+
+static void
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
+				 GLenum type, int no_alpha, int no_revert,
+				 int flip)
+{
+
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	static float vertices[8] = { -1, -1,
+		1, -1,
+		1, 1,
+		-1, 1
+	};
+	static float texcoords[8] = { 0, 1,
+		1, 1,
+		1, 0,
+		0, 0
+	};
+	static float texcoords_inv[8] = { 0, 0,
+		1, 0,
+		1, 1,
+		0, 1
+	};
+	float *ptexcoords;
+
+	GLuint tex;
+	int need_flip;
+	need_flip = (flip && !glamor_priv->yInverted);
+
+	/* Try fast path firstly, upload the pixmap to the texture attached
+	 * to the fbo directly. */
+	if (no_alpha == 0 && no_revert == 1 && !need_flip) {
+		__glamor_upload_pixmap_to_texture(pixmap, format, type,
+						  pixmap_priv->tex);
+		return;
+	}
+
+
+	if (need_flip)
+		ptexcoords = texcoords;
+	else
+		ptexcoords = texcoords_inv;
+
+	/* Slow path, we need to flip y or wire alpha to 1. */
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					ptexcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	dispatch->glGenTextures(1, &tex);
+
+	__glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+#ifndef GLAMOR_GLES2
+	dispatch->glEnable(GL_TEXTURE_2D);
+#endif
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUniform1i(glamor_priv->
+			      finish_access_no_revert[no_alpha],
+			      no_revert);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+			      0);
+
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+#ifndef GLAMOR_GLES2
+	dispatch->glDisable(GL_TEXTURE_2D);
+#endif
+	dispatch->glUseProgram(0);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDeleteTextures(1, &tex);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void
+glamor_pixmap_ensure_fb(PixmapPtr pixmap)
+{
+	int status;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+
+	if (pixmap_priv->fb == 0)
+		dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
+	assert(pixmap_priv->tex != 0);
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+	dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
+					 GL_COLOR_ATTACHMENT0,
+					 GL_TEXTURE_2D, pixmap_priv->tex,
+					 0);
+	status = dispatch->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+	if (status != GL_FRAMEBUFFER_COMPLETE) {
+		const char *str;
+		switch (status) {
+		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+			str = "incomplete attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+			str = "incomplete/missing attachment";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+			str = "incomplete draw buffer";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+			str = "incomplete read buffer";
+			break;
+		case GL_FRAMEBUFFER_UNSUPPORTED:
+			str = "unsupported";
+			break;
+		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+			str = "incomplete multiple";
+			break;
+		default:
+			str = "unknown error";
+			break;
+		}
+
+		LogMessageVerb(X_INFO, 0,
+			       "destination is framebuffer incomplete: %s [%#x]\n",
+			       str, status);
+		assert(0);
+	}
+}
+
+/*  
+ * Prepare to upload a pixmap to texture memory.
+ * no_alpha equals 1 means the format needs to wire alpha to 1.
+ * Two condtion need to setup a fbo for a pixmap
+ * 1. !yInverted, we need to do flip if we are not yInverted.
+ * 2. no_alpha != 0, we need to wire the alpha.
+ * */
+static int
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
+{
+	int need_fbo;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	if (!glamor_check_fbo_size
+	    (glamor_priv, pixmap->drawable.width, pixmap->drawable.height)
+	    || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
+		glamor_fallback
+		    ("upload failed reason: bad size or depth %d x %d @depth %d \n",
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     pixmap->drawable.depth);
+		return -1;
+	}
+
+	if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return 0;
+
+	if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
+		need_fbo = 1;
+	else
+		need_fbo = 0;
+
+	if (pixmap_priv->tex == 0)
+		dispatch->glGenTextures(1, &pixmap_priv->tex);
+
+	if (need_fbo) {
+		dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height, 0, GL_RGBA,
+				       GL_UNSIGNED_BYTE, NULL);
+		glamor_pixmap_ensure_fb(pixmap);
+	}
+
+	return 0;
+}
+
+enum glamor_pixmap_status
+glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
+{
+	GLenum format, type;
+	int no_alpha, no_revert;
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("Unknown pixmap depth %d.\n",
+				pixmap->drawable.depth);
+		return GLAMOR_UPLOAD_FAILED;
+	}
+	if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
+		return GLAMOR_UPLOAD_FAILED;
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
+			    "Uploading pixmap %p  %dx%d depth%d.\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					 no_revert, 1);
+	return GLAMOR_UPLOAD_DONE;
+}
+
+#if 0
+enum glamor_pixmap_status
+glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
+{
+	enum glamor_pixmap_status upload_status;
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+
+	assert(pixmap_priv->pbo_valid == 0);
+	assert(pixmap->devPrivate.ptr == NULL);
+	pixmap->devPrivate.ptr = data;
+	upload_status = glamor_upload_pixmap_to_texture(pixmap);
+	pixmap->devPrivate.ptr = NULL;
+	return upload_status;
+}
+#endif
+
+void
+glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
+{
+	GLenum format, type;
+	int no_alpha, no_revert;
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		ErrorF("Unknown pixmap depth %d.\n",
+		       pixmap->drawable.depth);
+		assert(0);
+	}
+
+	in_restore = 1;
+	_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
+					 no_revert, 1);
+	in_restore = 0;
+}
+
+/* 
+ * as gles2 only support a very small set of color format and
+ * type when do glReadPixel,  
+ * Before we use glReadPixels to get back a textured pixmap, 
+ * Use shader to convert it to a supported format and thus
+ * get a new temporary pixmap returned.
+ * */
+
+PixmapPtr
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
+			       GLenum * type, int no_alpha, int no_revert)
+{
+	glamor_pixmap_private *source_priv;
+	glamor_screen_private *glamor_priv;
+	ScreenPtr screen;
+	PixmapPtr temp_pixmap;
+	glamor_pixmap_private *temp_pixmap_priv;
+	glamor_gl_dispatch *dispatch;
+	static float vertices[8] = { -1, -1,
+		1, -1,
+		1, 1,
+		-1, 1
+	};
+	static float texcoords[8] = { 0, 0,
+		1, 0,
+		1, 1,
+		0, 1
+	};
+
+	int swap_rb = 0;
+
+	screen = source->drawable.pScreen;
+
+	glamor_priv = glamor_get_screen_private(screen);
+	source_priv = glamor_get_pixmap_private(source);
+	dispatch = &glamor_priv->dispatch;
+	if (*format == GL_BGRA) {
+		*format = GL_RGBA;
+		swap_rb = 1;
+	}
+
+
+	temp_pixmap = (*screen->CreatePixmap) (screen,
+					       source->drawable.width,
+					       source->drawable.height,
+					       source->drawable.depth, 0);
+
+	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+
+	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
+			       source->drawable.width,
+			       source->drawable.height, 0, *format, *type,
+			       NULL);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					texcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+
+	glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
+
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUniform1i(glamor_priv->
+			      finish_access_no_revert[no_alpha],
+			      no_revert);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+			      swap_rb);
+
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glUseProgram(0);
+	return temp_pixmap;
+}
+
+
+/**
+ * Move a pixmap to CPU memory.
+ * The input data is the pixmap's fbo.
+ * The output data is at pixmap->devPrivate.ptr. We always use pbo 
+ * to read the fbo and then map it to va. If possible, we will use
+ * it directly as devPrivate.ptr.
+ * If successfully download a fbo to cpu then return TRUE.
+ * Otherwise return FALSE.
+ **/
+
+Bool
+glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
+{
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	unsigned int stride, row_length, y;
+	GLenum format, type, gl_access, gl_usage;
+	int no_alpha, no_revert;
+	uint8_t *data = NULL, *read;
+	PixmapPtr temp_pixmap = NULL;
+	ScreenPtr screen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(pixmap->drawable.pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	screen = pixmap->drawable.pScreen;
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+		return TRUE;
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		ErrorF("Unknown pixmap depth %d.\n",
+		       pixmap->drawable.depth);
+		assert(0);	// Should never happen.
+		return FALSE;
+	}
+
+	pixmap_priv->access_mode = access;
+	glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+			    "Downloading pixmap %p  %dx%d depth%d\n",
+			    pixmap,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    pixmap->drawable.depth);
+
+	stride = pixmap->devKind;
+
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	/* XXX we may don't need to validate it on GPU here,
+	 * we can just validate it on CPU. */
+	glamor_validate_pixmap(pixmap);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+	    &&
+	    ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA)
+	     || no_revert != 1)) {
+
+		temp_pixmap =
+		    glamor_es2_pixmap_read_prepare(pixmap, &format,
+						   &type, no_alpha,
+						   no_revert);
+
+	}
+	switch (access) {
+	case GLAMOR_ACCESS_RO:
+		gl_access = GL_READ_ONLY;
+		gl_usage = GL_STREAM_READ;
+		break;
+	case GLAMOR_ACCESS_WO:
+		data = malloc(stride * pixmap->drawable.height);
+		goto done;
+		break;
+	case GLAMOR_ACCESS_RW:
+		gl_access = GL_READ_WRITE;
+		gl_usage = GL_DYNAMIC_DRAW;
+		break;
+	default:
+		ErrorF("Glamor: Invalid access code. %d\n", access);
+		assert(0);
+	}
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		data = malloc(stride * pixmap->drawable.height);
+	}
+	row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+		dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+	} else {
+		dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+		//  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+	}
+	if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
+
+		if (!glamor_priv->yInverted) {
+			assert(glamor_priv->gl_flavor ==
+			       GLAMOR_GL_DESKTOP);
+			dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
+		}
+
+		if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+			if (pixmap_priv->pbo == 0)
+				dispatch->glGenBuffers(1,
+						       &pixmap_priv->pbo);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
+					       pixmap_priv->pbo);
+			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+					       stride *
+					       pixmap->drawable.height,
+					       NULL, gl_usage);
+			dispatch->glReadPixels(0, 0, row_length,
+					       pixmap->drawable.height,
+					       format, type, 0);
+			data = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+						     gl_access);
+			pixmap_priv->pbo_valid = TRUE;
+
+			if (!glamor_priv->yInverted) {
+				assert(glamor_priv->gl_flavor ==
+				       GLAMOR_GL_DESKTOP);
+				dispatch->glPixelStorei
+				    (GL_PACK_INVERT_MESA, 0);
+			}
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+		} else {
+			if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
+				type = GL_UNSIGNED_SHORT_5_5_5_1;
+			dispatch->glReadPixels(0, 0,
+					       pixmap->drawable.width,
+					       pixmap->drawable.height,
+					       format, type, data);
+		}
+	} else {
+		data = malloc(stride * pixmap->drawable.height);
+		assert(data);
+		if (access != GLAMOR_ACCESS_WO) {
+			if (pixmap_priv->pbo == 0)
+				dispatch->glGenBuffers(1,
+						       &pixmap_priv->pbo);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
+					       pixmap_priv->pbo);
+			dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+					       stride *
+					       pixmap->drawable.height,
+					       NULL, GL_STREAM_READ);
+			dispatch->glReadPixels(0, 0, row_length,
+					       pixmap->drawable.height,
+					       format, type, 0);
+			read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
+						     GL_READ_ONLY);
+
+			for (y = 0; y < pixmap->drawable.height; y++)
+				memcpy(data + y * stride,
+				       read + (pixmap->drawable.height -
+					       y - 1) * stride, stride);
+			dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+			dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+			pixmap_priv->pbo_valid = FALSE;
+			dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
+			pixmap_priv->pbo = 0;
+		}
+	}
+
+	dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+      done:
+	pixmap->devPrivate.ptr = data;
+
+	if (temp_pixmap) {
+		(*screen->DestroyPixmap) (temp_pixmap);
+	}
+
+	return TRUE;
+}
+
+
+
+static void
+_glamor_destroy_upload_pixmap(PixmapPtr pixmap)
+{
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+
+	assert(pixmap_priv->gl_fbo == 0);
+	if (pixmap_priv->fb)
+		dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
+	if (pixmap_priv->tex)
+		dispatch->glDeleteTextures(1, &pixmap_priv->tex);
+	if (pixmap_priv->pbo)
+		dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
+	pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
+
+}
+
+void
+glamor_destroy_upload_pixmap(PixmapPtr pixmap)
+{
+	_glamor_destroy_upload_pixmap(pixmap);
+}
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 3cc4b52..762dfc2 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -39,72 +39,69 @@
 
 void
 glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc,
-		      int nrect,
-		      xRectangle *prect)
+		      GCPtr gc, int nrect, xRectangle * prect)
 {
-    int		    fullX1, fullX2, fullY1, fullY2;
-    int		    xorg, yorg;
-    int		    n;
-    register BoxPtr pbox;
-    RegionPtr pClip = fbGetCompositeClip(gc);
-    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
-	goto fail;
-    }
+	int fullX1, fullX2, fullY1, fullY2;
+	int xorg, yorg;
+	int n;
+	register BoxPtr pbox;
 
-    xorg = drawable->x;
-    yorg = drawable->y;
+	RegionPtr pClip = fbGetCompositeClip(gc);
+	if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
+		goto fail;
+	}
+
+	xorg = drawable->x;
+	yorg = drawable->y;
 
-        while (nrect--) {
-                fullX1 = prect->x + xorg;
-                fullY1 = prect->y + yorg;
-                fullX2 = fullX1 + (int)prect->width;
-                fullY2 = fullY1 + (int)prect->height;
-                prect++;
+	while (nrect--) {
+		fullX1 = prect->x + xorg;
+		fullY1 = prect->y + yorg;
+		fullX2 = fullX1 + (int) prect->width;
+		fullY2 = fullY1 + (int) prect->height;
+		prect++;
 
-                n = REGION_NUM_RECTS(pClip);
-                pbox = REGION_RECTS(pClip);
-                /*
-                 * clip the rectangle to each box in the clip region
-                 * this is logically equivalent to calling Intersect(),
-                 * but rectangles may overlap each other here.
-                 */
-                while (n--) {
-                        int x1 = fullX1;
-                        int x2 = fullX2;
-                        int y1 = fullY1;
-                        int y2 = fullY2;
+		n = REGION_NUM_RECTS(pClip);
+		pbox = REGION_RECTS(pClip);
+		/*
+		 * clip the rectangle to each box in the clip region
+		 * this is logically equivalent to calling Intersect(),
+		 * but rectangles may overlap each other here.
+		 */
+		while (n--) {
+			int x1 = fullX1;
+			int x2 = fullX2;
+			int y1 = fullY1;
+			int y2 = fullY2;
 
-                        if (pbox->x1 > x1)
-                                x1 = pbox->x1;
-                        if (pbox->x2 < x2)
-                                x2 = pbox->x2;
-                        if (pbox->y1 > y1)
-                                y1 = pbox->y1;
-                        if (pbox->y2 < y2)
-                                y2 = pbox->y2;
-                        pbox++;
+			if (pbox->x1 > x1)
+				x1 = pbox->x1;
+			if (pbox->x2 < x2)
+				x2 = pbox->x2;
+			if (pbox->y1 > y1)
+				y1 = pbox->y1;
+			if (pbox->y2 < y2)
+				y2 = pbox->y2;
+			pbox++;
 
-                        if (x1 >= x2 || y1 >= y2)
-                                continue;
-	                glamor_fill(drawable,
-			            gc,
-				    x1,
-				    y1,
-				    x2 - x1,
-                                    y2 - y1);
-                }
-    }
-    return;
+			if (x1 >= x2 || y1 >= y2)
+				continue;
+			if (!glamor_fill(drawable, gc, x1, y1, x2 - x1,
+					 y2 - y1))
+				goto fail;
+		}
+	}
+	return;
 
-fail:
-    glamor_fallback(" to %p (%c)\n",
-		    drawable, glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	if (glamor_prepare_access_gc(gc)) {
-	    fbPolyFillRect(drawable, gc, nrect, prect );
-	    glamor_finish_access_gc(gc);
+      fail:
+	glamor_fallback(" to %p (%c)\n",
+			drawable, glamor_get_drawable_location(drawable));
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access_gc(gc)) {
+			fbPolyFillRect(drawable, gc, nrect, prect);
+			glamor_finish_access_gc(gc);
+		}
+		glamor_finish_access(drawable);
 	}
-	glamor_finish_access(drawable);
-    }
+	return;
 }
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index d93b602..01124bb 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -46,134 +46,130 @@ void
 glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 		  DDXPointPtr points)
 {
-    xRectangle *rects;
-    int x1, x2, y1, y2;
-    int i;
-    int x_min = MAXSHORT;
-    int x_max = MINSHORT;
-    int y_min = MAXSHORT;
-    int y_max = MINSHORT;
-    DrawablePtr temp_dest;
-    PixmapPtr temp_pixmap;
-    GCPtr temp_gc = NULL;
-    /* Don't try to do wide lines or non-solid fill style. */
-    if (gc->lineWidth != 0) {
-	/* This ends up in miSetSpans, which is accelerated as well as we
-	 * can hope X wide lines will be.
-	 */
-	goto fail;
-    }
-    if (gc->lineStyle != LineSolid ||
-	gc->fillStyle != FillSolid) {
-	glamor_fallback("non-solid fill line style %d, fill style %d\n",
-                         gc->lineStyle, gc->fillStyle);
-	goto fail;
-    }
-
-    rects = malloc(sizeof(xRectangle) * (n - 1));
-    x1 = points[0].x;
-    y1 = points[0].y;
-    /* If we have any non-horizontal/vertical, fall back. */
-    for (i = 0; i < n - 1; i++) {
-	if (mode == CoordModePrevious) {
-	    x2 = x1 + points[i + 1].x;
-	    y2 = y1 + points[i + 1].y;
-	} else {
-	    x2 = points[i + 1].x;
-	    y2 = points[i + 1].y;
-	}
-	if (x1 != x2 && y1 != y2) {
-	    free(rects);
-	    glamor_fallback("stub diagonal poly_line\n");
-	    goto fail;
+	xRectangle *rects;
+	int x1, x2, y1, y2;
+	int i;
+	int x_min = MAXSHORT;
+	int x_max = MINSHORT;
+	int y_min = MAXSHORT;
+	int y_max = MINSHORT;
+	DrawablePtr temp_dest;
+	PixmapPtr temp_pixmap;
+	GCPtr temp_gc = NULL;
+	/* Don't try to do wide lines or non-solid fill style. */
+	if (gc->lineWidth != 0) {
+		/* This ends up in miSetSpans, which is accelerated as well as we
+		 * can hope X wide lines will be.
+		 */
+		goto fail;
 	}
-	if (x1 < x2) {
-	    rects[i].x = x1;
-	    rects[i].width = x2 - x1 + 1;
-	} else {
-	    rects[i].x = x2;
-	    rects[i].width = x1 - x2 + 1;
+	if (gc->lineStyle != LineSolid || gc->fillStyle != FillSolid) {
+		glamor_fallback
+		    ("non-solid fill line style %d, fill style %d\n",
+		     gc->lineStyle, gc->fillStyle);
+		goto fail;
 	}
-	if (y1 < y2) {
-	    rects[i].y = y1;
-	    rects[i].height = y2 - y1 + 1;
-	} else {
-	    rects[i].y = y2;
-	    rects[i].height = y1 - y2 + 1;
+
+	rects = malloc(sizeof(xRectangle) * (n - 1));
+	x1 = points[0].x;
+	y1 = points[0].y;
+	/* If we have any non-horizontal/vertical, fall back. */
+	for (i = 0; i < n - 1; i++) {
+		if (mode == CoordModePrevious) {
+			x2 = x1 + points[i + 1].x;
+			y2 = y1 + points[i + 1].y;
+		} else {
+			x2 = points[i + 1].x;
+			y2 = points[i + 1].y;
+		}
+		if (x1 != x2 && y1 != y2) {
+			free(rects);
+			glamor_fallback("stub diagonal poly_line\n");
+			goto fail;
+		}
+		if (x1 < x2) {
+			rects[i].x = x1;
+			rects[i].width = x2 - x1 + 1;
+		} else {
+			rects[i].x = x2;
+			rects[i].width = x1 - x2 + 1;
+		}
+		if (y1 < y2) {
+			rects[i].y = y1;
+			rects[i].height = y2 - y1 + 1;
+		} else {
+			rects[i].y = y2;
+			rects[i].height = y1 - y2 + 1;
+		}
+
+		x1 = x2;
+		y1 = y2;
 	}
+	gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
+	free(rects);
+	return;
+
+      fail:
+	for (i = 0; i < n; i++) {
+		if (x_min > points[i].x)
+			x_min = points[i].x;
+		if (x_max < points[i].x)
+			x_max = points[i].x;
 
-	x1 = x2;
-	y1 = y2;
-    }
-    gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
-    free(rects);
-    return;
+		if (y_min > points[i].y)
+			y_min = points[i].y;
+		if (y_max < points[i].y)
+			y_max = points[i].y;
+	}
 
-fail:
-   for(i = 0; i < n; i++)
-      {
-        if (x_min > points[i].x)
-          x_min = points[i].x;
-        if (x_max < points[i].x)
-          x_max = points[i].x;
+	temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
+						      x_max - x_min + 1,
+						      y_max - y_min + 1,
+						      drawable->depth, 0);
+	if (temp_pixmap) {
+		temp_dest = &temp_pixmap->drawable;
+		temp_gc =
+		    GetScratchGC(temp_dest->depth, temp_dest->pScreen);
+		ValidateGC(temp_dest, temp_gc);
+		for (i = 0; i < n; i++) {
+			points[i].x -= x_min;
+			points[i].y -= y_min;
+		}
+		(void) glamor_copy_area(drawable,
+					temp_dest,
+					temp_gc,
+					x_min, y_min,
+					x_max - x_min + 1,
+					y_max - y_min + 1, 0, 0);
 
-        if (y_min > points[i].y)
-          y_min = points[i].y;
-        if (y_max < points[i].y)
-          y_max = points[i].y;
-      }
+	} else
+		temp_dest = drawable;
 
-    temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
-                                                  x_max - x_min + 1, y_max - y_min + 1,
-                                                  drawable->depth,
-                                                  0);
-    if (temp_pixmap) {
-      temp_dest = &temp_pixmap->drawable;
-      temp_gc = GetScratchGC(temp_dest->depth, temp_dest->pScreen);
-      ValidateGC(temp_dest, temp_gc);
-      for(i = 0; i < n; i++)
-        {
-           points[i].x -= x_min;
-           points[i].y -= y_min;
-        }
-      (void)glamor_copy_area(drawable,
-			     temp_dest,
-		             temp_gc,
-			     x_min, y_min,
-			     x_max - x_min + 1, y_max - y_min + 1,
-			     0, 0);
-    
-    } 
-    else 
-      temp_dest = drawable;
+	if (gc->lineWidth == 0) {
+		if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
+			if (glamor_prepare_access_gc(gc)) {
+				fbPolyLine(temp_dest, gc, mode, n, points);
+				glamor_finish_access_gc(gc);
+			}
+			glamor_finish_access(temp_dest);
+		}
+	} else {
+		/* fb calls mi functions in the lineWidth != 0 case. */
+		fbPolyLine(drawable, gc, mode, n, points);
+	}
+	if (temp_dest != drawable) {
+		(void) glamor_copy_area(temp_dest,
+					drawable,
+					temp_gc,
+					0, 0,
+					x_max - x_min + 1,
+					y_max - y_min + 1, x_min, y_min);
+		drawable->pScreen->DestroyPixmap(temp_pixmap);
+		for (i = 0; i < n; i++) {
+			points[i].x += x_min;
+			points[i].y += y_min;
+		}
 
-    if (gc->lineWidth == 0) {
-	if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
-	    if (glamor_prepare_access_gc(gc)) {
-		fbPolyLine(temp_dest, gc, mode, n, points);
-		glamor_finish_access_gc(gc);
-	    }
-	    glamor_finish_access(temp_dest);
+		FreeScratchGC(temp_gc);
 	}
-    } 
-    else {
-    /* fb calls mi functions in the lineWidth != 0 case. */
-      fbPolyLine(drawable, gc, mode, n, points);
-    }
-    if (temp_dest != drawable) {
-      (void)glamor_copy_area(temp_dest,
-			     drawable,
-		             temp_gc,
-			     0, 0,
-			     x_max - x_min + 1, y_max - y_min + 1,
-			     x_min, y_min);
-      drawable->pScreen->DestroyPixmap(temp_pixmap);
-      for(i = 0; i < n; i++)
-        {
-           points[i].x += x_min;
-           points[i].y += y_min;
-        }
- 
-      FreeScratchGC(temp_gc);
-    }
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 5f82c78..66c4359 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,7 +31,7 @@
 #include <dix-config.h>
 #include <xorg-config.h>
 #endif
-
+#include <xorg-server.h>
 
 #include "glamor.h"
 
@@ -41,7 +41,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#define GLAMOR_DEFAULT_PRECISION   "precision mediump float;\n" 
+#define GLAMOR_DEFAULT_PRECISION   "precision mediump float;\n"
 #include "glamor_glext.h"
 #else
 #include <GL/gl.h>
@@ -56,63 +56,66 @@
 #include "glamor_debug.h"
 
 typedef struct glamor_composite_shader {
-  GLuint prog;
-  GLint dest_to_dest_uniform_location;
-  GLint dest_to_source_uniform_location;
-  GLint dest_to_mask_uniform_location;
-  GLint source_uniform_location;
-  GLint mask_uniform_location;
+	GLuint prog;
+	GLint dest_to_dest_uniform_location;
+	GLint dest_to_source_uniform_location;
+	GLint dest_to_mask_uniform_location;
+	GLint source_uniform_location;
+	GLint mask_uniform_location;
 } glamor_composite_shader;
 
 typedef struct {
-  INT16 x_src;
-  INT16 y_src;
-  INT16 x_mask;
-  INT16 y_mask;
-  INT16 x_dst;
-  INT16 y_dst;
-  INT16 width;
-  INT16 height;
+	INT16 x_src;
+	INT16 y_src;
+	INT16 x_mask;
+	INT16 y_mask;
+	INT16 x_dst;
+	INT16 y_dst;
+	INT16 width;
+	INT16 height;
 } glamor_composite_rect_t;
 
 
 enum glamor_vertex_type {
-     GLAMOR_VERTEX_POS,
-     GLAMOR_VERTEX_SOURCE,
-     GLAMOR_VERTEX_MASK
+	GLAMOR_VERTEX_POS,
+	GLAMOR_VERTEX_SOURCE,
+	GLAMOR_VERTEX_MASK
 };
 
 enum shader_source {
-  SHADER_SOURCE_SOLID,
-  SHADER_SOURCE_TEXTURE,
-  SHADER_SOURCE_TEXTURE_ALPHA,
-  SHADER_SOURCE_COUNT,
+	SHADER_SOURCE_SOLID,
+	SHADER_SOURCE_TEXTURE,
+	SHADER_SOURCE_TEXTURE_ALPHA,
+	SHADER_SOURCE_COUNT,
 };
 
 enum shader_mask {
-  SHADER_MASK_NONE,
-  SHADER_MASK_SOLID,
-  SHADER_MASK_TEXTURE,
-  SHADER_MASK_TEXTURE_ALPHA,
-  SHADER_MASK_COUNT,
+	SHADER_MASK_NONE,
+	SHADER_MASK_SOLID,
+	SHADER_MASK_TEXTURE,
+	SHADER_MASK_TEXTURE_ALPHA,
+	SHADER_MASK_COUNT,
 };
 
 enum shader_in {
-  SHADER_IN_SOURCE_ONLY,
-  SHADER_IN_NORMAL,
-  SHADER_IN_CA_SOURCE,
-  SHADER_IN_CA_ALPHA,
-  SHADER_IN_COUNT,
+	SHADER_IN_SOURCE_ONLY,
+	SHADER_IN_NORMAL,
+	SHADER_IN_CA_SOURCE,
+	SHADER_IN_CA_ALPHA,
+	SHADER_IN_COUNT,
 };
 
 struct glamor_screen_private;
 struct glamor_pixmap_private;
-typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, 
-					          struct glamor_pixmap_private*);
+typedef void (*glamor_pixmap_validate_function_t) (struct
+						   glamor_screen_private *,
+						   struct
+						   glamor_pixmap_private
+						   *);
 
 enum glamor_gl_flavor {
-   GLAMOR_GL_DESKTOP,        // OPENGL API
-   GLAMOR_GL_ES2             // OPENGL ES2.0 API
+	GLAMOR_GL_DESKTOP,	// OPENGL API
+	GLAMOR_GL_ES2		// OPENGL ES2.0 API
 };
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
@@ -121,98 +124,97 @@ enum glamor_gl_flavor {
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
 typedef struct {
-        PicturePtr picture;     /* Where the glyphs of the cache are stored */
-        GlyphPtr *glyphs;
-        uint16_t count;
-        uint16_t evict;
+	PicturePtr picture;	/* Where the glyphs of the cache are stored */
+	GlyphPtr *glyphs;
+	uint16_t count;
+	uint16_t evict;
 } glamor_glyph_cache_t;
 
 
 #include "glamor_gl_dispatch.h"
 
 typedef struct glamor_screen_private {
-  CloseScreenProcPtr saved_close_screen;
-  CreateGCProcPtr saved_create_gc;
-  CreatePixmapProcPtr saved_create_pixmap;
-  DestroyPixmapProcPtr saved_destroy_pixmap;
-  GetSpansProcPtr saved_get_spans;
-  GetImageProcPtr saved_get_image;
-  CompositeProcPtr saved_composite;
-  TrapezoidsProcPtr saved_trapezoids;
-  GlyphsProcPtr saved_glyphs;
-  ChangeWindowAttributesProcPtr saved_change_window_attributes;
-  CopyWindowProcPtr saved_copy_window;
-  BitmapToRegionProcPtr saved_bitmap_to_region;
-  TrianglesProcPtr saved_triangles;
-  CreatePictureProcPtr saved_create_picture;
-  DestroyPictureProcPtr saved_destroy_picture;
-  UnrealizeGlyphProcPtr saved_unrealize_glyph;
-
-  int yInverted;
-  int screen_fbo;
-  GLuint vbo;
-  int vbo_offset;
-  int vbo_size;
-  char *vb;
-  int vb_stride;
-  enum glamor_gl_flavor gl_flavor;
-  int has_pack_invert;
-  int has_fbo_blit;
-  int max_fbo_size;
-
-  /* glamor_finishaccess */
-  GLint finish_access_prog[2];
-  GLint finish_access_no_revert[2];
-  GLint finish_access_swap_rb[2];
-
-  /* glamor_solid */
-  GLint solid_prog;
-  GLint solid_color_uniform_location;
-
-  /* glamor_tile */
-  GLint tile_prog;
-
-  /* glamor_putimage */
-  GLint put_image_xybitmap_prog;
-  GLint put_image_xybitmap_fg_uniform_location;
-  GLint put_image_xybitmap_bg_uniform_location;
-
-  /* glamor_composite */
-  glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
-  [SHADER_MASK_COUNT]
-  [SHADER_IN_COUNT];
-  Bool has_source_coords, has_mask_coords;
-  int render_nr_verts;
-  glamor_pixmap_validate_function_t *pixmap_validate_funcs;
-  glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
-  char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
-  int  delayed_fallback_pending;
-
-  glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
-  Bool glyph_cache_initialized;
-  struct glamor_gl_dispatch dispatch; 
+	CloseScreenProcPtr saved_close_screen;
+	CreateGCProcPtr saved_create_gc;
+	CreatePixmapProcPtr saved_create_pixmap;
+	DestroyPixmapProcPtr saved_destroy_pixmap;
+	GetSpansProcPtr saved_get_spans;
+	GetImageProcPtr saved_get_image;
+	CompositeProcPtr saved_composite;
+	TrapezoidsProcPtr saved_trapezoids;
+	GlyphsProcPtr saved_glyphs;
+	ChangeWindowAttributesProcPtr saved_change_window_attributes;
+	CopyWindowProcPtr saved_copy_window;
+	BitmapToRegionProcPtr saved_bitmap_to_region;
+	TrianglesProcPtr saved_triangles;
+	CreatePictureProcPtr saved_create_picture;
+	DestroyPictureProcPtr saved_destroy_picture;
+	UnrealizeGlyphProcPtr saved_unrealize_glyph;
+
+	int yInverted;
+	int screen_fbo;
+	GLuint vbo;
+	int vbo_offset;
+	int vbo_size;
+	char *vb;
+	int vb_stride;
+	enum glamor_gl_flavor gl_flavor;
+	int has_pack_invert;
+	int has_fbo_blit;
+	int max_fbo_size;
+
+	/* glamor_finishaccess */
+	GLint finish_access_prog[2];
+	GLint finish_access_no_revert[2];
+	GLint finish_access_swap_rb[2];
+
+	/* glamor_solid */
+	GLint solid_prog;
+	GLint solid_color_uniform_location;
+
+	/* glamor_tile */
+	GLint tile_prog;
+
+	/* glamor_putimage */
+	GLint put_image_xybitmap_prog;
+	GLint put_image_xybitmap_fg_uniform_location;
+	GLint put_image_xybitmap_bg_uniform_location;
+
+	/* glamor_composite */
+	glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+	    [SHADER_MASK_COUNT][SHADER_IN_COUNT];
+	Bool has_source_coords, has_mask_coords;
+	int render_nr_verts;
+	glamor_pixmap_validate_function_t *pixmap_validate_funcs;
+	glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
+	char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
+	int delayed_fallback_pending;
+
+	glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
+	Bool glyph_cache_initialized;
+	struct glamor_gl_dispatch dispatch;
 } glamor_screen_private;
 
 typedef enum glamor_access {
-  GLAMOR_ACCESS_RO,
-  GLAMOR_ACCESS_RW,
-  GLAMOR_ACCESS_WO,
+	GLAMOR_ACCESS_RO,
+	GLAMOR_ACCESS_RW,
+	GLAMOR_ACCESS_WO,
 } glamor_access_t;
 
-enum _glamor_pending_op_type{
-    GLAMOR_PENDING_NONE,
-    GLAMOR_PENDING_FILL
+enum _glamor_pending_op_type {
+	GLAMOR_PENDING_NONE,
+	GLAMOR_PENDING_FILL
 };
 
 typedef struct _glamor_pending_fill {
-    unsigned int type;
-    GLfloat color4fv[4];
-    CARD32  colori;
+	unsigned int type;
+	GLfloat color4fv[4];
+	CARD32 colori;
 } glamor_pending_fill;
 
 typedef union _glamor_pending_op {
-    unsigned int type;
-    glamor_pending_fill fill;
+	unsigned int type;
+	glamor_pending_fill fill;
 } glamor_pending_op;
 
 /*
@@ -231,18 +233,18 @@ typedef union _glamor_pending_op {
  **/
 
 typedef struct glamor_pixmap_private {
-  unsigned char gl_fbo:1;
-  unsigned char gl_tex:1;
-  unsigned char pbo_valid:1;
-  unsigned char is_picture:1;
-  GLuint tex;			
-  GLuint fb;
-  GLuint pbo;                
-  glamor_access_t access_mode;
-  PictFormatShort pict_format;
-  glamor_pending_op pending_op;
-  PixmapPtr container;
-  glamor_screen_private *glamor_priv;
+	unsigned char gl_fbo:1;
+	unsigned char gl_tex:1;
+	unsigned char pbo_valid:1;
+	unsigned char is_picture:1;
+	GLuint tex;
+	GLuint fb;
+	GLuint pbo;
+	glamor_access_t access_mode;
+	PictFormatShort pict_format;
+	glamor_pending_op pending_op;
+	PixmapPtr container;
+	glamor_screen_private *glamor_priv;
 } glamor_pixmap_private;
 
 /* 
@@ -255,11 +257,11 @@ typedef struct glamor_pixmap_private {
  *
  * */
 typedef enum glamor_pixmap_status {
-  GLAMOR_NONE,
-  GLAMOR_UPLOAD_PENDING,
-  GLAMOR_UPLOAD_DONE,
-  GLAMOR_UPLOAD_FAILED
-} glamor_pixmap_status_t; 
+	GLAMOR_NONE,
+	GLAMOR_UPLOAD_PENDING,
+	GLAMOR_UPLOAD_DONE,
+	GLAMOR_UPLOAD_FAILED
+} glamor_pixmap_status_t;
 
 
 extern DevPrivateKey glamor_screen_private_key;
@@ -267,13 +269,16 @@ extern DevPrivateKey glamor_pixmap_private_key;
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
 {
-  return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
-						   glamor_screen_private_key);
+	return (glamor_screen_private *)
+	    dixLookupPrivate(&screen->devPrivates,
+			     glamor_screen_private_key);
 }
+
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
-  return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+	return dixLookupPrivate(&pixmap->devPrivates,
+				glamor_pixmap_private_key);
 }
 
 
@@ -284,8 +289,8 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
 static inline Bool
 glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
 {
-  return (planemask & FbFullMask(drawable->depth)) ==
-    FbFullMask(drawable->depth);
+	return (planemask & FbFullMask(drawable->depth)) ==
+	    FbFullMask(drawable->depth);
 }
 
 extern int glamor_debug_level;
@@ -299,19 +304,11 @@ Bool glamor_close_screen(int idx, ScreenPtr screen);
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
-		 int srcx, int srcy, int width, int height, int dstx, int dsty);
-void
-glamor_copy_n_to_n(DrawablePtr src,
-		   DrawablePtr dst,
-		   GCPtr gc,
-		   BoxPtr box,
-		   int nbox,
-		   int		dx,
-		   int		dy,
-		   Bool		reverse,
-		   Bool		upsidedown,
-		   Pixel		bitplane,
-		   void		*closure);
+		 int srcx, int srcy, int width, int height, int dstx,
+		 int dsty);
+void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+			BoxPtr box, int nbox, int dx, int dy, Bool reverse,
+			Bool upsidedown, Pixel bitplane, void *closure);
 
 /* glamor_copywindow.c */
 void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
@@ -334,30 +331,35 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    unsigned char alu, unsigned long planemask,
 		    unsigned long fg_pixel, unsigned long bg_pixel,
 		    int stipple_x, int stipple_y);
-GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source);
-void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog);
-void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
-				    GLfloat *color);
+GLint glamor_compile_glsl_prog(glamor_gl_dispatch * dispatch, GLenum type,
+			       const char *source);
+void glamor_link_glsl_prog(glamor_gl_dispatch * dispatch, GLint prog);
+void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
+				    unsigned long fg_pixel,
+				    GLfloat * color);
 
 int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
+int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
+				       pixmap_priv);
 
 /* nc means no check. caller must ensure this pixmap has valid fbo.
  * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
  * */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *
+					   pixmap_priv);
 
 
 PixmapPtr
-glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, 
-                               GLenum *type, int no_alpha, int no_revert);
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
+			       GLenum * type, int no_alpha, int no_revert);
 
-void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu);
+void glamor_set_alu(struct glamor_gl_dispatch *dispatch,
+		    unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 Bool glamor_gl_has_extension(char *extension);
-int  glamor_gl_get_version(void);
+int glamor_gl_get_version(void);
 
 #define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
           ((major) * 256)                       \
@@ -367,12 +369,8 @@ int  glamor_gl_get_version(void);
 
 
 /* glamor_fill.c */
-void glamor_fill(DrawablePtr drawable,
-		 GCPtr gc,
-		 int x,
-		 int y,
-		 int width,
-		 int height);
+Bool glamor_fill(DrawablePtr drawable,
+		 GCPtr gc, int x, int y, int width, int height);
 Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		  unsigned char alu, unsigned long planemask,
 		  unsigned long fg_pixel);
@@ -381,22 +379,18 @@ void glamor_solid_fail_region(PixmapPtr pixmap,
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
-		       GCPtr	gc,
-		       int n,
-		       DDXPointPtr points,
-		       int *widths,
-		       int sorted);
+		       GCPtr gc,
+		       int n, DDXPointPtr points, int *widths, int sorted);
 
 void glamor_init_solid_shader(ScreenPtr screen);
 
 /* glamor_getspans.c */
 void
+
 glamor_get_spans(DrawablePtr drawable,
 		 int wmax,
 		 DDXPointPtr points,
-		 int *widths,
-		 int nspans,
-		 char *dst_start);
+		 int *widths, int nspans, char *dst_start);
 
 /* glamor_glyphs.c */
 void glamor_glyphs_fini(ScreenPtr screen);
@@ -405,10 +399,10 @@ void glamor_glyphs(CARD8 op,
 		   PicturePtr pDst,
 		   PictFormatPtr maskFormat,
 		   INT16 xSrc,
-		   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
+		   INT16 ySrc, int nlist, GlyphListPtr list,
+		   GlyphPtr * glyphs);
 
-void
-glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph);
+void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		      DDXPointPtr points, int *widths, int n, int sorted);
@@ -416,17 +410,17 @@ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 /* glamor_polyfillrect.c */
 void
 glamor_poly_fill_rect(DrawablePtr drawable,
-		      GCPtr gc,
-		      int nrect,
-		      xRectangle *prect);
+		      GCPtr gc, int nrect, xRectangle * prect);
 
 /* glamor_polylines.c */
 void
+
 glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 		  DDXPointPtr points);
 
 /* glamor_putimage.c */
 void
+
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits);
 void glamor_init_putimage_shaders(ScreenPtr screen);
@@ -440,18 +434,16 @@ void glamor_composite(CARD8 op,
 		      INT16 ySrc,
 		      INT16 xMask,
 		      INT16 yMask,
-		      INT16 xDst,
-		      INT16 yDst,
-		      CARD16 width,
-		      CARD16 height);
+		      INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
 void glamor_trapezoids(CARD8 op,
 		       PicturePtr src, PicturePtr dst,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		       int ntrap, xTrapezoid *traps);
+		       int ntrap, xTrapezoid * traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
 void glamor_composite_rects(CARD8 op,
-			    PicturePtr src, PicturePtr mask, PicturePtr dst,
-			    int nrect, glamor_composite_rect_t *rects);
+			    PicturePtr src, PicturePtr mask,
+			    PicturePtr dst, int nrect,
+			    glamor_composite_rect_t * rects);
 
 /* glamor_tile.c */
 Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
@@ -462,19 +454,16 @@ void glamor_init_tile_shader(ScreenPtr screen);
 
 /* glamor_triangles.c */
 void
-glamor_triangles (CARD8	    op,
-		  PicturePtr    pSrc,
-		  PicturePtr    pDst,
-		  PictFormatPtr maskFormat,
-		  INT16	    xSrc,
-		  INT16	    ySrc,
-		  int	    ntris,
-		  xTriangle    *tris);
+
+glamor_triangles(CARD8 op,
+		 PicturePtr pSrc,
+		 PicturePtr pDst,
+		 PictFormatPtr maskFormat,
+		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris);
 
 /* glamor_pixmap.c */
 
-void
-glamor_pixmap_init(ScreenPtr screen);
+void glamor_pixmap_init(ScreenPtr screen);
 /** 
  * Download a pixmap's texture to cpu memory. If success,
  * One copy of current pixmap's texture will be put into
@@ -484,8 +473,8 @@ glamor_pixmap_init(ScreenPtr screen);
  * gl_tex must be 1. Used by glamor_prepare_access.
  *
  */
-Bool 
-glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
+Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap,
+				   glamor_access_t access);
 
 /**
  * Restore a pixmap's data which is downloaded by 
@@ -496,8 +485,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
  * in texture originally. In other word, the gl_fbo
  * must be 1.
  **/
-void
-glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
+void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
 /**
  * Ensure to have a fbo attached to the pixmap. 
  * If the pixmap already has one fbo then do nothing.
@@ -506,53 +494,49 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
  * The pixmap must has a valid texture before call this
  * API, othersie, it will trigger a assert.
  */
-void
-glamor_pixmap_ensure_fb(PixmapPtr pixmap);
+void glamor_pixmap_ensure_fb(PixmapPtr pixmap);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
  * uploading feature. The pixmap must be a software pixmap.
  * This function will change current FBO and current shaders.
  */
-enum glamor_pixmap_status 
-glamor_upload_pixmap_to_texture(PixmapPtr pixmap);
+enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr
+							  pixmap);
 
 /** 
  * Upload a picture to gl texture. Similar to the
  * glamor_upload_pixmap_to_texture. Used in rendering.
  **/
-enum glamor_pixmap_status 
-glamor_upload_picture_to_texture(PicturePtr picture);
+enum glamor_pixmap_status
+ glamor_upload_picture_to_texture(PicturePtr picture);
 
 /**
  * Destroy all the resources allocated on the uploading
  * phase, includs the tex and fbo.
  **/
-void
-glamor_destroy_upload_pixmap(PixmapPtr pixmap);
+void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
 
-void
-glamor_validate_pixmap(PixmapPtr pixmap);
+void glamor_validate_pixmap(PixmapPtr pixmap);
 
-int
-glamor_create_picture(PicturePtr picture);
+int glamor_create_picture(PicturePtr picture);
 
 Bool
 glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
 
-void
-glamor_finish_access_picture(PicturePtr picture);
+void glamor_finish_access_picture(PicturePtr picture);
 
-void
-glamor_destroy_picture(PicturePtr picture);
+void glamor_destroy_picture(PicturePtr picture);
 
-enum glamor_pixmap_status 
-glamor_upload_picture_to_texture(PicturePtr picture);
+enum glamor_pixmap_status
+ glamor_upload_picture_to_texture(PicturePtr picture);
+
+void
 
-void 
-glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv);
+glamor_picture_format_fixup(PicturePtr picture,
+			    glamor_pixmap_private * pixmap_priv);
 
-#include"glamor_utils.h" 
+#include"glamor_utils.h"
 
 /* Dynamic pixmap upload to texture if needed. 
  * Sometimes, the target is a gl texture pixmap/picture,
@@ -561,9 +545,9 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
  * fallback the whole process to cpu. Most of the time,
  * this will increase performance obviously. */
 
-#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
-#define GLAMOR_DELAYED_FILLING
+#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+//#define GLAMOR_DELAYED_FILLING
 
 
 
-#endif /* GLAMOR_PRIV_H */
+#endif				/* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index cdcde5e..a8cafed 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -36,56 +36,50 @@ void
 glamor_init_putimage_shaders(ScreenPtr screen)
 {
 #if 0
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    const char *xybitmap_vs =
-	"uniform float x_bias;\n"
-	"uniform float x_scale;\n"
-	"uniform float y_bias;\n"
-	"uniform float y_scale;\n"
-	"varying vec2 bitmap_coords;\n"
-	"void main()\n"
-	"{\n"
-	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
-	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
-	"			   0,\n"
-	"			   1);\n"
-	"	bitmap_coords = gl_MultiTexCoord0.xy;\n"
-	"}\n";
-    const char *xybitmap_fs =
-	"uniform vec4 fg, bg;\n"
-	"varying vec2 bitmap_coords;\n"
-	"uniform sampler2D bitmap_sampler;\n"
-	"void main()\n"
-	"{\n"
-	"	float bitmap_value = texture2D(bitmap_sampler,\n"
-	"				       bitmap_coords).x;\n"
-	"	gl_FragColor = mix(bg, fg, bitmap_value);\n"
-	"}\n";
-    GLint fs_prog, vs_prog, prog;
-    GLint sampler_uniform_location;
-
-    if (!GLEW_ARB_fragment_shader)
-	return;
-
-    prog = dispatch->glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
-    dispatch->glAttachShader(prog, vs_prog);
-    dispatch->glAttachShader(prog, fs_prog);
-    glamor_link_glsl_prog(prog);
-
-    dispatch->glUseProgram(prog);
-    sampler_uniform_location = dispatch->glGetUniformLocation(prog, "bitmap_sampler");
-    dispatch->glUniform1i(sampler_uniform_location, 0);
-
-    glamor_priv->put_image_xybitmap_fg_uniform_location =
-	dispatch->glGetUniformLocation(prog, "fg");
-    glamor_priv->put_image_xybitmap_bg_uniform_location =
-	dispatch->glGetUniformLocation(prog, "bg");
-    glamor_get_transform_uniform_locations(prog,
-					   &glamor_priv->put_image_xybitmap_transform);
-    glamor_priv->put_image_xybitmap_prog = prog;
-    dispatch->glUseProgram(0);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	const char *xybitmap_vs =
+	    "uniform float x_bias;\n" "uniform float x_scale;\n"
+	    "uniform float y_bias;\n" "uniform float y_scale;\n"
+	    "varying vec2 bitmap_coords;\n" "void main()\n" "{\n"
+	    "	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+	    "			   (gl_Vertex.y + y_bias) * y_scale,\n"
+	    "			   0,\n"
+	    "			   1);\n"
+	    "	bitmap_coords = gl_MultiTexCoord0.xy;\n" "}\n";
+	const char *xybitmap_fs =
+	    "uniform vec4 fg, bg;\n" "varying vec2 bitmap_coords;\n"
+	    "uniform sampler2D bitmap_sampler;\n" "void main()\n" "{\n"
+	    "	float bitmap_value = texture2D(bitmap_sampler,\n"
+	    "				       bitmap_coords).x;\n"
+	    "	gl_FragColor = mix(bg, fg, bitmap_value);\n" "}\n";
+	GLint fs_prog, vs_prog, prog;
+	GLint sampler_uniform_location;
+
+	if (!GLEW_ARB_fragment_shader)
+		return;
+
+	prog = dispatch->glCreateProgram();
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
+	fs_prog =
+	    glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
+	dispatch->glAttachShader(prog, vs_prog);
+	dispatch->glAttachShader(prog, fs_prog);
+	glamor_link_glsl_prog(prog);
+
+	dispatch->glUseProgram(prog);
+	sampler_uniform_location =
+	    dispatch->glGetUniformLocation(prog, "bitmap_sampler");
+	dispatch->glUniform1i(sampler_uniform_location, 0);
+
+	glamor_priv->put_image_xybitmap_fg_uniform_location =
+	    dispatch->glGetUniformLocation(prog, "fg");
+	glamor_priv->put_image_xybitmap_bg_uniform_location =
+	    dispatch->glGetUniformLocation(prog, "bg");
+	glamor_get_transform_uniform_locations(prog,
+					       &glamor_priv->put_image_xybitmap_transform);
+	glamor_priv->put_image_xybitmap_prog = prog;
+	dispatch->glUseProgram(0);
 #endif
 }
 
@@ -106,13 +100,13 @@ glamor_init_putimage_shaders(ScreenPtr screen)
 static int
 y_flip(PixmapPtr pixmap, int y)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 
-    if (pixmap == screen_pixmap)
-	return (pixmap->drawable.height - 1) - y;
-    else
-	return y;
+	if (pixmap == screen_pixmap)
+		return (pixmap->drawable.height - 1) - y;
+	else
+		return y;
 }
 
 
@@ -121,129 +115,127 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 			  int x, int y, int w, int h, int left_pad,
 			  int image_format, char *bits)
 {
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    float fg[4], bg[4];
-    GLuint tex;
-    unsigned int stride = PixmapBytePad(1, w + left_pad);
-    RegionPtr clip;
-    BoxPtr box;
-    int nbox;
-    float dest_coords[8];
-    const float bitmap_coords[8] = {
-	0.0, 0.0,
-	1.0, 0.0,
-	1.0, 1.0,
-	0.0, 1.0,
-    };
-    GLfloat xscale, yscale;
-    glamor_pixmap_private *pixmap_priv;
-   
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
-    glamor_set_normalize_vcoords(xscale, yscale,
-				 x, y,
-				 x + w, y + h,
-				 glamor_priv->yInverted,
-				 dest_coords);
-
-    glamor_fallback("glamor_put_image_xybitmap: disabled\n");
-    goto fail;
-
-    if (glamor_priv->put_image_xybitmap_prog == 0) {
-	ErrorF("no program for xybitmap putimage\n");
-	goto fail;
-    }
-
-    glamor_set_alu(gc->alu);
-    if (!glamor_set_planemask(pixmap, gc->planemask))
+	ScreenPtr screen = drawable->pScreen;
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	float fg[4], bg[4];
+	GLuint tex;
+	unsigned int stride = PixmapBytePad(1, w + left_pad);
+	RegionPtr clip;
+	BoxPtr box;
+	int nbox;
+	float dest_coords[8];
+	const float bitmap_coords[8] = {
+		0.0, 0.0,
+		1.0, 0.0,
+		1.0, 1.0,
+		0.0, 1.0,
+	};
+	GLfloat xscale, yscale;
+	glamor_pixmap_private *pixmap_priv;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
+	glamor_set_normalize_vcoords(xscale, yscale,
+				     x, y,
+				     x + w, y + h,
+				     glamor_priv->yInverted, dest_coords);
+
+	glamor_fallback("glamor_put_image_xybitmap: disabled\n");
 	goto fail;
 
-    dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
-
-    glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
-    dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location,
-		    1, fg);
-    glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
-    dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location,
-		    1, bg);
-
-    dispatch->glGenTextures(1, &tex);
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glEnable(GL_TEXTURE_2D);
-    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
-		 w, h, 0,
-		 GL_COLOR_INDEX, GL_BITMAP, bits);
-    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-    dispatch->glEnable(GL_TEXTURE_2D);
-
-    /* Now that we've set up our bitmap texture and the shader, shove
-     * the destination rectangle through the cliprects and run the
-     * shader on the resulting fragments.
-     */
-    dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
-    dispatch->glEnableClientState(GL_VERTEX_ARRAY);
-    dispatch->glClientActiveTexture(GL_TEXTURE0);
-    dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
-    dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-    dispatch->glEnable(GL_SCISSOR_TEST);
-    clip = fbGetCompositeClip(gc);
-    for (nbox = REGION_NUM_RECTS(clip),
-	 box = REGION_RECTS(clip);
-	 nbox--;
-	 box++)
-    {
-	int x1 = x;
-	int y1 = y;
-	int x2 = x + w;
-	int y2 = y + h;
-
-	if (x1 < box->x1)
-	    x1 = box->x1;
-	if (y1 < box->y1)
-	    y1 = box->y1;
-	if (x2 > box->x2)
-	    x2 = box->x2;
-	if (y2 > box->y2)
-	    y2 = box->y2;
-	if (x1 >= x2 || y1 >= y2)
-	    continue;
-
-	dispatch->glScissor(box->x1,
-		  y_flip(pixmap, box->y1),
-		  box->x2 - box->x1,
-		  box->y2 - box->y1);
-	dispatch->glDrawArrays(GL_QUADS, 0, 4);
-    }
-
-    dispatch->glDisable(GL_SCISSOR_TEST);
-    glamor_set_alu(GXcopy);
-    glamor_set_planemask(pixmap, ~0);
-    dispatch->glDeleteTextures(1, &tex);
-    dispatch->glDisable(GL_TEXTURE_2D);
-    dispatch->glDisableClientState(GL_VERTEX_ARRAY);
-    dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    return;
-    glamor_set_alu(GXcopy);
-    glamor_set_planemask(pixmap, ~0);
-    glamor_fallback(": to %p (%c)\n",
-		    drawable, glamor_get_drawable_location(drawable));
-fail:
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits);
-	glamor_finish_access(drawable);
-    }
+	if (glamor_priv->put_image_xybitmap_prog == 0) {
+		ErrorF("no program for xybitmap putimage\n");
+		goto fail;
+	}
+
+	glamor_set_alu(gc->alu);
+	if (!glamor_set_planemask(pixmap, gc->planemask))
+		goto fail;
+
+	dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
+
+	glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
+	dispatch->glUniform4fv
+	    (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
+	glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
+	dispatch->glUniform4fv
+	    (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
+
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
+	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
+	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+			       w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
+	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+	dispatch->glEnable(GL_TEXTURE_2D);
+
+	/* Now that we've set up our bitmap texture and the shader, shove
+	 * the destination rectangle through the cliprects and run the
+	 * shader on the resulting fragments.
+	 */
+	dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
+	dispatch->glEnableClientState(GL_VERTEX_ARRAY);
+	dispatch->glClientActiveTexture(GL_TEXTURE0);
+	dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
+	dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	dispatch->glEnable(GL_SCISSOR_TEST);
+	clip = fbGetCompositeClip(gc);
+	for (nbox = REGION_NUM_RECTS(clip),
+	     box = REGION_RECTS(clip); nbox--; box++) {
+		int x1 = x;
+		int y1 = y;
+		int x2 = x + w;
+		int y2 = y + h;
+
+		if (x1 < box->x1)
+			x1 = box->x1;
+		if (y1 < box->y1)
+			y1 = box->y1;
+		if (x2 > box->x2)
+			x2 = box->x2;
+		if (y2 > box->y2)
+			y2 = box->y2;
+		if (x1 >= x2 || y1 >= y2)
+			continue;
+
+		dispatch->glScissor(box->x1,
+				    y_flip(pixmap, box->y1),
+				    box->x2 - box->x1, box->y2 - box->y1);
+		dispatch->glDrawArrays(GL_QUADS, 0, 4);
+	}
+
+	dispatch->glDisable(GL_SCISSOR_TEST);
+	glamor_set_alu(GXcopy);
+	glamor_set_planemask(pixmap, ~0);
+	dispatch->glDeleteTextures(1, &tex);
+	dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glDisableClientState(GL_VERTEX_ARRAY);
+	dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+	return;
+	glamor_set_alu(GXcopy);
+	glamor_set_planemask(pixmap, ~0);
+	glamor_fallback(": to %p (%c)\n",
+			drawable, glamor_get_drawable_location(drawable));
+      fail:
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
+			   bits);
+		glamor_finish_access(drawable);
+	}
 }
 #endif
 
@@ -252,166 +244,162 @@ void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int left_pad, int image_format, char *bits)
 {
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(drawable->pScreen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    GLenum type, format, iformat;
-    RegionPtr clip;
-    BoxPtr pbox;
-    int nbox;
-    int src_stride = PixmapBytePad(w, drawable->depth);
-    int x_off, y_off;
-    float vertices[8], texcoords[8];
-    GLfloat xscale, yscale, txscale, tyscale;
-    GLuint tex;
-    int no_alpha, no_revert;
-    if (image_format == XYBitmap) {
-	assert(depth == 1);
-        goto fail;
-	return;
-    }
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-	glamor_fallback("has no fbo.\n");
-        goto fail;
-    }
-
-    if (image_format != ZPixmap) {
-	glamor_fallback("non-ZPixmap\n");
-	goto fail;
-    }
-
-    if (!glamor_set_planemask(pixmap, gc->planemask)) {
-	goto fail;
-    }
-    glamor_set_alu(dispatch, gc->alu);
-
-    if (glamor_get_tex_format_type_from_pixmap(pixmap,
-                                               &format, 
-                                               &type, 
-                                               &no_alpha,
-                                               &no_revert
-                                               )) {
-      glamor_fallback("unknown depth. %d \n", 
-                     drawable->depth);
-      goto fail;
-    }
-
-    /* XXX consider to reuse a function to do the following work. */
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-    glamor_validate_pixmap(pixmap);
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
-                        2 * sizeof(float),
-                        texcoords);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-      dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
-  		    pixmap->drawable.bitsPerPixel);
-    }
-    else {
-      dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(drawable->pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_pixmap_private *pixmap_priv =
+	    glamor_get_pixmap_private(pixmap);
+	GLenum type, format, iformat;
+	RegionPtr clip;
+	BoxPtr pbox;
+	int nbox;
+	int src_stride = PixmapBytePad(w, drawable->depth);
+	int x_off, y_off;
+	float vertices[8], texcoords[8];
+	GLfloat xscale, yscale, txscale, tyscale;
+	GLuint tex;
+	int no_alpha, no_revert;
+	if (image_format == XYBitmap) {
+		assert(depth == 1);
+		goto fail;
+		return;
+	}
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+		glamor_fallback("has no fbo.\n");
+		goto fail;
+	}
+
+	if (image_format != ZPixmap) {
+		glamor_fallback("non-ZPixmap\n");
+		goto fail;
+	}
+
+	if (!glamor_set_planemask(pixmap, gc->planemask)) {
+		goto fail;
+	}
+	glamor_set_alu(dispatch, gc->alu);
+
+	if (glamor_get_tex_format_type_from_pixmap(pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("unknown depth. %d \n", drawable->depth);
+		goto fail;
+	}
+
+	/* XXX consider to reuse a function to do the following work. */
+	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+	glamor_validate_pixmap(pixmap);
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					texcoords);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH,
+					src_stride * 8 /
+					pixmap->drawable.bitsPerPixel);
+	} else {
+		dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 //      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    }
-    
-    dispatch->glGenTextures(1, &tex);
-    dispatch->glActiveTexture(GL_TEXTURE0);
-    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-      iformat = format;
-    } 
-    else {
-      iformat = GL_RGBA;
-    }
-
-    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
-		 w, h, 0,
-		 format, type, bits);
-
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	}
+
+	dispatch->glGenTextures(1, &tex);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		iformat = format;
+	} else {
+		iformat = GL_RGBA;
+	}
+
+	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
+			       w, h, 0, format, type, bits);
+
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+				  GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+				  GL_NEAREST);
 #ifndef GLAMOR_GLES2
-    dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
 
-    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
-
-    x += drawable->x;
-    y += drawable->y;
-
-    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-    clip = fbGetCompositeClip(gc);
-
-    txscale = 1.0/w;
-    tyscale = 1.0/h;
-    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
-    for (nbox = REGION_NUM_RECTS(clip),
-	 pbox = REGION_RECTS(clip);
-	 nbox--;
-	 pbox++)
-    {
-	int x1 = x;
-	int y1 = y;
-	int x2 = x + w;
-	int y2 = y + h;
-
-	if (x1 < pbox->x1)
-	    x1 = pbox->x1;
-	if (y1 < pbox->y1)
-	    y1 = pbox->y1;
-	if (x2 > pbox->x2)
-	    x2 = pbox->x2;
-	if (y2 > pbox->y2)
-	    y2 = pbox->y2;
-	if (x1 >= x2 || y1 >= y2)
-	    continue;
-
-	glamor_set_normalize_tcoords( txscale, tyscale, 
-				      x1 - x, y1 - y,
-				      x2 - x, y2 - y,
-				      1,
-				      texcoords);
-
-	glamor_set_normalize_vcoords( xscale, yscale,
-				      x1 + x_off, y1 + y_off,
-				      x2 + x_off, y2 + y_off,
-				      glamor_priv->yInverted,
-				      vertices);
-
-	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    }
+	dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+	dispatch->glUniform1i(glamor_priv->
+			      finish_access_no_revert[no_alpha],
+			      no_revert);
+	dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+			      0);
+
+	x += drawable->x;
+	y += drawable->y;
+
+	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+	clip = fbGetCompositeClip(gc);
+
+	txscale = 1.0 / w;
+	tyscale = 1.0 / h;
+	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
+	for (nbox = REGION_NUM_RECTS(clip),
+	     pbox = REGION_RECTS(clip); nbox--; pbox++) {
+		int x1 = x;
+		int y1 = y;
+		int x2 = x + w;
+		int y2 = y + h;
+
+		if (x1 < pbox->x1)
+			x1 = pbox->x1;
+		if (y1 < pbox->y1)
+			y1 = pbox->y1;
+		if (x2 > pbox->x2)
+			x2 = pbox->x2;
+		if (y2 > pbox->y2)
+			y2 = pbox->y2;
+		if (x1 >= x2 || y1 >= y2)
+			continue;
+
+		glamor_set_normalize_tcoords(txscale, tyscale,
+					     x1 - x, y1 - y,
+					     x2 - x, y2 - y, 1, texcoords);
+
+		glamor_set_normalize_vcoords(xscale, yscale,
+					     x1 + x_off, y1 + y_off,
+					     x2 + x_off, y2 + y_off,
+					     glamor_priv->yInverted,
+					     vertices);
+
+		dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	}
 
 #ifndef GLAMOR_GLES2
-    dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-    dispatch->glUseProgram(0);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    dispatch->glDeleteTextures(1, &tex);
-    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    glamor_set_alu(dispatch, GXcopy);
-    glamor_set_planemask(pixmap, ~0);
-    return;
-
-fail:
-    glamor_set_planemask(pixmap, ~0);
-    glamor_fallback("to %p (%c)\n",
-		    drawable, glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
-	fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format,
-		   bits);
-	glamor_finish_access(&pixmap->drawable);
-    }
+	dispatch->glUseProgram(0);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDeleteTextures(1, &tex);
+	if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+		dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+	glamor_set_alu(dispatch, GXcopy);
+	glamor_set_planemask(pixmap, ~0);
+	return;
+
+      fail:
+	glamor_set_planemask(pixmap, ~0);
+	glamor_fallback("to %p (%c)\n",
+			drawable, glamor_get_drawable_location(drawable));
+	if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
+		fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h,
+			   left_pad, image_format, bits);
+		glamor_finish_access(&pixmap->drawable);
+	}
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d649c98..7f52c7b 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -39,446 +39,452 @@
 //#include "glu3/glu3.h"
 
 struct shader_key {
-  enum shader_source source;
-  enum shader_mask mask;
-  enum shader_in in;
+	enum shader_source source;
+	enum shader_mask mask;
+	enum shader_in in;
 };
 
 struct blendinfo {
-  Bool dest_alpha;
-  Bool source_alpha;
-  GLenum source_blend;
-  GLenum dest_blend;
+	Bool dest_alpha;
+	Bool source_alpha;
+	GLenum source_blend;
+	GLenum dest_blend;
 };
 
 static struct blendinfo composite_op_info[] = {
-  [PictOpClear] =       {0, 0, GL_ZERO,                GL_ZERO},
-  [PictOpSrc] =         {0, 0, GL_ONE,                 GL_ZERO},
-  [PictOpDst] =         {0, 0, GL_ZERO,                GL_ONE},
-  [PictOpOver] =        {0, 1, GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA},
-  [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
-  [PictOpIn] =          {1, 0, GL_DST_ALPHA,           GL_ZERO},
-  [PictOpInReverse] =   {0, 1, GL_ZERO,                GL_SRC_ALPHA},
-  [PictOpOut] =         {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
-  [PictOpOutReverse] =  {0, 1, GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA},
-  [PictOpAtop] =        {1, 1, GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA},
-  [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
-  [PictOpXor] =         {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
-  [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
+	[PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
+	[PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
+	[PictOpDst] = {0, 0, GL_ZERO, GL_ONE},
+	[PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
+	[PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+	[PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO},
+	[PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA},
+	[PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+	[PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
+	[PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+	[PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+	[PictOpXor] =
+	    {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+	[PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
 };
 
 static GLuint
-glamor_create_composite_fs(glamor_gl_dispatch *dispatch, struct shader_key *key)
+glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
+			   struct shader_key *key)
 {
-  const char *source_solid_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "uniform vec4 source;\n"
-    "vec4 get_source()\n"
-    "{\n"
-    "	return source;\n"
-    "}\n";
-  const char *source_alpha_pixmap_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 source_texture;\n"
-    "uniform sampler2D source_sampler;\n"
-    "vec4 get_source()\n"
-    "{\n"
-    "	return texture2D(source_sampler, source_texture);\n"
-    "}\n";
-  const char *source_pixmap_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 source_texture;\n"
-    "uniform sampler2D source_sampler;\n"
-    "vec4 get_source()\n"
-    "{\n"
-    "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
-    "}\n";
-  const char *mask_solid_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "uniform vec4 mask;\n"
-    "vec4 get_mask()\n"
-    "{\n"
-    "	return mask;\n"
-    "}\n";
-  const char *mask_alpha_pixmap_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 mask_texture;\n"
-    "uniform sampler2D mask_sampler;\n"
-    "vec4 get_mask()\n"
-    "{\n"
-    "	return texture2D(mask_sampler, mask_texture);\n"
-    "}\n";
-  const char *mask_pixmap_fetch =
-    GLAMOR_DEFAULT_PRECISION
-    "varying vec2 mask_texture;\n"
-    "uniform sampler2D mask_sampler;\n"
-    "vec4 get_mask()\n"
-    "{\n"
-    "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
-    "}\n";
-  const char *in_source_only =
-    GLAMOR_DEFAULT_PRECISION
-    "void main()\n"
-    "{\n"
-    "	gl_FragColor = get_source();\n"
-    "}\n";
-  const char *in_normal =
-    GLAMOR_DEFAULT_PRECISION
-    "void main()\n"
-    "{\n"
-    "	gl_FragColor = get_source() * get_mask().a;\n"
-    "}\n";
-  const char *in_ca_source =
-    GLAMOR_DEFAULT_PRECISION
-    "void main()\n"
-    "{\n"
-    "	gl_FragColor = get_source() * get_mask();\n"
-    "}\n";
-  const char *in_ca_alpha =
-    GLAMOR_DEFAULT_PRECISION
-    "void main()\n"
-    "{\n"
-    "	gl_FragColor = get_source().a * get_mask();\n"
-    "}\n";
-  char *source;
-  const char *source_fetch;
-  const char *mask_fetch = "";
-  const char *in;
-  GLuint prog;
-
-  switch (key->source) {
-  case SHADER_SOURCE_SOLID:
-    source_fetch = source_solid_fetch;
-    break;
-  case SHADER_SOURCE_TEXTURE_ALPHA:
-    source_fetch = source_alpha_pixmap_fetch;
-    break;
-  case SHADER_SOURCE_TEXTURE:
-    source_fetch = source_pixmap_fetch;
-    break;
-  default:
-    FatalError("Bad composite shader source");
-  }
-
-  switch (key->mask) {
-  case SHADER_MASK_NONE:
-    break;
-  case SHADER_MASK_SOLID:
-    mask_fetch = mask_solid_fetch;
-    break;
-  case SHADER_MASK_TEXTURE_ALPHA:
-    mask_fetch = mask_alpha_pixmap_fetch;
-    break;
-  case SHADER_MASK_TEXTURE:
-    mask_fetch = mask_pixmap_fetch;
-    break;
-  default:
-    FatalError("Bad composite shader mask");
-  }
-
-  switch (key->in) {
-  case SHADER_IN_SOURCE_ONLY:
-    in = in_source_only;
-    break;
-  case SHADER_IN_NORMAL:
-    in = in_normal;
-    break;
-  case SHADER_IN_CA_SOURCE:
-    in = in_ca_source;
-    break;
-  case SHADER_IN_CA_ALPHA:
-    in = in_ca_alpha;
-    break;
-  default:
-    FatalError("Bad composite IN type");
-  }
-
-  XNFasprintf(&source,
-	      "%s%s%s",
-	      source_fetch,
-	      mask_fetch,
-	      in);
- 
-
-  prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
-  free(source);
-
-  return prog;
+	const char *source_solid_fetch =
+	    GLAMOR_DEFAULT_PRECISION
+	    "uniform vec4 source;\n"
+	    "vec4 get_source()\n" "{\n" "	return source;\n" "}\n";
+	const char *source_alpha_pixmap_fetch =
+	    GLAMOR_DEFAULT_PRECISION
+	    "varying vec2 source_texture;\n"
+	    "uniform sampler2D source_sampler;\n"
+	    "vec4 get_source()\n"
+	    "{\n" "	return texture2D(source_sampler, source_texture);\n"
+	    "}\n";
+	const char *source_pixmap_fetch =
+	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
+	    "uniform sampler2D source_sampler;\n" "vec4 get_source()\n"
+	    "{\n"
+	    "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
+	    "}\n";
+	const char *mask_solid_fetch =
+	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
+	    "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
+	const char *mask_alpha_pixmap_fetch =
+	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
+	    "	return texture2D(mask_sampler, mask_texture);\n" "}\n";
+	const char *mask_pixmap_fetch =
+	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
+	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
+	    "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+	    "}\n";
+	const char *in_source_only =
+	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+	    "	gl_FragColor = get_source();\n" "}\n";
+	const char *in_normal =
+	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+	    "	gl_FragColor = get_source() * get_mask().a;\n" "}\n";
+	const char *in_ca_source =
+	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+	    "	gl_FragColor = get_source() * get_mask();\n" "}\n";
+	const char *in_ca_alpha =
+	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
+	    "	gl_FragColor = get_source().a * get_mask();\n" "}\n";
+	char *source;
+	const char *source_fetch;
+	const char *mask_fetch = "";
+	const char *in;
+	GLuint prog;
+
+	switch (key->source) {
+	case SHADER_SOURCE_SOLID:
+		source_fetch = source_solid_fetch;
+		break;
+	case SHADER_SOURCE_TEXTURE_ALPHA:
+		source_fetch = source_alpha_pixmap_fetch;
+		break;
+	case SHADER_SOURCE_TEXTURE:
+		source_fetch = source_pixmap_fetch;
+		break;
+	default:
+		FatalError("Bad composite shader source");
+	}
+
+	switch (key->mask) {
+	case SHADER_MASK_NONE:
+		break;
+	case SHADER_MASK_SOLID:
+		mask_fetch = mask_solid_fetch;
+		break;
+	case SHADER_MASK_TEXTURE_ALPHA:
+		mask_fetch = mask_alpha_pixmap_fetch;
+		break;
+	case SHADER_MASK_TEXTURE:
+		mask_fetch = mask_pixmap_fetch;
+		break;
+	default:
+		FatalError("Bad composite shader mask");
+	}
+
+	switch (key->in) {
+	case SHADER_IN_SOURCE_ONLY:
+		in = in_source_only;
+		break;
+	case SHADER_IN_NORMAL:
+		in = in_normal;
+		break;
+	case SHADER_IN_CA_SOURCE:
+		in = in_ca_source;
+		break;
+	case SHADER_IN_CA_ALPHA:
+		in = in_ca_alpha;
+		break;
+	default:
+		FatalError("Bad composite IN type");
+	}
+
+	XNFasprintf(&source, "%s%s%s", source_fetch, mask_fetch, in);
+
+
+	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+					source);
+	free(source);
+
+	return prog;
 }
 
 static GLuint
-glamor_create_composite_vs(glamor_gl_dispatch *dispatch, struct shader_key *key)
+glamor_create_composite_vs(glamor_gl_dispatch * dispatch,
+			   struct shader_key *key)
 {
-  const char *main_opening =
-    "attribute vec4 v_position;\n"
-    "attribute vec4 v_texcoord0;\n"
-    "attribute vec4 v_texcoord1;\n"
-    "varying vec2 source_texture;\n"
-    "varying vec2 mask_texture;\n"
-    "void main()\n"
-    "{\n"
-    "	gl_Position = v_position;\n";
-  const char *source_coords =
-    "	source_texture = v_texcoord0.xy;\n";
-  const char *mask_coords =
-    "	mask_texture = v_texcoord1.xy;\n";
-  const char *main_closing =
-    "}\n";
-  const char *source_coords_setup = "";
-  const char *mask_coords_setup = "";
-  char *source;
-  GLuint prog;
-
-  if (key->source != SHADER_SOURCE_SOLID)
-    source_coords_setup = source_coords;
-
-  if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
-    mask_coords_setup = mask_coords;
-
-  XNFasprintf(&source,
-	      "%s%s%s%s",
-	      main_opening,
-	      source_coords_setup,
-	      mask_coords_setup,
-	      main_closing);
-
-  prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
-  free(source);
-
-  return prog;
+	const char *main_opening =
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord0;\n"
+	    "attribute vec4 v_texcoord1;\n"
+	    "varying vec2 source_texture;\n"
+	    "varying vec2 mask_texture;\n"
+	    "void main()\n" "{\n" "	gl_Position = v_position;\n";
+	const char *source_coords =
+	    "	source_texture = v_texcoord0.xy;\n";
+	const char *mask_coords = "	mask_texture = v_texcoord1.xy;\n";
+	const char *main_closing = "}\n";
+	const char *source_coords_setup = "";
+	const char *mask_coords_setup = "";
+	char *source;
+	GLuint prog;
+
+	if (key->source != SHADER_SOURCE_SOLID)
+		source_coords_setup = source_coords;
+
+	if (key->mask != SHADER_MASK_NONE
+	    && key->mask != SHADER_MASK_SOLID)
+		mask_coords_setup = mask_coords;
+
+	XNFasprintf(&source,
+		    "%s%s%s%s",
+		    main_opening,
+		    source_coords_setup, mask_coords_setup, main_closing);
+
+	prog =
+	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
+	free(source);
+
+	return prog;
 }
 
 static void
 glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
-			       glamor_composite_shader *shader)
+			       glamor_composite_shader * shader)
 {
-  GLuint vs, fs, prog;
-  GLint source_sampler_uniform_location, mask_sampler_uniform_location;
-  glamor_screen_private *glamor = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor->dispatch;
-
-  vs = glamor_create_composite_vs(dispatch, key);
-  if (vs == 0)
-    return;
-  fs = glamor_create_composite_fs(dispatch, key);
-  if (fs == 0)
-    return;
-
-  prog = dispatch->glCreateProgram();
-  dispatch->glAttachShader(prog, vs);
-  dispatch->glAttachShader(prog, fs);
-
-  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
-  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
-
-  glamor_link_glsl_prog(dispatch, prog);
-
-  shader->prog = prog;
-
-  dispatch->glUseProgram(prog);
-
-  if (key->source == SHADER_SOURCE_SOLID) {
-    shader->source_uniform_location = dispatch->glGetUniformLocation(prog,
-							      "source");
-  } else {
-    source_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
-							      "source_sampler");
-    dispatch->glUniform1i(source_sampler_uniform_location, 0);
-  }
-
-  if (key->mask != SHADER_MASK_NONE) {
-    if (key->mask == SHADER_MASK_SOLID) {
-      shader->mask_uniform_location = dispatch->glGetUniformLocation(prog,
-							      "mask");
-    } else {
-      mask_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
-							      "mask_sampler");
-      dispatch->glUniform1i(mask_sampler_uniform_location, 1);
-    }
-  }
+	GLuint vs, fs, prog;
+	GLint source_sampler_uniform_location,
+	    mask_sampler_uniform_location;
+	glamor_screen_private *glamor = glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor->dispatch;
+
+	vs = glamor_create_composite_vs(dispatch, key);
+	if (vs == 0)
+		return;
+	fs = glamor_create_composite_fs(dispatch, key);
+	if (fs == 0)
+		return;
+
+	prog = dispatch->glCreateProgram();
+	dispatch->glAttachShader(prog, vs);
+	dispatch->glAttachShader(prog, fs);
+
+	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS,
+				       "v_position");
+	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE,
+				       "v_texcoord0");
+	dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK,
+				       "v_texcoord1");
+
+	glamor_link_glsl_prog(dispatch, prog);
+
+	shader->prog = prog;
+
+	dispatch->glUseProgram(prog);
+
+	if (key->source == SHADER_SOURCE_SOLID) {
+		shader->source_uniform_location =
+		    dispatch->glGetUniformLocation(prog, "source");
+	} else {
+		source_sampler_uniform_location =
+		    dispatch->glGetUniformLocation(prog, "source_sampler");
+		dispatch->glUniform1i(source_sampler_uniform_location, 0);
+	}
+
+	if (key->mask != SHADER_MASK_NONE) {
+		if (key->mask == SHADER_MASK_SOLID) {
+			shader->mask_uniform_location =
+			    dispatch->glGetUniformLocation(prog, "mask");
+		} else {
+			mask_sampler_uniform_location =
+			    dispatch->glGetUniformLocation(prog,
+							   "mask_sampler");
+			dispatch->glUniform1i
+			    (mask_sampler_uniform_location, 1);
+		}
+	}
 }
 
 static glamor_composite_shader *
-glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
+glamor_lookup_composite_shader(ScreenPtr screen, struct
+			       shader_key
+			       *key)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_composite_shader *shader;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_composite_shader *shader;
 
-  shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
-  if (shader->prog == 0)
-    glamor_create_composite_shader(screen, key, shader);
+	shader =
+	    &glamor_priv->composite_shader[key->source][key->
+							mask][key->in];
+	if (shader->prog == 0)
+		glamor_create_composite_shader(screen, key, shader);
 
-  return shader;
+	return shader;
 }
+
 #define GLAMOR_COMPOSITE_VBO_SIZE 8192
 
 static void
 glamor_reset_composite_vbo(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_priv->vbo_offset = 0;
-  glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE;
-  glamor_priv->render_nr_verts = 0;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_priv->vbo_offset = 0;
+	glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE;
+	glamor_priv->render_nr_verts = 0;
 }
 
 
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE);
-  assert(glamor_priv->vb != NULL);
-  glamor_reset_composite_vbo(screen);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE);
+	assert(glamor_priv->vb != NULL);
+	glamor_reset_composite_vbo(screen);
 }
 
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
 			CARD8 op, PicturePtr dest, PicturePtr mask)
 {
-  GLenum source_blend, dest_blend;
-  struct blendinfo *op_info;
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-  if (op >= ARRAY_SIZE(composite_op_info)) {
-    glamor_fallback("unsupported render op %d \n", op);
-    return GL_FALSE;
-  }
-  op_info = &composite_op_info[op];
-
-  source_blend = op_info->source_blend;
-  dest_blend = op_info->dest_blend;
-
-  /* If there's no dst alpha channel, adjust the blend op so that we'll treat
-   * it as always 1.
-   */
-  if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
-    if (source_blend == GL_DST_ALPHA)
-      source_blend = GL_ONE;
-    else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
-      source_blend = GL_ZERO;
-  }
-
-  /* Set up the source alpha value for blending in component alpha mode. */
-  if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
-      op_info->source_alpha) {
-    if (source_blend != GL_ZERO) {
-      glamor_fallback("Dual-source composite blending not supported\n");
-      return GL_FALSE;
-    }
-    if (dest_blend == GL_SRC_ALPHA)
-      dest_blend = GL_SRC_COLOR;
-    else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
-      dest_blend = GL_ONE_MINUS_SRC_COLOR;
-  }
-
-  if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
-    dispatch->glDisable(GL_BLEND);
-  } else {
-    dispatch->glEnable(GL_BLEND);
-    dispatch->glBlendFunc(source_blend, dest_blend);
-  }
-  return TRUE;
+	GLenum source_blend, dest_blend;
+	struct blendinfo *op_info;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	if (op >= ARRAY_SIZE(composite_op_info)) {
+		glamor_fallback("unsupported render op %d \n", op);
+		return GL_FALSE;
+	}
+	op_info = &composite_op_info[op];
+
+	source_blend = op_info->source_blend;
+	dest_blend = op_info->dest_blend;
+
+	/* If there's no dst alpha channel, adjust the blend op so that we'll treat
+	 * it as always 1.
+	 */
+	if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
+		if (source_blend == GL_DST_ALPHA)
+			source_blend = GL_ONE;
+		else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
+			source_blend = GL_ZERO;
+	}
+
+	/* Set up the source alpha value for blending in component alpha mode. */
+	if (mask && mask->componentAlpha
+	    && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha)
+	{
+		if (source_blend != GL_ZERO) {
+			glamor_fallback
+			    ("Dual-source composite blending not supported\n");
+			return GL_FALSE;
+		}
+		if (dest_blend == GL_SRC_ALPHA)
+			dest_blend = GL_SRC_COLOR;
+		else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+			dest_blend = GL_ONE_MINUS_SRC_COLOR;
+	}
+
+	if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
+		dispatch->glDisable(GL_BLEND);
+	} else {
+		dispatch->glEnable(GL_BLEND);
+		dispatch->glBlendFunc(source_blend, dest_blend);
+	}
+	return TRUE;
 }
 
 static void
-glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
-			     glamor_pixmap_private *pixmap_priv)
+glamor_set_composite_texture(ScreenPtr screen, int unit,
+			     PicturePtr picture,
+			     glamor_pixmap_private * pixmap_priv)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  dispatch->glActiveTexture(GL_TEXTURE0 + unit);
-  dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-  switch (picture->repeatType) {
-  case RepeatNone:
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
+	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+	switch (picture->repeatType) {
+	case RepeatNone:
 #ifndef GLAMOR_GLES2
-    /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+		/* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_CLAMP_TO_BORDER);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_CLAMP_TO_BORDER);
 #endif
-    break;
-  case RepeatNormal:
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    break;
-  case RepeatPad:
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    break;
-  case RepeatReflect:
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
-    break;
-  }
-
-  switch (picture->filter) {
-  case PictFilterNearest:
-    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    break;
-  case PictFilterBilinear:
-  default:
-    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    break;
-  }
+		break;
+	case RepeatNormal:
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_REPEAT);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_REPEAT);
+		break;
+	case RepeatPad:
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_CLAMP_TO_EDGE);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_CLAMP_TO_EDGE);
+		break;
+	case RepeatReflect:
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_MIRRORED_REPEAT);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_MIRRORED_REPEAT);
+		break;
+	}
+
+	switch (picture->filter) {
+	case PictFilterNearest:
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+		break;
+	case PictFilterBilinear:
+	default:
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_LINEAR);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_LINEAR);
+		break;
+	}
 #ifndef GLAMOR_GLES2
-  dispatch->glEnable(GL_TEXTURE_2D);
+	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
 }
 
 static void
-glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color, GLint uniform_location)
+glamor_set_composite_solid(glamor_gl_dispatch * dispatch, float *color,
+			   GLint uniform_location)
 {
-  dispatch->glUniform4fv(uniform_location, 1, color);
+	dispatch->glUniform4fv(uniform_location, 1, color);
 }
 
 static int
-compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
+compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src)
 {
-  if (op == PictOpSrc) {
-    if (src->format == dst->format)
-      return 1;
-
-    if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
-      return 1;
-
-    if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
-      return 1;
-  } else if (op == PictOpOver) {
-    if (src->alphaMap || dst->alphaMap)
-      return 0;
-
-    if (src->format != dst->format)
-      return 0;
-
-    if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
-      return 1;
-  }
-
-  return 0;
+	if (op == PictOpSrc) {
+		if (src->format == dst->format)
+			return 1;
+
+		if (src->format == PICT_a8r8g8b8
+		    && dst->format == PICT_x8r8g8b8)
+			return 1;
+
+		if (src->format == PICT_a8b8g8r8
+		    && dst->format == PICT_x8b8g8r8)
+			return 1;
+	} else if (op == PictOpOver) {
+		if (src->alphaMap || dst->alphaMap)
+			return 0;
+
+		if (src->format != dst->format)
+			return 0;
+
+		if (src->format == PICT_x8r8g8b8
+		    || src->format == PICT_x8b8g8r8)
+			return 1;
+	}
+
+	return 0;
 }
 
 static char
 glamor_get_picture_location(PicturePtr picture)
 {
-  if (picture == NULL)
-    return ' ';
-
-  if (picture->pDrawable == NULL) {
-    switch (picture->pSourcePict->type) {
-    case SourcePictTypeSolidFill:
-      return 'c';
-    case SourcePictTypeLinear:
-      return 'l';
-    case SourcePictTypeRadial:
-      return 'r';
-    default:
-      return '?';
-    }
-  }
-  return glamor_get_drawable_location(picture->pDrawable);
+	if (picture == NULL)
+		return ' ';
+
+	if (picture->pDrawable == NULL) {
+		switch (picture->pSourcePict->type) {
+		case SourcePictTypeSolidFill:
+			return 'c';
+		case SourcePictTypeLinear:
+			return 'l';
+		case SourcePictTypeRadial:
+			return 'r';
+		default:
+			return '?';
+		}
+	}
+	return glamor_get_drawable_location(picture->pDrawable);
 }
 
 static Bool
@@ -488,119 +494,127 @@ glamor_composite_with_copy(CARD8 op,
 			   INT16 x_source,
 			   INT16 y_source,
 			   INT16 x_dest,
-			   INT16 y_dest,
-			   CARD16 width,
-			   CARD16 height)
+			   INT16 y_dest, CARD16 width, CARD16 height)
 {
-  RegionRec region;
-
-  if (!source->pDrawable)
-    return FALSE;
-
-  if (!compatible_formats(op, dest, source))
-    return FALSE;
-
-  if (source->repeat || source->transform)
-    return FALSE;
-
-  x_dest += dest->pDrawable->x;
-  y_dest += dest->pDrawable->y;
-  x_source += source->pDrawable->x;
-  y_source += source->pDrawable->y;
-
-  if (!miComputeCompositeRegion(&region,
-				source, NULL, dest,
-				x_source, y_source,
-				0, 0,
-				x_dest, y_dest,
-				width, height))
-    return TRUE;
-
-  glamor_copy_n_to_n(source->pDrawable,
-		     dest->pDrawable, NULL,
-		     REGION_RECTS(&region),
-		     REGION_NUM_RECTS(&region),
-		     x_source - x_dest, y_source - y_dest,
-		     FALSE, FALSE, 0, NULL);
-  REGION_UNINIT(dest->pDrawable->pScreen,
-		&region);
-  return TRUE;
+	RegionRec region;
+
+	if (!source->pDrawable)
+		return FALSE;
+
+	if (!compatible_formats(op, dest, source))
+		return FALSE;
+
+	if (source->repeat || source->transform)
+		return FALSE;
+
+	x_dest += dest->pDrawable->x;
+	y_dest += dest->pDrawable->y;
+	x_source += source->pDrawable->x;
+	y_source += source->pDrawable->y;
+
+	if (!miComputeCompositeRegion(&region,
+				      source, NULL, dest,
+				      x_source, y_source,
+				      0, 0, x_dest, y_dest, width, height))
+		return TRUE;
+
+	glamor_copy_n_to_n(source->pDrawable,
+			   dest->pDrawable, NULL,
+			   REGION_RECTS(&region),
+			   REGION_NUM_RECTS(&region),
+			   x_source - x_dest, y_source - y_dest,
+			   FALSE, FALSE, 0, NULL);
+	REGION_UNINIT(dest->pDrawable->pScreen, &region);
+	return TRUE;
 }
 
 static void
 glamor_setup_composite_vbo(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-  glamor_priv->vb_stride = 2 * sizeof(float);
-  if (glamor_priv->has_source_coords)
-    glamor_priv->vb_stride += 2 * sizeof(float);
-  if (glamor_priv->has_mask_coords)
-    glamor_priv->vb_stride += 2 * sizeof(float);
-
-  dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
-
-  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
-                        glamor_priv->vb_stride,
-                       (void *)((long)glamor_priv->vbo_offset));
-  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-  if (glamor_priv->has_source_coords) {
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
-                        glamor_priv->vb_stride,
-                       (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-  }
-
-  if (glamor_priv->has_mask_coords) {
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, 
-                        glamor_priv->vb_stride,
-                       (void *)((long)glamor_priv->vbo_offset + 
-			       (glamor_priv->has_source_coords ? 4 : 2) *
-                               sizeof(float)));
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
-  }
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	glamor_priv->vb_stride = 2 * sizeof(float);
+	if (glamor_priv->has_source_coords)
+		glamor_priv->vb_stride += 2 * sizeof(float);
+	if (glamor_priv->has_mask_coords)
+		glamor_priv->vb_stride += 2 * sizeof(float);
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, glamor_priv->vb_stride,
+					(void *) ((long)
+						  glamor_priv->vbo_offset));
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+	if (glamor_priv->has_source_coords) {
+		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+						GL_FLOAT, GL_FALSE,
+						glamor_priv->vb_stride,
+						(void *) ((long)
+							  glamor_priv->vbo_offset
+							  +
+							  2 *
+							  sizeof(float)));
+		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	}
+
+	if (glamor_priv->has_mask_coords) {
+		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2,
+						GL_FLOAT, GL_FALSE,
+						glamor_priv->vb_stride,
+						(void *) ((long)
+							  glamor_priv->vbo_offset
+							  +
+							  (glamor_priv->has_source_coords
+							   ? 4 : 2) *
+							  sizeof(float)));
+		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
+	}
 }
 
 static void
 glamor_emit_composite_vert(ScreenPtr screen,
 			   const float *src_coords,
 			   const float *mask_coords,
-			   const float *dst_coords,
-			   int i)
+			   const float *dst_coords, int i)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset);
-  int j = 0;
-
-  vb[j++] = dst_coords[i * 2 + 0];
-  vb[j++] = dst_coords[i * 2 + 1];
-  if (glamor_priv->has_source_coords) {
-    vb[j++] = src_coords[i * 2 + 0];
-    vb[j++] = src_coords[i * 2 + 1];
-  }
-  if (glamor_priv->has_mask_coords) {
-    vb[j++] = mask_coords[i * 2 + 0];
-    vb[j++] = mask_coords[i * 2 + 1];
-  }
-
-  glamor_priv->render_nr_verts++;
-  glamor_priv->vbo_offset += glamor_priv->vb_stride;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	float *vb = (float *) (glamor_priv->vb + glamor_priv->vbo_offset);
+	int j = 0;
+
+	vb[j++] = dst_coords[i * 2 + 0];
+	vb[j++] = dst_coords[i * 2 + 1];
+	if (glamor_priv->has_source_coords) {
+		vb[j++] = src_coords[i * 2 + 0];
+		vb[j++] = src_coords[i * 2 + 1];
+	}
+	if (glamor_priv->has_mask_coords) {
+		vb[j++] = mask_coords[i * 2 + 0];
+		vb[j++] = mask_coords[i * 2 + 1];
+	}
+
+	glamor_priv->render_nr_verts++;
+	glamor_priv->vbo_offset += glamor_priv->vb_stride;
 }
 
 static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  if (!glamor_priv->render_nr_verts)
-    return;
-  dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
-	    GL_STREAM_DRAW);
-
-  dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
-  glamor_reset_composite_vbo(screen);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	if (!glamor_priv->render_nr_verts)
+		return;
+	dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
+			       glamor_priv->vb, GL_STREAM_DRAW);
+
+	dispatch->glDrawArrays(GL_TRIANGLES, 0,
+			       glamor_priv->render_nr_verts);
+	glamor_reset_composite_vbo(screen);
 }
 
 static void
@@ -609,93 +623,100 @@ glamor_emit_composite_rect(ScreenPtr screen,
 			   const float *mask_coords,
 			   const float *dst_coords)
 {
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-  if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
-      glamor_priv->vbo_size)
-    {
-      glamor_flush_composite_rects(screen);
-    }
-
-  if (glamor_priv->vbo_offset == 0) {
-    if (glamor_priv->vbo == 0)
-      dispatch->glGenBuffers(1, &glamor_priv->vbo);
-
-    glamor_setup_composite_vbo(screen);
-  }
-
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
-  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
+	    glamor_priv->vbo_size) {
+		glamor_flush_composite_rects(screen);
+	}
+
+	if (glamor_priv->vbo_offset == 0) {
+		if (glamor_priv->vbo == 0)
+			dispatch->glGenBuffers(1, &glamor_priv->vbo);
+
+		glamor_setup_composite_vbo(screen);
+	}
+
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 0);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 1);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 2);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 0);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 2);
+	glamor_emit_composite_vert(screen, src_coords, mask_coords,
+				   dst_coords, 3);
 }
 
 
-int pict_format_combine_tab[][3] = 
-  {
-    {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
-    {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
-  };
+int pict_format_combine_tab[][3] = {
+	{PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
+	{PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
+};
 
-static Bool 
-combine_pict_format(PictFormatShort *des, const PictFormatShort src, 
-                    const PictFormatShort mask, enum shader_in in_ca)
+static Bool
+combine_pict_format(PictFormatShort * des, const PictFormatShort src,
+		    const PictFormatShort mask, enum shader_in in_ca)
 {
-  PictFormatShort new_vis;
-  int src_type, mask_type, src_bpp, mask_bpp;
-  int i;
-  if (src == mask) {
-    *des = src;
-    return TRUE;
-  }
-  src_bpp = PICT_FORMAT_BPP(src);
-  mask_bpp = PICT_FORMAT_BPP(mask);
-
-  assert(src_bpp == mask_bpp);
- 
-  new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
-
-  switch(in_ca) {
-  case SHADER_IN_SOURCE_ONLY:
-    return TRUE;
-  case SHADER_IN_NORMAL:
-    src_type = PICT_FORMAT_TYPE(src);
-    mask_type = PICT_TYPE_A;
-    break;
-  case SHADER_IN_CA_SOURCE:
-    src_type = PICT_FORMAT_TYPE(src);
-    mask_type = PICT_FORMAT_TYPE(mask);
-    break;
-  case SHADER_IN_CA_ALPHA:
-    src_type = PICT_TYPE_A;
-    mask_type = PICT_FORMAT_TYPE(mask);
-    break;
-  default:
-    return FALSE;
-  }
-
-
-  if (src_type == mask_type) {
-    *des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
-    return TRUE;
-  }
-
-  for(i = 0; 
-      i < sizeof(pict_format_combine_tab)/sizeof(pict_format_combine_tab[0]);
-      i++) 
-    {
-      if ((src_type == pict_format_combine_tab[i][0] 
-	   && mask_type == pict_format_combine_tab[i][1])
-	  ||(src_type == pict_format_combine_tab[i][1]
-	     && mask_type == pict_format_combine_tab[i][0])) {
-        *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i][2], new_vis);
-        return TRUE;
-      } 
-    } 
-  return FALSE;
+	PictFormatShort new_vis;
+	int src_type, mask_type, src_bpp, mask_bpp;
+	int i;
+	if (src == mask) {
+		*des = src;
+		return TRUE;
+	}
+	src_bpp = PICT_FORMAT_BPP(src);
+	mask_bpp = PICT_FORMAT_BPP(mask);
+
+	assert(src_bpp == mask_bpp);
+
+	new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
+
+	switch (in_ca) {
+	case SHADER_IN_SOURCE_ONLY:
+		return TRUE;
+	case SHADER_IN_NORMAL:
+		src_type = PICT_FORMAT_TYPE(src);
+		mask_type = PICT_TYPE_A;
+		break;
+	case SHADER_IN_CA_SOURCE:
+		src_type = PICT_FORMAT_TYPE(src);
+		mask_type = PICT_FORMAT_TYPE(mask);
+		break;
+	case SHADER_IN_CA_ALPHA:
+		src_type = PICT_TYPE_A;
+		mask_type = PICT_FORMAT_TYPE(mask);
+		break;
+	default:
+		return FALSE;
+	}
+
+
+	if (src_type == mask_type) {
+		*des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
+		return TRUE;
+	}
+
+	for (i = 0;
+	     i <
+	     sizeof(pict_format_combine_tab) /
+	     sizeof(pict_format_combine_tab[0]); i++) {
+		if ((src_type == pict_format_combine_tab[i][0]
+		     && mask_type == pict_format_combine_tab[i][1])
+		    || (src_type == pict_format_combine_tab[i][1]
+			&& mask_type == pict_format_combine_tab[i][0])) {
+			*des = PICT_VISFORMAT(src_bpp,
+					      pict_format_combine_tab[i]
+					      [2], new_vis);
+			return TRUE;
+		}
+	}
+	return FALSE;
 }
 
 static Bool
@@ -703,425 +724,470 @@ glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
 			     PicturePtr mask,
 			     PicturePtr dest,
-			     int nrect,
-			     glamor_composite_rect_t *rects)
+			     int nrect, glamor_composite_rect_t * rects)
 {
-  ScreenPtr screen = dest->pDrawable->pScreen;
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-  PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-  PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-  glamor_pixmap_private *source_pixmap_priv = NULL;
-  glamor_pixmap_private *mask_pixmap_priv = NULL;
-  glamor_pixmap_private *dest_pixmap_priv = NULL;
-  GLfloat dst_xscale, dst_yscale;
-  GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
-  struct shader_key key;
-  glamor_composite_shader *shader;
-  RegionRec region;
-  float vertices[8], source_texcoords[8], mask_texcoords[8];
-  int i;
-  BoxPtr box;
-  int dest_x_off, dest_y_off;
-  int source_x_off, source_y_off;
-  int mask_x_off, mask_y_off;
-  enum glamor_pixmap_status source_status = GLAMOR_NONE;
-  enum glamor_pixmap_status mask_status = GLAMOR_NONE;
-  PictFormatShort saved_source_format = 0; 
-  float src_matrix[9], mask_matrix[9];
-  GLfloat source_solid_color[4], mask_solid_color[4];
-
-  dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
-  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-    glamor_fallback("dest has no fbo.\n");
-    goto fail;
-  }
-  memset(&key, 0, sizeof(key));
-  if (!source->pDrawable) {
-    if (source->pSourcePict->type == SourcePictTypeSolidFill) {
-      key.source = SHADER_SOURCE_SOLID;
-      glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color,
-				 &source_solid_color[0], 
-				 &source_solid_color[1], 
-				 &source_solid_color[2], 
-				 &source_solid_color[3], 
-				 PICT_a8r8g8b8);
-    } else {
-      glamor_fallback("gradient source\n");
-      goto fail;
-    }
-  } else {
-    key.source = SHADER_SOURCE_TEXTURE_ALPHA;
-  }
-  if (mask) {
-    if (!mask->pDrawable) {
-      if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
-	key.mask = SHADER_MASK_SOLID;
-        glamor_get_rgba_from_pixel(mask->pSourcePict->solidFill.color,
-				 &mask_solid_color[0], 
-				 &mask_solid_color[1], 
-				 &mask_solid_color[2], 
-				 &mask_solid_color[3], 
-				 PICT_a8r8g8b8);
-      } else {
-	glamor_fallback("gradient mask\n");
-	goto fail;
-      }
-    } else {
-      key.mask = SHADER_MASK_TEXTURE_ALPHA;
-    }
-
-    if (!mask->componentAlpha) {
-      key.in = SHADER_IN_NORMAL;
-    } else {
-      /* We only handle two CA modes. */
-      if (op == PictOpAdd)
-	key.in = SHADER_IN_CA_SOURCE;
-      else if (op == PictOpOutReverse) {
-	key.in = SHADER_IN_CA_ALPHA;
-      } else {
-	glamor_fallback("Unsupported component alpha op: %d\n", op);
-	goto fail;
-      }
-    }
-  } else {
-    key.mask = SHADER_MASK_NONE;
-    key.in = SHADER_IN_SOURCE_ONLY;
-  }
-
-  if (source->alphaMap) {
-    glamor_fallback("source alphaMap\n");
-    goto fail;
-  }
-  if (mask && mask->alphaMap) {
-    glamor_fallback("mask alphaMap\n");
-    goto fail;
-  }
-  if (key.source == SHADER_SOURCE_TEXTURE ||
-      key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
-    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-    if (source_pixmap == dest_pixmap) {
-      glamor_fallback("source == dest\n");
-      goto fail;
-    }
-    if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
-    /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
-     * equal to zero when the pixmap is screen pixmap. Then we may
-     * refer the tex zero directly latter in the composition. 
-     * It seems that it works fine, but it may have potential problem*/
+	ScreenPtr screen = dest->pDrawable->pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	PixmapPtr dest_pixmap =
+	    glamor_get_drawable_pixmap(dest->pDrawable);
+	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+	glamor_pixmap_private *source_pixmap_priv = NULL;
+	glamor_pixmap_private *mask_pixmap_priv = NULL;
+	glamor_pixmap_private *dest_pixmap_priv = NULL;
+	GLfloat dst_xscale, dst_yscale;
+	GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale =
+	    1, src_yscale = 1;
+	struct shader_key key;
+	glamor_composite_shader *shader;
+	RegionRec region;
+	float vertices[8], source_texcoords[8], mask_texcoords[8];
+	int i;
+	BoxPtr box;
+	int dest_x_off, dest_y_off;
+	int source_x_off, source_y_off;
+	int mask_x_off, mask_y_off;
+	enum glamor_pixmap_status source_status = GLAMOR_NONE;
+	enum glamor_pixmap_status mask_status = GLAMOR_NONE;
+	PictFormatShort saved_source_format = 0;
+	float src_matrix[9], mask_matrix[9];
+	GLfloat source_solid_color[4], mask_solid_color[4];
+
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		glamor_fallback("dest has no fbo.\n");
+		goto fail;
+	}
+	memset(&key, 0, sizeof(key));
+	if (!source->pDrawable) {
+		if (source->pSourcePict->type == SourcePictTypeSolidFill) {
+			key.source = SHADER_SOURCE_SOLID;
+			glamor_get_rgba_from_pixel(source->
+						   pSourcePict->solidFill.
+						   color,
+						   &source_solid_color[0],
+						   &source_solid_color[1],
+						   &source_solid_color[2],
+						   &source_solid_color[3],
+						   PICT_a8r8g8b8);
+		} else {
+			glamor_fallback("gradient source\n");
+			goto fail;
+		}
+	} else {
+		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+	}
+	if (mask) {
+		if (!mask->pDrawable) {
+			if (mask->pSourcePict->type ==
+			    SourcePictTypeSolidFill) {
+				key.mask = SHADER_MASK_SOLID;
+				glamor_get_rgba_from_pixel
+				    (mask->pSourcePict->solidFill.color,
+				     &mask_solid_color[0],
+				     &mask_solid_color[1],
+				     &mask_solid_color[2],
+				     &mask_solid_color[3], PICT_a8r8g8b8);
+			} else {
+				glamor_fallback("gradient mask\n");
+				goto fail;
+			}
+		} else {
+			key.mask = SHADER_MASK_TEXTURE_ALPHA;
+		}
+
+		if (!mask->componentAlpha) {
+			key.in = SHADER_IN_NORMAL;
+		} else {
+			/* We only handle two CA modes. */
+			if (op == PictOpAdd)
+				key.in = SHADER_IN_CA_SOURCE;
+			else if (op == PictOpOutReverse) {
+				key.in = SHADER_IN_CA_ALPHA;
+			} else {
+				glamor_fallback
+				    ("Unsupported component alpha op: %d\n",
+				     op);
+				goto fail;
+			}
+		}
+	} else {
+		key.mask = SHADER_MASK_NONE;
+		key.in = SHADER_IN_SOURCE_ONLY;
+	}
+
+	if (source->alphaMap) {
+		glamor_fallback("source alphaMap\n");
+		goto fail;
+	}
+	if (mask && mask->alphaMap) {
+		glamor_fallback("mask alphaMap\n");
+		goto fail;
+	}
+	if (key.source == SHADER_SOURCE_TEXTURE ||
+	    key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
+		source_pixmap =
+		    glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv =
+		    glamor_get_pixmap_private(source_pixmap);
+		if (source_pixmap == dest_pixmap) {
+			glamor_fallback("source == dest\n");
+			goto fail;
+		}
+		if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
+			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
+			 * equal to zero when the pixmap is screen pixmap. Then we may
+			 * refer the tex zero directly latter in the composition. 
+			 * It seems that it works fine, but it may have potential problem*/
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-      source_status = GLAMOR_UPLOAD_PENDING;
+			source_status = GLAMOR_UPLOAD_PENDING;
 #else
-      glamor_fallback("no texture in source\n");
-      goto fail;
+			glamor_fallback("no texture in source\n");
+			goto fail;
 #endif
-    } 
-    else if (source_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
-      key.source = SHADER_SOURCE_SOLID;
-      memcpy(source_solid_color, source_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
-    }
-  }
-  if (key.mask == SHADER_MASK_TEXTURE ||
-      key.mask == SHADER_MASK_TEXTURE_ALPHA) {
-    mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-    mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-    if (mask_pixmap == dest_pixmap) {
-      glamor_fallback("mask == dest\n");
-      goto fail;
-    }
-    if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) {
+		} else if (source_pixmap_priv->pending_op.type ==
+			   GLAMOR_PENDING_FILL) {
+			key.source = SHADER_SOURCE_SOLID;
+			memcpy(source_solid_color,
+			       source_pixmap_priv->pending_op.
+			       fill.color4fv, 4 * sizeof(float));
+		}
+	}
+	if (key.mask == SHADER_MASK_TEXTURE ||
+	    key.mask == SHADER_MASK_TEXTURE_ALPHA) {
+		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+		if (mask_pixmap == dest_pixmap) {
+			glamor_fallback("mask == dest\n");
+			goto fail;
+		}
+		if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-      mask_status = GLAMOR_UPLOAD_PENDING;
+			mask_status = GLAMOR_UPLOAD_PENDING;
 #else
-      glamor_fallback("no texture in mask\n");
-      goto fail;
+			glamor_fallback("no texture in mask\n");
+			goto fail;
 #endif
-    }
-    else if (mask_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
-      key.mask = SHADER_MASK_SOLID;
-      memcpy(mask_solid_color, mask_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
-    }
-  }
+		} else if (mask_pixmap_priv->pending_op.type ==
+			   GLAMOR_PENDING_FILL) {
+			key.mask = SHADER_MASK_SOLID;
+			memcpy(mask_solid_color,
+			       mask_pixmap_priv->pending_op.fill.color4fv,
+			       4 * sizeof(float));
+		}
+	}
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-  if (source_status == GLAMOR_UPLOAD_PENDING 
-      && mask_status == GLAMOR_UPLOAD_PENDING 
-      && source_pixmap == mask_pixmap) {
-
-    if (source->format != mask->format) {
-      saved_source_format = source->format;
-
-      if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) {
-	glamor_fallback("combine source %x mask %x failed.\n", 
-			source->format, mask->format);
-	goto fail;
-      }
-
-      if (source->format != saved_source_format) {
-	glamor_picture_format_fixup(source, source_pixmap_priv);
-      }
-      /* XXX  
-       * By default, glamor_upload_picture_to_texture will wire alpha to 1
-       * if one picture doesn't have alpha. So we don't do that again in 
-       * rendering function. But here is a special case, as source and
-       * mask share the same texture but may have different formats. For 
-       * example, source doesn't have alpha, but mask has alpha. Then the
-       * texture will have the alpha value for the mask. And will not wire
-       * to 1 for the source. In this case, we have to use different shader
-       * to wire the source's alpha to 1.
-       *
-       * But this may cause a potential problem if the source's repeat mode 
-       * is REPEAT_NONE, and if the source is smaller than the dest, then
-       * for the region not covered by the source may be painted incorrectly.
-       * because we wire the alpha to 1.
-       *
-       **/ 
-      if (!PICT_FORMAT_A(saved_source_format) && PICT_FORMAT_A(mask->format))
-	key.source = SHADER_SOURCE_TEXTURE;
-    
-      if (!PICT_FORMAT_A(mask->format) && PICT_FORMAT_A(saved_source_format))
-	key.mask = SHADER_MASK_TEXTURE;
-
-      mask_status = GLAMOR_NONE;
-    }
-    source_status = glamor_upload_picture_to_texture(source);
-     
-    if (source_status != GLAMOR_UPLOAD_DONE) {
-      glamor_fallback("Failed to upload source texture.\n");
-      goto fail;
-    }
-  } 
-  else {
-
-    if (source_status == GLAMOR_UPLOAD_PENDING) {
-      source_status = glamor_upload_picture_to_texture(source);
-      if (source_status != GLAMOR_UPLOAD_DONE) {
-	glamor_fallback("Failed to upload source texture.\n");
-	goto fail;
-      }
-    }
-
-    if (mask_status == GLAMOR_UPLOAD_PENDING) {
-      mask_status = glamor_upload_picture_to_texture(mask);
-      if (mask_status != GLAMOR_UPLOAD_DONE) {
-	glamor_fallback("Failed to upload mask texture.\n");
-	goto fail;
-      }
-    }
-  }
+	if (source_status == GLAMOR_UPLOAD_PENDING
+	    && mask_status == GLAMOR_UPLOAD_PENDING
+	    && source_pixmap == mask_pixmap) {
+
+		if (source->format != mask->format) {
+			saved_source_format = source->format;
+
+			if (!combine_pict_format
+			    (&source->format, source->format,
+			     mask->format, key.in)) {
+				glamor_fallback
+				    ("combine source %x mask %x failed.\n",
+				     source->format, mask->format);
+				goto fail;
+			}
+
+			if (source->format != saved_source_format) {
+				glamor_picture_format_fixup(source,
+							    source_pixmap_priv);
+			}
+			/* XXX  
+			 * By default, glamor_upload_picture_to_texture will wire alpha to 1
+			 * if one picture doesn't have alpha. So we don't do that again in 
+			 * rendering function. But here is a special case, as source and
+			 * mask share the same texture but may have different formats. For 
+			 * example, source doesn't have alpha, but mask has alpha. Then the
+			 * texture will have the alpha value for the mask. And will not wire
+			 * to 1 for the source. In this case, we have to use different shader
+			 * to wire the source's alpha to 1.
+			 *
+			 * But this may cause a potential problem if the source's repeat mode 
+			 * is REPEAT_NONE, and if the source is smaller than the dest, then
+			 * for the region not covered by the source may be painted incorrectly.
+			 * because we wire the alpha to 1.
+			 *
+			 **/
+			if (!PICT_FORMAT_A(saved_source_format)
+			    && PICT_FORMAT_A(mask->format))
+				key.source = SHADER_SOURCE_TEXTURE;
+
+			if (!PICT_FORMAT_A(mask->format)
+			    && PICT_FORMAT_A(saved_source_format))
+				key.mask = SHADER_MASK_TEXTURE;
+
+			mask_status = GLAMOR_NONE;
+		}
+		source_status = glamor_upload_picture_to_texture(source);
+
+		if (source_status != GLAMOR_UPLOAD_DONE) {
+			glamor_fallback
+			    ("Failed to upload source texture.\n");
+			goto fail;
+		}
+	} else {
+
+		if (source_status == GLAMOR_UPLOAD_PENDING) {
+			source_status =
+			    glamor_upload_picture_to_texture(source);
+			if (source_status != GLAMOR_UPLOAD_DONE) {
+				glamor_fallback
+				    ("Failed to upload source texture.\n");
+				goto fail;
+			}
+		}
+
+		if (mask_status == GLAMOR_UPLOAD_PENDING) {
+			mask_status =
+			    glamor_upload_picture_to_texture(mask);
+			if (mask_status != GLAMOR_UPLOAD_DONE) {
+				glamor_fallback
+				    ("Failed to upload mask texture.\n");
+				goto fail;
+			}
+		}
+	}
 #endif
-  glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
-  glamor_validate_pixmap(dest_pixmap);
-  if (!glamor_set_composite_op(screen, op, dest, mask)) {
-    goto fail;
-  }
-
-  shader = glamor_lookup_composite_shader(screen, &key);
-  if (shader->prog == 0) {
-    glamor_fallback("no shader program for this render acccel mode\n");
-    goto fail;
-  }
-
-  dispatch->glUseProgram(shader->prog);
-
-
-  if (key.source == SHADER_SOURCE_SOLID) {
-    glamor_set_composite_solid(dispatch, source_solid_color, shader->source_uniform_location);
-  } else {
-    glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
-  }
-  if (key.mask != SHADER_MASK_NONE) {
-    if (key.mask == SHADER_MASK_SOLID) {
-      glamor_set_composite_solid(dispatch, mask_solid_color, shader->mask_uniform_location);
-    } else {
-      glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
-    }
-  }
-
-  glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
-  glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
-				  key.mask != SHADER_MASK_SOLID);
-
-  glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
-			     &dest_x_off, &dest_y_off);
-  pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
-
-
-
-  if (glamor_priv->has_source_coords) {
-    glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
-			       &source_x_off, &source_y_off);
-    pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
-    glamor_picture_get_matrixf(source, src_matrix);
-  }
-
-  if (glamor_priv->has_mask_coords) {
-    glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
-			       &mask_x_off, &mask_y_off);
-    pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
-    glamor_picture_get_matrixf(mask, mask_matrix);
-  }
-
-  while (nrect--) {
-    INT16 x_source;
-    INT16 y_source;
-    INT16 x_mask;
-    INT16 y_mask;
-    INT16 x_dest;
-    INT16 y_dest;
-    CARD16 width;
-    CARD16 height;
-
-    x_dest = rects->x_dst;
-    y_dest = rects->y_dst;
-    x_source = rects->x_src;
-    y_source = rects->y_src;
-    x_mask = rects->x_mask;
-    y_mask = rects->y_mask;
-    width = rects->width;
-    height = rects->height;
-
-    x_dest += dest->pDrawable->x;
-    y_dest += dest->pDrawable->y;
-    if (source->pDrawable) {
-      x_source += source->pDrawable->x;
-      y_source += source->pDrawable->y;
-    }
-    if (mask && mask->pDrawable) {
-      x_mask += mask->pDrawable->x;
-      y_mask += mask->pDrawable->y;
-    }
-
-    if (!miComputeCompositeRegion(&region,
-				  source, mask, dest,
-				  x_source, y_source,
-				  x_mask, y_mask,
-				  x_dest, y_dest,
-				  width, height))
-      continue;
-
-    x_source += source_x_off;
-    y_source += source_y_off;
-    x_mask += mask_x_off;
-    y_mask += mask_y_off;
-   
-    box = REGION_RECTS(&region);
-    for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-      int vx1 = box[i].x1 + dest_x_off;
-      int vx2 = box[i].x2 + dest_x_off;
-      int vy1 = box[i].y1 + dest_y_off;
-      int vy2 = box[i].y2 + dest_y_off;
-     glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, 
-				   glamor_priv->yInverted, vertices);
-
-      if (key.source != SHADER_SOURCE_SOLID) {
-	int tx1 = box[i].x1 + x_source - x_dest;
-	int ty1 = box[i].y1 + y_source - y_dest;
-	int tx2 = box[i].x2 + x_source - x_dest;
-	int ty2 = box[i].y2 + y_source - y_dest;
-	if (source->transform)
-	  glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale, src_yscale, 
-						   tx1, ty1, tx2, ty2,
-						   glamor_priv->yInverted, 
-						   source_texcoords);
-	else
-	  glamor_set_normalize_tcoords(src_xscale, src_yscale, tx1, ty1, tx2, ty2,
-				       glamor_priv->yInverted, source_texcoords);
-      }   
-
-      if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-	float tx1 = box[i].x1 + x_mask - x_dest;
-	float ty1 = box[i].y1 + y_mask - y_dest;
-	float tx2 = box[i].x2 + x_mask - x_dest;
-	float ty2 = box[i].y2 + y_mask - y_dest;
-	if (mask->transform)
-	  glamor_set_transformed_normalize_tcoords(mask_matrix, mask_xscale, mask_yscale, 
-						   tx1, ty1, tx2, ty2,
-						   glamor_priv->yInverted, 
-						   mask_texcoords);
-	else
-	  glamor_set_normalize_tcoords(mask_xscale, mask_yscale, tx1, ty1, tx2, ty2,
-				       glamor_priv->yInverted, mask_texcoords);
-      }
-      glamor_emit_composite_rect(screen, source_texcoords,
-				 mask_texcoords, vertices);
-    }
-    rects++;
-  }
-  glamor_flush_composite_rects(screen);
-
-  dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
-  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-  REGION_UNINIT(dst->pDrawable->pScreen, &region);
-  dispatch->glDisable(GL_BLEND);
+	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+	glamor_validate_pixmap(dest_pixmap);
+	if (!glamor_set_composite_op(screen, op, dest, mask)) {
+		goto fail;
+	}
+
+	shader = glamor_lookup_composite_shader(screen, &key);
+	if (shader->prog == 0) {
+		glamor_fallback
+		    ("no shader program for this render acccel mode\n");
+		goto fail;
+	}
+
+	dispatch->glUseProgram(shader->prog);
+
+
+	if (key.source == SHADER_SOURCE_SOLID) {
+		glamor_set_composite_solid(dispatch, source_solid_color,
+					   shader->source_uniform_location);
+	} else {
+		glamor_set_composite_texture(screen, 0, source,
+					     source_pixmap_priv);
+	}
+	if (key.mask != SHADER_MASK_NONE) {
+		if (key.mask == SHADER_MASK_SOLID) {
+			glamor_set_composite_solid(dispatch,
+						   mask_solid_color,
+						   shader->mask_uniform_location);
+		} else {
+			glamor_set_composite_texture(screen, 1, mask,
+						     mask_pixmap_priv);
+		}
+	}
+
+	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+					key.mask != SHADER_MASK_SOLID);
+
+	glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
+				   &dest_x_off, &dest_y_off);
+	pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+
+
+
+	if (glamor_priv->has_source_coords) {
+		glamor_get_drawable_deltas(source->pDrawable,
+					   source_pixmap, &source_x_off,
+					   &source_y_off);
+		pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
+				      &src_yscale);
+		glamor_picture_get_matrixf(source, src_matrix);
+	}
+
+	if (glamor_priv->has_mask_coords) {
+		glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
+					   &mask_x_off, &mask_y_off);
+		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
+				      &mask_yscale);
+		glamor_picture_get_matrixf(mask, mask_matrix);
+	}
+
+	while (nrect--) {
+		INT16 x_source;
+		INT16 y_source;
+		INT16 x_mask;
+		INT16 y_mask;
+		INT16 x_dest;
+		INT16 y_dest;
+		CARD16 width;
+		CARD16 height;
+
+		x_dest = rects->x_dst;
+		y_dest = rects->y_dst;
+		x_source = rects->x_src;
+		y_source = rects->y_src;
+		x_mask = rects->x_mask;
+		y_mask = rects->y_mask;
+		width = rects->width;
+		height = rects->height;
+
+		x_dest += dest->pDrawable->x;
+		y_dest += dest->pDrawable->y;
+		if (source->pDrawable) {
+			x_source += source->pDrawable->x;
+			y_source += source->pDrawable->y;
+		}
+		if (mask && mask->pDrawable) {
+			x_mask += mask->pDrawable->x;
+			y_mask += mask->pDrawable->y;
+		}
+
+		if (!miComputeCompositeRegion(&region,
+					      source, mask, dest,
+					      x_source, y_source,
+					      x_mask, y_mask,
+					      x_dest, y_dest, width,
+					      height))
+			continue;
+
+		x_source += source_x_off;
+		y_source += source_y_off;
+		x_mask += mask_x_off;
+		y_mask += mask_y_off;
+
+		box = REGION_RECTS(&region);
+		for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
+			int vx1 = box[i].x1 + dest_x_off;
+			int vx2 = box[i].x2 + dest_x_off;
+			int vy1 = box[i].y1 + dest_y_off;
+			int vy2 = box[i].y2 + dest_y_off;
+			glamor_set_normalize_vcoords(dst_xscale,
+						     dst_yscale, vx1,
+						     vy1, vx2, vy2,
+						     glamor_priv->yInverted,
+						     vertices);
+
+			if (key.source != SHADER_SOURCE_SOLID) {
+				int tx1 = box[i].x1 + x_source - x_dest;
+				int ty1 = box[i].y1 + y_source - y_dest;
+				int tx2 = box[i].x2 + x_source - x_dest;
+				int ty2 = box[i].y2 + y_source - y_dest;
+				if (source->transform)
+					glamor_set_transformed_normalize_tcoords
+					    (src_matrix, src_xscale,
+					     src_yscale, tx1, ty1,
+					     tx2, ty2,
+					     glamor_priv->yInverted,
+					     source_texcoords);
+				else
+					glamor_set_normalize_tcoords
+					    (src_xscale, src_yscale,
+					     tx1, ty1, tx2, ty2,
+					     glamor_priv->yInverted,
+					     source_texcoords);
+			}
+
+			if (key.mask != SHADER_MASK_NONE
+			    && key.mask != SHADER_MASK_SOLID) {
+				float tx1 = box[i].x1 + x_mask - x_dest;
+				float ty1 = box[i].y1 + y_mask - y_dest;
+				float tx2 = box[i].x2 + x_mask - x_dest;
+				float ty2 = box[i].y2 + y_mask - y_dest;
+				if (mask->transform)
+					glamor_set_transformed_normalize_tcoords
+					    (mask_matrix,
+					     mask_xscale,
+					     mask_yscale, tx1, ty1,
+					     tx2, ty2,
+					     glamor_priv->yInverted,
+					     mask_texcoords);
+				else
+					glamor_set_normalize_tcoords
+					    (mask_xscale,
+					     mask_yscale, tx1, ty1,
+					     tx2, ty2,
+					     glamor_priv->yInverted,
+					     mask_texcoords);
+			}
+			glamor_emit_composite_rect(screen,
+						   source_texcoords,
+						   mask_texcoords,
+						   vertices);
+		}
+		rects++;
+	}
+	glamor_flush_composite_rects(screen);
+
+	dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+	REGION_UNINIT(dst->pDrawable->pScreen, &region);
+	dispatch->glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-  dispatch->glActiveTexture(GL_TEXTURE0);
-  dispatch->glDisable(GL_TEXTURE_2D);
-  dispatch->glActiveTexture(GL_TEXTURE1);
-  dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glActiveTexture(GL_TEXTURE0);
+	dispatch->glDisable(GL_TEXTURE_2D);
+	dispatch->glActiveTexture(GL_TEXTURE1);
+	dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-  dispatch->glUseProgram(0);
-  if (saved_source_format) 
-    source->format = saved_source_format;
-  return TRUE;
-
- fail:
-  if (saved_source_format) 
-    source->format = saved_source_format;
-
-  dispatch->glDisable(GL_BLEND);
-  dispatch->glUseProgram(0);
-  return FALSE;
+	dispatch->glUseProgram(0);
+	if (saved_source_format)
+		source->format = saved_source_format;
+	return TRUE;
+
+      fail:
+	if (saved_source_format)
+		source->format = saved_source_format;
+
+	dispatch->glDisable(GL_BLEND);
+	dispatch->glUseProgram(0);
+	return FALSE;
 }
 
 static PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
-                                PicturePtr source,
-                                int x_source,
-                                int y_source,
-                                int width,
-                                int height)
+				PicturePtr source,
+				int x_source,
+				int y_source, int width, int height)
 {
-  PixmapPtr pixmap;
-  PicturePtr dst;
-  int error;
-  PictFormatShort format;
-
-  if (!source->pDrawable)
-    format = PICT_a8r8g8b8;
-  else
-    format = source->format;
-
-  pixmap = screen->CreatePixmap(screen, 
-                                width, 
-                                height, 
-                                PIXMAN_FORMAT_DEPTH(format),
-                                GLAMOR_CREATE_PIXMAP_CPU);
-
-  if (!pixmap)
-    return NULL;
-  
-  dst = CreatePicture(0, 
-                      &pixmap->drawable,
-                      PictureMatchFormat(screen,
-                                         PIXMAN_FORMAT_DEPTH(format),
-                                         format),
-                      0, 
-                      0, 
-                      serverClient, 
-                      &error);
-  screen->DestroyPixmap(pixmap);
-  if (!dst)
-     return NULL;
-
-  ValidatePicture(dst);
-
-  fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
-              0, 0, 0, 0, width, height);
-  return dst;
+	PixmapPtr pixmap;
+	PicturePtr dst;
+	int error;
+	PictFormatShort format;
+
+	if (!source->pDrawable)
+		format = PICT_a8r8g8b8;
+	else
+		format = source->format;
+
+	pixmap = screen->CreatePixmap(screen,
+				      width,
+				      height,
+				      PIXMAN_FORMAT_DEPTH(format),
+				      GLAMOR_CREATE_PIXMAP_CPU);
+
+	if (!pixmap)
+		return NULL;
+
+	dst = CreatePicture(0,
+			    &pixmap->drawable,
+			    PictureMatchFormat(screen,
+					       PIXMAN_FORMAT_DEPTH(format),
+					       format),
+			    0, 0, serverClient, &error);
+	screen->DestroyPixmap(pixmap);
+	if (!dst)
+		return NULL;
+
+	ValidatePicture(dst);
+
+	fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
+		    0, 0, 0, 0, width, height);
+	return dst;
 }
 
 void
@@ -1133,166 +1199,182 @@ glamor_composite(CARD8 op,
 		 INT16 y_source,
 		 INT16 x_mask,
 		 INT16 y_mask,
-		 INT16 x_dest,
-		 INT16 y_dest,
-		 CARD16 width,
-		 CARD16 height)
+		 INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
 {
-  ScreenPtr screen = dest->pDrawable->pScreen;
-  glamor_pixmap_private *dest_pixmap_priv;
-  glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
-  PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-  PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-  PicturePtr temp_src = source, temp_mask = mask;
-  int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
-  glamor_composite_rect_t rect;
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-
-  x_temp_src = x_source;
-  y_temp_src = y_source;
-  x_temp_mask = x_mask;
-  y_temp_mask = y_mask;
-
-  dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-  /* Currently. Always fallback to cpu if destination is in CPU memory. */
-  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
-    goto fail;
-  }
-
-  if (source->pDrawable) {
-    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-  }
-
-  if (mask && mask->pDrawable) {
-    mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-    mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-  }
-
-  if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill))
-      || (source->pDrawable 
-	  && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) 
-	  && ((width * height * 4 
-	       < (source_pixmap->drawable.width * source_pixmap->drawable.height))
-	      || !(glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width,
-						 source_pixmap->drawable.height))))) {
-    temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height);
-    if (!temp_src) {
-      temp_src = source;
-      goto fail; 
-    }
-    x_temp_src = y_temp_src = 0;
-  }
-
-  if (mask 
-      && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill))
-	  || (mask->pDrawable 
-	      && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
-	      && ((width * height * 4 
-		   < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))
-		  || !(glamor_check_fbo_size(glamor_priv, mask_pixmap->drawable.width,
-						     mask_pixmap->drawable.height)))))) {
-    /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
-     * to do reduce one convertion. */
-    temp_mask = glamor_convert_gradient_picture(screen, mask, x_mask, y_mask, width, height);
-    if (!temp_mask) {
-      temp_mask = mask;
-      goto fail; 
-    }
-    x_temp_mask = y_temp_mask = 0;
-  }
-  /* Do two-pass PictOpOver componentAlpha, until we enable
-   * dual source color blending.
-   */
-
-  if (mask && mask->componentAlpha) {
-    if (op == PictOpOver) {
-      glamor_composite(PictOpOutReverse,
-		       temp_src, temp_mask, dest,
-		       x_temp_src, y_temp_src,
-		       x_temp_mask, y_temp_mask,
-		       x_dest, y_dest,
-		       width, height);
-      glamor_composite(PictOpAdd,
-		       temp_src, temp_mask, dest,
-		       x_temp_src, y_temp_src,
-		       x_temp_mask, y_temp_mask,
-		       x_dest, y_dest,
-		       width, height);
-      goto done;
-
-    } else if (op != PictOpAdd && op != PictOpOutReverse) {
-      glamor_fallback("glamor_composite(): component alpha\n");
-      goto fail;
-    }
-  }
-
-  if (!mask) {
-    if (glamor_composite_with_copy(op, temp_src, dest,
-				   x_temp_src, y_temp_src,
-				   x_dest, y_dest,
-				   width, height))
-      goto done;
-  }
-
-  rect.x_src = x_temp_src;
-  rect.y_src = y_temp_src;
-  rect.x_mask = x_temp_mask;
-  rect.y_mask = y_temp_mask;
-  rect.x_dst = x_dest;
-  rect.y_dst = y_dest;
-  rect.width = width;
-  rect.height = height;
-  if (glamor_composite_with_shader(op, temp_src, temp_mask, dest, 1, &rect))
-    goto done;
-
-fail:
-
-  glamor_fallback(
-		  "from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
-		  source, 
-                  source->pDrawable,
-		  source->pDrawable ? source->pDrawable->width : 0,
-		  source->pDrawable ? source->pDrawable->height : 0,
-		  mask, 
-                  (!mask) ? NULL : mask->pDrawable,
-		  (!mask || !mask->pDrawable)? 0 : mask->pDrawable->width,
-		  (!mask || !mask->pDrawable)? 0 : mask->pDrawable->height,
-		  glamor_get_picture_location(source),
-		  glamor_get_picture_location(mask),
-		  dest,
-		  dest->pDrawable,
-		  dest->pDrawable->width,
-		  dest->pDrawable->height,
-		  glamor_get_picture_location(dest));
-
-  dispatch->glUseProgram(0);
-  dispatch->glDisable(GL_BLEND);
-  if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
-    if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
-      {
-	if (!mask ||
-	    glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO))
-	  {
-	    fbComposite(op,
-			source, mask, dest,
-			x_source, y_source,
-			x_mask, y_mask,
-			x_dest, y_dest,
-			width, height);
-	    if (mask)
-	      glamor_finish_access_picture(mask);
-	  }
-	glamor_finish_access_picture(source);
-      }
-    glamor_finish_access_picture(dest);
-  }
-done:
-    if (temp_src != source)
-      FreePicture(temp_src, 0);
-    if (temp_mask != mask)
-      FreePicture(temp_mask, 0);
+	ScreenPtr screen = dest->pDrawable->pScreen;
+	glamor_pixmap_private *dest_pixmap_priv;
+	glamor_pixmap_private *source_pixmap_priv =
+	    NULL, *mask_pixmap_priv = NULL;
+	PixmapPtr dest_pixmap =
+	    glamor_get_drawable_pixmap(dest->pDrawable);
+	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+	PicturePtr temp_src = source, temp_mask = mask;
+	int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
+	glamor_composite_rect_t rect;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+
+	x_temp_src = x_source;
+	y_temp_src = y_source;
+	x_temp_mask = x_mask;
+	y_temp_mask = y_mask;
+
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+	/* Currently. Always fallback to cpu if destination is in CPU memory. */
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+		goto fail;
+	}
+
+	if (source->pDrawable) {
+		source_pixmap =
+		    glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv =
+		    glamor_get_pixmap_private(source_pixmap);
+	}
+
+	if (mask && mask->pDrawable) {
+		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+	}
+
+	if ((!source->pDrawable
+	     && (source->pSourcePict->type != SourcePictTypeSolidFill))
+	    || (source->pDrawable
+		&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
+		&&
+		((width * height * 4 <
+		  (source_pixmap->drawable.width *
+		   source_pixmap->drawable.height))
+		 ||
+		 !(glamor_check_fbo_size
+		   (glamor_priv, source_pixmap->drawable.width,
+		    source_pixmap->drawable.height))))) {
+		temp_src =
+		    glamor_convert_gradient_picture(screen, source,
+						    x_source, y_source,
+						    width, height);
+		if (!temp_src) {
+			temp_src = source;
+			goto fail;
+		}
+		x_temp_src = y_temp_src = 0;
+	}
+
+	if (mask
+	    &&
+	    ((!mask->pDrawable
+	      && (mask->pSourcePict->type != SourcePictTypeSolidFill))
+	     || (mask->pDrawable
+		 && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
+		 &&
+		 ((width * height * 4 <
+		   (mask_pixmap->drawable.width *
+		    mask_pixmap->drawable.height))
+		  ||
+		  !(glamor_check_fbo_size
+		    (glamor_priv, mask_pixmap->drawable.width,
+		     mask_pixmap->drawable.height)))))) {
+		/* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
+		 * to do reduce one convertion. */
+		temp_mask =
+		    glamor_convert_gradient_picture(screen, mask,
+						    x_mask, y_mask,
+						    width, height);
+		if (!temp_mask) {
+			temp_mask = mask;
+			goto fail;
+		}
+		x_temp_mask = y_temp_mask = 0;
+	}
+	/* Do two-pass PictOpOver componentAlpha, until we enable
+	 * dual source color blending.
+	 */
+
+	if (mask && mask->componentAlpha) {
+		if (op == PictOpOver) {
+			glamor_composite(PictOpOutReverse,
+					 temp_src, temp_mask, dest,
+					 x_temp_src, y_temp_src,
+					 x_temp_mask, y_temp_mask,
+					 x_dest, y_dest, width, height);
+			glamor_composite(PictOpAdd,
+					 temp_src, temp_mask, dest,
+					 x_temp_src, y_temp_src,
+					 x_temp_mask, y_temp_mask,
+					 x_dest, y_dest, width, height);
+			goto done;
+
+		} else if (op != PictOpAdd && op != PictOpOutReverse) {
+			glamor_fallback
+			    ("glamor_composite(): component alpha\n");
+			goto fail;
+		}
+	}
+
+	if (!mask) {
+		if (glamor_composite_with_copy(op, temp_src, dest,
+					       x_temp_src, y_temp_src,
+					       x_dest, y_dest, width,
+					       height))
+			goto done;
+	}
+
+	rect.x_src = x_temp_src;
+	rect.y_src = y_temp_src;
+	rect.x_mask = x_temp_mask;
+	rect.y_mask = y_temp_mask;
+	rect.x_dst = x_dest;
+	rect.y_dst = y_dest;
+	rect.width = width;
+	rect.height = height;
+	if (glamor_composite_with_shader
+	    (op, temp_src, temp_mask, dest, 1, &rect))
+		goto done;
+
+      fail:
+
+	glamor_fallback
+	    ("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
+	     source, source->pDrawable,
+	     source->pDrawable ? source->pDrawable->width : 0,
+	     source->pDrawable ? source->pDrawable->height : 0, mask,
+	     (!mask) ? NULL : mask->pDrawable, (!mask
+						|| !mask->pDrawable) ? 0 :
+	     mask->pDrawable->width, (!mask
+				      || !mask->
+				      pDrawable) ? 0 : mask->pDrawable->
+	     height, glamor_get_picture_location(source),
+	     glamor_get_picture_location(mask), dest, dest->pDrawable,
+	     dest->pDrawable->width, dest->pDrawable->height,
+	     glamor_get_picture_location(dest));
+
+	dispatch->glUseProgram(0);
+	dispatch->glDisable(GL_BLEND);
+	if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
+		if (glamor_prepare_access_picture
+		    (source, GLAMOR_ACCESS_RO)) {
+			if (!mask
+			    || glamor_prepare_access_picture(mask,
+							     GLAMOR_ACCESS_RO))
+			{
+				fbComposite(op,
+					    source, mask, dest,
+					    x_source, y_source,
+					    x_mask, y_mask, x_dest,
+					    y_dest, width, height);
+				if (mask)
+					glamor_finish_access_picture(mask);
+			}
+			glamor_finish_access_picture(source);
+		}
+		glamor_finish_access_picture(dest);
+	}
+      done:
+	if (temp_src != source)
+		FreePicture(temp_src, 0);
+	if (temp_mask != mask)
+		FreePicture(temp_mask, 0);
 }
 
 
@@ -1304,31 +1386,32 @@ static PicturePtr
 glamor_create_mask_picture(ScreenPtr screen,
 			   PicturePtr dst,
 			   PictFormatPtr pict_format,
-			   CARD16 width,
-			   CARD16 height)
+			   CARD16 width, CARD16 height)
 {
-  PixmapPtr pixmap;
-  PicturePtr picture;
-  int	error;
-
-  if (!pict_format) {
-    if (dst->polyEdge == PolyEdgeSharp)
-      pict_format = PictureMatchFormat(screen, 1, PICT_a1);
-    else
-      pict_format = PictureMatchFormat(screen, 8, PICT_a8);
-    if (!pict_format)
-      return 0;
-  }
-
-  pixmap = screen->CreatePixmap(screen, 0, 0,
-				pict_format->depth,
-				GLAMOR_CREATE_PIXMAP_CPU);
-  if (!pixmap)
-    return 0;
-  picture = CreatePicture(0, &pixmap->drawable, pict_format,
-			  0, 0, serverClient, &error);
-  screen->DestroyPixmap(pixmap);
-  return picture;
+	PixmapPtr pixmap;
+	PicturePtr picture;
+	int error;
+
+	if (!pict_format) {
+		if (dst->polyEdge == PolyEdgeSharp)
+			pict_format =
+			    PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			pict_format =
+			    PictureMatchFormat(screen, 8, PICT_a8);
+		if (!pict_format)
+			return 0;
+	}
+
+	pixmap = screen->CreatePixmap(screen, 0, 0,
+				      pict_format->depth,
+				      GLAMOR_CREATE_PIXMAP_CPU);
+	if (!pixmap)
+		return 0;
+	picture = CreatePicture(0, &pixmap->drawable, pict_format,
+				0, 0, serverClient, &error);
+	screen->DestroyPixmap(pixmap);
+	return picture;
 }
 
 /**
@@ -1339,108 +1422,110 @@ void
 glamor_trapezoids(CARD8 op,
 		  PicturePtr src, PicturePtr dst,
 		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
-		  int ntrap, xTrapezoid *traps)
+		  int ntrap, xTrapezoid * traps)
 {
-  ScreenPtr screen = dst->pDrawable->pScreen;
-  BoxRec bounds;
-  PicturePtr picture;
-  INT16 x_dst, y_dst;
-  INT16 x_rel, y_rel;
-  int width, height, stride;
-  PixmapPtr pixmap;
-  pixman_image_t *image;
-
-  /* If a mask format wasn't provided, we get to choose, but behavior should
-   * be as if there was no temporary mask the traps were accumulated into.
-   */
-  if (!mask_format) {
-    if (dst->polyEdge == PolyEdgeSharp)
-      mask_format = PictureMatchFormat(screen, 1, PICT_a1);
-    else
-      mask_format = PictureMatchFormat(screen, 8, PICT_a8);
-    for (; ntrap; ntrap--, traps++)
-      glamor_trapezoids(op, src, dst, mask_format, x_src, y_src,
-			1, traps);
-    return;
-  }
-
-  miTrapezoidBounds(ntrap, traps, &bounds);
-
-  if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-    return;
-
-  x_dst = traps[0].left.p1.x >> 16;
-  y_dst = traps[0].left.p1.y >> 16;
-
-  width = bounds.x2 - bounds.x1;
-  height = bounds.y2 - bounds.y1;
-  stride = PixmapBytePad(width, mask_format->depth);
-  picture = glamor_create_mask_picture(screen, dst, mask_format,
-				       width, height);
-  if (!picture)
-    return;
-
-  image = pixman_image_create_bits(picture->format,
-				   width, height,
-				   NULL, stride);
-  if (!image) {
-    FreePicture(picture, 0);
-    return;
-  }
-
-  for (; ntrap; ntrap--, traps++)
-    pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps,
-			       -bounds.x1, -bounds.y1);
-
-  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
- 
-  screen->ModifyPixmapHeader(pixmap, width, height, 
-                             mask_format->depth, 
-	                     BitsPerPixel(mask_format->depth),
-			     PixmapBytePad(width, mask_format->depth),
-			     pixman_image_get_data(image));
-
-  x_rel = bounds.x1 + x_src - x_dst;
-  y_rel = bounds.y1 + y_src - y_dst;
-  CompositePicture(op, src, picture, dst,
-		   x_rel, y_rel,
-		   0, 0,
-		   bounds.x1, bounds.y1,
-		   bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
-
-  pixman_image_unref(image);
-
-  FreePicture(picture, 0);
+	ScreenPtr screen = dst->pDrawable->pScreen;
+	BoxRec bounds;
+	PicturePtr picture;
+	INT16 x_dst, y_dst;
+	INT16 x_rel, y_rel;
+	int width, height, stride;
+	PixmapPtr pixmap;
+	pixman_image_t *image;
+
+	/* If a mask format wasn't provided, we get to choose, but behavior should
+	 * be as if there was no temporary mask the traps were accumulated into.
+	 */
+	if (!mask_format) {
+		if (dst->polyEdge == PolyEdgeSharp)
+			mask_format =
+			    PictureMatchFormat(screen, 1, PICT_a1);
+		else
+			mask_format =
+			    PictureMatchFormat(screen, 8, PICT_a8);
+		for (; ntrap; ntrap--, traps++)
+			glamor_trapezoids(op, src, dst, mask_format, x_src,
+					  y_src, 1, traps);
+		return;
+	}
+
+	miTrapezoidBounds(ntrap, traps, &bounds);
+
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		return;
+
+	x_dst = traps[0].left.p1.x >> 16;
+	y_dst = traps[0].left.p1.y >> 16;
+
+	width = bounds.x2 - bounds.x1;
+	height = bounds.y2 - bounds.y1;
+	stride = PixmapBytePad(width, mask_format->depth);
+	picture = glamor_create_mask_picture(screen, dst, mask_format,
+					     width, height);
+	if (!picture)
+		return;
+
+	image = pixman_image_create_bits(picture->format,
+					 width, height, NULL, stride);
+	if (!image) {
+		FreePicture(picture, 0);
+		return;
+	}
+
+	for (; ntrap; ntrap--, traps++)
+		pixman_rasterize_trapezoid(image,
+					   (pixman_trapezoid_t *) traps,
+					   -bounds.x1, -bounds.y1);
+
+	pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+
+	screen->ModifyPixmapHeader(pixmap, width, height,
+				   mask_format->depth,
+				   BitsPerPixel(mask_format->depth),
+				   PixmapBytePad(width,
+						 mask_format->depth),
+				   pixman_image_get_data(image));
+
+	x_rel = bounds.x1 + x_src - x_dst;
+	y_rel = bounds.y1 + y_src - y_dst;
+	CompositePicture(op, src, picture, dst,
+			 x_rel, y_rel,
+			 0, 0,
+			 bounds.x1, bounds.y1,
+			 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+
+	pixman_image_unref(image);
+
+	FreePicture(picture, 0);
 }
 
 void
 glamor_composite_rects(CARD8 op,
 		       PicturePtr src, PicturePtr mask, PicturePtr dst,
-		       int nrect, glamor_composite_rect_t *rects)
+		       int nrect, glamor_composite_rect_t * rects)
 {
-  int n;
-  glamor_composite_rect_t *r;
-
-  ValidatePicture(src);
-  ValidatePicture(dst);
-
-  if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
-    return;
-
-  n = nrect;
-  r = rects;
-
-  while (n--) {
-    CompositePicture(op,
-		     src,
-		     mask,
-		     dst,
-		     r->x_src, r->y_src,
-		     r->x_mask, r->y_mask,
-		     r->x_dst, r->y_dst,
-		     r->width, r->height);
-    r++;
-  }
+	int n;
+	glamor_composite_rect_t *r;
+
+	ValidatePicture(src);
+	ValidatePicture(dst);
+
+	if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
+		return;
+
+	n = nrect;
+	r = rects;
+
+	while (n--) {
+		CompositePicture(op,
+				 src,
+				 mask,
+				 dst,
+				 r->x_src, r->y_src,
+				 r->x_mask, r->y_mask,
+				 r->x_dst, r->y_dst, r->width, r->height);
+		r++;
+	}
 }
 
-#endif /* RENDER */
+#endif				/* RENDER */
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index bb4bffd..61163ce 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -35,76 +35,72 @@ void
 glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 DDXPointPtr points, int *widths, int n, int sorted)
 {
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    GLenum format, type;
-    int no_alpha, no_revert, i;
-    uint8_t *drawpixels_src = (uint8_t *)src;
-    RegionPtr clip = fbGetCompositeClip(gc);
-    BoxRec *pbox;
-    int x_off, y_off;
+	PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(drawable->pScreen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	GLenum format, type;
+	int no_alpha, no_revert, i;
+	uint8_t *drawpixels_src = (uint8_t *) src;
+	RegionPtr clip = fbGetCompositeClip(gc);
+	BoxRec *pbox;
+	int x_off, y_off;
 
-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-      glamor_fallback("ES2 fallback.\n");
-      goto fail;
-    }
+	if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+		glamor_fallback("ES2 fallback.\n");
+		goto fail;
+	}
 
-    if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
-                                               &format, 
-                                               &type, 
-                                               &no_alpha,
-                                               &no_revert
-                                               )) {
-      glamor_fallback("unknown depth. %d \n", 
-                     drawable->depth);
-      goto fail;
-    }
+	if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
+						   &format,
+						   &type, &no_alpha,
+						   &no_revert)) {
+		glamor_fallback("unknown depth. %d \n", drawable->depth);
+		goto fail;
+	}
 
 
-    if (glamor_set_destination_pixmap(dest_pixmap))
-	goto fail;
+	if (glamor_set_destination_pixmap(dest_pixmap))
+		goto fail;
 
-    glamor_validate_pixmap(dest_pixmap);
-    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
-	goto fail;
-    glamor_set_alu(dispatch, gc->alu);
-    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
-	goto fail;
+	glamor_validate_pixmap(dest_pixmap);
+	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
+		goto fail;
+	glamor_set_alu(dispatch, gc->alu);
+	if (!glamor_set_planemask(dest_pixmap, gc->planemask))
+		goto fail;
 
-    glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
+	glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
 
-    for (i = 0; i < n; i++) {
+	for (i = 0; i < n; i++) {
 
-	n = REGION_NUM_RECTS(clip);
-	pbox = REGION_RECTS(clip);
-	while (n--) {
-	    if (pbox->y1 > points[i].y)
-		break;
-	    dispatch->glScissor(pbox->x1,
-		      points[i].y + y_off,
-		      pbox->x2 - pbox->x1,
-		      1);
-	    dispatch->glEnable(GL_SCISSOR_TEST);
-	    dispatch->glRasterPos2i(points[i].x + x_off,
-			  points[i].y + y_off);
-	    dispatch->glDrawPixels(widths[i],
-			 1,
-			 format, type,
-			 drawpixels_src);
+		n = REGION_NUM_RECTS(clip);
+		pbox = REGION_RECTS(clip);
+		while (n--) {
+			if (pbox->y1 > points[i].y)
+				break;
+			dispatch->glScissor(pbox->x1,
+					    points[i].y + y_off,
+					    pbox->x2 - pbox->x1, 1);
+			dispatch->glEnable(GL_SCISSOR_TEST);
+			dispatch->glRasterPos2i(points[i].x + x_off,
+						points[i].y + y_off);
+			dispatch->glDrawPixels(widths[i], 1, format,
+					       type, drawpixels_src);
+		}
+		drawpixels_src +=
+		    PixmapBytePad(widths[i], drawable->depth);
 	}
-	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
-    }
-    glamor_set_planemask(dest_pixmap, ~0);
-    glamor_set_alu(dispatch, GXcopy);
-    dispatch->glDisable(GL_SCISSOR_TEST);
-    return;
-fail:
+	glamor_set_planemask(dest_pixmap, ~0);
+	glamor_set_alu(dispatch, GXcopy);
+	dispatch->glDisable(GL_SCISSOR_TEST);
+	return;
+      fail:
 
-    glamor_fallback("to %p (%c)\n",
-		    drawable, glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
-	glamor_finish_access(drawable);
-    }
+	glamor_fallback("to %p (%c)\n",
+			drawable, glamor_get_drawable_location(drawable));
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+		fbSetSpans(drawable, gc, src, points, widths, n, sorted);
+		glamor_finish_access(drawable);
+	}
 }
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 687cc6a..bd5192c 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -39,43 +39,49 @@
 void
 glamor_init_tile_shader(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    const char *tile_vs =
-        "attribute vec4 v_position;\n"
-        "attribute vec4 v_texcoord0;\n"
-        "varying vec2 tile_texture;\n"
-	"void main()\n"
-	"{\n"
-        "       gl_Position = v_position;\n"
-        "       tile_texture = v_texcoord0.xy;\n"
-	"}\n";
-    const char *tile_fs =
-        GLAMOR_DEFAULT_PRECISION
-        "varying vec2 tile_texture;\n"
-	"uniform sampler2D sampler;\n"
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = texture2D(sampler, tile_texture);\n"
-	"}\n";
-    GLint fs_prog, vs_prog;
-    GLint sampler_uniform_location;
-
-    glamor_priv->tile_prog = dispatch->glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
-    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs);
-    dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
-    dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
-
-    dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position");
-    dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
-
-    sampler_uniform_location =
-	dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler");
-    dispatch->glUseProgram(glamor_priv->tile_prog);
-    dispatch->glUniform1i(sampler_uniform_location, 0);
-    dispatch->glUseProgram(0);
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	const char *tile_vs =
+	    "attribute vec4 v_position;\n"
+	    "attribute vec4 v_texcoord0;\n"
+	    "varying vec2 tile_texture;\n"
+	    "void main()\n"
+	    "{\n"
+	    "       gl_Position = v_position;\n"
+	    "       tile_texture = v_texcoord0.xy;\n" "}\n";
+	const char *tile_fs =
+	    GLAMOR_DEFAULT_PRECISION
+	    "varying vec2 tile_texture;\n"
+	    "uniform sampler2D sampler;\n"
+	    "void main()\n"
+	    "{\n" "	gl_FragColor = texture2D(sampler, tile_texture);\n"
+	    "}\n";
+	GLint fs_prog, vs_prog;
+	GLint sampler_uniform_location;
+
+	glamor_priv->tile_prog = dispatch->glCreateProgram();
+	vs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
+	fs_prog =
+	    glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
+				     tile_fs);
+	dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
+	dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
+
+	dispatch->glBindAttribLocation(glamor_priv->tile_prog,
+				       GLAMOR_VERTEX_POS, "v_position");
+	dispatch->glBindAttribLocation(glamor_priv->tile_prog,
+				       GLAMOR_VERTEX_SOURCE,
+				       "v_texcoord0");
+	glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
+
+	sampler_uniform_location =
+	    dispatch->glGetUniformLocation(glamor_priv->tile_prog,
+					   "sampler");
+	dispatch->glUseProgram(glamor_priv->tile_prog);
+	dispatch->glUniform1i(sampler_uniform_location, 0);
+	dispatch->glUseProgram(0);
 }
 
 Bool
@@ -84,111 +90,124 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	    unsigned char alu, unsigned long planemask,
 	    int tile_x, int tile_y)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
-    int x1 = x;
-    int x2 = x + width;
-    int y1 = y;
-    int y2 = y + height;
-    int tile_x1 = tile_x;
-    int tile_x2 = tile_x + width;
-    int tile_y1 = tile_y;
-    int tile_y2 = tile_y + height;
-    float vertices[8];
-    float source_texcoords[8];
-    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
-    glamor_pixmap_private *src_pixmap_priv;
-    glamor_pixmap_private *dst_pixmap_priv;
-
-    src_pixmap_priv = glamor_get_pixmap_private(tile);
-    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
-         || ((tile_y != 0) && (tile_y + height > tile->drawable.height)))  {
-       ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
-       goto fail;
-    }
-    if (glamor_priv->tile_prog == 0) {
-	glamor_fallback("Tiling unsupported\n");
-	goto fail;
-    }
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {      
-      glamor_fallback("dest has no fbo.\n");
-      goto fail;
-    }
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
-      /* XXX dynamic uploading candidate. */
-      glamor_fallback("Non-texture tile pixmap\n");
-      goto fail;
-    }
-
-    if (!glamor_set_planemask(pixmap, planemask)) {
-        glamor_fallback("unsupported planemask %lx\n", planemask);
-	goto fail;
-    }
-    if (alu != GXcopy) {
-      glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
-      glamor_validate_pixmap(tile);
-    }
- 
-    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
-    glamor_validate_pixmap(pixmap);
-    pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-
-    glamor_set_alu(dispatch, alu);
-
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-      pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-      dispatch->glUseProgram(glamor_priv->tile_prog);
- 
-      dispatch->glActiveTexture(GL_TEXTURE0);
-      dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	int x1 = x;
+	int x2 = x + width;
+	int y1 = y;
+	int y2 = y + height;
+	int tile_x1 = tile_x;
+	int tile_x2 = tile_x + width;
+	int tile_y1 = tile_y;
+	int tile_y2 = tile_y + height;
+	float vertices[8];
+	float source_texcoords[8];
+	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+	glamor_pixmap_private *src_pixmap_priv;
+	glamor_pixmap_private *dst_pixmap_priv;
+
+	src_pixmap_priv = glamor_get_pixmap_private(tile);
+	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
+		goto fail;
+
+	if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
+	    || ((tile_y != 0)
+		&& (tile_y + height > tile->drawable.height))) {
+		ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
+		goto fail;
+	}
+	if (glamor_priv->tile_prog == 0) {
+		glamor_fallback("Tiling unsupported\n");
+		goto fail;
+	}
+
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+		glamor_fallback("dest has no fbo.\n");
+		goto fail;
+	}
+	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+		/* XXX dynamic uploading candidate. */
+		glamor_fallback("Non-texture tile pixmap\n");
+		goto fail;
+	}
+
+	if (!glamor_set_planemask(pixmap, planemask)) {
+		glamor_fallback("unsupported planemask %lx\n", planemask);
+		goto fail;
+	}
+	if (alu != GXcopy) {
+		glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
+		glamor_validate_pixmap(tile);
+	}
+
+	glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+	glamor_validate_pixmap(pixmap);
+	pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+
+	glamor_set_alu(dispatch, alu);
+
+	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+		pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
+				      &src_yscale);
+		dispatch->glUseProgram(glamor_priv->tile_prog);
+
+		dispatch->glActiveTexture(GL_TEXTURE0);
+		dispatch->glBindTexture(GL_TEXTURE_2D,
+					src_pixmap_priv->tex);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MIN_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D,
+					  GL_TEXTURE_MAG_FILTER,
+					  GL_NEAREST);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+					  GL_REPEAT);
+		dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+					  GL_REPEAT);
 #ifndef GLAMOR_GLES2
-      dispatch->glEnable(GL_TEXTURE_2D);
+		dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-      glamor_set_normalize_tcoords(src_xscale, src_yscale,
-				 tile_x1, tile_y1,
-				 tile_x2, tile_y2,
-				 glamor_priv->yInverted,
-				 source_texcoords);
-      dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
-                            2 * sizeof(float),
-                            source_texcoords);
-      dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-   } 
-   else {
-     GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
-   }
- 
-    glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
-				 x1, y1,x2, y2,
-				 glamor_priv->yInverted,
-				 vertices);
-
-    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
-                          2 * sizeof(float),
-                         vertices);
-    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+		glamor_set_normalize_tcoords(src_xscale, src_yscale,
+					     tile_x1, tile_y1,
+					     tile_x2, tile_y2,
+					     glamor_priv->yInverted,
+					     source_texcoords);
+		dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
+						GL_FLOAT, GL_FALSE,
+						2 * sizeof(float),
+						source_texcoords);
+		dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+	} else {
+		GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
+					  src_pixmap_priv);
+	}
+
+	glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+				     x1, y1, x2, y2,
+				     glamor_priv->yInverted, vertices);
+
+	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+					GL_FALSE, 2 * sizeof(float),
+					vertices);
+	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+	if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+		dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-    dispatch->glDisable(GL_TEXTURE_2D);
+		dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-    }
-    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    dispatch->glUseProgram(0);
-    glamor_set_alu(dispatch, GXcopy);
-    glamor_set_planemask(pixmap, ~0);
-    return TRUE;
-
-fail:
-    return FALSE;
+	}
+	dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+	dispatch->glUseProgram(0);
+	glamor_set_alu(dispatch, GXcopy);
+	glamor_set_planemask(pixmap, ~0);
+	return TRUE;
+
+      fail:
+	return FALSE;
 }
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
index 168d485..3cbdd55 100644
--- a/glamor/glamor_triangles.c
+++ b/glamor/glamor_triangles.c
@@ -33,29 +33,24 @@
 #include "glamor_priv.h"
 
 void
-glamor_triangles (CARD8	    op,
-	     PicturePtr    pSrc,
-	     PicturePtr    pDst,
-	     PictFormatPtr maskFormat,
-	     INT16	    xSrc,
-	     INT16	    ySrc,
-	     int	    ntris,
-	     xTriangle    *tris)
-{ 
-
-    if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
-	if (pSrc->pDrawable == NULL ||
-	    glamor_prepare_access(pSrc->pDrawable, GLAMOR_ACCESS_RO))
-	{
-
-                fbTriangles(op, 
-                            pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
-	}
-	    if (pSrc->pDrawable != NULL)
-		glamor_finish_access(pSrc->pDrawable);
-
-	glamor_finish_access(pDst->pDrawable);
+glamor_triangles(CARD8 op,
+		 PicturePtr pSrc,
+		 PicturePtr pDst,
+		 PictFormatPtr maskFormat,
+		 INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
+{
+
+	if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
+		if (pSrc->pDrawable == NULL ||
+		    glamor_prepare_access(pSrc->pDrawable,
+					  GLAMOR_ACCESS_RO)) {
+
+			fbTriangles(op, pSrc, pDst, maskFormat, xSrc,
+				    ySrc, ntris, tris);
+		}
+		if (pSrc->pDrawable != NULL)
+			glamor_finish_access(pSrc->pDrawable);
+
+		glamor_finish_access(pDst->pDrawable);
 	}
 }
-
-
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index fe5bd4e..265d9ed 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -7,8 +7,8 @@
 
 #define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
 #define v_from_x_coord_y(_yscale_, _y_)          (-2 * (_y_) * (_yscale_) + 1.0)
-#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) 
-#define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_)) 
+#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
+#define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_))
 #define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
 #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
 
@@ -17,7 +17,7 @@
     *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width;	\
     *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height;	\
   } while(0)
-        
+
 
 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
 			      + ((float)xFixedFrac(_val_) / 65536.0))
@@ -124,40 +124,38 @@
 inline static void
 glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
 {
-  int x_min, y_min;
-  int x_max, y_max;
-  int i;
-  x_min = y_min = MAXSHORT;
-  x_max = y_max = MINSHORT;
-  for(i = 0; i < nbox; i++)
-    {
-      if (x_min > boxes[i].x1)
-        x_min = boxes[i].x1;
-      if (y_min > boxes[i].y1)
-        y_min = boxes[i].y1;
-
-      if (x_max < boxes[i].x2)
-        x_max = boxes[i].x2;
-      if (y_max < boxes[i].y2)
-        y_max = boxes[i].y2;
-    }
-  bound->x1 = x_min;
-  bound->y1 = y_min;
-  bound->x2 = x_max;
-  bound->y2 = y_max;
+	int x_min, y_min;
+	int x_max, y_max;
+	int i;
+	x_min = y_min = MAXSHORT;
+	x_max = y_max = MINSHORT;
+	for (i = 0; i < nbox; i++) {
+		if (x_min > boxes[i].x1)
+			x_min = boxes[i].x1;
+		if (y_min > boxes[i].y1)
+			y_min = boxes[i].y1;
+
+		if (x_max < boxes[i].x2)
+			x_max = boxes[i].x2;
+		if (y_max < boxes[i].y2)
+			y_max = boxes[i].y2;
+	}
+	bound->x1 = x_min;
+	bound->y1 = y_min;
+	bound->x2 = x_max;
+	bound->y2 = y_max;
 }
 
-inline static void 
+inline static void
 glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 {
-  int i;
-  for (i = 0; i < nbox; i++)
-    {
-      boxes[i].x1 += dx;
-      boxes[i].y1 += dy;
-      boxes[i].x2 += dx;
-      boxes[i].y2 += dy;
-    }
+	int i;
+	for (i = 0; i < nbox; i++) {
+		boxes[i].x1 += dx;
+		boxes[i].y1 += dy;
+		boxes[i].x2 += dx;
+		boxes[i].y2 += dy;
+	}
 }
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -195,7 +193,7 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
                         _pixmap_priv_->pending_op.fill.color4fv); \
       } \
   } while(0)
- 
+
 
 /**
  * Borrow from uxa.
@@ -203,34 +201,42 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
 static inline CARD32
 format_for_depth(int depth)
 {
-  switch (depth) {
-  case 1: return PICT_a1;
-  case 4: return PICT_a4;
-  case 8: return PICT_a8;
-  case 15: return PICT_x1r5g5b5;
-  case 16: return PICT_r5g6b5;
-  default:
-  case 24: return PICT_x8r8g8b8;
+	switch (depth) {
+	case 1:
+		return PICT_a1;
+	case 4:
+		return PICT_a4;
+	case 8:
+		return PICT_a8;
+	case 15:
+		return PICT_x1r5g5b5;
+	case 16:
+		return PICT_r5g6b5;
+	default:
+	case 24:
+		return PICT_x8r8g8b8;
 #if XORG_VERSION_CURRENT >= 10699900
-  case 30: return PICT_x2r10g10b10;
+	case 30:
+		return PICT_x2r10g10b10;
 #endif
-  case 32: return PICT_a8r8g8b8;
-  }
+	case 32:
+		return PICT_a8r8g8b8;
+	}
 }
 
 static inline CARD32
 format_for_pixmap(PixmapPtr pixmap)
 {
-  glamor_pixmap_private *pixmap_priv;
-  PictFormatShort pict_format;
+	glamor_pixmap_private *pixmap_priv;
+	PictFormatShort pict_format;
 
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-    pict_format = pixmap_priv->pict_format;
-  else
-    pict_format = format_for_depth(pixmap->drawable.depth);
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+		pict_format = pixmap_priv->pict_format;
+	else
+		pict_format = format_for_depth(pixmap->drawable.depth);
 
-  return pict_format;
+	return pict_format;
 }
 
 /*
@@ -240,298 +246,299 @@ format_for_pixmap(PixmapPtr pixmap)
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
 #ifndef GLAMOR_GLES2
-static inline int 
+static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum *tex_format, 
-					   GLenum *tex_type,
-					   int *no_alpha,
-                                           int *no_revert)
+					   GLenum * tex_format,
+					   GLenum * tex_type,
+					   int *no_alpha, int *no_revert)
 {
-  *no_alpha = 0;
-  *no_revert = 1;
-  switch (format) {
-  case PICT_a1:
-    *tex_format = GL_COLOR_INDEX;
-    *tex_type = GL_BITMAP;
-    break;
-  case PICT_b8g8r8x8:
-    *no_alpha = 1;
-  case PICT_b8g8r8a8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8;
-    break;
-
-  case PICT_x8r8g8b8:
-    *no_alpha = 1;
-  case PICT_a8r8g8b8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-    break;
-  case PICT_x8b8g8r8:
-    *no_alpha = 1;
-  case PICT_a8b8g8r8:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-    break;
-  case PICT_x2r10g10b10:
-    *no_alpha = 1;
-  case PICT_a2r10g10b10:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-    break;
-  case PICT_x2b10g10r10:
-    *no_alpha = 1;
-  case PICT_a2b10g10r10:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-    break;
- 
-  case PICT_r5g6b5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    break;
-  case PICT_b5g6r5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
-    break;
-  case PICT_x1b5g5r5:
-    *no_alpha = 1;
-  case PICT_a1b5g5r5:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    break;
-               
-  case PICT_x1r5g5b5:
-    *no_alpha = 1;
-  case PICT_a1r5g5b5:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    break;
-  case PICT_a8:
-    *tex_format = GL_ALPHA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-  case PICT_x4r4g4b4:
-    *no_alpha = 1;
-  case PICT_a4r4g4b4:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    break;
-
-  case PICT_x4b4g4r4:
-    *no_alpha = 1;
-  case PICT_a4b4g4r4:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    break;
- 
-  default:
-    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
-    return -1;
-  }
-  return 0;
+	*no_alpha = 0;
+	*no_revert = 1;
+	switch (format) {
+	case PICT_a1:
+		*tex_format = GL_COLOR_INDEX;
+		*tex_type = GL_BITMAP;
+		break;
+	case PICT_b8g8r8x8:
+		*no_alpha = 1;
+	case PICT_b8g8r8a8:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_INT_8_8_8_8;
+		break;
+
+	case PICT_x8r8g8b8:
+		*no_alpha = 1;
+	case PICT_a8r8g8b8:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+		break;
+	case PICT_x8b8g8r8:
+		*no_alpha = 1;
+	case PICT_a8b8g8r8:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+		break;
+	case PICT_x2r10g10b10:
+		*no_alpha = 1;
+	case PICT_a2r10g10b10:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+		break;
+	case PICT_x2b10g10r10:
+		*no_alpha = 1;
+	case PICT_a2b10g10r10:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+		break;
+
+	case PICT_r5g6b5:
+		*tex_format = GL_RGB;
+		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
+		break;
+	case PICT_b5g6r5:
+		*tex_format = GL_RGB;
+		*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+		break;
+	case PICT_x1b5g5r5:
+		*no_alpha = 1;
+	case PICT_a1b5g5r5:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+		break;
+
+	case PICT_x1r5g5b5:
+		*no_alpha = 1;
+	case PICT_a1r5g5b5:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+		break;
+	case PICT_a8:
+		*tex_format = GL_ALPHA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		break;
+	case PICT_x4r4g4b4:
+		*no_alpha = 1;
+	case PICT_a4r4g4b4:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+		break;
+
+	case PICT_x4b4g4r4:
+		*no_alpha = 1;
+	case PICT_a4b4g4r4:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+		break;
+
+	default:
+		LogMessageVerb(X_INFO, 0,
+			       "fail to get matched format for %x \n",
+			       format);
+		return -1;
+	}
+	return 0;
 }
 #else
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
-static inline int 
+static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum *tex_format, 
-					   GLenum *tex_type,
-					   int *no_alpha,
-                                           int *no_revert)
+					   GLenum * tex_format,
+					   GLenum * tex_type,
+					   int *no_alpha, int *no_revert)
 {
-  *no_alpha = 0;
-  *no_revert = IS_LITTLE_ENDIAN;
-
-  switch (format) {
-  case PICT_b8g8r8x8:
-    *no_alpha = 1;
-  case PICT_b8g8r8a8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    *no_revert = !IS_LITTLE_ENDIAN;
-    break;
-
-  case PICT_x8r8g8b8:
-    *no_alpha = 1;
-  case PICT_a8r8g8b8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-
-  case PICT_x8b8g8r8:
-    *no_alpha = 1;
-  case PICT_a8b8g8r8:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-
-  case PICT_x2r10g10b10:
-    *no_alpha = 1;
-  case PICT_a2r10g10b10:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x2b10g10r10:
-    *no_alpha = 1;
-  case PICT_a2b10g10r10:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
-    *no_revert = TRUE;
-    break;
- 
-  case PICT_r5g6b5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_b5g6r5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    *no_revert = FALSE;
-    break;
-
-  case PICT_x1b5g5r5:
-    *no_alpha = 1;
-  case PICT_a1b5g5r5:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    *no_revert = TRUE;
-    break;
-               
-  case PICT_x1r5g5b5:
-    *no_alpha = 1;
-  case PICT_a1r5g5b5:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_a8:
-    *tex_format = GL_ALPHA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x4r4g4b4:
-    *no_alpha = 1;
-  case PICT_a4r4g4b4:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x4b4g4r4:
-    *no_alpha = 1;
-  case PICT_a4b4g4r4:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    *no_revert = TRUE;
-    break;
- 
-  default:
-    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
-    return -1;
-  }
-  return 0;
+	*no_alpha = 0;
+	*no_revert = IS_LITTLE_ENDIAN;
+
+	switch (format) {
+	case PICT_b8g8r8x8:
+		*no_alpha = 1;
+	case PICT_b8g8r8a8:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		*no_revert = !IS_LITTLE_ENDIAN;
+		break;
+
+	case PICT_x8r8g8b8:
+		*no_alpha = 1;
+	case PICT_a8r8g8b8:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		break;
+
+	case PICT_x8b8g8r8:
+		*no_alpha = 1;
+	case PICT_a8b8g8r8:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		break;
+
+	case PICT_x2r10g10b10:
+		*no_alpha = 1;
+	case PICT_a2r10g10b10:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_x2b10g10r10:
+		*no_alpha = 1;
+	case PICT_a2b10g10r10:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_INT_10_10_10_2;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_r5g6b5:
+		*tex_format = GL_RGB;
+		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_b5g6r5:
+		*tex_format = GL_RGB;
+		*tex_type = GL_UNSIGNED_SHORT_5_6_5;
+		*no_revert = FALSE;
+		break;
+
+	case PICT_x1b5g5r5:
+		*no_alpha = 1;
+	case PICT_a1b5g5r5:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_x1r5g5b5:
+		*no_alpha = 1;
+	case PICT_a1r5g5b5:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_a8:
+		*tex_format = GL_ALPHA;
+		*tex_type = GL_UNSIGNED_BYTE;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_x4r4g4b4:
+		*no_alpha = 1;
+	case PICT_a4r4g4b4:
+		*tex_format = GL_BGRA;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+		*no_revert = TRUE;
+		break;
+
+	case PICT_x4b4g4r4:
+		*no_alpha = 1;
+	case PICT_a4b4g4r4:
+		*tex_format = GL_RGBA;
+		*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+		*no_revert = TRUE;
+		break;
+
+	default:
+		LogMessageVerb(X_INFO, 0,
+			       "fail to get matched format for %x \n",
+			       format);
+		return -1;
+	}
+	return 0;
 }
 
 
 #endif
 
 
-static inline int 
+static inline int
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
-                                       GLenum *format, 
-                                       GLenum *type, 
-                                       int *no_alpha,
-                                       int *no_revert)
+				       GLenum * format,
+				       GLenum * type,
+				       int *no_alpha, int *no_revert)
 {
-  glamor_pixmap_private *pixmap_priv;
-  PictFormatShort pict_format;
-
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-    pict_format = pixmap_priv->pict_format;
-  else
-    pict_format = format_for_depth(pixmap->drawable.depth);
-
-  return glamor_get_tex_format_type_from_pictformat(pict_format, 
-						    format, type, 
-                                                    no_alpha, no_revert);  
+	glamor_pixmap_private *pixmap_priv;
+	PictFormatShort pict_format;
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+	if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+		pict_format = pixmap_priv->pict_format;
+	else
+		pict_format = format_for_depth(pixmap->drawable.depth);
+
+	return glamor_get_tex_format_type_from_pictformat(pict_format,
+							  format, type,
+							  no_alpha,
+							  no_revert);
 }
 
 
 /* borrowed from uxa */
 static inline Bool
 glamor_get_rgba_from_pixel(CARD32 pixel,
-			   float * red,
-			   float * green,
-			   float * blue,
-			   float * alpha,
-			   CARD32 format)
+			   float *red,
+			   float *green,
+			   float *blue, float *alpha, CARD32 format)
 {
-  int rbits, bbits, gbits, abits;
-  int rshift, bshift, gshift, ashift;
-
-  rbits = PICT_FORMAT_R(format);
-  gbits = PICT_FORMAT_G(format);
-  bbits = PICT_FORMAT_B(format);
-  abits = PICT_FORMAT_A(format);
-
-  if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
-    rshift = gshift = bshift = ashift = 0;
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
-    bshift = 0;
-    gshift = bbits;
-    rshift = gshift + gbits;
-    ashift = rshift + rbits;
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
-    rshift = 0;
-    gshift = rbits;
-    bshift = gshift + gbits;
-    ashift = bshift + bbits;
+	int rbits, bbits, gbits, abits;
+	int rshift, bshift, gshift, ashift;
+
+	rbits = PICT_FORMAT_R(format);
+	gbits = PICT_FORMAT_G(format);
+	bbits = PICT_FORMAT_B(format);
+	abits = PICT_FORMAT_A(format);
+
+	if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
+		rshift = gshift = bshift = ashift = 0;
+	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+		bshift = 0;
+		gshift = bbits;
+		rshift = gshift + gbits;
+		ashift = rshift + rbits;
+	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+		rshift = 0;
+		gshift = rbits;
+		bshift = gshift + gbits;
+		ashift = bshift + bbits;
 #if XORG_VERSION_CURRENT >= 10699900
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
-    ashift = 0;
-    rshift = abits;
-    if (abits == 0)
-      rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
-    gshift = rshift + rbits;
-    bshift = gshift + gbits;
+	} else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+		ashift = 0;
+		rshift = abits;
+		if (abits == 0)
+			rshift = PICT_FORMAT_BPP(format) - (rbits + gbits +
+							    bbits);
+		gshift = rshift + rbits;
+		bshift = gshift + gbits;
 #endif
-  } else {
-    return FALSE;
-  }
+	} else {
+		return FALSE;
+	}
 #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
   *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
-    / (float)((1<<(_bits_)) - 1) 
+    / (float)((1<<(_bits_)) - 1)
 
-  if (rbits) 
-    COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
-  else
-    *red = 0;
+	if (rbits)
+		COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
+	else
+		*red = 0;
 
-  if (gbits) 
-    COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
-  else
-    *green = 0;
+	if (gbits)
+		COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
+	else
+		*green = 0;
 
-  if (bbits) 
-    COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
-  else
-    *blue = 0;
+	if (bbits)
+		COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
+	else
+		*blue = 0;
 
-  if (abits) 
-    COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
-  else
-    *alpha = 1;
+	if (abits)
+		COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
+	else
+		*alpha = 1;
 
-  return TRUE;
+	return TRUE;
 }
 
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
index 05555b2..f6e4cd1 100644
--- a/glamor/glamor_window.c
+++ b/glamor/glamor_window.c
@@ -34,41 +34,42 @@
 
 
 static void
-glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap)
+glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr * ppPixmap)
 {
-    PixmapPtr pPixmap = *ppPixmap;
-    glamor_pixmap_private *pixmap_priv;
+	PixmapPtr pPixmap = *ppPixmap;
+	glamor_pixmap_private *pixmap_priv;
 
-    if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
-    {
-        pixmap_priv = glamor_get_pixmap_private(pPixmap);
-        if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-          glamor_fallback("pixmap %p has no fbo\n", pPixmap);
-          goto fail;
-        }
-        glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n");
-    }
-    return;
+	if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
+		pixmap_priv = glamor_get_pixmap_private(pPixmap);
+		if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+			glamor_fallback("pixmap %p has no fbo\n", pPixmap);
+			goto fail;
+		}
+		glamor_debug_output(GLAMOR_DEBUG_UNIMPL,
+				    "To be implemented.\n");
+	}
+	return;
 
-fail:
-     GLAMOR_PANIC(" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
-		  " is broken for glamor. \n");
+      fail:
+	GLAMOR_PANIC
+	    (" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
+	     " is broken for glamor. \n");
 }
 
 Bool
 glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
 {
-    if (mask & CWBackPixmap) {
-       if (pWin->backgroundState == BackgroundPixmap) 
-         glamor_fixup_window_pixmap(&pWin->drawable, &pWin->background.pixmap);
-    }
+	if (mask & CWBackPixmap) {
+		if (pWin->backgroundState == BackgroundPixmap)
+			glamor_fixup_window_pixmap(&pWin->drawable,
+						   &pWin->
+						   background.pixmap);
+	}
 
-    if (mask & CWBorderPixmap) {
-       if (pWin->borderIsPixel == FALSE)
-         glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap);
-    }
-    return TRUE;
+	if (mask & CWBorderPixmap) {
+		if (pWin->borderIsPixel == FALSE)
+			glamor_fixup_window_pixmap(&pWin->drawable,
+						   &pWin->border.pixmap);
+	}
+	return TRUE;
 }
-
-
-
commit 2dbbe2565052cc024ce0e98918ed34c1239b780a
Merge: 4d62646 7982eca
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:21:07 2013 -0800

    Merge branch 'glamor-gongzg-merge'

commit 7982eca622bbc4b6a4845801a77da8a16138004a
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Dec 18 11:16:15 2013 -0800

    Revert changes outside of glamor from the glamor branch.
    
    We want to merge the external glamor code to the xserver, with the
    internal history retained.  However, we don't want a bunch of
    non-building changes along the way, so remove all the build system and
    support code outside of glamor for now.

diff --git a/Makefile.am b/Makefile.am
index 632258e..cea140b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,10 +17,6 @@ if RECORD
 RECORD_DIR=record
 endif
 
-if GLAMOR
-GLAMOR_DIR=glamor
-endif
-
 SUBDIRS = \
 	doc \
 	man \
@@ -42,7 +38,6 @@ SUBDIRS = \
 	$(COMPOSITE_DIR) \
 	$(GLX_DIR) \
 	exa \
-	$(GLAMOR_DIR) \
 	config \
 	hw \
 	test
@@ -93,7 +88,6 @@ DIST_SUBDIRS = \
 	composite \
 	glx \
 	exa \
-	glamor \
 	config \
 	hw \
 	test
diff --git a/README b/README
index c240ac7..b2499a0 100644
--- a/README
+++ b/README
@@ -1,41 +1,4 @@
-			Glamor setup
-
-1. Prerequirement.
-Please install makedepend and libudev-devel firstly. 
-
-2. Build xserver-glamor.
-
-Then do the following steps one by one.
-2.1. get latest glamor at github.
-
-2.2 Setup xorg development environment, use xserver-glamor to 
-    replace the official xserver. 
- Here is the link of how to setup xorg development environment: 
- http://www.x.org/wiki/ModularDevelopersGuide
- 
- For most of the packages, we prefer latest git version. Especially
- for the mesa package.
-
- When build mesa, use the following parameters: (assume you want to 
- install the experimental xorg to /opt/gfx-test) 
-#mesa/./autogen.sh --prefix=/opt/gfx-test --with-egl-platforms=drm --disable-gallium  --disable-gallium-egl
-
- build xserver-glamor as below:
-#xserver-glamor/./autogen.sh --disable-glx --enable-kdrive --enable-xephyr
-
- Once you finish all the building process, you can have a try as below:
-xserver-glamor#startx -- `pwd`/hw/xfree86/Xorg If you can find the 
- following messages on the console, then everything should work correctly.
-Mesa: Initializing x86-64 optimizations
-
-
-3. Restrictions:
-
-Currently, glamor doesn't support glx extension, will be fixed in the future.
-
-Glamor setup done.
-
-				X Server
+					X Server
 
 The X server accepts requests from client applications to create windows,
 which are (normally rectangular) "virtual screens" that the client program
diff --git a/configure.ac b/configure.ac
index bf17435..b0d2643 100644
--- a/configure.ac
+++ b/configure.ac
@@ -646,8 +646,6 @@ AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest serv
 AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
 AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
 AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
-AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
-AC_ARG_ENABLE(glamor-ddx,     AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no])
 dnl kdrive and its subsystems
 AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
 AC_ARG_ENABLE(xephyr,         AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
@@ -657,8 +655,6 @@ dnl kdrive options
 AC_ARG_ENABLE(kdrive-kbd,     AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
 AC_ARG_ENABLE(kdrive-mouse,   AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
 AC_ARG_ENABLE(kdrive-evdev,   AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
-dnl glamor options
-AC_ARG_ENABLE(glamor-gles2,         AS_HELP_STRING([--enable-glamor-gles2], [Build glamor based on gles2 (default: no)]), [GLAMOR_GLES2=$enableval], [GLAMOR_GLES2=no])
 
 
 dnl chown/chmod to be setuid root as part of build
@@ -801,9 +797,7 @@ LIBUDEV="libudev >= 143"
 LIBSELINUX="libselinux >= 2.0.86"
 LIBDBUS="dbus-1 >= 1.0"
 LIBPIXMAN="pixman-1 >= 0.21.8"
-LIBEGL="egl"
-LIBGLESV2="glesv2"
-LIBGBM="gbm"
+
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
 PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
@@ -1771,37 +1765,6 @@ AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
 AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
 AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 
-dnl glamor 
-
-if [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes] ; then
-   GLAMOR=yes
-fi
-
-AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes])
-AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes])
-AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes])
-
-if test "x$GLAMOR" = xyes; then 
-   AC_DEFINE(GLAMOR,1,[Build Glamor])
-
-   if test "x$GLAMOR_GLES2" = xyes; then
-      AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2])
-      PKG_CHECK_MODULES(GLESV2, $LIBGLESV2)
-      REQUIRED_LIBS="$REQUIRED_LIBS $LIBGLESV2"
-   else 
-      AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL])
-      PKG_CHECK_MODULES(GL, $LIBGL)
-      REQUIRED_LIBS="$REQUIRED_LIBS $LIBGL"
-   fi
-
-   if test "x$GLAMOR_DDX" = xyes; then
-     AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver])
-     PKG_CHECK_MODULES(EGL, $LIBEGL)
-     PKG_CHECK_MODULES(EGL, $LIBGBM)
-     REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL"
-   fi
-fi
-
 dnl XWin DDX
 
 AC_MSG_CHECKING([whether to build XWin DDX])
@@ -2035,10 +1998,6 @@ if test "$KDRIVE" = yes; then
     if test "x$DRI" = xyes && test "x$GLX" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
     fi
-    # The glamor stuff requires libGL, but that conflicts with GLX currently.
-    if test "x$GLX" = xno; then
-        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS gl"
-    fi
 
     PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
     if test "x$XEPHYR" = xauto; then
@@ -2174,7 +2133,6 @@ Xext/Makefile
 Xi/Makefile
 xfixes/Makefile
 exa/Makefile
-glamor/Makefile
 hw/Makefile
 hw/xfree86/Makefile
 hw/xfree86/common/Makefile
@@ -2212,7 +2170,6 @@ hw/xfree86/utils/Makefile
 hw/xfree86/utils/man/Makefile
 hw/xfree86/utils/cvt/Makefile
 hw/xfree86/utils/gtf/Makefile
-hw/xfree86/glamor/Makefile
 hw/dmx/config/Makefile
 hw/dmx/config/man/Makefile
 hw/dmx/doc/Makefile
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 744604e..9d9b64e 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -7,8 +7,7 @@ INCLUDES = 			\
 	@XEPHYR_CFLAGS@		\
 	@DRIPROTO_CFLAGS@	\
 	-I$(top_srcdir)		\
-	-I$(top_srcdir)/exa	\
-	-I$(top_srcdir)/glamor
+	-I$(top_srcdir)/exa
 
 if XV
 LIBXEPHYR_HOSTXV=libxephyr-hostxv.la
@@ -48,7 +47,6 @@ XEPHYR_SRCS =			\
 	ephyr.h			\
 	ephyrlog.h		\
 	ephyr_draw.c		\
-	ephyr_glamor.c		\
 	os.c
 
 libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS)
@@ -66,28 +64,18 @@ libxephyr_la_SOURCES = $(XEPHYR_SRCS)
 Xephyr_SOURCES = \
 	ephyrinit.c
 
-if GLAMOR_GLES2
-GLAMOR_GL_LIB = -lGLESv2
-else
-GLAMOR_GL_LIB = -lGL
-endif
-
 Xephyr_LDADD = 						\
 	libxephyr.la					\
 	libxephyr-hostx.la				\
 	$(LIBXEPHYR_HOSTXV)				\
 	$(LIBXEPHYR_HOSTDRI)				\
 	$(top_builddir)/exa/libexa.la			\
-	$(top_builddir)/glamor/libglamor.la		\
 	@KDRIVE_LIBS@					\
-	@XEPHYR_LIBS@                                   \
-        $(GLAMOR_GL_LIB)
+	@XEPHYR_LIBS@
 
 Xephyr_DEPENDENCIES =	\
 	libxephyr.la					\
 	libxephyr-hostx.la				\
-	$(top_builddir)/exa/libexa.la			\
-	$(top_builddir)/glamor/libglamor.la		\
 	$(LIBXEPHYR_HOSTXV)				\
 	$(LIBXEPHYR_HOSTDRI)				\
 	@KDRIVE_LOCAL_LIBS@
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 5e21748..7ebf1c2 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -394,7 +394,7 @@ ephyrSetInternalDamage (ScreenPtr pScreen)
   KdScreenInfo	*screen = pScreenPriv->screen;
   EphyrScrPriv	*scrpriv = screen->driver;
   PixmapPtr      pPixmap = NULL;
-
+  
   scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
 				   (DamageDestroyFunc) 0,
 				   DamageReportNone,
@@ -669,9 +669,7 @@ ephyrInitScreen (ScreenPtr pScreen)
   }
   if (!ephyrNoDRI) {
     ephyrDRIExtensionInit (pScreen) ;
-#if 0
     ephyrHijackGLXExtension () ;
-#endif
   }
 #endif
 
@@ -684,7 +682,6 @@ ephyrInitScreen (ScreenPtr pScreen)
   return TRUE;
 }
 
-
 Bool
 ephyrFinishInitScreen (ScreenPtr pScreen)
 {
@@ -701,7 +698,6 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
 
   return TRUE;
 }
-extern Bool ephyr_glamor;
 
 Bool
 ephyrCreateResources (ScreenPtr pScreen)
@@ -712,20 +708,14 @@ ephyrCreateResources (ScreenPtr pScreen)
 
   EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
             pScreen, pScreen->myNum, scrpriv->shadow);
+
   if (scrpriv->shadow) 
     return KdShadowSet (pScreen, 
 			scrpriv->randr, 
 			ephyrShadowUpdate, 
 			ephyrWindowLinear);
-  else {
-    if (ephyr_glamor) {
-      KdScreenPriv(pScreen);
-      KdScreenInfo	*screen = pScreenPriv->screen;
-      if (!glamor_glyphs_init(pScreen)) return FALSE;
-      glamor_set_screen_pixmap_texture(pScreen, screen->width, screen->height, 0);
-    }
+  else
     return ephyrSetInternalDamage(pScreen); 
-  }
 }
 
 void
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 9dcde8d..2384800 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -196,13 +196,6 @@ ephyrDrawDisable(ScreenPtr pScreen);
 void
 ephyrDrawFini(ScreenPtr pScreen);
 
-/* ephyr_glamor.c */
-Bool ephyr_glamor_init(ScreenPtr pScreen);
-void ephyr_glamor_enable(ScreenPtr pScreen);
-void ephyr_glamor_disable(ScreenPtr pScreen);
-void ephyr_glamor_fini(ScreenPtr pScreen);
-void ephyr_glamor_host_paint_rect(ScreenPtr pScreen);
-
 /*ephyvideo.c*/
 
 Bool ephyrInitVideo(ScreenPtr pScreen) ;
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
deleted file mode 100644
index 53bfbb9..0000000
--- a/hw/kdrive/ephyr/ephyr_glamor.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include "ephyr.h"
-#include "glamor.h"
-
-/**
- * This function initializes EXA to use the fake acceleration implementation
- * which just falls through to software.  The purpose is to have a reliable,
- * correct driver with which to test changes to the EXA core.
- */
-Bool
-ephyr_glamor_init(ScreenPtr screen)
-{
-    KdScreenPriv(screen);
-    KdScreenInfo *kd_screen = pScreenPriv->screen;
-
-    ephyr_glamor_host_create_context(kd_screen);
-
-    glamor_init(screen, GLAMOR_HOSTX);
-
-    return TRUE;
-}
-
-void
-ephyr_glamor_enable(ScreenPtr screen)
-{
-}
-
-void
-ephyr_glamor_disable(ScreenPtr screen)
-{
-}
-
-void
-ephyr_glamor_fini(ScreenPtr screen)
-{
-    glamor_fini(screen);
-}
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 9155d08..b674bb8 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -31,7 +31,6 @@
 
 extern Window EphyrPreExistingHostWin;
 extern Bool   EphyrWantGrayScale;
-extern Bool   ephyr_glamor;
 extern Bool   kdHasPointer;
 extern Bool   kdHasKbd;
 
@@ -118,7 +117,6 @@ ddxUseMsg (void)
   ErrorF("-host-cursor         Re-use exisiting X host server cursor\n");
   ErrorF("-fullscreen          Attempt to run Xephyr fullscreen\n");
   ErrorF("-grayscale           Simulate 8bit grayscale\n");
-  ErrorF("-glamor              Enable 2D acceleration using glamor\n");
   ErrorF("-fakexa              Simulate acceleration using software rendering\n");
   ErrorF("-verbosity <level>   Set log verbosity level\n");
 #ifdef GLXEXT
@@ -222,15 +220,6 @@ ddxProcessArgument (int argc, char **argv, int i)
       EphyrWantGrayScale = 1;      
       return 1;
     }
-  else if (!strcmp (argv[i], "-glamor"))
-    {
-      ephyr_glamor = TRUE;
-      ephyrFuncs.initAccel = ephyr_glamor_init;
-      ephyrFuncs.enableAccel = ephyr_glamor_enable;
-      ephyrFuncs.disableAccel = ephyr_glamor_disable;
-      ephyrFuncs.finiAccel = ephyr_glamor_fini;
-      return 1;
-    }
   else if (!strcmp (argv[i], "-fakexa"))
     {
       ephyrFuncs.initAccel = ephyrDrawInit;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 935c7c6..4caf451 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -46,7 +46,6 @@
 #include <unistd.h>
 #include <string.h> 		/* for memset */
 #include <time.h>
-#include <err.h>
 
 #include <sys/ipc.h>
 #include <sys/shm.h>
@@ -62,7 +61,6 @@
 #include <GL/glx.h>
 #endif /* XF86DRI */
 #include "ephyrlog.h"
-#include "GL/glx.h"
 
 #ifdef XF86DRI
 extern Bool XF86DRIQueryExtension (Display *dpy,
@@ -97,7 +95,6 @@ struct EphyrHostXVars
   Display        *dpy;
   int             screen;
   Visual         *visual;
-  XVisualInfo    *visual_info;
   Window          winroot;
   GC              gc;
   int             depth;
@@ -126,14 +123,10 @@ extern int            monitorResolution;
 char           *ephyrResName = NULL;
 int             ephyrResNameFromCmd = 0;
 char	       *ephyrTitle = NULL;
-Bool ephyr_glamor = FALSE;
 
 static void
 hostx_set_fullscreen_hint(void);
 
-static void
-ephyr_glamor_get_visual(void);
-
 /* X Error traps */
 
 static int trapped_error_code = 0;
@@ -369,11 +362,8 @@ hostx_init (void)
   HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
   HostX.gc      = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
   HostX.depth   = DefaultDepth(HostX.dpy, HostX.screen);
-  if (ephyr_glamor) {
-      ephyr_glamor_get_visual();
-  } else {
-      HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen);
-  }
+  HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen);
+
   class_hint = XAllocClassHint();
 
   for (index = 0 ; index < HostX.n_screens ; index++)
@@ -767,11 +757,6 @@ hostx_screen_init (EphyrScreenInfo screen,
 static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
                                     int x,     int y,
                                     int width, int height);
-static void
-ephyr_glamor_paint_rect (EphyrScreenInfo screen,
-			 int sx,    int sy,
-			 int dx,    int dy,
-			 int width, int height);
 
 void
 hostx_paint_rect (EphyrScreenInfo screen,
@@ -783,11 +768,6 @@ hostx_paint_rect (EphyrScreenInfo screen,
 
   EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
 
-  if (ephyr_glamor) {
-      ephyr_glamor_paint_rect(screen, sx, sy, dx, dy, width, height);
-      return;
-  }
-
   /*
    *  Copy the image data updated by the shadow layer
    *  on to the window
@@ -1465,82 +1445,3 @@ hostx_has_glx (void)
 }
 
 #endif /* XF86DRI */
-
-static void
-ephyr_glamor_get_visual(void)
-{
-    Display *dpy = HostX.dpy;
-    int attribs[] = {GLX_RGBA,
-		     GLX_RED_SIZE, 1,
-		     GLX_GREEN_SIZE, 1,
-		     GLX_BLUE_SIZE, 1,
-		     GLX_DOUBLEBUFFER, 1,
-		     None};
-    XVisualInfo *visual_info;
-    int event_base = 0, error_base = 0;
-
-    if (!glXQueryExtension (dpy, &event_base, &error_base))
-        errx(1, "Couldn't find GLX extension\n");
-
-    visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
-    if (visual_info == NULL)
-	errx(1, "Couldn't get RGB visual\n");
-
-    HostX.visual_info = visual_info;
-    HostX.visual = visual_info->visual;
-}
-
-void
-ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
-{
-    Display *dpy = HostX.dpy;
-    GLXContext ctx;
-    struct EphyrHostScreen *host_screen;
-
-    host_screen = host_screen_from_screen_info(ephyr_screen);
-
-    ctx = glXCreateContext(dpy, HostX.visual_info, NULL, True);
-    if (ctx == NULL)
-	errx(1, "glXCreateContext failed\n");
-
-    if (!glXMakeCurrent(dpy, host_screen->win, ctx))
-	errx(1, "glXMakeCurrent failed\n");
-}
-
-static void
-ephyr_glamor_paint_rect (EphyrScreenInfo screen,
-			 int sx,    int sy,
-			 int dx,    int dy,
-			 int width, int height)
-{
-    struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
-    static PFNGLXCOPYSUBBUFFERMESAPROC pglXCopySubBufferMESA = NULL;
-
-    if (!pglXCopySubBufferMESA) {
-	pglXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)
-	    glXGetProcAddressARB((const GLubyte*)"glXCopySubBufferMESA");
-	assert(pglXCopySubBufferMESA);
-    }
-
-    /* Always copy the full screen until we get things rendering correctly. */
-#if 0
-    pglXCopySubBufferMESA(HostX.dpy, host_screen->win,
-			  sx, sy, width, height);
-#else
-    pglXCopySubBufferMESA(HostX.dpy, host_screen->win,
-			  0, 0,
-			  host_screen->win_width, host_screen->win_height);
-#endif
-}
-
-struct glamor_gl_dispatch;
-extern Bool 
-glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, int gl_version, void* func);
-
-Bool
-glamor_gl_dispatch_init(void *screen, struct glamor_gl_dispatch *dispatch, int gl_version)
-{
-        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, glXGetProcAddress))
-          return FALSE;
-        return TRUE;
-}
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index d5cb0fa..4257857 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -261,7 +261,4 @@ int hostx_has_dri (void) ;
 int hostx_has_glx (void) ;
 #endif /* XF86DRI */
 
-/* ephyr_glamor_host.c */
-void ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen);
-
 #endif /*_XLIBS_STUFF_H_*/
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index f76a361..e3ef14f 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -27,16 +27,12 @@ if INT10MODULE
 INT10_SUBDIR = int10
 endif
 
-if GLAMOR
-GLAMOR_DIR=glamor
-endif
-
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw $(GLAMOR_DIR) os-support parser \
+SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
 	  ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
 	  loader dixmods exa modes \
 	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
 
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw $(GLAMOR_DIR) os-support \
+DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
                parser ramdac shadowfb vbe vgahw xaa \
                loader dixmods dri dri2 exa modes \
 	       utils doc man
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index 173d765..c031d4b 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -89,10 +89,4 @@ if LNXACPI
 XORG_CFLAGS += -DHAVE_ACPI
 endif
 
-if GLAMOR_DDX
-GLAMOR_DDX_CFLAGS = -DGLAMOR_DDX
-endif
-
-AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_DDX_CFLAGS)
-
-
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 7ab3f28..447b192 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1118,11 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev,
             } else if (dev->device_id == 0x8108) {
                 break; /* "hooray" for poulsbo */
 	    } else {
-#ifdef GLAMOR_DDX
-	      driverList[0] = "glamor";
-#else
-	      driverList[0] = "intel";
-#endif
+		driverList[0] = "intel";
 	    }
 	    break;
 	case 0x102b:		    driverList[0] = "mga";	break;
diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index ba4aeb4..1a162ab 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -14,14 +14,9 @@ if RECORD
 RECORDMOD = librecord.la
 endif
 
-if GLAMOR
-LIBGLAMOR_DIX = libglamor_dix.la
-endif
-
 module_LTLIBRARIES = libfb.la \
                      libwfb.la \
-                     libshadow.la \
-                     $(LIBGLAMOR_DIX)
+                     libshadow.la
 
 extsmoduledir = $(moduledir)/extensions
 extsmodule_LTLIBRARIES = $(RECORDMOD) \
@@ -34,17 +29,11 @@ INCLUDES = @XORG_INCS@ \
            -I$(top_srcdir)/hw/xfree86/loader \
            -I$(top_srcdir)/miext/shadow \
            -I$(top_srcdir)/glx
-           
 
 libdbe_la_LDFLAGS = -avoid-version
 libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
 libdbe_la_SOURCES = dbemodule.c
-if GLAMOR
-libglamor_dix_la_LDFLAGS = -avoid-version
-libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la
-libglamor_dix_la_SOURCES = glamor_module.c $(top_srcdir)/glamor/glamor_egl.c
-libglamor_dix_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/glamor $(LIBDRM_CFLAGS)
-endif
+
 libfb_la_LDFLAGS = -avoid-version
 libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
 libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
diff --git a/hw/xfree86/dixmods/glamor_module.c b/hw/xfree86/dixmods/glamor_module.c
deleted file mode 100644
index ee2dba8..0000000
--- a/hw/xfree86/dixmods/glamor_module.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 1998 The XFree86 Project, Inc.  All Rights Reserved.
- *
- * 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
- * XFREE86 PROJECT 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.
- *
- * Except as contained in this notice, the name of the XFree86 Project shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from the
- * XFree86 Project.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86Module.h"
-
-static XF86ModuleVersionInfo VersRec =
-{
-	"glamor_dix",
-	MODULEVENDORSTRING,
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XORG_VERSION_CURRENT,
-	1, 0, 0,
-	ABI_CLASS_ANSIC,		/* Only need the ansic layer */
-	ABI_ANSIC_VERSION,
-	MOD_CLASS_NONE,
-	{0,0,0,0}       /* signature, to be patched into the file by a tool */
-};
-
-_X_EXPORT XF86ModuleData glamor_dixModuleData = { &VersRec, NULL, NULL };
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
deleted file mode 100644
index 1d729f4..0000000
--- a/hw/xfree86/glamor/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-glamor_la_LTLIBRARIES = glamor.la
-glamor_la_CFLAGS =					\
-	-DHAVE_XORG_CONFIG_H				\
-	@DIX_CFLAGS@ @XORG_CFLAGS@ @LIBDRM_CFLAGS@	\
-	-I$(top_srcdir)/hw/xfree86/common		\
-	-I$(top_srcdir)/hw/xfree86/os-support/bus	\
-	-I$(top_srcdir)/hw/xfree86/parser		\
-	-I$(top_srcdir)/hw/xfree86/modes		\
-	-I$(top_srcdir)/hw/xfree86/ddc			\
-	-I$(top_srcdir)/hw/xfree86/ramdac		\
-	-I$(top_srcdir)/hw/xfree86/i2c			\
-        -I$(top_srcdir)/glamor
-
-if GLAMOR_GLES2
-glamor_la_CFLAGS+=-DGLAMOR_GLES2
-endif
-
-glamor_la_LDFLAGS = -module -avoid-version \
-                     $(EGL_LIBS)
-
-glamor_ladir = $(moduledir)/drivers
-glamor_la_SOURCES =				\
-	glamor_ddx.c				\
-	glamor_crtc.c				\
-	glamor_ddx.h
-
-glamor_la_DEPENDENCIES = 			\
- $(top_builddir)/glamor/libglamor.la
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
deleted file mode 100644
index ce4f31f..0000000
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ /dev/null
@@ -1,1565 +0,0 @@
-/*
- * Copyright © 2007 Red Hat, Inc.
- * Copyright © 2010 Intel Corporation.
- *
- * 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 (including
- * the next paragraph) 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.
- *
- * Authors:
- *    Dave Airlie <airlied at redhat.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <poll.h>
-#include <stdint.h>
-#include <X11/Xdefs.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/dpmsconst.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <xf86Crtc.h>
-#include <xf86DDC.h>
-#include <xorgVersion.h>
-#include <libkms/libkms.h>
-
-#include "glamor_ddx.h"
-
-typedef struct {
-    int fd;
-    uint32_t fb_id;
-    drmModeResPtr mode_res;
-    int cpp;
-    
-    drmEventContext event_context;
-    void *event_data;
-    int old_fb_id;
-    int flip_count;
-} drmmode_rec, *drmmode_ptr;
-
-typedef struct {
-    drmmode_ptr drmmode;
-    drmModeCrtcPtr mode_crtc;
-    uint32_t rotate_fb_id;
-    struct glamor_gbm_cursor *cursor;
-} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
-
-typedef struct {
-    drmModePropertyPtr mode_prop;
-    uint64_t value;
-    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
-    Atom *atoms;
-} drmmode_prop_rec, *drmmode_prop_ptr;
-
-struct fixed_panel_lvds {
-	int hdisplay;
-	int vdisplay;
-};
-typedef struct {
-    drmmode_ptr drmmode;
-    int output_id;
-    drmModeConnectorPtr mode_output;
-    drmModeEncoderPtr mode_encoder;
-    drmModePropertyBlobPtr edid_blob;
-    int num_props;
-    drmmode_prop_ptr props;
-    void *private_data;
-    int dpms_mode;
-    char *backlight_iface;
-    int backlight_active_level;
-    int backlight_max;
-} drmmode_output_private_rec, *drmmode_output_private_ptr;
-
-static void
-drmmode_output_dpms(xf86OutputPtr output, int mode);
-static Bool
-drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height);
-
-#define BACKLIGHT_CLASS "/sys/class/backlight"
-
-/*
- * List of available kernel interfaces in priority order
- */
-static char *backlight_interfaces[] = {
-    "asus-laptop",
-    "eeepc",
-    "thinkpad_screen",
-    "acpi_video1",
-    "acpi_video0",
-    "fujitsu-laptop",
-    "sony",
-    "samsung",
-    NULL,
-};
-/*
- * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table +
- * '/' + "max_backlight"
- */
-#define BACKLIGHT_PATH_LEN 80
-/* Enough for 10 digits of backlight + '\n' + '\0' */
-#define BACKLIGHT_VALUE_LEN 12
-
-static void
-drmmode_backlight_set(xf86OutputPtr output, int level)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
-    int fd, len, ret;
-
-    if (level > drmmode_output->backlight_max)
-	level = drmmode_output->backlight_max;
-    if (! drmmode_output->backlight_iface || level < 0)
-	return;
-
-    len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level);
-    sprintf(path, "%s/%s/brightness",
-	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
-    fd = open(path, O_RDWR);
-    if (fd == -1) {
-	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
-		   "control: %s\n", path, strerror(errno));
-	return;
-    }
-
-    ret = write(fd, val, len);
-    if (ret == -1) {
-	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "write to %s for backlight "
-		   "control failed: %s\n", path, strerror(errno));
-    }
-
-    close(fd);
-}
-
-static int
-drmmode_backlight_get(xf86OutputPtr output)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
-    int fd, level;
-
-    if (! drmmode_output->backlight_iface)
-	return -1;
-
-    sprintf(path, "%s/%s/actual_brightness",
-	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
-    fd = open(path, O_RDONLY);
-    if (fd == -1) {
-	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s "
-		   "for backlight control: %s\n", path, strerror(errno));
-	return -1;
-    }
-
-    memset(val, 0, sizeof(val));
-    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) {
-	close(fd);
-	return -1;
-    }
-
-    close(fd);
-
-    level = atoi(val);
-    if (level > drmmode_output->backlight_max)
-	level = drmmode_output->backlight_max;
-    if (level < 0)
-	level = -1;
-    return level;
-}
-
-static int
-drmmode_backlight_get_max(xf86OutputPtr output)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
-    int fd, max = 0;
-
-    sprintf(path, "%s/%s/max_brightness",
-	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
-    fd = open(path, O_RDONLY);
-    if (fd == -1) {
-	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s "
-		   "for backlight control: %s\n", path, strerror(errno));
-	return 0;
-    }
-
-    memset(val, 0, sizeof(val));
-    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) {
-	close(fd);
-	return -1;
-    }
-
-    close(fd);
-
-    max = atoi(val);
-    if (max <= 0)
-	max  = -1;
-    return max;
-}
-
-static void
-drmmode_backlight_init(xf86OutputPtr output)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    char path[BACKLIGHT_PATH_LEN];
-    struct stat buf;
-    int i;
-
-    for (i = 0; backlight_interfaces[i] != NULL; i++) {
-	sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
-	if (!stat(path, &buf)) {
-	    drmmode_output->backlight_iface = backlight_interfaces[i];
-	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
-		       "found backlight control interface %s\n", path);
-	    drmmode_output->backlight_max = drmmode_backlight_get_max(output);
-	    drmmode_output->backlight_active_level = drmmode_backlight_get(output);
-	    return;
-	}
-    }
-    drmmode_output->backlight_iface = NULL;
-}
-
-
-static void
-drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
-			 drmModeModeInfoPtr kmode,
-			 DisplayModePtr	mode)
-{
-	memset(mode, 0, sizeof(DisplayModeRec));
-	mode->status = MODE_OK;
-
-	mode->Clock = kmode->clock;
-
-	mode->HDisplay = kmode->hdisplay;
-	mode->HSyncStart = kmode->hsync_start;
-	mode->HSyncEnd = kmode->hsync_end;
-	mode->HTotal = kmode->htotal;
-	mode->HSkew = kmode->hskew;
-
-	mode->VDisplay = kmode->vdisplay;
-	mode->VSyncStart = kmode->vsync_start;
-	mode->VSyncEnd = kmode->vsync_end;
-	mode->VTotal = kmode->vtotal;
-	mode->VScan = kmode->vscan;
-
-	mode->Flags = kmode->flags; //& FLAG_BITS;
-	mode->name = strdup(kmode->name);
-
-	if (kmode->type & DRM_MODE_TYPE_DRIVER)
-		mode->type = M_T_DRIVER;
-	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
-		mode->type |= M_T_PREFERRED;
-	xf86SetModeCrtc (mode, scrn->adjustFlags);
-}
-
-static void
-drmmode_ConvertToKMode(ScrnInfoPtr scrn,
-		       drmModeModeInfoPtr kmode,
-		       DisplayModePtr mode)
-{
-	memset(kmode, 0, sizeof(*kmode));
-
-	kmode->clock = mode->Clock;
-	kmode->hdisplay = mode->HDisplay;
-	kmode->hsync_start = mode->HSyncStart;
-	kmode->hsync_end = mode->HSyncEnd;
-	kmode->htotal = mode->HTotal;
-	kmode->hskew = mode->HSkew;
-
-	kmode->vdisplay = mode->VDisplay;
-	kmode->vsync_start = mode->VSyncStart;
-	kmode->vsync_end = mode->VSyncEnd;
-	kmode->vtotal = mode->VTotal;
-	kmode->vscan = mode->VScan;
-
-	kmode->flags = mode->Flags; //& FLAG_BITS;
-	if (mode->name)
-		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
-	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
-
-}
-
-static void
-drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
-{
-
-}
-
-static Bool
-drmmode_update_fb (ScrnInfoPtr scrn, int width, int height)
-{
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	drmmode_crtc_private_ptr
-		drmmode_crtc = xf86_config->crtc[0]->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	uint32_t handle, pitch;
-	int ret;
-
-	if (drmmode->fb_id != 0 &&
-	    scrn->virtualX == width && scrn->virtualY == height) 
-		return TRUE;
-	if (!glamor_front_buffer_resize(scrn, width, height))
-		return FALSE;
-	if (drmmode->fb_id != 0)
-		drmModeRmFB(drmmode->fd, drmmode->fb_id);
-	glamor_frontbuffer_handle(scrn, &handle, &pitch);
-	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
-			   scrn->bitsPerPixel, pitch /** drmmode->cpp*/,
-			   handle, &drmmode->fb_id);
-	if (ret)
-		/* FIXME: Undo glamor_resize() */
-		return FALSE;
-
-	return TRUE;
-}
-
-static Bool
-drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
-		       Rotation rotation, int x, int y)
-{
-	ScrnInfoPtr scrn = crtc->scrn;
-	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int saved_x, saved_y;
-	Rotation saved_rotation;
-	DisplayModeRec saved_mode;
-	uint32_t *output_ids;
-	int output_count = 0;
-	int ret = TRUE;
-	int i;
-	int fb_id;
-        uint32_t handle, pitch;
-	drmModeModeInfo kmode;
-
-        if (drmmode->fb_id == 0) {
-
-	        glamor_frontbuffer_handle(scrn, &handle, &pitch);
-                ret = drmModeAddFB(drmmode->fd,
-                                   scrn->virtualX, scrn->virtualY,
-                                   scrn->depth, scrn->bitsPerPixel,
-                                   pitch, handle,
-                                   &drmmode->fb_id);
-                if (ret < 0) {
-                        ErrorF("failed to add fb\n");
-                        return FALSE;
-                }
-        }
-
-	saved_mode = crtc->mode;
-	saved_x = crtc->x;
-	saved_y = crtc->y;
-	saved_rotation = crtc->rotation;
-
-	crtc->mode = *mode;
-	crtc->x = x;
-	crtc->y = y;
-	crtc->rotation = rotation;
-
-	output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
-	if (!output_ids) {
-		ret = FALSE;
-		goto done;
-	}
-
-	for (i = 0; i < xf86_config->num_output; i++) {
-		xf86OutputPtr output = xf86_config->output[i];
-		drmmode_output_private_ptr drmmode_output;
-
-		if (output->crtc != crtc)
-			continue;
-
-		drmmode_output = output->driver_private;
-		output_ids[output_count] =
-			drmmode_output->mode_output->connector_id;
-		output_count++;
-	}
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0)
-	if (!xf86CrtcRotate(crtc, mode, rotation))
-		goto done;
-#else
-	if (!xf86CrtcRotate(crtc))
-		goto done;
-#endif
-
-#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0)
-	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
-			       crtc->gamma_blue, crtc->gamma_size);
-#endif
-
-	drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
-
-
-	fb_id = drmmode->fb_id;
-	if (drmmode_crtc->rotate_fb_id) {
-		fb_id = drmmode_crtc->rotate_fb_id;
-		x = 0;
-		y = 0;
-	}
-	ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-			     fb_id, x, y, output_ids, output_count, &kmode);
-	if (ret)
-		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "failed to set mode: %s", strerror(-ret));
-	else
-		ret = TRUE;
-
-	/* Turn on any outputs on this crtc that may have been disabled */
-	for (i = 0; i < xf86_config->num_output; i++) {
-		xf86OutputPtr output = xf86_config->output[i];
-
-		if (output->crtc != crtc)
-			continue;
-
-		drmmode_output_dpms(output, DPMSModeOn);
-	}
-
-	if (scrn->pScreen)
-		xf86_reload_cursors(scrn->pScreen);
-done:
-	if (!ret) {
-		crtc->x = saved_x;
-		crtc->y = saved_y;
-		crtc->rotation = saved_rotation;
-		crtc->mode = saved_mode;
-	}
-	return ret;
-}
-
-static void
-drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
-{
-
-}
-
-static void
-drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
-{
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
-	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
-}
-
-static void
-drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
-{
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	ScrnInfoPtr scrn = crtc->scrn;
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        GCPtr gc;
-
-	if (drmmode_crtc->cursor == NULL)
-	{
-             drmmode_crtc->cursor = calloc(1, sizeof(*drmmode_crtc->cursor));
-             if (drmmode_crtc->cursor == NULL) {
-                ErrorF("Failed to allocate cursor.\n");
-                return;
-             }
-	     if (!glamor_create_cursor(scrn, drmmode_crtc->cursor, 64, 64)) {
-                free(drmmode_crtc->cursor);
-                drmmode_crtc->cursor = NULL;
-                ErrorF("Failed to create glamor cursor.\n");
-		return;
-             }
-	}
-
-        gc = GetScratchGC (drmmode_crtc->cursor->cursor_pixmap->drawable.depth, screen);
-        if (!gc)
-          return;
-
-        ValidateGC (&drmmode_crtc->cursor->cursor_pixmap->drawable, gc);
-        (*gc->ops->PutImage)(&drmmode_crtc->cursor->cursor_pixmap->drawable, gc, 
-                             32, 0, 0, 64, 64, 0, ZPixmap, (char*)image); 
-        FreeScratchGC (gc);
-}
-
-
-static void
-drmmode_hide_cursor (xf86CrtcPtr crtc)
-{
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
-	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-			 0, 64, 64);
-}
-
-
-static void
-_drmmode_destroy_cursor(xf86CrtcPtr crtc)
-{
-       drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
-       if (drmmode_crtc->cursor == NULL)
-         return;
-       drmmode_hide_cursor(crtc);
-       glamor_destroy_cursor(crtc->scrn, drmmode_crtc->cursor);
-       free(drmmode_crtc->cursor);
-       drmmode_crtc->cursor = NULL;
-}
-
-static void
-drmmode_destroy_cursor(ScrnInfoPtr scrn)
-{
-       int i;
-       xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
-       for (i = 0; i < xf86_config->num_crtc; i++) 
-             _drmmode_destroy_cursor(xf86_config->crtc[i]);
-}
-
-
-
-
-static void
-drmmode_show_cursor (xf86CrtcPtr crtc)
-{
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	uint32_t handle, stride;
-
-	ErrorF("show cursor\n");
-	glamor_cursor_handle(drmmode_crtc->cursor, &handle, &stride);
-
-	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-			 handle, 64, 64);
-}
-
-#if 0
-static void *
-drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
-{
-	ScrnInfoPtr scrn = crtc->scrn;
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int size, ret;
-	unsigned long rotate_pitch;
-
-	width = i830_pad_drawable_width(width, drmmode->cpp);
-	rotate_pitch = width * drmmode->cpp;
-	size = rotate_pitch * height;
-
-	drmmode_crtc->rotate_bo =
-		drm_intel_bo_alloc(intel->bufmgr, "rotate", size, 4096);
-
-	if (!drmmode_crtc->rotate_bo) {
-		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "Couldn't allocate shadow memory for rotated CRTC\n");
-		return NULL;
-	}
-
-	drm_intel_bo_disable_reuse(drmmode_crtc->rotate_bo);
-
-	ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
-			   crtc->scrn->bitsPerPixel, rotate_pitch,
-			   drmmode_crtc->rotate_bo->handle,
-			   &drmmode_crtc->rotate_fb_id);
-	if (ret) {
-		ErrorF("failed to add rotate fb\n");
-		drm_intel_bo_unreference(drmmode_crtc->rotate_bo);
-		return NULL;
-	}
-
-	return drmmode_crtc->rotate_bo;
-}
-
-static PixmapPtr
-drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
-{
-	ScrnInfoPtr scrn = crtc->scrn;
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	unsigned long rotate_pitch;
-	PixmapPtr rotate_pixmap;
-
-	if (!data) {
-		data = drmmode_crtc_shadow_allocate (crtc, width, height);
-		if (!data) {
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-				   "Couldn't allocate shadow pixmap for rotated CRTC\n");
-			return NULL;
-		}
-	}
-
-	rotate_pitch =
-		i830_pad_drawable_width(width, drmmode->cpp) * drmmode->cpp;
-	rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen,
-					       width, height,
-					       scrn->depth,
-					       scrn->bitsPerPixel,
-					       rotate_pitch,
-					       NULL);
-
-	if (rotate_pixmap == NULL) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
-		return NULL;
-	}
-
-	if (drmmode_crtc->rotate_bo)
-		i830_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo);
-
-	intel->shadow_present = TRUE;
-
-	return rotate_pixmap;
-}
-
-static void
-drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
-{
-}
-#endif
-
-static void
-drmmode_crtc_gamma_set(xf86CrtcPtr crtc,
-		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
-{
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
-	drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-			    size, red, green, blue);
-}
-static void
-drmmode_crtc_destroy(xf86CrtcPtr crtc)
-{
-	ScrnInfoPtr scrn = crtc->scrn;
-        _drmmode_destroy_cursor(crtc);
-        crtc->driver_private = NULL;
-}
-
-static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
-	.dpms = drmmode_crtc_dpms,
-	.set_mode_major = drmmode_set_mode_major,
-	.set_cursor_colors = drmmode_set_cursor_colors,
-	.set_cursor_position = drmmode_set_cursor_position,
-	.show_cursor = drmmode_show_cursor,
-	.hide_cursor = drmmode_hide_cursor,
-	.load_cursor_argb = drmmode_load_cursor_argb,
-	.load_cursor_image = NULL,
-#if 0
-	.shadow_create = drmmode_crtc_shadow_create,
-	.shadow_allocate = drmmode_crtc_shadow_allocate,
-	.shadow_destroy = drmmode_crtc_shadow_destroy,
-#endif
-	.gamma_set = drmmode_crtc_gamma_set,
-	.destroy = drmmode_crtc_destroy
-};
-
-
-static void
-drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
-{
-	xf86CrtcPtr crtc;
-	drmmode_crtc_private_ptr drmmode_crtc;
-
-	crtc = xf86CrtcCreate(scrn, &drmmode_crtc_funcs);
-	if (crtc == NULL)
-		return;
-
-	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
-	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
-						 drmmode->mode_res->crtcs[num]);
-	drmmode_crtc->drmmode = drmmode;
-	crtc->driver_private = drmmode_crtc;
-
-	return;
-}
-
-static xf86OutputStatus
-drmmode_output_detect(xf86OutputPtr output)
-{
-	/* go to the hw and retrieve a new output struct */
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	drmmode_ptr drmmode = drmmode_output->drmmode;
-	xf86OutputStatus status;
-	drmModeFreeConnector(drmmode_output->mode_output);
-
-	drmmode_output->mode_output =
-		drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
-
-	switch (drmmode_output->mode_output->connection) {
-	case DRM_MODE_CONNECTED:
-		status = XF86OutputStatusConnected;
-		break;
-	case DRM_MODE_DISCONNECTED:
-		status = XF86OutputStatusDisconnected;
-		break;
-	default:
-	case DRM_MODE_UNKNOWNCONNECTION:
-		status = XF86OutputStatusUnknown;
-		break;
-	}
-	return status;
-}
-
-static Bool
-drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	drmModeConnectorPtr koutput = drmmode_output->mode_output;
-	struct fixed_panel_lvds *p_lvds = drmmode_output->private_data;
-
-	/*
-	 * If the connector type is LVDS, we will use the panel limit to
-	 * verfiy whether the mode is valid.
-	 */
-	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
-		if (pModes->HDisplay > p_lvds->hdisplay ||
-			pModes->VDisplay > p_lvds->vdisplay)
-			return MODE_PANEL;
-		else
-			return MODE_OK;
-	}
-	return MODE_OK;
-}
-
-static void fill_detailed_lvds_block(struct detailed_monitor_section *det_mon,
-					DisplayModePtr mode)
-{
-	struct detailed_timings *timing = &det_mon->section.d_timings;
-
-	det_mon->type = DT;
-	timing->clock = mode->Clock * 1000;
-	timing->h_active = mode->HDisplay;
-	timing->h_blanking = mode->HTotal - mode->HDisplay;
-	timing->v_active = mode->VDisplay;
-	timing->v_blanking = mode->VTotal - mode->VDisplay;
-	timing->h_sync_off = mode->HSyncStart - mode->HDisplay;
-	timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart;
-	timing->v_sync_off = mode->VSyncStart - mode->VDisplay;
-	timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart;
-
-	if (mode->Flags & V_PVSYNC)
-		timing->misc |= 0x02;
-
-	if (mode->Flags & V_PHSYNC)
-		timing->misc |= 0x01;
-}
-
-static int drmmode_output_lvds_edid(xf86OutputPtr output,
-				struct fixed_panel_lvds *p_lvds)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	drmModeConnectorPtr koutput = drmmode_output->mode_output;
-	int i, j;
-	DisplayModePtr pmode;
-	xf86MonPtr	edid_mon;
-	drmModeModeInfo *mode_ptr;
-	struct detailed_monitor_section *det_mon;
-
-	if (output->MonInfo) {
-		/*
-		 * If there exists the EDID, we will either find a DS_RANGES
-		 * or replace a DS_VENDOR block, smashing it into a DS_RANGES
-		 * block with opern refresh to match all the default modes.
-		 */
-		int edid_det_block_num;
-		edid_mon = output->MonInfo;
-		edid_mon->features.msc |= 0x01;
-		j = -1;
-		edid_det_block_num = sizeof(edid_mon->det_mon) /
-					sizeof(edid_mon->det_mon[0]);
-		for (i = 0; i < edid_det_block_num; i++) {
-			if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1)
-				j = i;
-			if (edid_mon->det_mon[i].type == DS_RANGES) {
-				j = i;
-				break;
-			}
-		}
-		if (j != -1) {
-			struct monitor_ranges	*ranges =
-				&edid_mon->det_mon[j].section.ranges;
-			edid_mon->det_mon[j].type = DS_RANGES;
-			ranges->min_v = 0;
-			ranges->max_v = 200;
-			ranges->min_h = 0;
-			ranges->max_h = 200;
-		}
-		return 0;
-	}
-	/*
-	 * If there is no EDID, we will construct a bogus EDID for LVDS output
-	 * device. This is similar to what we have done in i830_lvds.c
-	 */
-	edid_mon = NULL;
-	edid_mon = calloc(1, sizeof(xf86Monitor));
-	if (!edid_mon) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-			"Can't allocate memory for edid_mon.\n");
-		return 0;
-	}
-	/* Find the fixed panel mode.
-	 * In theory when there is no EDID, KMS kernel will return only one
-	 * mode. And this can be regarded as fixed lvds panel mode.
-	 * But it will be better to traverse the mode list to get the fixed
-	 * lvds panel mode again as we don't know whether some new modes
-	 * are added for the LVDS output device
-	 */
-	j = 0;
-	for (i = 0; i < koutput->count_modes; i++) {
-		mode_ptr = &koutput->modes[i];
-		if ((mode_ptr->hdisplay == p_lvds->hdisplay) &&
-			(mode_ptr->vdisplay == p_lvds->vdisplay)) {
-			/* find the fixed panel mode */
-			j = i;
-			break;
-		}
-	}
-	pmode = xnfalloc(sizeof(DisplayModeRec));
-	drmmode_ConvertFromKMode(output->scrn, &koutput->modes[j], pmode);
-	/*support DPM, instead of DPMS*/
-	edid_mon->features.dpms |= 0x1;
-	/*defaultly support RGB color display*/
-	edid_mon->features.display_type |= 0x1;
-	/*defaultly display support continuous-freqencey*/
-	edid_mon->features.msc |= 0x1;
-	/*defaultly  the EDID version is 1.4 */
-	edid_mon->ver.version = 1;
-	edid_mon->ver.revision = 4;
-	det_mon = edid_mon->det_mon;
-	if (pmode) {
-		/* now we construct new EDID monitor,
-		 * so filled one detailed timing block
-		 */
-		fill_detailed_lvds_block(det_mon, pmode);
-		/* the filed timing block should be set preferred*/
-		edid_mon->features.msc |= 0x2;
-		det_mon = det_mon + 1;
-	}
-	/* Set wide sync ranges so we get all modes
-	 * handed to valid_mode for checking
-	 */
-	det_mon->type = DS_RANGES;
-	det_mon->section.ranges.min_v = 0;
-	det_mon->section.ranges.max_v = 200;
-	det_mon->section.ranges.min_h = 0;
-	det_mon->section.ranges.max_h = 200;
-	output->MonInfo = edid_mon;
-	return 0;
-}
-
-static DisplayModePtr
-drmmode_output_get_modes(xf86OutputPtr output)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	drmModeConnectorPtr koutput = drmmode_output->mode_output;
-	drmmode_ptr drmmode = drmmode_output->drmmode;
-	int i;
-	DisplayModePtr Modes = NULL, Mode;
-	drmModePropertyPtr props;
-	struct fixed_panel_lvds *p_lvds;
-	drmModeModeInfo *mode_ptr;
-
-	/* look for an EDID property */
-	for (i = 0; i < koutput->count_props; i++) {
-		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
-		if (!props)
-			continue;
-		if (!(props->flags & DRM_MODE_PROP_BLOB)) {
-			drmModeFreeProperty(props);
-			continue;
-		}
-
-		if (!strcmp(props->name, "EDID")) {
-			drmModeFreePropertyBlob(drmmode_output->edid_blob);
-			drmmode_output->edid_blob =
-				drmModeGetPropertyBlob(drmmode->fd,
-						       koutput->prop_values[i]);
-		}
-		drmModeFreeProperty(props);
-	}
-
-	if (drmmode_output->edid_blob)
-		xf86OutputSetEDID(output,
-				  xf86InterpretEDID(output->scrn->scrnIndex,
-						    drmmode_output->edid_blob->data));
-	else
-		xf86OutputSetEDID(output,
-				  xf86InterpretEDID(output->scrn->scrnIndex,
-						    NULL));
-
-	/* modes should already be available */
-	for (i = 0; i < koutput->count_modes; i++) {
-		Mode = xnfalloc(sizeof(DisplayModeRec));
-
-		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i],
-					 Mode);
-		Modes = xf86ModesAdd(Modes, Mode);
-
-	}
-	p_lvds = drmmode_output->private_data;
-	/*
-	 * If the connector type is LVDS, we will traverse the kernel mode to
-	 * get the panel limit.
-	 * If it is incorrect, please fix me.
-	 */
-	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
-		p_lvds->hdisplay = 0;
-		p_lvds->vdisplay = 0;
-		for (i = 0; i < koutput->count_modes; i++) {
-			mode_ptr = &koutput->modes[i];
-			if ((mode_ptr->hdisplay >= p_lvds->hdisplay) &&
-				(mode_ptr->vdisplay >= p_lvds->vdisplay)) {
-				p_lvds->hdisplay = mode_ptr->hdisplay;
-				p_lvds->vdisplay = mode_ptr->vdisplay;
-			}
-		}
-		if (!p_lvds->hdisplay || !p_lvds->vdisplay)
-			xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-				"Incorrect KMS mode.\n");
-		drmmode_output_lvds_edid(output, p_lvds);
-	}
-	return Modes;
-}
-
-static void
-drmmode_output_destroy(xf86OutputPtr output)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	int i;
-
-	if (drmmode_output->edid_blob)
-		drmModeFreePropertyBlob(drmmode_output->edid_blob);
-	for (i = 0; i < drmmode_output->num_props; i++) {
-	    drmModeFreeProperty(drmmode_output->props[i].mode_prop);
-	    free(drmmode_output->props[i].atoms);
-	}
-	free(drmmode_output->props);
-	drmModeFreeConnector(drmmode_output->mode_output);
-	if (drmmode_output->private_data) {
-		free(drmmode_output->private_data);
-		drmmode_output->private_data = NULL;
-	}
-	if (drmmode_output->backlight_iface)
-		drmmode_backlight_set(output, drmmode_output->backlight_active_level);
-	free(drmmode_output);
-	output->driver_private = NULL;
-}
-
-static void
-drmmode_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-
-	if (!drmmode_output->backlight_iface)
-		return;
-
-	if (mode == DPMSModeOn) {
-		/* If we're going from off->on we may need to turn on the backlight. */
-		if (oldmode != DPMSModeOn)
-			drmmode_backlight_set(output, drmmode_output->backlight_active_level);
-	} else {
-		/* Only save the current backlight value if we're going from on to off. */
-		if (oldmode == DPMSModeOn)
-			drmmode_output->backlight_active_level = drmmode_backlight_get(output);
-		drmmode_backlight_set(output, 0);
-	}
-}
-
-static void
-drmmode_output_dpms(xf86OutputPtr output, int mode)
-{
-	drmmode_output_private_ptr drmmode_output = output->driver_private;
-	drmModeConnectorPtr koutput = drmmode_output->mode_output;
-	drmmode_ptr drmmode = drmmode_output->drmmode;
-	int i;
-	drmModePropertyPtr props;
-
-	for (i = 0; i < koutput->count_props; i++) {
-		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
-		if (!props)
-			continue;
-
-		if (!strcmp(props->name, "DPMS")) {
-                        drmModeConnectorSetProperty(drmmode->fd,
-                                drmmode_output->output_id,
-                                props->prop_id,
-                                mode);
-			drmmode_output_dpms_backlight(output,
-				drmmode_output->dpms_mode,
-				mode);
-			drmmode_output->dpms_mode = mode;
-                        drmModeFreeProperty(props);
-                        return;
-		}
-		drmModeFreeProperty(props);
-	}
-}
-
-static Bool
-drmmode_property_ignore(drmModePropertyPtr prop)
-{
-    if (!prop)
-	return TRUE;
-    /* ignore blob prop */
-    if (prop->flags & DRM_MODE_PROP_BLOB)
-	return TRUE;
-    /* ignore standard property */
-    if (!strcmp(prop->name, "EDID") ||
-	    !strcmp(prop->name, "DPMS"))
-	return TRUE;
-
-    return FALSE;
-}
-
-#define BACKLIGHT_NAME             "Backlight"
-#define BACKLIGHT_DEPRECATED_NAME  "BACKLIGHT"
-static Atom backlight_atom, backlight_deprecated_atom;
-
-static void
-drmmode_output_create_resources(xf86OutputPtr output)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    drmModeConnectorPtr mode_output = drmmode_output->mode_output;
-    drmmode_ptr drmmode = drmmode_output->drmmode;
-    drmModePropertyPtr drmmode_prop;
-    int i, j, err;
-
-    drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
-    if (!drmmode_output->props)
-	return;
-
-    drmmode_output->num_props = 0;
-    for (i = 0, j = 0; i < mode_output->count_props; i++) {
-	drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
-	if (drmmode_property_ignore(drmmode_prop)) {
-	    drmModeFreeProperty(drmmode_prop);
-	    continue;
-	}
-	drmmode_output->props[j].mode_prop = drmmode_prop;
-	drmmode_output->props[j].value = mode_output->prop_values[i];
-	drmmode_output->num_props++;
-	j++;
-    }
-
-    for (i = 0; i < drmmode_output->num_props; i++) {
-	drmmode_prop_ptr p = &drmmode_output->props[i];
-	drmmode_prop = p->mode_prop;
-
-	if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
-	    INT32 range[2];
-
-	    p->num_atoms = 1;
-	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
-	    if (!p->atoms)
-		continue;
-	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
-	    range[0] = drmmode_prop->values[0];
-	    range[1] = drmmode_prop->values[1];
-	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
-		    FALSE, TRUE,
-		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
-		    2, range);
-	    if (err != 0) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-			"RRConfigureOutputProperty error, %d\n", err);
-	    }
-	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
-		    XA_INTEGER, 32, PropModeReplace, 1, &p->value, FALSE, TRUE);
-	    if (err != 0) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-			"RRChangeOutputProperty error, %d\n", err);
-	    }
-	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
-	    p->num_atoms = drmmode_prop->count_enums + 1;
-	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
-	    if (!p->atoms)
-		continue;
-	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
-	    for (j = 1; j <= drmmode_prop->count_enums; j++) {
-		struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
-		p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
-	    }
-	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
-		    FALSE, FALSE,
-		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
-		    p->num_atoms - 1, (INT32 *)&p->atoms[1]);
-	    if (err != 0) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-			"RRConfigureOutputProperty error, %d\n", err);
-	    }
-	    for (j = 0; j < drmmode_prop->count_enums; j++)
-		if (drmmode_prop->enums[j].value == p->value)
-		    break;
-	    /* there's always a matching value */
-	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
-		    XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE);
-	    if (err != 0) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-			"RRChangeOutputProperty error, %d\n", err);
-	    }
-	}
-    }
-
-    if (drmmode_output->backlight_iface) {
-	INT32 data, backlight_range[2];
-	/* Set up the backlight property, which takes effect immediately
-	 * and accepts values only within the backlight_range. */
-	backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, TRUE);
-	backlight_deprecated_atom = MakeAtom(BACKLIGHT_DEPRECATED_NAME,
-		sizeof(BACKLIGHT_DEPRECATED_NAME) - 1, TRUE);
-
-	backlight_range[0] = 0;
-	backlight_range[1] = drmmode_output->backlight_max;
-	err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
-	                                FALSE, TRUE, FALSE, 2, backlight_range);
-	if (err != 0) {
-	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-	               "RRConfigureOutputProperty error, %d\n", err);
-	}
-	err = RRConfigureOutputProperty(output->randr_output, backlight_deprecated_atom,
-	                                FALSE, TRUE, FALSE, 2, backlight_range);
-	if (err != 0) {
-	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-	               "RRConfigureOutputProperty error, %d\n", err);
-	}
-	/* Set the current value of the backlight property */
-	data = drmmode_output->backlight_active_level;
-	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
-	                             XA_INTEGER, 32, PropModeReplace, 1, &data,
-	                             FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-	               "RRChangeOutputProperty error, %d\n", err);
-	}
-	err = RRChangeOutputProperty(output->randr_output, backlight_deprecated_atom,
-	                             XA_INTEGER, 32, PropModeReplace, 1, &data,
-	                             FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-	               "RRChangeOutputProperty error, %d\n", err);
-	}
-    }
-}
-
-static Bool
-drmmode_output_set_property(xf86OutputPtr output, Atom property,
-		RRPropertyValuePtr value)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    drmmode_ptr drmmode = drmmode_output->drmmode;
-    int i;
-
-    if (property == backlight_atom || property == backlight_deprecated_atom) {
-	INT32 val;
-
-	if (value->type != XA_INTEGER || value->format != 32 ||
-	    value->size != 1)
-	{
-	    return FALSE;
-	}
-
-	val = *(INT32 *)value->data;
-	if (val < 0 || val > drmmode_output->backlight_max)
-	    return FALSE;
-
-	if (drmmode_output->dpms_mode == DPMSModeOn)
-	    drmmode_backlight_set(output, val);
-	drmmode_output->backlight_active_level = val;
-	return TRUE;
-    }
-
-    for (i = 0; i < drmmode_output->num_props; i++) {
-	drmmode_prop_ptr p = &drmmode_output->props[i];
-
-	if (p->atoms[0] != property)
-	    continue;
-
-	if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
-	    uint32_t val;
-
-	    if (value->type != XA_INTEGER || value->format != 32 ||
-		    value->size != 1)
-		return FALSE;
-	    val = *(uint32_t *)value->data;
-
-	    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
-		    p->mode_prop->prop_id, (uint64_t)val);
-	    return TRUE;
-	} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
-	    Atom	atom;
-	    const char	*name;
-	    int		j;
-
-	    if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
-		return FALSE;
-	    memcpy(&atom, value->data, 4);
-	    name = NameForAtom(atom);
-
-	    /* search for matching name string, then set its value down */
-	    for (j = 0; j < p->mode_prop->count_enums; j++) {
-		if (!strcmp(p->mode_prop->enums[j].name, name)) {
-		    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
-			    p->mode_prop->prop_id, p->mode_prop->enums[j].value);
-		    return TRUE;
-		}
-	    }
-	    return FALSE;
-	}
-    }
-
-    return TRUE;
-}
-
-static Bool
-drmmode_output_get_property(xf86OutputPtr output, Atom property)
-{
-    drmmode_output_private_ptr drmmode_output = output->driver_private;
-    int err;
-
-    if (property == backlight_atom || property == backlight_deprecated_atom) {
-	INT32 val;
-
-	if (! drmmode_output->backlight_iface)
-	    return FALSE;
-
-	val = drmmode_backlight_get(output);
-	if (val < 0)
-	    return FALSE;
-	err = RRChangeOutputProperty(output->randr_output, property,
-	                             XA_INTEGER, 32, PropModeReplace, 1, &val,
-	                             FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-	               "RRChangeOutputProperty error, %d\n", err);
-	    return FALSE;
-	}
-
-	return TRUE;
-    }
-
-    return TRUE;
-}
-
-static const xf86OutputFuncsRec drmmode_output_funcs = {
-	.create_resources = drmmode_output_create_resources,
-#ifdef RANDR_12_INTERFACE
-	.set_property = drmmode_output_set_property,
-	.get_property = drmmode_output_get_property,
-#endif
-	.dpms = drmmode_output_dpms,
-	.detect = drmmode_output_detect,
-	.mode_valid = drmmode_output_mode_valid,
-
-	.get_modes = drmmode_output_get_modes,
-	.destroy = drmmode_output_destroy
-};
-
-static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
-				      SubPixelHorizontalRGB,
-				      SubPixelHorizontalBGR,
-				      SubPixelVerticalRGB,
-				      SubPixelVerticalBGR,
-				      SubPixelNone };
-
-static const char *output_names[] = { "None",
-				      "VGA",
-				      "DVI",
-				      "DVI",
-				      "DVI",
-				      "Composite",
-				      "TV",
-				      "LVDS",
-				      "CTV",
-				      "DIN",
-				      "DP",
-				      "HDMI",
-				      "HDMI",
-};
-
-
-static void
-drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
-{
-	xf86OutputPtr output;
-	drmModeConnectorPtr koutput;
-	drmModeEncoderPtr kencoder;
-	drmmode_output_private_ptr drmmode_output;
-	char name[32];
-
-	koutput = drmModeGetConnector(drmmode->fd,
-				      drmmode->mode_res->connectors[num]);
-	if (!koutput)
-		return;
-
-	kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
-	if (!kencoder) {
-		drmModeFreeConnector(koutput);
-		return;
-	}
-
-	snprintf(name, 32, "%s%d", output_names[koutput->connector_type],
-		 koutput->connector_type_id);
-
-	output = xf86OutputCreate (scrn, &drmmode_output_funcs, name);
-	if (!output) {
-		drmModeFreeEncoder(kencoder);
-		drmModeFreeConnector(koutput);
-		return;
-	}
-
-	drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
-	if (!drmmode_output) {
-		xf86OutputDestroy(output);
-		drmModeFreeConnector(koutput);
-		drmModeFreeEncoder(kencoder);
-		return;
-	}
-	/*
-	 * If the connector type of the output device is LVDS, we will
-	 * allocate the private_data to store the panel limit.
-	 * For example: hdisplay, vdisplay
-	 */
-	drmmode_output->private_data = NULL;
-	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) {
-		drmmode_output->private_data = calloc(
-				sizeof(struct fixed_panel_lvds), 1);
-		if (!drmmode_output->private_data)
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-				"Can't allocate private memory for LVDS.\n");
-	}
-	drmmode_output->output_id = drmmode->mode_res->connectors[num];
-	drmmode_output->mode_output = koutput;
-	drmmode_output->mode_encoder = kencoder;
-	drmmode_output->drmmode = drmmode;
-	output->mm_width = koutput->mmWidth;
-	output->mm_height = koutput->mmHeight;
-
-	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
-	output->driver_private = drmmode_output;
-
-	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS)
-		drmmode_backlight_init(output);
-
-	output->possible_crtcs = kencoder->possible_crtcs;
-	output->possible_clones = kencoder->possible_clones;
-	return;
-}
-
-
-static Bool
-drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
-{
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	int i;
-
-	if (!drmmode_update_fb(scrn, width, height))
-		return FALSE;
-	for (i = 0; i < xf86_config->num_crtc; i++) {
-		xf86CrtcPtr crtc = xf86_config->crtc[i];
-
-		if (!crtc->enabled)
-			continue;
-		drmmode_set_mode_major(crtc, &crtc->mode,
-				       crtc->rotation, crtc->x, crtc->y);
-	}
-
-	return TRUE;
-}
-
-static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
-	drmmode_xf86crtc_resize
-};
-
-#if 0
-Bool
-drmmode_do_pageflip(ScreenPtr screen, dri_bo *new_front, dri_bo *old_front,
-		    void *data)
-{
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	intel_screen_private *intel = intel_get_screen_private(scrn);
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-	drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	unsigned int pitch = scrn->displayWidth * intel->cpp;
-	int i, old_fb_id;
-	unsigned int crtc_id;
-
-	/*
-	 * Create a new handle for the back buffer
-	 */
-	old_fb_id = drmmode->fb_id;
-	if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY,
-			 scrn->depth, scrn->bitsPerPixel, pitch,
-			 new_front->handle, &drmmode->fb_id))
-		goto error_out;
-
-	/*
-	 * Queue flips on all enabled CRTCs
-	 * Note that if/when we get per-CRTC buffers, we'll have to update this.
-	 * Right now it assumes a single shared fb across all CRTCs, with the
-	 * kernel fixing up the offset of each CRTC as necessary.
-	 *
-	 * Also, flips queued on disabled or incorrectly configured displays
-	 * may never complete; this is a configuration error.
-	 */
-	for (i = 0; i < config->num_crtc; i++) {
-		xf86CrtcPtr crtc = config->crtc[i];
-
-		if (!crtc->enabled)
-			continue;
-
-		drmmode_crtc = crtc->driver_private;
-		crtc_id = drmmode_crtc->mode_crtc->crtc_id;
-		drmmode->event_data = data;
-		drmmode->flip_count++;
-		if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id,
-				    DRM_MODE_PAGE_FLIP_EVENT, drmmode)) {
-			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-				   "flip queue failed: %s\n", strerror(errno));
-			goto error_undo;
-		}
-	}
-
-	dri_bo_pin(new_front, 0);
-	dri_bo_unpin(new_front);
-
-	scrn->fbOffset = new_front->offset;
-	intel->front_buffer->bo = new_front;
-	intel->front_buffer->offset = new_front->offset;
-	drmmode->old_fb_id = old_fb_id;
-
-	return TRUE;
-
-error_undo:
-	drmModeRmFB(drmmode->fd, drmmode->fb_id);
-	drmmode->fb_id = old_fb_id;
-
-error_out:
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
-		   strerror(errno));
-	return FALSE;
-}
-
-static void
-drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec,
-		       unsigned int tv_usec, void *event_data)
-{
-	I830DRI2FrameEventHandler(frame, tv_sec, tv_usec, event_data);
-}
-
-static void
-drmmode_page_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
-			  unsigned int tv_usec, void *event_data)
-{
-	drmmode_ptr drmmode = event_data;
-
-	drmmode->flip_count--;
-	if (drmmode->flip_count > 0)
-		return;
-
-	drmModeRmFB(drmmode->fd, drmmode->old_fb_id);
-
-	I830DRI2FlipEventHandler(frame, tv_sec, tv_usec, drmmode->event_data);
-}
-
-static void
-drm_wakeup_handler(pointer data, int err, pointer p)
-{
-    drmmode_ptr drmmode = data;
-    fd_set *read_mask = p;
-
-    if (err >= 0 && FD_ISSET(drmmode->fd, read_mask))
-	drmHandleEvent(drmmode->fd, &drmmode->event_context);
-}
-#endif
-
-Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
-{
-	drmmode_ptr drmmode;
-	unsigned int i;
-
-	drmmode = xnfalloc(sizeof *drmmode);
-	drmmode->fd = fd;
-	drmmode->fb_id = 0;
-
-	xf86CrtcConfigInit(scrn, &drmmode_xf86crtc_config_funcs);
-
-	drmmode->cpp = cpp;
-	drmmode->mode_res = drmModeGetResources(drmmode->fd);
-	if (!drmmode->mode_res) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "failed to get resources: %s\n", strerror(errno));
-		return FALSE;
-	}
-
-	xf86CrtcSetSizeRange(scrn, 320, 200, drmmode->mode_res->max_width,
-			     drmmode->mode_res->max_height);
-	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
-		drmmode_crtc_init(scrn, drmmode, i);
-
-	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
-		drmmode_output_init(scrn, drmmode, i);
-
-	xf86InitialConfiguration(scrn, TRUE);
-
-#if 0
-	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
-	gp.value = &has_flipping;
-	(void)drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp,
-				  sizeof(gp));
-	if (has_flipping) {
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "Kernel page flipping support detected, enabling\n");
-		intel->use_pageflipping = TRUE;
-		drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
-		drmmode->event_context.vblank_handler = drmmode_vblank_handler;
-		drmmode->event_context.page_flip_handler =
-		    drmmode_page_flip_handler;
-		AddGeneralSocket(fd);
-		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-					       drm_wakeup_handler, drmmode);
-	}
-#endif
-
-	return TRUE;
-}
-
-void drmmode_closefb(ScrnInfoPtr scrn)
-{
-	xf86CrtcConfigPtr xf86_config;
-	drmmode_crtc_private_ptr drmmode_crtc;
-	drmmode_ptr drmmode;
-
-	xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
-	drmmode_crtc = xf86_config->crtc[0]->driver_private;
-	drmmode = drmmode_crtc->drmmode;
-
-        drmmode_destroy_cursor(scrn);
-
-	drmModeRmFB(drmmode->fd, drmmode->fb_id);
-	drmmode->fb_id = 0;
-}
diff --git a/hw/xfree86/glamor/glamor_ddx.c b/hw/xfree86/glamor/glamor_ddx.c
deleted file mode 100644
index f4b37ab..0000000
--- a/hw/xfree86/glamor/glamor_ddx.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation.
- *
- * 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 (including
- * the next paragraph) 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.
- *
- * Authors:
- *    Kristian Høgsberg <krh at bitplanet.net>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <gbm.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <xf86drm.h>
-
-#include "../../../mi/micmap.h"
-#include <xf86Crtc.h>
-#include <xf86.h>
-//#define GC XORG_GC
-#include <glamor.h>
-//#undef GC
-
-#include "glamor_ddx.h"
-
-#define GLAMOR_VERSION_MAJOR 0
-#define GLAMOR_VERSION_MINOR 1
-#define GLAMOR_VERSION_PATCH 0
-
-static const char glamor_ddx_name[] = "glamor";
-
-static void
-glamor_ddx_identify(int flags)
-{
-	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
-}
-
-static Bool
-glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
-                                        GBM_BO_FORMAT_ARGB8888,
-                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
-	if (glamor->root_bo == NULL)
-		return FALSE;
-
-        scrn->virtualX = width;
-        scrn->virtualY = height; 
-        /* XXX shall we update displayWidth here ? */
-        return TRUE;
-}
-
-static Bool
-glamor_create_screen_image(ScrnInfoPtr scrn)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-	unsigned int handle, stride;
-        handle = gbm_bo_get_handle(glamor->root_bo).u32;
-        stride = gbm_bo_get_pitch(glamor->root_bo);
-        return glamor_create_egl_screen_image(screen, handle, stride);
-}
-
-Bool
-glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-
-        if (glamor->root_bo != NULL) {
-          glamor_close_egl_screen(screen);
-          gbm_bo_destroy(glamor->root_bo);
-          glamor->root_bo = NULL;
-        } 
-
-        if (!glamor_ddx_init_front_buffer(scrn, width, height)) 
-           return FALSE;
-        return glamor_create_screen_image(scrn);
-}
-
-void
-glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        *handle = gbm_bo_get_handle(glamor->root_bo).u32;
-        *pitch = gbm_bo_get_pitch(glamor->root_bo);
-}
-
-Bool
-glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-        unsigned int handle, stride;
-        
-
-        if (cursor->cursor_pixmap) 
-          glamor_destroy_cursor(scrn, cursor);
-
-        cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0);
-        if (cursor->cursor_pixmap == NULL)
-           return FALSE;
-        screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0);
-        cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
-                                          GBM_BO_FORMAT_ARGB8888,
-                                          GBM_BO_USE_SCANOUT 
-                                          | GBM_BO_USE_RENDERING 
-                                          | GBM_BO_USE_CURSOR_64X64);
-
-	if (cursor->cursor_bo == NULL) 
-          goto fail; 
-        glamor_cursor_handle(cursor, &handle, &stride);
-        if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride))
-          goto fail;
-
-        return TRUE;
-
-fail:
-        glamor_destroy_cursor(scrn, cursor);
-        return FALSE; 
-}
-
-void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor)
-{
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-        if (cursor->cursor_pixmap)
-          screen->DestroyPixmap(cursor->cursor_pixmap);
-        if (cursor->cursor_bo)
-          gbm_bo_destroy(cursor->cursor_bo);  
-        cursor->cursor_bo = NULL;
-        cursor->cursor_pixmap = NULL;
-}
-
-void
-glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch)
-{
-        *handle = gbm_bo_get_handle(cursor->cursor_bo).u32;
-        *pitch = gbm_bo_get_pitch(cursor->cursor_bo);
-	ErrorF("cursor stride: %d\n", *pitch);
-}
-
-char * dri_device_name = "/dev/dri/card0";
-static Bool
-glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags)
-{
-	struct glamor_ddx_screen_private *glamor;
-	rgb defaultWeight = { 0, 0, 0 };
-
-	glamor = xnfcalloc(sizeof *glamor, 1);
-
-	scrn->driverPrivate = glamor;
-	glamor->fd = open(dri_device_name, O_RDWR);
-	if (glamor->fd == -1 ) {
-	  ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
-	  goto fail;
-	}
-
-	glamor->cpp = 4;
-
-	scrn->monitor = scrn->confScreen->monitor;
-	scrn->progClock = TRUE;
-	scrn->rgbBits = 8;
-
-	if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb))
-	  goto fail;
-
-	xf86PrintDepthBpp(scrn);
-
-	if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
-	  goto fail;
-	if (!xf86SetDefaultVisual(scrn, -1))
-	  goto fail;
-
-	glamor->cpp = scrn->bitsPerPixel / 8;
-
-	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Kernel modesetting setup failed\n");
-         goto fail;
-	}
-
-	scrn->currentMode = scrn->modes;
-	xf86SetDpi(scrn, 0, 0);
-
-	/* Load the required sub modules */
-	if (!xf86LoadSubModule(scrn, "fb"))
-	  goto fail;
-
-	if (!xf86LoadSubModule(scrn, "glamor_dix"))
-	  goto fail;
-
-	return TRUE;
-
-fail:
-	scrn->driverPrivate = NULL;
-	free(glamor);
-	return FALSE;
-}
-
-static void
-glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags)
-{
-}
-
-static Bool
-glamor_ddx_enter_vt(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	if (drmSetMaster(glamor->fd)) {
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "drmSetMaster failed: %s\n", strerror(errno));
-		return FALSE;
-	}
-        if (!xf86SetDesiredModes(scrn))
-	  return FALSE;
-	return TRUE;
-}
-
-static void
-glamor_ddx_leave_vt(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	drmDropMaster(glamor->fd);
-}
-
-static Bool
-glamor_ddx_create_screen_resources(ScreenPtr screen)
-{
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	screen->CreateScreenResources = glamor->CreateScreenResources;
-	if (!(*screen->CreateScreenResources) (screen))
-		return FALSE;
-        if (!glamor_glyphs_init(screen))
-                return FALSE;
-        if (glamor->root_bo == NULL)
-                return FALSE;
-        if (!glamor_create_screen_image(scrn))
-                return FALSE;
-	return TRUE;
-}
-
-static Bool
-glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	screen->CloseScreen = glamor->CloseScreen;
-	(*screen->CloseScreen) (scrnIndex, screen);
-
-	if (scrn->vtSema == TRUE)
-		glamor_ddx_leave_vt(scrnIndex, 0);
-
-	glamor_fini(screen);
-        glamor_close_egl_screen(screen);
-        gbm_bo_destroy(glamor->root_bo);
-	drmmode_closefb(scrn);
-	
-	return TRUE;
-}
-
-static Bool
-glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
-{
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	VisualPtr visual;
-
-        glamor->gbm = gbm_create_device(glamor->fd);
-        if (glamor->gbm == NULL) {
-          ErrorF("couldn't create gbm device\n");
-          return FALSE;
-        }
-
-	glamor_egl_init(scrn, glamor->fd);
-
-	miClearVisualTypes();
-	if (!miSetVisualTypes(scrn->depth,
-			      miGetDefaultVisualMask(scrn->depth),
-			      scrn->rgbBits, scrn->defaultVisual))
-		return FALSE;
-	if (!miSetPixmapDepths())
-		return FALSE;
-
-        if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY))
-                return FALSE;
-
-	if (!fbScreenInit(screen, NULL,
-			  scrn->virtualX, scrn->virtualY,
-			  scrn->xDpi, scrn->yDpi,
-			  1, scrn->bitsPerPixel))
-		return FALSE;
-
-	if (scrn->bitsPerPixel > 8) {
-	  /* Fixup RGB ordering */
-	  visual = screen->visuals + screen->numVisuals;
-	  while(--visual >= screen->visuals) {
-	    if ((visual->class | DynamicClass) == DirectColor) {
-	      visual->offsetRed = scrn->offset.red;
-	      visual->offsetGreen = scrn->offset.green;
-	      visual->offsetBlue = scrn->offset.blue;
-	      visual->redMask = scrn->mask.red;
-	      visual->blueMask = scrn->mask.blue;
-	    }
-	  }
-	}
-
-	fbPictureInit(screen, NULL, 0);
-	xf86SetBlackWhitePixels(screen);
-
-	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to initialize glamor\n");
-		return FALSE;
-	}
-	
-	miInitializeBackingStore(screen);
-	xf86SetBackingStore(screen);
-	xf86SetSilkenMouse(screen);
-	miDCInitialize(screen, xf86GetPointerScreenFuncs());
-
-	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
-
-	if (!xf86_cursors_init(screen, 64, 64,
-			       (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
-				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
-				HARDWARE_CURSOR_INVERT_MASK |
-				HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
-				HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
-				HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
-				HARDWARE_CURSOR_UPDATE_UNHIDDEN |
-				HARDWARE_CURSOR_ARGB))) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Hardware cursor initialization failed\n");
-	}
-
-	/* Must force it before EnterVT, so we are in control of VT and
-	 * later memory should be bound when allocating, e.g rotate_mem */
-	scrn->vtSema = TRUE;
-
-	if (!glamor_ddx_enter_vt(scrnIndex, 0))
-		return FALSE;
-
-	screen->SaveScreen = xf86SaveScreen;
-	glamor->CreateScreenResources = screen->CreateScreenResources;
-	screen->CreateScreenResources = glamor_ddx_create_screen_resources;
-	glamor->CloseScreen = screen->CloseScreen;
-	screen->CloseScreen = glamor_ddx_close_screen;
-	/* Fixme should we init crtc screen here? */
-	if (!xf86CrtcScreenInit(screen))
-	  return FALSE;
-	if (!miCreateDefColormap(screen))
-	  return FALSE;
-	/* Fixme should we add handle colormap here? */
-
-	xf86DPMSInit(screen, xf86DPMSSet, 0);
-
-	return TRUE;
-}
-
-static void
-glamor_ddx_free_screen(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	if (glamor != NULL)
-	{
-	  close(glamor->fd);
-	  free(glamor);
-	  scrn->driverPrivate = NULL;
-	}
-}
-
-static ModeStatus
-glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
-	if (mode->Flags & V_INTERLACE) {
-		if (verbose) {
-			xf86DrvMsg(scrnIndex, X_PROBED,
-				   "Removing interlaced mode \"%s\"\n",
-				   mode->name);
-		}
-		return MODE_BAD;
-	}
-	return MODE_OK;
-}
-
-static Bool
-glamor_ddx_probe(struct _DriverRec *drv, int flags)
-{
-	ScrnInfoPtr scrn = NULL;
-       	GDevPtr *sections;
-	int entity, n;
-
-	n = xf86MatchDevice(glamor_ddx_name, &sections);
-	if (n <= 0)
-	    return FALSE;
-
-	entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE);
-
-	scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
-	if (scrn == NULL) {
-		xf86Msg(X_ERROR, "Failed to add fb entity\n");
-		return FALSE;
-	}
-
-	scrn->driverVersion = 1;
-	scrn->driverName = (char *) glamor_ddx_name;
-	scrn->name = (char *) glamor_ddx_name;
-	scrn->Probe = NULL;
-
-	scrn->PreInit = glamor_ddx_pre_init;
-	scrn->ScreenInit = glamor_ddx_screen_init;
-	scrn->AdjustFrame = glamor_ddx_adjust_frame;
-	scrn->EnterVT = glamor_ddx_enter_vt;
-	scrn->LeaveVT = glamor_ddx_leave_vt;
-	scrn->FreeScreen = glamor_ddx_free_screen;
-	scrn->ValidMode = glamor_ddx_valid_mode;
-
-	return TRUE;
-}
-
-static const OptionInfoRec *
-glamor_ddx_available_options(int chipid, int busid)
-{
-	return NULL;
-}
-
-static Bool
-glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
-{
-	xorgHWFlags *flag;
-
-	switch (op) {
-        case GET_REQUIRED_HW_INTERFACES:
-		flag = (CARD32*)ptr;
-		(*flag) = 0;
-		return TRUE;
-        default:
-		/* Unknown or deprecated function */
-		return FALSE;
-	}
-}
-
-_X_EXPORT DriverRec glamor_ddx = {
-	1,
-	"glamor",
-	glamor_ddx_identify,
-	glamor_ddx_probe,
-	glamor_ddx_available_options,
-	NULL,
-	0,
-	glamor_ddx_driver_func,
-};
-
-static pointer
-glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
-   static Bool setupDone = 0;
-
-   /* This module should be loaded only once, but check to be sure.
-    */
-   if (!setupDone) {
-      setupDone = 1;
-      xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs);
-
-      /*
-       * The return value must be non-NULL on success even though there
-       * is no TearDownProc.
-       */
-      return (pointer) 1;
-   } else {
-      if (errmaj)
-	 *errmaj = LDR_ONCEONLY;
-      return NULL;
-   }
-}
-
-static XF86ModuleVersionInfo glamor_ddx_version_info = {
-	glamor_ddx_name,
-	MODULEVENDORSTRING,
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XORG_VERSION_CURRENT,
-	GLAMOR_VERSION_MAJOR,
-	GLAMOR_VERSION_MINOR,
-	GLAMOR_VERSION_PATCH,
-	ABI_CLASS_VIDEODRV,
-	ABI_VIDEODRV_VERSION,
-	MOD_CLASS_VIDEODRV,
-	{0, 0, 0, 0}
-};
-
-_X_EXPORT XF86ModuleData glamorModuleData = {
-	&glamor_ddx_version_info,
-	glamor_ddx_setup,
-	NULL
-};
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
deleted file mode 100644
index 3ffd488..0000000
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef GLAMOR_DDX_H
-#define GLAMOR_DDX_H
-
-#include <gbm.h>
-#define GLAMOR_FOR_XORG 1
-#include <glamor.h>
-struct glamor_ddx_screen_private {
-        struct gbm_bo *root_bo;
-        struct gbm_bo *cursor_bo;
-        struct gbm_device *gbm;
-
-	CreateScreenResourcesProcPtr CreateScreenResources;
-	CloseScreenProcPtr CloseScreen;
-	int fd;
-	int cpp;
-};
-
-struct glamor_gbm_cursor {
-       struct gbm_bo *cursor_bo;
-       PixmapPtr cursor_pixmap;
-};
-
-inline static struct glamor_ddx_screen_private *
-glamor_ddx_get_screen_private(ScrnInfoPtr scrn)
-{
-	return (struct glamor_ddx_screen_private *) (scrn->driverPrivate);
-}
-
-Bool glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height);
-void glamor_frontbuffer_handle(ScrnInfoPtr scrn,
-			       uint32_t *handle, uint32_t *pitch);
-Bool glamor_load_cursor(ScrnInfoPtr scrn,
-			int width, int height);
-
-void glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch);
-Bool glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height);
-void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) ;
-
-Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
-void drmmode_closefb(ScrnInfoPtr scrn);
-
-#endif
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index c9760b0..0d1ea91 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -139,15 +139,4 @@
 /* Build with libdrm support */
 #undef WITH_LIBDRM
 
-
-/* Build GLAMOR */
-#undef GLAMOR
-
-/* Build GLAMOR over GLES2*/
-#undef GLAMOR_GLES2
-
-/* Build GLAMOR ddx*/
-#undef GLAMOR_DDX
-
-
 #endif /* _XORG_CONFIG_H_ */
commit 284328a6beb0bd0ab6653973ce52b5a68b4e791f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 17:04:56 2011 +0800

    glamor-ddx: Rename glamor.c to glamor_ddx.c.
    
    As glamor's dix module already has a glamor.c, rename this
    glamor.c to other name to avoid file name conflict which
    may confuse gdb.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index fbd561c..1d729f4 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -20,7 +20,7 @@ glamor_la_LDFLAGS = -module -avoid-version \
 
 glamor_ladir = $(moduledir)/drivers
 glamor_la_SOURCES =				\
-	glamor.c				\
+	glamor_ddx.c				\
 	glamor_crtc.c				\
 	glamor_ddx.h
 
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
deleted file mode 100644
index f4b37ab..0000000
--- a/hw/xfree86/glamor/glamor.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright © 2010 Intel Corporation.
- *
- * 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 (including
- * the next paragraph) 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.
- *
- * Authors:
- *    Kristian Høgsberg <krh at bitplanet.net>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <gbm.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <xf86drm.h>
-
-#include "../../../mi/micmap.h"
-#include <xf86Crtc.h>
-#include <xf86.h>
-//#define GC XORG_GC
-#include <glamor.h>
-//#undef GC
-
-#include "glamor_ddx.h"
-
-#define GLAMOR_VERSION_MAJOR 0
-#define GLAMOR_VERSION_MINOR 1
-#define GLAMOR_VERSION_PATCH 0
-
-static const char glamor_ddx_name[] = "glamor";
-
-static void
-glamor_ddx_identify(int flags)
-{
-	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
-}
-
-static Bool
-glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
-                                        GBM_BO_FORMAT_ARGB8888,
-                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
-	if (glamor->root_bo == NULL)
-		return FALSE;
-
-        scrn->virtualX = width;
-        scrn->virtualY = height; 
-        /* XXX shall we update displayWidth here ? */
-        return TRUE;
-}
-
-static Bool
-glamor_create_screen_image(ScrnInfoPtr scrn)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-	unsigned int handle, stride;
-        handle = gbm_bo_get_handle(glamor->root_bo).u32;
-        stride = gbm_bo_get_pitch(glamor->root_bo);
-        return glamor_create_egl_screen_image(screen, handle, stride);
-}
-
-Bool
-glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-
-        if (glamor->root_bo != NULL) {
-          glamor_close_egl_screen(screen);
-          gbm_bo_destroy(glamor->root_bo);
-          glamor->root_bo = NULL;
-        } 
-
-        if (!glamor_ddx_init_front_buffer(scrn, width, height)) 
-           return FALSE;
-        return glamor_create_screen_image(scrn);
-}
-
-void
-glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        *handle = gbm_bo_get_handle(glamor->root_bo).u32;
-        *pitch = gbm_bo_get_pitch(glamor->root_bo);
-}
-
-Bool
-glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-        unsigned int handle, stride;
-        
-
-        if (cursor->cursor_pixmap) 
-          glamor_destroy_cursor(scrn, cursor);
-
-        cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0);
-        if (cursor->cursor_pixmap == NULL)
-           return FALSE;
-        screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0);
-        cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
-                                          GBM_BO_FORMAT_ARGB8888,
-                                          GBM_BO_USE_SCANOUT 
-                                          | GBM_BO_USE_RENDERING 
-                                          | GBM_BO_USE_CURSOR_64X64);
-
-	if (cursor->cursor_bo == NULL) 
-          goto fail; 
-        glamor_cursor_handle(cursor, &handle, &stride);
-        if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride))
-          goto fail;
-
-        return TRUE;
-
-fail:
-        glamor_destroy_cursor(scrn, cursor);
-        return FALSE; 
-}
-
-void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor)
-{
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-        if (cursor->cursor_pixmap)
-          screen->DestroyPixmap(cursor->cursor_pixmap);
-        if (cursor->cursor_bo)
-          gbm_bo_destroy(cursor->cursor_bo);  
-        cursor->cursor_bo = NULL;
-        cursor->cursor_pixmap = NULL;
-}
-
-void
-glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch)
-{
-        *handle = gbm_bo_get_handle(cursor->cursor_bo).u32;
-        *pitch = gbm_bo_get_pitch(cursor->cursor_bo);
-	ErrorF("cursor stride: %d\n", *pitch);
-}
-
-char * dri_device_name = "/dev/dri/card0";
-static Bool
-glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags)
-{
-	struct glamor_ddx_screen_private *glamor;
-	rgb defaultWeight = { 0, 0, 0 };
-
-	glamor = xnfcalloc(sizeof *glamor, 1);
-
-	scrn->driverPrivate = glamor;
-	glamor->fd = open(dri_device_name, O_RDWR);
-	if (glamor->fd == -1 ) {
-	  ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
-	  goto fail;
-	}
-
-	glamor->cpp = 4;
-
-	scrn->monitor = scrn->confScreen->monitor;
-	scrn->progClock = TRUE;
-	scrn->rgbBits = 8;
-
-	if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb))
-	  goto fail;
-
-	xf86PrintDepthBpp(scrn);
-
-	if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
-	  goto fail;
-	if (!xf86SetDefaultVisual(scrn, -1))
-	  goto fail;
-
-	glamor->cpp = scrn->bitsPerPixel / 8;
-
-	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Kernel modesetting setup failed\n");
-         goto fail;
-	}
-
-	scrn->currentMode = scrn->modes;
-	xf86SetDpi(scrn, 0, 0);
-
-	/* Load the required sub modules */
-	if (!xf86LoadSubModule(scrn, "fb"))
-	  goto fail;
-
-	if (!xf86LoadSubModule(scrn, "glamor_dix"))
-	  goto fail;
-
-	return TRUE;
-
-fail:
-	scrn->driverPrivate = NULL;
-	free(glamor);
-	return FALSE;
-}
-
-static void
-glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags)
-{
-}
-
-static Bool
-glamor_ddx_enter_vt(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	if (drmSetMaster(glamor->fd)) {
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "drmSetMaster failed: %s\n", strerror(errno));
-		return FALSE;
-	}
-        if (!xf86SetDesiredModes(scrn))
-	  return FALSE;
-	return TRUE;
-}
-
-static void
-glamor_ddx_leave_vt(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	drmDropMaster(glamor->fd);
-}
-
-static Bool
-glamor_ddx_create_screen_resources(ScreenPtr screen)
-{
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	screen->CreateScreenResources = glamor->CreateScreenResources;
-	if (!(*screen->CreateScreenResources) (screen))
-		return FALSE;
-        if (!glamor_glyphs_init(screen))
-                return FALSE;
-        if (glamor->root_bo == NULL)
-                return FALSE;
-        if (!glamor_create_screen_image(scrn))
-                return FALSE;
-	return TRUE;
-}
-
-static Bool
-glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-
-	screen->CloseScreen = glamor->CloseScreen;
-	(*screen->CloseScreen) (scrnIndex, screen);
-
-	if (scrn->vtSema == TRUE)
-		glamor_ddx_leave_vt(scrnIndex, 0);
-
-	glamor_fini(screen);
-        glamor_close_egl_screen(screen);
-        gbm_bo_destroy(glamor->root_bo);
-	drmmode_closefb(scrn);
-	
-	return TRUE;
-}
-
-static Bool
-glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
-{
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	VisualPtr visual;
-
-        glamor->gbm = gbm_create_device(glamor->fd);
-        if (glamor->gbm == NULL) {
-          ErrorF("couldn't create gbm device\n");
-          return FALSE;
-        }
-
-	glamor_egl_init(scrn, glamor->fd);
-
-	miClearVisualTypes();
-	if (!miSetVisualTypes(scrn->depth,
-			      miGetDefaultVisualMask(scrn->depth),
-			      scrn->rgbBits, scrn->defaultVisual))
-		return FALSE;
-	if (!miSetPixmapDepths())
-		return FALSE;
-
-        if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY))
-                return FALSE;
-
-	if (!fbScreenInit(screen, NULL,
-			  scrn->virtualX, scrn->virtualY,
-			  scrn->xDpi, scrn->yDpi,
-			  1, scrn->bitsPerPixel))
-		return FALSE;
-
-	if (scrn->bitsPerPixel > 8) {
-	  /* Fixup RGB ordering */
-	  visual = screen->visuals + screen->numVisuals;
-	  while(--visual >= screen->visuals) {
-	    if ((visual->class | DynamicClass) == DirectColor) {
-	      visual->offsetRed = scrn->offset.red;
-	      visual->offsetGreen = scrn->offset.green;
-	      visual->offsetBlue = scrn->offset.blue;
-	      visual->redMask = scrn->mask.red;
-	      visual->blueMask = scrn->mask.blue;
-	    }
-	  }
-	}
-
-	fbPictureInit(screen, NULL, 0);
-	xf86SetBlackWhitePixels(screen);
-
-	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to initialize glamor\n");
-		return FALSE;
-	}
-	
-	miInitializeBackingStore(screen);
-	xf86SetBackingStore(screen);
-	xf86SetSilkenMouse(screen);
-	miDCInitialize(screen, xf86GetPointerScreenFuncs());
-
-	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
-
-	if (!xf86_cursors_init(screen, 64, 64,
-			       (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
-				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
-				HARDWARE_CURSOR_INVERT_MASK |
-				HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
-				HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
-				HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
-				HARDWARE_CURSOR_UPDATE_UNHIDDEN |
-				HARDWARE_CURSOR_ARGB))) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Hardware cursor initialization failed\n");
-	}
-
-	/* Must force it before EnterVT, so we are in control of VT and
-	 * later memory should be bound when allocating, e.g rotate_mem */
-	scrn->vtSema = TRUE;
-
-	if (!glamor_ddx_enter_vt(scrnIndex, 0))
-		return FALSE;
-
-	screen->SaveScreen = xf86SaveScreen;
-	glamor->CreateScreenResources = screen->CreateScreenResources;
-	screen->CreateScreenResources = glamor_ddx_create_screen_resources;
-	glamor->CloseScreen = screen->CloseScreen;
-	screen->CloseScreen = glamor_ddx_close_screen;
-	/* Fixme should we init crtc screen here? */
-	if (!xf86CrtcScreenInit(screen))
-	  return FALSE;
-	if (!miCreateDefColormap(screen))
-	  return FALSE;
-	/* Fixme should we add handle colormap here? */
-
-	xf86DPMSInit(screen, xf86DPMSSet, 0);
-
-	return TRUE;
-}
-
-static void
-glamor_ddx_free_screen(int scrnIndex, int flags)
-{
-	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	if (glamor != NULL)
-	{
-	  close(glamor->fd);
-	  free(glamor);
-	  scrn->driverPrivate = NULL;
-	}
-}
-
-static ModeStatus
-glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
-	if (mode->Flags & V_INTERLACE) {
-		if (verbose) {
-			xf86DrvMsg(scrnIndex, X_PROBED,
-				   "Removing interlaced mode \"%s\"\n",
-				   mode->name);
-		}
-		return MODE_BAD;
-	}
-	return MODE_OK;
-}
-
-static Bool
-glamor_ddx_probe(struct _DriverRec *drv, int flags)
-{
-	ScrnInfoPtr scrn = NULL;
-       	GDevPtr *sections;
-	int entity, n;
-
-	n = xf86MatchDevice(glamor_ddx_name, &sections);
-	if (n <= 0)
-	    return FALSE;
-
-	entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE);
-
-	scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
-	if (scrn == NULL) {
-		xf86Msg(X_ERROR, "Failed to add fb entity\n");
-		return FALSE;
-	}
-
-	scrn->driverVersion = 1;
-	scrn->driverName = (char *) glamor_ddx_name;
-	scrn->name = (char *) glamor_ddx_name;
-	scrn->Probe = NULL;
-
-	scrn->PreInit = glamor_ddx_pre_init;
-	scrn->ScreenInit = glamor_ddx_screen_init;
-	scrn->AdjustFrame = glamor_ddx_adjust_frame;
-	scrn->EnterVT = glamor_ddx_enter_vt;
-	scrn->LeaveVT = glamor_ddx_leave_vt;
-	scrn->FreeScreen = glamor_ddx_free_screen;
-	scrn->ValidMode = glamor_ddx_valid_mode;
-
-	return TRUE;
-}
-
-static const OptionInfoRec *
-glamor_ddx_available_options(int chipid, int busid)
-{
-	return NULL;
-}
-
-static Bool
-glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
-{
-	xorgHWFlags *flag;
-
-	switch (op) {
-        case GET_REQUIRED_HW_INTERFACES:
-		flag = (CARD32*)ptr;
-		(*flag) = 0;
-		return TRUE;
-        default:
-		/* Unknown or deprecated function */
-		return FALSE;
-	}
-}
-
-_X_EXPORT DriverRec glamor_ddx = {
-	1,
-	"glamor",
-	glamor_ddx_identify,
-	glamor_ddx_probe,
-	glamor_ddx_available_options,
-	NULL,
-	0,
-	glamor_ddx_driver_func,
-};
-
-static pointer
-glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
-   static Bool setupDone = 0;
-
-   /* This module should be loaded only once, but check to be sure.
-    */
-   if (!setupDone) {
-      setupDone = 1;
-      xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs);
-
-      /*
-       * The return value must be non-NULL on success even though there
-       * is no TearDownProc.
-       */
-      return (pointer) 1;
-   } else {
-      if (errmaj)
-	 *errmaj = LDR_ONCEONLY;
-      return NULL;
-   }
-}
-
-static XF86ModuleVersionInfo glamor_ddx_version_info = {
-	glamor_ddx_name,
-	MODULEVENDORSTRING,
-	MODINFOSTRING1,
-	MODINFOSTRING2,
-	XORG_VERSION_CURRENT,
-	GLAMOR_VERSION_MAJOR,
-	GLAMOR_VERSION_MINOR,
-	GLAMOR_VERSION_PATCH,
-	ABI_CLASS_VIDEODRV,
-	ABI_VIDEODRV_VERSION,
-	MOD_CLASS_VIDEODRV,
-	{0, 0, 0, 0}
-};
-
-_X_EXPORT XF86ModuleData glamorModuleData = {
-	&glamor_ddx_version_info,
-	glamor_ddx_setup,
-	NULL
-};
diff --git a/hw/xfree86/glamor/glamor_ddx.c b/hw/xfree86/glamor/glamor_ddx.c
new file mode 100644
index 0000000..f4b37ab
--- /dev/null
+++ b/hw/xfree86/glamor/glamor_ddx.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright © 2010 Intel Corporation.
+ *
+ * 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 (including
+ * the next paragraph) 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.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh at bitplanet.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <gbm.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <xf86drm.h>
+
+#include "../../../mi/micmap.h"
+#include <xf86Crtc.h>
+#include <xf86.h>
+//#define GC XORG_GC
+#include <glamor.h>
+//#undef GC
+
+#include "glamor_ddx.h"
+
+#define GLAMOR_VERSION_MAJOR 0
+#define GLAMOR_VERSION_MINOR 1
+#define GLAMOR_VERSION_PATCH 0
+
+static const char glamor_ddx_name[] = "glamor";
+
+static void
+glamor_ddx_identify(int flags)
+{
+	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
+}
+
+static Bool
+glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+
+        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
+                                        GBM_BO_FORMAT_ARGB8888,
+                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+	if (glamor->root_bo == NULL)
+		return FALSE;
+
+        scrn->virtualX = width;
+        scrn->virtualY = height; 
+        /* XXX shall we update displayWidth here ? */
+        return TRUE;
+}
+
+static Bool
+glamor_create_screen_image(ScrnInfoPtr scrn)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+	unsigned int handle, stride;
+        handle = gbm_bo_get_handle(glamor->root_bo).u32;
+        stride = gbm_bo_get_pitch(glamor->root_bo);
+        return glamor_create_egl_screen_image(screen, handle, stride);
+}
+
+Bool
+glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+
+        if (glamor->root_bo != NULL) {
+          glamor_close_egl_screen(screen);
+          gbm_bo_destroy(glamor->root_bo);
+          glamor->root_bo = NULL;
+        } 
+
+        if (!glamor_ddx_init_front_buffer(scrn, width, height)) 
+           return FALSE;
+        return glamor_create_screen_image(scrn);
+}
+
+void
+glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+        *handle = gbm_bo_get_handle(glamor->root_bo).u32;
+        *pitch = gbm_bo_get_pitch(glamor->root_bo);
+}
+
+Bool
+glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+        unsigned int handle, stride;
+        
+
+        if (cursor->cursor_pixmap) 
+          glamor_destroy_cursor(scrn, cursor);
+
+        cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0);
+        if (cursor->cursor_pixmap == NULL)
+           return FALSE;
+        screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0);
+        cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
+                                          GBM_BO_FORMAT_ARGB8888,
+                                          GBM_BO_USE_SCANOUT 
+                                          | GBM_BO_USE_RENDERING 
+                                          | GBM_BO_USE_CURSOR_64X64);
+
+	if (cursor->cursor_bo == NULL) 
+          goto fail; 
+        glamor_cursor_handle(cursor, &handle, &stride);
+        if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride))
+          goto fail;
+
+        return TRUE;
+
+fail:
+        glamor_destroy_cursor(scrn, cursor);
+        return FALSE; 
+}
+
+void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor)
+{
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+        if (cursor->cursor_pixmap)
+          screen->DestroyPixmap(cursor->cursor_pixmap);
+        if (cursor->cursor_bo)
+          gbm_bo_destroy(cursor->cursor_bo);  
+        cursor->cursor_bo = NULL;
+        cursor->cursor_pixmap = NULL;
+}
+
+void
+glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch)
+{
+        *handle = gbm_bo_get_handle(cursor->cursor_bo).u32;
+        *pitch = gbm_bo_get_pitch(cursor->cursor_bo);
+	ErrorF("cursor stride: %d\n", *pitch);
+}
+
+char * dri_device_name = "/dev/dri/card0";
+static Bool
+glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags)
+{
+	struct glamor_ddx_screen_private *glamor;
+	rgb defaultWeight = { 0, 0, 0 };
+
+	glamor = xnfcalloc(sizeof *glamor, 1);
+
+	scrn->driverPrivate = glamor;
+	glamor->fd = open(dri_device_name, O_RDWR);
+	if (glamor->fd == -1 ) {
+	  ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
+	  goto fail;
+	}
+
+	glamor->cpp = 4;
+
+	scrn->monitor = scrn->confScreen->monitor;
+	scrn->progClock = TRUE;
+	scrn->rgbBits = 8;
+
+	if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb))
+	  goto fail;
+
+	xf86PrintDepthBpp(scrn);
+
+	if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
+	  goto fail;
+	if (!xf86SetDefaultVisual(scrn, -1))
+	  goto fail;
+
+	glamor->cpp = scrn->bitsPerPixel / 8;
+
+	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Kernel modesetting setup failed\n");
+         goto fail;
+	}
+
+	scrn->currentMode = scrn->modes;
+	xf86SetDpi(scrn, 0, 0);
+
+	/* Load the required sub modules */
+	if (!xf86LoadSubModule(scrn, "fb"))
+	  goto fail;
+
+	if (!xf86LoadSubModule(scrn, "glamor_dix"))
+	  goto fail;
+
+	return TRUE;
+
+fail:
+	scrn->driverPrivate = NULL;
+	free(glamor);
+	return FALSE;
+}
+
+static void
+glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags)
+{
+}
+
+static Bool
+glamor_ddx_enter_vt(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+
+	if (drmSetMaster(glamor->fd)) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "drmSetMaster failed: %s\n", strerror(errno));
+		return FALSE;
+	}
+        if (!xf86SetDesiredModes(scrn))
+	  return FALSE;
+	return TRUE;
+}
+
+static void
+glamor_ddx_leave_vt(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+
+	drmDropMaster(glamor->fd);
+}
+
+static Bool
+glamor_ddx_create_screen_resources(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+
+	screen->CreateScreenResources = glamor->CreateScreenResources;
+	if (!(*screen->CreateScreenResources) (screen))
+		return FALSE;
+        if (!glamor_glyphs_init(screen))
+                return FALSE;
+        if (glamor->root_bo == NULL)
+                return FALSE;
+        if (!glamor_create_screen_image(scrn))
+                return FALSE;
+	return TRUE;
+}
+
+static Bool
+glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+
+	screen->CloseScreen = glamor->CloseScreen;
+	(*screen->CloseScreen) (scrnIndex, screen);
+
+	if (scrn->vtSema == TRUE)
+		glamor_ddx_leave_vt(scrnIndex, 0);
+
+	glamor_fini(screen);
+        glamor_close_egl_screen(screen);
+        gbm_bo_destroy(glamor->root_bo);
+	drmmode_closefb(scrn);
+	
+	return TRUE;
+}
+
+static Bool
+glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	VisualPtr visual;
+
+        glamor->gbm = gbm_create_device(glamor->fd);
+        if (glamor->gbm == NULL) {
+          ErrorF("couldn't create gbm device\n");
+          return FALSE;
+        }
+
+	glamor_egl_init(scrn, glamor->fd);
+
+	miClearVisualTypes();
+	if (!miSetVisualTypes(scrn->depth,
+			      miGetDefaultVisualMask(scrn->depth),
+			      scrn->rgbBits, scrn->defaultVisual))
+		return FALSE;
+	if (!miSetPixmapDepths())
+		return FALSE;
+
+        if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY))
+                return FALSE;
+
+	if (!fbScreenInit(screen, NULL,
+			  scrn->virtualX, scrn->virtualY,
+			  scrn->xDpi, scrn->yDpi,
+			  1, scrn->bitsPerPixel))
+		return FALSE;
+
+	if (scrn->bitsPerPixel > 8) {
+	  /* Fixup RGB ordering */
+	  visual = screen->visuals + screen->numVisuals;
+	  while(--visual >= screen->visuals) {
+	    if ((visual->class | DynamicClass) == DirectColor) {
+	      visual->offsetRed = scrn->offset.red;
+	      visual->offsetGreen = scrn->offset.green;
+	      visual->offsetBlue = scrn->offset.blue;
+	      visual->redMask = scrn->mask.red;
+	      visual->blueMask = scrn->mask.blue;
+	    }
+	  }
+	}
+
+	fbPictureInit(screen, NULL, 0);
+	xf86SetBlackWhitePixels(screen);
+
+	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to initialize glamor\n");
+		return FALSE;
+	}
+	
+	miInitializeBackingStore(screen);
+	xf86SetBackingStore(screen);
+	xf86SetSilkenMouse(screen);
+	miDCInitialize(screen, xf86GetPointerScreenFuncs());
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
+
+	if (!xf86_cursors_init(screen, 64, 64,
+			       (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+				HARDWARE_CURSOR_INVERT_MASK |
+				HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+				HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+				HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
+				HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+				HARDWARE_CURSOR_ARGB))) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Hardware cursor initialization failed\n");
+	}
+
+	/* Must force it before EnterVT, so we are in control of VT and
+	 * later memory should be bound when allocating, e.g rotate_mem */
+	scrn->vtSema = TRUE;
+
+	if (!glamor_ddx_enter_vt(scrnIndex, 0))
+		return FALSE;
+
+	screen->SaveScreen = xf86SaveScreen;
+	glamor->CreateScreenResources = screen->CreateScreenResources;
+	screen->CreateScreenResources = glamor_ddx_create_screen_resources;
+	glamor->CloseScreen = screen->CloseScreen;
+	screen->CloseScreen = glamor_ddx_close_screen;
+	/* Fixme should we init crtc screen here? */
+	if (!xf86CrtcScreenInit(screen))
+	  return FALSE;
+	if (!miCreateDefColormap(screen))
+	  return FALSE;
+	/* Fixme should we add handle colormap here? */
+
+	xf86DPMSInit(screen, xf86DPMSSet, 0);
+
+	return TRUE;
+}
+
+static void
+glamor_ddx_free_screen(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	if (glamor != NULL)
+	{
+	  close(glamor->fd);
+	  free(glamor);
+	  scrn->driverPrivate = NULL;
+	}
+}
+
+static ModeStatus
+glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+	if (mode->Flags & V_INTERLACE) {
+		if (verbose) {
+			xf86DrvMsg(scrnIndex, X_PROBED,
+				   "Removing interlaced mode \"%s\"\n",
+				   mode->name);
+		}
+		return MODE_BAD;
+	}
+	return MODE_OK;
+}
+
+static Bool
+glamor_ddx_probe(struct _DriverRec *drv, int flags)
+{
+	ScrnInfoPtr scrn = NULL;
+       	GDevPtr *sections;
+	int entity, n;
+
+	n = xf86MatchDevice(glamor_ddx_name, &sections);
+	if (n <= 0)
+	    return FALSE;
+
+	entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE);
+
+	scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
+	if (scrn == NULL) {
+		xf86Msg(X_ERROR, "Failed to add fb entity\n");
+		return FALSE;
+	}
+
+	scrn->driverVersion = 1;
+	scrn->driverName = (char *) glamor_ddx_name;
+	scrn->name = (char *) glamor_ddx_name;
+	scrn->Probe = NULL;
+
+	scrn->PreInit = glamor_ddx_pre_init;
+	scrn->ScreenInit = glamor_ddx_screen_init;
+	scrn->AdjustFrame = glamor_ddx_adjust_frame;
+	scrn->EnterVT = glamor_ddx_enter_vt;
+	scrn->LeaveVT = glamor_ddx_leave_vt;
+	scrn->FreeScreen = glamor_ddx_free_screen;
+	scrn->ValidMode = glamor_ddx_valid_mode;
+
+	return TRUE;
+}
+
+static const OptionInfoRec *
+glamor_ddx_available_options(int chipid, int busid)
+{
+	return NULL;
+}
+
+static Bool
+glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
+{
+	xorgHWFlags *flag;
+
+	switch (op) {
+        case GET_REQUIRED_HW_INTERFACES:
+		flag = (CARD32*)ptr;
+		(*flag) = 0;
+		return TRUE;
+        default:
+		/* Unknown or deprecated function */
+		return FALSE;
+	}
+}
+
+_X_EXPORT DriverRec glamor_ddx = {
+	1,
+	"glamor",
+	glamor_ddx_identify,
+	glamor_ddx_probe,
+	glamor_ddx_available_options,
+	NULL,
+	0,
+	glamor_ddx_driver_func,
+};
+
+static pointer
+glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+   static Bool setupDone = 0;
+
+   /* This module should be loaded only once, but check to be sure.
+    */
+   if (!setupDone) {
+      setupDone = 1;
+      xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs);
+
+      /*
+       * The return value must be non-NULL on success even though there
+       * is no TearDownProc.
+       */
+      return (pointer) 1;
+   } else {
+      if (errmaj)
+	 *errmaj = LDR_ONCEONLY;
+      return NULL;
+   }
+}
+
+static XF86ModuleVersionInfo glamor_ddx_version_info = {
+	glamor_ddx_name,
+	MODULEVENDORSTRING,
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XORG_VERSION_CURRENT,
+	GLAMOR_VERSION_MAJOR,
+	GLAMOR_VERSION_MINOR,
+	GLAMOR_VERSION_PATCH,
+	ABI_CLASS_VIDEODRV,
+	ABI_VIDEODRV_VERSION,
+	MOD_CLASS_VIDEODRV,
+	{0, 0, 0, 0}
+};
+
+_X_EXPORT XF86ModuleData glamorModuleData = {
+	&glamor_ddx_version_info,
+	glamor_ddx_setup,
+	NULL
+};
commit 101b69dddff6cc538cb369c70377bbad825aa765
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 16:33:52 2011 +0800

    glamor: Check libgbm if enable glamor ddx.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index 80daf82..bf17435 100644
--- a/configure.ac
+++ b/configure.ac
@@ -803,6 +803,7 @@ LIBDBUS="dbus-1 >= 1.0"
 LIBPIXMAN="pixman-1 >= 0.21.8"
 LIBEGL="egl"
 LIBGLESV2="glesv2"
+LIBGBM="gbm"
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
 PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
@@ -1796,6 +1797,7 @@ if test "x$GLAMOR" = xyes; then
    if test "x$GLAMOR_DDX" = xyes; then
      AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver])
      PKG_CHECK_MODULES(EGL, $LIBEGL)
+     PKG_CHECK_MODULES(EGL, $LIBGBM)
      REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL"
    fi
 fi
commit 6a7ad1c92934b35eb2431c3e0f11c0c56a097dc9
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 16:13:57 2011 +0800

    glamor-ddx: Don't double free the cursor memory.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index e86466a..ce4f31f 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -516,8 +516,7 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
 static void
 _drmmode_destroy_cursor(xf86CrtcPtr crtc)
 {
-       drmmode_crtc_private_ptr
-       drmmode_crtc = crtc->driver_private;
+       drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
        if (drmmode_crtc->cursor == NULL)
          return;
@@ -654,11 +653,8 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc,
 static void
 drmmode_crtc_destroy(xf86CrtcPtr crtc)
 {
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
 	ScrnInfoPtr scrn = crtc->scrn;
         _drmmode_destroy_cursor(crtc);
-        free(drmmode_crtc->cursor);
         crtc->driver_private = NULL;
 }
 
commit fe4c95ce843afffed981ac8bb89ca433bd20f1e2
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 16:08:29 2011 +0800

    glamor: Refine the screen pixmap initialization for Xephyr.
    
    The previous implementation is to override the CreatePixmap
    firstly and assume the first call to CreatePixmap must be
    screen pixmap. This is not clean. Now Refine it to normal
    way. Let the Xephyr to set texture 0 to screen pixmap
    during creating screen resources.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index a35fbee..ee83fd3 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -73,8 +73,14 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
      * to it.
      */
     pixmap_priv->gl_fbo = 1;
-    pixmap_priv->gl_tex = 1;
-    glamor_pixmap_ensure_fb(pixmap);
+    if (tex != 0) {
+      glamor_pixmap_ensure_fb(pixmap);
+      pixmap_priv->gl_tex = 1;
+    }
+    else {
+      pixmap_priv->fb = 0;
+      pixmap_priv->gl_tex = 0;
+    }
     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
@@ -173,42 +179,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     return pixmap;
 }
 
-
-/**
- * For Xephyr use only. set up the screen pixmap to correct state. 
- **/
-static PixmapPtr
-glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
-		     unsigned int usage)
-{
-    PixmapPtr pixmap;
-    glamor_pixmap_private *pixmap_priv;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    assert(w ==0 && h == 0);
-
-    glamor_priv->screen_fbo = 0; 
-    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
-
-    if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
-        fbDestroyPixmap(pixmap);
-	ErrorF("Fail to allocate privates for PIXMAP.\n");
-	return NullPixmap;
-    }	 
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    pixmap_priv->tex = 0; 
-    pixmap_priv->gl_fbo = 1;
-    pixmap_priv->gl_tex = 0;
-    pixmap_priv->container = pixmap;
-    pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
-    
-    screen->CreatePixmap = glamor_create_pixmap;
-    return pixmap;
-}
-
-
-
-
 static Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
@@ -334,11 +304,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     screen->CreateGC = glamor_create_gc;
 
     glamor_priv->saved_create_pixmap = screen->CreatePixmap;
-
-    if (flags & GLAMOR_HOSTX)
-      screen->CreatePixmap = glamor_create_screen_pixmap;
-    else
-      screen->CreatePixmap = glamor_create_pixmap;
+    screen->CreatePixmap = glamor_create_pixmap;
 
     glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
     screen->DestroyPixmap = glamor_destroy_pixmap;
commit 1fb58860cc02d28545c66a916956a45918596870
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 16:05:52 2011 +0800

    ephyr-glamor:  Implment gl disptach function for host glx.
    
    We should pass back the glXGetProcAddress to the underlying
    gl dispatch initialization function to get those gl function
    pointers.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 15dfc70..935c7c6 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1532,3 +1532,15 @@ ephyr_glamor_paint_rect (EphyrScreenInfo screen,
 			  host_screen->win_width, host_screen->win_height);
 #endif
 }
+
+struct glamor_gl_dispatch;
+extern Bool 
+glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, int gl_version, void* func);
+
+Bool
+glamor_gl_dispatch_init(void *screen, struct glamor_gl_dispatch *dispatch, int gl_version)
+{
+        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, glXGetProcAddress))
+          return FALSE;
+        return TRUE;
+}
commit df070205600cd736750d8a43426976a518b1fbae
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 26 16:01:03 2011 +0800

    ephyr-glamor: Set texture 0 to screen pixmap.
    
    In Xephyr, screen pixmap is different from other pixmap.
    It use fbo zero and texture zero. We initialize it during
    creating screen resources.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index e2cd7a4..5e21748 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -718,8 +718,12 @@ ephyrCreateResources (ScreenPtr pScreen)
 			ephyrShadowUpdate, 
 			ephyrWindowLinear);
   else {
-    if (ephyr_glamor)
+    if (ephyr_glamor) {
+      KdScreenPriv(pScreen);
+      KdScreenInfo	*screen = pScreenPriv->screen;
       if (!glamor_glyphs_init(pScreen)) return FALSE;
+      glamor_set_screen_pixmap_texture(pScreen, screen->width, screen->height, 0);
+    }
     return ephyrSetInternalDamage(pScreen); 
   }
 }
commit 937d3bcecf04305c01159f5c5084833f28014061
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Sep 22 13:39:01 2011 +0800

    glamor: Correct the version check for GLES2.
    
    If we are using GLES2, then the version number should be no
    less than 2.0 rather than no less than 1.3 which is for GL
    API.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index ea4099e..a35fbee 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -295,10 +295,17 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     gl_version = glamor_gl_get_version();
 
+#ifndef GLAMOR_GLES2
     if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3))  {
-        ErrorF("Require Opengl 1.3 or latter.\n");
+        ErrorF("Require OpenGL version 1.3 or latter.\n");
         goto fail;
     }
+#else
+    if (gl_version < GLAMOR_GL_VERSION_ENCODE(2,0))  {
+        ErrorF("Require Open GLES2.0 or latter.\n");
+        goto fail;
+    }
+#endif
 
     glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version);
 
commit 483717484afb4ccf5b48483b3a21a9fe91213dd4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Sep 20 17:15:12 2011 +0800

    glamor-ddx: Destroy all the pixmap cursors when close current screen.
    
    As now we use pixmap to handle cursor, and pixmaps are related to
    current screen. If we close the screen, then we have to destroy all
    the related cursors.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 854e816..e86466a 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -512,6 +512,34 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
 			 0, 64, 64);
 }
 
+
+static void
+_drmmode_destroy_cursor(xf86CrtcPtr crtc)
+{
+       drmmode_crtc_private_ptr
+       drmmode_crtc = crtc->driver_private;
+
+       if (drmmode_crtc->cursor == NULL)
+         return;
+       drmmode_hide_cursor(crtc);
+       glamor_destroy_cursor(crtc->scrn, drmmode_crtc->cursor);
+       free(drmmode_crtc->cursor);
+       drmmode_crtc->cursor = NULL;
+}
+
+static void
+drmmode_destroy_cursor(ScrnInfoPtr scrn)
+{
+       int i;
+       xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+       for (i = 0; i < xf86_config->num_crtc; i++) 
+             _drmmode_destroy_cursor(xf86_config->crtc[i]);
+}
+
+
+
+
 static void
 drmmode_show_cursor (xf86CrtcPtr crtc)
 {
@@ -629,12 +657,7 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc)
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
 	ScrnInfoPtr scrn = crtc->scrn;
-        if (drmmode_crtc->cursor) {
-          drmmode_hide_cursor(crtc);
-	  glamor_destroy_cursor(scrn, drmmode_crtc->cursor);
-          free(drmmode_crtc->cursor);
-          drmmode_crtc->cursor = NULL;
-        }
+        _drmmode_destroy_cursor(crtc);
         free(drmmode_crtc->cursor);
         crtc->driver_private = NULL;
 }
@@ -1539,6 +1562,8 @@ void drmmode_closefb(ScrnInfoPtr scrn)
 	drmmode_crtc = xf86_config->crtc[0]->driver_private;
 	drmmode = drmmode_crtc->drmmode;
 
+        drmmode_destroy_cursor(scrn);
+
 	drmModeRmFB(drmmode->fd, drmmode->fb_id);
 	drmmode->fb_id = 0;
 }
commit f1c36c611efaa56e49758d8e8b19d07c10a8277e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Sep 20 17:10:50 2011 +0800

    glamor-ddx: Don't need to call preInit in screen_init.
    
    The previous implementation call preInit again to reopen
    the device if the device is closed by eglTerminate. Now
    we don't need it anymore, as glamor dix doesn't call
    eglTerminate any more when close screen.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 0dbee18..f4b37ab 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -287,11 +287,8 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
 	glamor_fini(screen);
         glamor_close_egl_screen(screen);
         gbm_bo_destroy(glamor->root_bo);
-
 	drmmode_closefb(scrn);
 	
-	glamor->fd = -1;
-
 	return TRUE;
 }
 
@@ -301,22 +298,6 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	VisualPtr visual;
-	/* If serverGeneration != 1 then fd was closed during the last
-	 time closing screen, actually in eglTerminate(). */
-
-	if (glamor->fd == -1 && serverGeneration != 1) {
-	  glamor->fd = open(dri_device_name, O_RDWR);
-	  if (glamor->fd == -1 ) {
-	    ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
-	    return FALSE;
-	  }
-	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Kernel modesetting setup failed\n");
-            return FALSE;
-	}
-
-	}
 
         glamor->gbm = gbm_create_device(glamor->fd);
         if (glamor->gbm == NULL) {
commit 09c63d320112fbb4995696d813c488e82915c2f5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Sep 20 15:19:13 2011 +0800

    glamor-ddx: Reuse glamor_dix module to handle egl platform.
    
    We already have a glamor egl module at glamor directory which
    could initialize and create egl context and also can attach a
    gbm buffer to a specified pixmap or to the screen pixmap. This
    commit remove all the duplicated code here and use the glamor_dix
    module directly.
    
    As we don't want to handle egl stuffs in this layer, we have to
    change the way to handle hardware cursor. Previous method is to
    call egl functions to create a egl image and then bind the image
    to a texutre then call gl functions to load texture image to the
    cursor bo. Now we can bind the cursor bo to a cursor pixmap and
    then use putimage to load new image to the cursor bo. Then we can
    completely avoid to call egl or gl functions directly in this
    ddx driver.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index 8432645..fbd561c 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -9,14 +9,13 @@ glamor_la_CFLAGS =					\
 	-I$(top_srcdir)/hw/xfree86/ddc			\
 	-I$(top_srcdir)/hw/xfree86/ramdac		\
 	-I$(top_srcdir)/hw/xfree86/i2c			\
-	-I$(top_srcdir)/glamor
+        -I$(top_srcdir)/glamor
 
 if GLAMOR_GLES2
 glamor_la_CFLAGS+=-DGLAMOR_GLES2
 endif
 
 glamor_la_LDFLAGS = -module -avoid-version \
-                    $(top_builddir)/glamor/libglamor.la  \
                      $(EGL_LIBS)
 
 glamor_ladir = $(moduledir)/drivers
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 1bb5835..0dbee18 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -41,9 +41,9 @@
 #include "../../../mi/micmap.h"
 #include <xf86Crtc.h>
 #include <xf86.h>
-#define GC XORG_GC
+//#define GC XORG_GC
 #include <glamor.h>
-#undef GC
+//#undef GC
 
 #include "glamor_ddx.h"
 
@@ -59,50 +59,50 @@ glamor_ddx_identify(int flags)
 	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
 }
 
-Bool
-glamor_resize(ScrnInfoPtr scrn, int width, int height)
+static Bool
+glamor_ddx_init_front_buffer(ScrnInfoPtr scrn, int width, int height)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
-	EGLImageKHR image;
-	GLuint texture;
 
-	if (glamor->root != EGL_NO_IMAGE_KHR &&
-	    scrn->virtualX == width && scrn->virtualY == height)
-		return TRUE;
-        else if (scrn->virtualX != width || scrn->virtualY != height) {
-
-            if (glamor->root != EGL_NO_IMAGE_KHR) {
-              eglDestroyImageKHR(glamor->display, glamor->root);
-              gbm_bo_destroy(glamor->root_bo);
-              glamor->root = EGL_NO_IMAGE_KHR;
-            }
-            glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
+        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
                                         GBM_BO_FORMAT_ARGB8888,
                                         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-        }
-        
+
 	if (glamor->root_bo == NULL)
 		return FALSE;
 
-        image = glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->root_bo, NULL);
+        scrn->virtualX = width;
+        scrn->virtualY = height; 
+        /* XXX shall we update displayWidth here ? */
+        return TRUE;
+}
 
-	if (image == EGL_NO_IMAGE_KHR) {
-                gbm_bo_destroy(glamor->root_bo);
-                return FALSE;
-        }
+static Bool
+glamor_create_screen_image(ScrnInfoPtr scrn)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+	unsigned int handle, stride;
+        handle = gbm_bo_get_handle(glamor->root_bo).u32;
+        stride = gbm_bo_get_pitch(glamor->root_bo);
+        return glamor_create_egl_screen_image(screen, handle, stride);
+}
+
+Bool
+glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
 
-	glGenTextures(1, &texture);
-	glBindTexture(GL_TEXTURE_2D, texture);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
+        if (glamor->root_bo != NULL) {
+          glamor_close_egl_screen(screen);
+          gbm_bo_destroy(glamor->root_bo);
+          glamor->root_bo = NULL;
+        } 
 
-	glamor_set_screen_pixmap_texture(screen, width, height, texture);
-	glamor->root = image;
-	scrn->virtualX = width;
-	scrn->virtualY = height;
-	return TRUE;
+        if (!glamor_ddx_init_front_buffer(scrn, width, height)) 
+           return FALSE;
+        return glamor_create_screen_image(scrn);
 }
 
 void
@@ -113,32 +113,56 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
         *pitch = gbm_bo_get_pitch(glamor->root_bo);
 }
 
-EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
+Bool
+glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        glamor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+        unsigned int handle, stride;
+        
+
+        if (cursor->cursor_pixmap) 
+          glamor_destroy_cursor(scrn, cursor);
+
+        cursor->cursor_pixmap = screen->CreatePixmap(screen, 0, 0, 32, 0);
+        if (cursor->cursor_pixmap == NULL)
+           return FALSE;
+        screen->ModifyPixmapHeader(cursor->cursor_pixmap, width, height, 0, 0, 0, 0);
+        cursor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
                                           GBM_BO_FORMAT_ARGB8888,
-                                          GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_CURSOR_64X64);
+                                          GBM_BO_USE_SCANOUT 
+                                          | GBM_BO_USE_RENDERING 
+                                          | GBM_BO_USE_CURSOR_64X64);
+
+	if (cursor->cursor_bo == NULL) 
+          goto fail; 
+        glamor_cursor_handle(cursor, &handle, &stride);
+        if (!glamor_create_egl_pixmap_image(cursor->cursor_pixmap, handle, stride))
+          goto fail;
 
-	if (glamor->cursor_bo == NULL)
-		return EGL_NO_IMAGE_KHR;
+        return TRUE;
 
-        return glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->cursor_bo, NULL);
+fail:
+        glamor_destroy_cursor(scrn, cursor);
+        return FALSE; 
 }
 
-void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor)
+void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor)
 {
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        eglDestroyImageKHR(glamor->display, cursor);
-        gbm_bo_destroy(glamor->cursor_bo);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+        if (cursor->cursor_pixmap)
+          screen->DestroyPixmap(cursor->cursor_pixmap);
+        if (cursor->cursor_bo)
+          gbm_bo_destroy(cursor->cursor_bo);  
+        cursor->cursor_bo = NULL;
+        cursor->cursor_pixmap = NULL;
 }
 
 void
-glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch)
+glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch)
 {
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        *handle = gbm_bo_get_handle(glamor->cursor_bo).u32;
-        *pitch = gbm_bo_get_pitch(glamor->cursor_bo);
+        *handle = gbm_bo_get_handle(cursor->cursor_bo).u32;
+        *pitch = gbm_bo_get_pitch(cursor->cursor_bo);
 	ErrorF("cursor stride: %d\n", *pitch);
 }
 
@@ -189,6 +213,9 @@ glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags)
 	if (!xf86LoadSubModule(scrn, "fb"))
 	  goto fail;
 
+	if (!xf86LoadSubModule(scrn, "glamor_dix"))
+	  goto fail;
+
 	return TRUE;
 
 fail:
@@ -232,16 +259,16 @@ glamor_ddx_create_screen_resources(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        int width = scrn->virtualX;
-        int height = scrn->virtualY;
 
 	screen->CreateScreenResources = glamor->CreateScreenResources;
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
         if (!glamor_glyphs_init(screen))
                 return FALSE;
-        glamor_resize(scrn, width, height);
-
+        if (glamor->root_bo == NULL)
+                return FALSE;
+        if (!glamor_create_screen_image(scrn))
+                return FALSE;
 	return TRUE;
 }
 
@@ -258,79 +285,22 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
 		glamor_ddx_leave_vt(scrnIndex, 0);
 
 	glamor_fini(screen);
-
-        eglDestroyImageKHR(glamor->display, glamor->root);
+        glamor_close_egl_screen(screen);
         gbm_bo_destroy(glamor->root_bo);
 
-	eglMakeCurrent(glamor->display,
-		       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-	eglTerminate(glamor->display);
-
 	drmmode_closefb(scrn);
 	
 	glamor->fd = -1;
 
-	glamor->root = EGL_NO_IMAGE_KHR;
-
 	return TRUE;
 }
 
-
-
-static Bool
-glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extension)
-{
-  const char *egl_extensions;
-  char *pext;
-  int  ext_len;
-  ext_len = strlen(extension);
- 
-  egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS);
-  pext = (char*)egl_extensions;
- 
-  if (pext == NULL || extension == NULL)
-    return FALSE;
-  while((pext = strstr(pext, extension)) != NULL) {
-    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
-      return TRUE;
-    pext += ext_len;
-  }
-  return FALSE;
-}
-
-static Bool
-glamor_ddx_init_front_buffer(ScrnInfoPtr scrn)
-{
-	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-        int width = scrn->virtualX;
-        int height = scrn->virtualY;
-
-        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
-                                        GBM_BO_FORMAT_ARGB8888,
-                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
-	if (glamor->root_bo == NULL)
-		return FALSE;
-
-        /* XXX shall we update displayWidth here ? */
-        return TRUE;
-}
-
 static Bool
 glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	const char *version;
 	VisualPtr visual;
-        EGLint config_attribs[] = {
-#ifdef GLAMOR_GLES2
-          EGL_CONTEXT_CLIENT_VERSION, 2, 
-#endif
-          EGL_NONE
-        };
-
-
 	/* If serverGeneration != 1 then fd was closed during the last
 	 time closing screen, actually in eglTerminate(). */
 
@@ -354,62 +324,7 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
           return FALSE;
         }
 
-	glamor->display = eglGetDisplay(glamor->gbm); 
-#ifndef GLAMOR_GLES2
-	eglBindAPI(EGL_OPENGL_API);
-#else
-	eglBindAPI(EGL_OPENGL_ES_API);
-#endif
-	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "eglInitialize() failed\n");
-		return FALSE;
-	}
-
-	version = eglQueryString(glamor->display, EGL_VERSION);
-	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_ddx_name, version);
-
-#define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
-        if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) {  \
-               ErrorF("EGL_" #EXT "required.\n");  \
-               return FALSE;  \
-        } 
-
-        GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
-#ifdef GLAMOR_GLES2
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
-#else
-        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
-#endif
-
-	glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA");
-        glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
-                                       eglGetProcAddress("eglCreateImageKHR");
-	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA");
-	glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
-
-	if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa ||
-			!glamor->egl_image_target_texture2d_oes) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "eglGetProcAddress() failed\n");
-		return FALSE;
-	}
-
-	glamor->context = eglCreateContext(glamor->display,
-					   NULL, EGL_NO_CONTEXT, config_attribs);
-	if (glamor->context == EGL_NO_CONTEXT) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to create EGL context\n");
-		return FALSE;
-	}
-
-	if (!eglMakeCurrent(glamor->display,
-			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to make EGL context current\n");
-		return FALSE;
-	}
+	glamor_egl_init(scrn, glamor->fd);
 
 	miClearVisualTypes();
 	if (!miSetVisualTypes(scrn->depth,
@@ -419,7 +334,7 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	if (!miSetPixmapDepths())
 		return FALSE;
 
-        if (!glamor_ddx_init_front_buffer(scrn))
+        if (!glamor_ddx_init_front_buffer(scrn, scrn->virtualX, scrn->virtualY))
                 return FALSE;
 
 	if (!fbScreenInit(screen, NULL,
@@ -613,18 +528,6 @@ glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin)
    }
 }
 
-Bool
-glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
-{
-        ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-        struct glamor_ddx_screen_private *glamor_egl = glamor_ddx_get_screen_private(scrn);
-        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
-          return FALSE;
-        glamor_egl->dispatch = dispatch;
-        return TRUE;
-}
-
-
 static XF86ModuleVersionInfo glamor_ddx_version_info = {
 	glamor_ddx_name,
 	MODULEVENDORSTRING,
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 4cb3780..854e816 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -50,23 +50,6 @@
 #include <xorgVersion.h>
 #include <libkms/libkms.h>
 
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#define EGL_DISPLAY_NO_X_MESA
-
-#if GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#ifndef GL_BGRA
-#define GL_BGRA GL_BGRA_EXT
-#endif
-#else
-#include <GL/gl.h>
-#endif
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
 #include "glamor_ddx.h"
 
 typedef struct {
@@ -85,8 +68,7 @@ typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     uint32_t rotate_fb_id;
-    EGLImageKHR cursor;
-    unsigned int cursor_tex;
+    struct glamor_gbm_cursor *cursor;
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
 typedef struct {
@@ -341,7 +323,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height)
 	if (drmmode->fb_id != 0 &&
 	    scrn->virtualX == width && scrn->virtualY == height) 
 		return TRUE;
-	if (!glamor_resize(scrn, width, height))
+	if (!glamor_front_buffer_resize(scrn, width, height))
 		return FALSE;
 	if (drmmode->fb_id != 0)
 		drmModeRmFB(drmmode->fd, drmmode->fb_id);
@@ -490,37 +472,33 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	ScrnInfoPtr scrn = crtc->scrn;
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+        GCPtr gc;
 
 	if (drmmode_crtc->cursor == NULL)
 	{
-	     drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64);
-	     if (drmmode_crtc->cursor == EGL_NO_IMAGE_KHR)
+             drmmode_crtc->cursor = calloc(1, sizeof(*drmmode_crtc->cursor));
+             if (drmmode_crtc->cursor == NULL) {
+                ErrorF("Failed to allocate cursor.\n");
+                return;
+             }
+	     if (!glamor_create_cursor(scrn, drmmode_crtc->cursor, 64, 64)) {
+                free(drmmode_crtc->cursor);
+                drmmode_crtc->cursor = NULL;
+                ErrorF("Failed to create glamor cursor.\n");
 		return;
-		glGenTextures(1, &drmmode_crtc->cursor_tex);
-		glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
-		glTexParameteri(GL_TEXTURE_2D,
-				GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		glTexParameteri(GL_TEXTURE_2D,
-				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-		(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, drmmode_crtc->cursor);
+             }
 	}
-	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
-#ifdef GLAMOR_GLES2
-       /* XXX Actually, the image is BGRA not RGBA, so the r and b
-        * should be swapped. But as normally, they are the same value
-        * ignore this currently, don't want to let CPU to do the swizzle.
-        * considering to put this function to the glamor rendering directory.
-        * Thus we can reuse the shader to do this.*/
-       glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
-	  GL_RGBA,  GL_UNSIGNED_BYTE, image);
-#else
-	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
-	  GL_BGRA,  GL_UNSIGNED_INT_8_8_8_8_REV, image);
-#endif
 
+        gc = GetScratchGC (drmmode_crtc->cursor->cursor_pixmap->drawable.depth, screen);
+        if (!gc)
+          return;
+
+        ValidateGC (&drmmode_crtc->cursor->cursor_pixmap->drawable, gc);
+        (*gc->ops->PutImage)(&drmmode_crtc->cursor->cursor_pixmap->drawable, gc, 
+                             32, 0, 0, 64, 64, 0, ZPixmap, (char*)image); 
+        FreeScratchGC (gc);
 }
 
 
@@ -537,13 +515,12 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
 static void
 drmmode_show_cursor (xf86CrtcPtr crtc)
 {
-	ScrnInfoPtr scrn = crtc->scrn;
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	uint32_t handle, stride;
 
 	ErrorF("show cursor\n");
-	glamor_cursor_handle(scrn, drmmode_crtc->cursor, &handle, &stride);
+	glamor_cursor_handle(drmmode_crtc->cursor, &handle, &stride);
 
 	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 			 handle, 64, 64);
@@ -654,8 +631,9 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc)
 	ScrnInfoPtr scrn = crtc->scrn;
         if (drmmode_crtc->cursor) {
           drmmode_hide_cursor(crtc);
-          glDeleteTextures(1, &drmmode_crtc->cursor_tex);
 	  glamor_destroy_cursor(scrn, drmmode_crtc->cursor);
+          free(drmmode_crtc->cursor);
+          drmmode_crtc->cursor = NULL;
         }
         free(drmmode_crtc->cursor);
         crtc->driver_private = NULL;
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index bed7bb9..3ffd488 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -1,43 +1,23 @@
 #ifndef GLAMOR_DDX_H
 #define GLAMOR_DDX_H
 
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#define EGL_DISPLAY_NO_X_MESA
-
-#if GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#else
-#include <GL/gl.h>
-#endif
-
-#define MESA_EGL_NO_X11_HEADERS
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
 #include <gbm.h>
-#include "glamor_gl_dispatch.h"
+#define GLAMOR_FOR_XORG 1
+#include <glamor.h>
 struct glamor_ddx_screen_private {
-	EGLDisplay display;
-	EGLContext context;
-	EGLImageKHR root;
         struct gbm_bo *root_bo;
         struct gbm_bo *cursor_bo;
-
-	EGLint major, minor;
+        struct gbm_device *gbm;
 
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
 	int fd;
 	int cpp;
-        struct gbm_device *gbm;
+};
 
-	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
-	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
-        PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
-	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
-        struct glamor_gl_dispatch *dispatch;
+struct glamor_gbm_cursor {
+       struct gbm_bo *cursor_bo;
+       PixmapPtr cursor_pixmap;
 };
 
 inline static struct glamor_ddx_screen_private *
@@ -46,15 +26,15 @@ glamor_ddx_get_screen_private(ScrnInfoPtr scrn)
 	return (struct glamor_ddx_screen_private *) (scrn->driverPrivate);
 }
 
-Bool glamor_resize(ScrnInfoPtr scrn, int width, int height);
+Bool glamor_front_buffer_resize(ScrnInfoPtr scrn, int width, int height);
 void glamor_frontbuffer_handle(ScrnInfoPtr scrn,
 			       uint32_t *handle, uint32_t *pitch);
 Bool glamor_load_cursor(ScrnInfoPtr scrn,
-			CARD32 *image, int width, int height);
+			int width, int height);
 
-void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch);
-EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height);
-void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor);
+void glamor_cursor_handle(struct glamor_gbm_cursor *cursor, uint32_t *handle, uint32_t *pitch);
+Bool glamor_create_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor, int width, int height);
+void glamor_destroy_cursor(ScrnInfoPtr scrn, struct glamor_gbm_cursor *cursor) ;
 
 Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
 void drmmode_closefb(ScrnInfoPtr scrn);
commit 1590da001129ea61d6f7f8758d1d2842825be81b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Sep 20 15:14:49 2011 +0800

    glamor-egl: Add gbm device support.
    
    Latest mesa EGL implementation move to use gbm to manage/allocate buffers.
    To keep backward compatibility, we still try to use eglGetDRMDisplayMESA
    firstly, and if failed, then turn to use eglGetDisplay(gbm).
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index d95828e..921023e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -40,6 +40,8 @@
 #define EGL_EGLEXT_PROTOTYPES
 #define EGL_DISPLAY_NO_X_MESA
 
+#include <gbm.h>
+
 #if GLAMOR_GLES2
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
@@ -79,6 +81,7 @@ struct glamor_egl_screen_private {
 	int fd;
         int front_buffer_handle;
 	int cpp;
+        struct gbm_device *gbm;
 
 	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
@@ -184,6 +187,8 @@ glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride)
 /*
  * This function will be called from the dri buffer allocation.
  * It is somehow very familiar with the create screen image.
+ * XXX the egl image here is not stored at any data structure.
+ * Does this cause a leak problem?
  */
 Bool
 glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride)
@@ -271,7 +276,18 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
         scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
 
         glamor_egl->fd = fd;
-	glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
+
+        glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
+
+        if (glamor_egl->display == EGL_NO_DISPLAY) {
+          glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
+          if (glamor_egl->gbm == NULL) {
+            ErrorF("couldn't get display device\n");
+            return FALSE;
+          }
+        }
+
+	glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
 #else
commit 2d4d40a4b5938249f3c73ed14fe5c5b926c2fefd
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 19 09:45:32 2011 +0800

    glamor-ddx: Fix the broken switching between VTs.
    
    Now we can allocate frame buffer during the screen initialization.
    And set mode major when enter VT. This is the correct logic. The
    previous implementation defer the set mode major to create screen
    resource which will cause the switching between VTs broken.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index a515939..1bb5835 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -70,11 +70,18 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	if (glamor->root != EGL_NO_IMAGE_KHR &&
 	    scrn->virtualX == width && scrn->virtualY == height)
 		return TRUE;
-
-        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
+        else if (scrn->virtualX != width || scrn->virtualY != height) {
+
+            if (glamor->root != EGL_NO_IMAGE_KHR) {
+              eglDestroyImageKHR(glamor->display, glamor->root);
+              gbm_bo_destroy(glamor->root_bo);
+              glamor->root = EGL_NO_IMAGE_KHR;
+            }
+            glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
                                         GBM_BO_FORMAT_ARGB8888,
                                         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
+        }
+        
 	if (glamor->root_bo == NULL)
 		return FALSE;
 
@@ -206,10 +213,8 @@ glamor_ddx_enter_vt(int scrnIndex, int flags)
 			   "drmSetMaster failed: %s\n", strerror(errno));
 		return FALSE;
 	}
-#if 0
         if (!xf86SetDesiredModes(scrn))
 	  return FALSE;
-#endif               
 	return TRUE;
 }
 
@@ -227,15 +232,15 @@ glamor_ddx_create_screen_resources(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+        int width = scrn->virtualX;
+        int height = scrn->virtualY;
 
 	screen->CreateScreenResources = glamor->CreateScreenResources;
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
         if (!glamor_glyphs_init(screen))
                 return FALSE;
-
-	if (!xf86SetDesiredModes(scrn))
-		return FALSE;
+        glamor_resize(scrn, width, height);
 
 	return TRUE;
 }
@@ -293,7 +298,23 @@ glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extensi
   return FALSE;
 }
 
+static Bool
+glamor_ddx_init_front_buffer(ScrnInfoPtr scrn)
+{
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
+        int width = scrn->virtualX;
+        int height = scrn->virtualY;
+
+        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
+                                        GBM_BO_FORMAT_ARGB8888,
+                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+	if (glamor->root_bo == NULL)
+		return FALSE;
 
+        /* XXX shall we update displayWidth here ? */
+        return TRUE;
+}
 
 static Bool
 glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
@@ -304,10 +325,10 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	VisualPtr visual;
         EGLint config_attribs[] = {
 #ifdef GLAMOR_GLES2
-        EGL_CONTEXT_CLIENT_VERSION, 2, 
+          EGL_CONTEXT_CLIENT_VERSION, 2, 
 #endif
           EGL_NONE
-    };
+        };
 
 
 	/* If serverGeneration != 1 then fd was closed during the last
@@ -398,6 +419,9 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	if (!miSetPixmapDepths())
 		return FALSE;
 
+        if (!glamor_ddx_init_front_buffer(scrn))
+                return FALSE;
+
 	if (!fbScreenInit(screen, NULL,
 			  scrn->virtualX, scrn->virtualY,
 			  scrn->xDpi, scrn->yDpi,
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 60af8b5..4cb3780 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -372,10 +372,22 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	int ret = TRUE;
 	int i;
 	int fb_id;
+        uint32_t handle, pitch;
 	drmModeModeInfo kmode;
 
-	if (!drmmode_update_fb(scrn, scrn->virtualX, scrn->virtualY))
-		return FALSE;
+        if (drmmode->fb_id == 0) {
+
+	        glamor_frontbuffer_handle(scrn, &handle, &pitch);
+                ret = drmModeAddFB(drmmode->fd,
+                                   scrn->virtualX, scrn->virtualY,
+                                   scrn->depth, scrn->bitsPerPixel,
+                                   pitch, handle,
+                                   &drmmode->fb_id);
+                if (ret < 0) {
+                        ErrorF("failed to add fb\n");
+                        return FALSE;
+                }
+        }
 
 	saved_mode = crtc->mode;
 	saved_x = crtc->x;
commit 4c8ed1756aa5121a559aa604926a730180a1403f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Mon Sep 19 06:31:57 2011 +0800

    glamor-ddx: Use gbm to allocate front buffer and cursor image.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index eef8eeb..a515939 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -30,12 +30,14 @@
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
+
+#include <gbm.h>
+
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <xf86drm.h>
 
-
 #include "../../../mi/micmap.h"
 #include <xf86Crtc.h>
 #include <xf86.h>
@@ -57,7 +59,6 @@ glamor_ddx_identify(int flags)
 	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
 }
 
-
 Bool
 glamor_resize(ScrnInfoPtr scrn, int width, int height)
 {
@@ -65,25 +66,25 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
 	EGLImageKHR image;
 	GLuint texture;
-	EGLint attribs[] = {
-		EGL_WIDTH,	0,
-		EGL_HEIGHT,	0,
-		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
-					EGL_DRM_BUFFER_USE_SCANOUT_MESA,
-		EGL_NONE
-	};
 
 	if (glamor->root != EGL_NO_IMAGE_KHR &&
 	    scrn->virtualX == width && scrn->virtualY == height)
 		return TRUE;
 
-	attribs[1] = width;
-	attribs[3] = height;
-	image =	 (glamor->egl_create_drm_image_mesa)(glamor->display, attribs);  
-	if (image == EGL_NO_IMAGE_KHR)
+        glamor->root_bo = gbm_bo_create(glamor->gbm, width, height,
+                                        GBM_BO_FORMAT_ARGB8888,
+                                        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+	if (glamor->root_bo == NULL)
 		return FALSE;
 
+        image = glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->root_bo, NULL);
+
+	if (image == EGL_NO_IMAGE_KHR) {
+                gbm_bo_destroy(glamor->root_bo);
+                return FALSE;
+        }
+
 	glGenTextures(1, &texture);
 	glBindTexture(GL_TEXTURE_2D, texture);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -101,39 +102,36 @@ void
 glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	EGLint name;
-	(glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch);
+        *handle = gbm_bo_get_handle(glamor->root_bo).u32;
+        *pitch = gbm_bo_get_pitch(glamor->root_bo);
 }
 
 EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	EGLint attribs[] = {
-		EGL_WIDTH,	0,
-		EGL_HEIGHT,	0,
-		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
-					EGL_DRM_BUFFER_USE_SCANOUT_MESA | EGL_DRM_BUFFER_USE_CURSOR_MESA,
-		EGL_NONE
-	};
-
-	attribs[1] = width;
-	attribs[3] = height;
-	return	(glamor->egl_create_drm_image_mesa)(glamor->display, attribs); 
+        glamor->cursor_bo = gbm_bo_create(glamor->gbm, width, height,
+                                          GBM_BO_FORMAT_ARGB8888,
+                                          GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_CURSOR_64X64);
+
+	if (glamor->cursor_bo == NULL)
+		return EGL_NO_IMAGE_KHR;
+
+        return glamor->egl_create_image_khr(glamor->display, NULL, EGL_NATIVE_PIXMAP_KHR, glamor->cursor_bo, NULL);
 }
 
 void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
         eglDestroyImageKHR(glamor->display, cursor);
+        gbm_bo_destroy(glamor->cursor_bo);
 }
 
 void
 glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
-	EGLint name;
-	(glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch);
+        *handle = gbm_bo_get_handle(glamor->cursor_bo).u32;
+        *pitch = gbm_bo_get_pitch(glamor->cursor_bo);
 	ErrorF("cursor stride: %d\n", *pitch);
 }
 
@@ -257,6 +255,7 @@ glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
 	glamor_fini(screen);
 
         eglDestroyImageKHR(glamor->display, glamor->root);
+        gbm_bo_destroy(glamor->root_bo);
 
 	eglMakeCurrent(glamor->display,
 		       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -328,9 +327,13 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 
 	}
 
+        glamor->gbm = gbm_create_device(glamor->fd);
+        if (glamor->gbm == NULL) {
+          ErrorF("couldn't create gbm device\n");
+          return FALSE;
+        }
 
-
-	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
+	glamor->display = eglGetDisplay(glamor->gbm); 
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
 #else
@@ -360,6 +363,8 @@ glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 #endif
 
 	glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA");
+        glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
+                                       eglGetProcAddress("eglCreateImageKHR");
 	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA");
 	glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index e083864..bed7bb9 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -16,25 +16,31 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include <gbm.h>
 #include "glamor_gl_dispatch.h"
 struct glamor_ddx_screen_private {
 	EGLDisplay display;
 	EGLContext context;
 	EGLImageKHR root;
+        struct gbm_bo *root_bo;
+        struct gbm_bo *cursor_bo;
+
 	EGLint major, minor;
 
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
 	int fd;
 	int cpp;
+        struct gbm_device *gbm;
 
 	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
+        PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
         struct glamor_gl_dispatch *dispatch;
 };
 
-inline struct glamor_ddx_screen_private *
+inline static struct glamor_ddx_screen_private *
 glamor_ddx_get_screen_private(ScrnInfoPtr scrn)
 {
 	return (struct glamor_ddx_screen_private *) (scrn->driverPrivate);
commit 82a9b0c540dcf1064f5184c36a05d6216fb11034
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Sep 16 13:37:13 2011 +0800

    glamor-ddx: Change naming of glamor ddx module.
    
    Use glamor_ddx prefix for all standalone glamor ddx functions.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 90357d2..eef8eeb 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -49,19 +49,19 @@
 #define GLAMOR_VERSION_MINOR 1
 #define GLAMOR_VERSION_PATCH 0
 
-static const char glamor_name[] = "glamor";
+static const char glamor_ddx_name[] = "glamor";
 
 static void
-glamor_identify(int flags)
+glamor_ddx_identify(int flags)
 {
-	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name);
+	xf86Msg(X_INFO, "Standalone %s: OpenGL accelerated X.org driver\n", glamor_ddx_name);
 }
 
 
 Bool
 glamor_resize(ScrnInfoPtr scrn, int width, int height)
 {
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
 	EGLImageKHR image;
 	GLuint texture;
@@ -100,14 +100,14 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 void
 glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
 {
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	EGLint name;
 	(glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch);
 }
 
 EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 {
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	EGLint attribs[] = {
 		EGL_WIDTH,	0,
 		EGL_HEIGHT,	0,
@@ -124,14 +124,14 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 
 void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor)
 {
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
         eglDestroyImageKHR(glamor->display, cursor);
 }
 
 void
 glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch)
 {
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	EGLint name;
 	(glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch);
 	ErrorF("cursor stride: %d\n", *pitch);
@@ -139,9 +139,9 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin
 
 char * dri_device_name = "/dev/dri/card0";
 static Bool
-glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags)
+glamor_ddx_pre_init(ScrnInfoPtr scrn, int flags)
 {
-	struct glamor_screen_private *glamor;
+	struct glamor_ddx_screen_private *glamor;
 	rgb defaultWeight = { 0, 0, 0 };
 
 	glamor = xnfcalloc(sizeof *glamor, 1);
@@ -193,15 +193,15 @@ fail:
 }
 
 static void
-glamor_adjust_frame_ddx(int scrnIndex, int x, int y, int flags)
+glamor_ddx_adjust_frame(int scrnIndex, int x, int y, int flags)
 {
 }
 
 static Bool
-glamor_enter_vt_ddx(int scrnIndex, int flags)
+glamor_ddx_enter_vt(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 
 	if (drmSetMaster(glamor->fd)) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -216,19 +216,19 @@ glamor_enter_vt_ddx(int scrnIndex, int flags)
 }
 
 static void
-glamor_leave_vt_ddx(int scrnIndex, int flags)
+glamor_ddx_leave_vt(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 
 	drmDropMaster(glamor->fd);
 }
 
 static Bool
-glamor_create_screen_resources_ddx(ScreenPtr screen)
+glamor_ddx_create_screen_resources(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 
 	screen->CreateScreenResources = glamor->CreateScreenResources;
 	if (!(*screen->CreateScreenResources) (screen))
@@ -243,16 +243,16 @@ glamor_create_screen_resources_ddx(ScreenPtr screen)
 }
 
 static Bool
-glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
+glamor_ddx_close_screen(int scrnIndex, ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 
 	screen->CloseScreen = glamor->CloseScreen;
 	(*screen->CloseScreen) (scrnIndex, screen);
 
 	if (scrn->vtSema == TRUE)
-		glamor_leave_vt_ddx(scrnIndex, 0);
+		glamor_ddx_leave_vt(scrnIndex, 0);
 
 	glamor_fini(screen);
 
@@ -274,7 +274,7 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
 
 
 static Bool
-glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
+glamor_egl_has_extension(struct glamor_ddx_screen_private *glamor, char *extension)
 {
   const char *egl_extensions;
   char *pext;
@@ -297,10 +297,10 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
 
 
 static Bool
-glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
+glamor_ddx_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	const char *version;
 	VisualPtr visual;
         EGLint config_attribs[] = {
@@ -343,7 +343,7 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	}
 
 	version = eglQueryString(glamor->display, EGL_VERSION);
-	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
+	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_ddx_name, version);
 
 #define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
         if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) {  \
@@ -446,14 +446,14 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	 * later memory should be bound when allocating, e.g rotate_mem */
 	scrn->vtSema = TRUE;
 
-	if (!glamor_enter_vt_ddx(scrnIndex, 0))
+	if (!glamor_ddx_enter_vt(scrnIndex, 0))
 		return FALSE;
 
 	screen->SaveScreen = xf86SaveScreen;
 	glamor->CreateScreenResources = screen->CreateScreenResources;
-	screen->CreateScreenResources = glamor_create_screen_resources_ddx;
+	screen->CreateScreenResources = glamor_ddx_create_screen_resources;
 	glamor->CloseScreen = screen->CloseScreen;
-	screen->CloseScreen = glamor_close_screen_ddx;
+	screen->CloseScreen = glamor_ddx_close_screen;
 	/* Fixme should we init crtc screen here? */
 	if (!xf86CrtcScreenInit(screen))
 	  return FALSE;
@@ -467,10 +467,10 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 }
 
 static void
-glamor_free_screen_ddx(int scrnIndex, int flags)
+glamor_ddx_free_screen(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 	if (glamor != NULL)
 	{
 	  close(glamor->fd);
@@ -480,7 +480,7 @@ glamor_free_screen_ddx(int scrnIndex, int flags)
 }
 
 static ModeStatus
-glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+glamor_ddx_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
 {
 	if (mode->Flags & V_INTERLACE) {
 		if (verbose) {
@@ -494,13 +494,13 @@ glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flag
 }
 
 static Bool
-glamor_probe(struct _DriverRec *drv, int flags)
+glamor_ddx_probe(struct _DriverRec *drv, int flags)
 {
 	ScrnInfoPtr scrn = NULL;
        	GDevPtr *sections;
 	int entity, n;
 
-	n = xf86MatchDevice(glamor_name, &sections);
+	n = xf86MatchDevice(glamor_ddx_name, &sections);
 	if (n <= 0)
 	    return FALSE;
 
@@ -513,29 +513,29 @@ glamor_probe(struct _DriverRec *drv, int flags)
 	}
 
 	scrn->driverVersion = 1;
-	scrn->driverName = (char *) glamor_name;
-	scrn->name = (char *) glamor_name;
+	scrn->driverName = (char *) glamor_ddx_name;
+	scrn->name = (char *) glamor_ddx_name;
 	scrn->Probe = NULL;
 
-	scrn->PreInit = glamor_pre_init_ddx;
-	scrn->ScreenInit = glamor_screen_init_ddx;
-	scrn->AdjustFrame = glamor_adjust_frame_ddx;
-	scrn->EnterVT = glamor_enter_vt_ddx;
-	scrn->LeaveVT = glamor_leave_vt_ddx;
-	scrn->FreeScreen = glamor_free_screen_ddx;
-	scrn->ValidMode = glamor_valid_mode_ddx;
+	scrn->PreInit = glamor_ddx_pre_init;
+	scrn->ScreenInit = glamor_ddx_screen_init;
+	scrn->AdjustFrame = glamor_ddx_adjust_frame;
+	scrn->EnterVT = glamor_ddx_enter_vt;
+	scrn->LeaveVT = glamor_ddx_leave_vt;
+	scrn->FreeScreen = glamor_ddx_free_screen;
+	scrn->ValidMode = glamor_ddx_valid_mode;
 
 	return TRUE;
 }
 
 static const OptionInfoRec *
-glamor_available_options(int chipid, int busid)
+glamor_ddx_available_options(int chipid, int busid)
 {
 	return NULL;
 }
 
 static Bool
-glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
+glamor_ddx_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
 {
 	xorgHWFlags *flag;
 
@@ -550,19 +550,19 @@ glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
 	}
 }
 
-_X_EXPORT DriverRec glamor = {
+_X_EXPORT DriverRec glamor_ddx = {
 	1,
 	"glamor",
-	glamor_identify,
-	glamor_probe,
-	glamor_available_options,
+	glamor_ddx_identify,
+	glamor_ddx_probe,
+	glamor_ddx_available_options,
 	NULL,
 	0,
-	glamor_driver_func,
+	glamor_ddx_driver_func,
 };
 
 static pointer
-glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+glamor_ddx_setup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
    static Bool setupDone = 0;
 
@@ -570,7 +570,7 @@ glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin)
     */
    if (!setupDone) {
       setupDone = 1;
-      xf86AddDriver(&glamor, module, HaveDriverFuncs);
+      xf86AddDriver(&glamor_ddx, module, HaveDriverFuncs);
 
       /*
        * The return value must be non-NULL on success even though there
@@ -588,7 +588,7 @@ Bool
 glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
 {
         ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-        struct glamor_screen_private *glamor_egl = glamor_get_screen_private(scrn);
+        struct glamor_ddx_screen_private *glamor_egl = glamor_ddx_get_screen_private(scrn);
         if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
           return FALSE;
         glamor_egl->dispatch = dispatch;
@@ -596,8 +596,8 @@ glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, i
 }
 
 
-static XF86ModuleVersionInfo glamor_version_info = {
-	glamor_name,
+static XF86ModuleVersionInfo glamor_ddx_version_info = {
+	glamor_ddx_name,
 	MODULEVENDORSTRING,
 	MODINFOSTRING1,
 	MODINFOSTRING2,
@@ -612,7 +612,7 @@ static XF86ModuleVersionInfo glamor_version_info = {
 };
 
 _X_EXPORT XF86ModuleData glamorModuleData = {
-	&glamor_version_info,
-	glamor_setup,
+	&glamor_ddx_version_info,
+	glamor_ddx_setup,
 	NULL
 };
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index ef6ee29..60af8b5 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -478,7 +478,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	ScrnInfoPtr scrn = crtc->scrn;
-	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	struct glamor_ddx_screen_private *glamor = glamor_ddx_get_screen_private(scrn);
 
 	if (drmmode_crtc->cursor == NULL)
 	{
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 2c14ca1..e083864 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -17,7 +17,7 @@
 #include <EGL/eglext.h>
 
 #include "glamor_gl_dispatch.h"
-struct glamor_screen_private {
+struct glamor_ddx_screen_private {
 	EGLDisplay display;
 	EGLContext context;
 	EGLImageKHR root;
@@ -34,10 +34,10 @@ struct glamor_screen_private {
         struct glamor_gl_dispatch *dispatch;
 };
 
-inline struct glamor_screen_private *
-glamor_get_screen_private(ScrnInfoPtr scrn)
+inline struct glamor_ddx_screen_private *
+glamor_ddx_get_screen_private(ScrnInfoPtr scrn)
 {
-	return (struct glamor_screen_private *) (scrn->driverPrivate);
+	return (struct glamor_ddx_screen_private *) (scrn->driverPrivate);
 }
 
 Bool glamor_resize(ScrnInfoPtr scrn, int width, int height);
commit 67dbe0ddf87a6dd602d3d4a6049072f6386d757e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Sep 8 15:16:01 2011 +0800

    glamor-egl: Added new function to create image for a pixmap.
    
    This function is used to support dri2. In the underlying
    driver, it will create a buffer object for a given pixmap.
    And then call this api to create a egl image from that
    buffer object, and then bind that image to a texture, and
    then bind that texture to the pixmap.
    
    Normally, this pixmap's content is shared between a dri2
    client and the x server.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 773f90e..d95828e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -54,7 +54,7 @@
 #define GLAMOR_FOR_XORG
 
 #include <glamor.h>
-#include <glamor_gl_dispatch.h>
+#include "glamor_gl_dispatch.h"
 
 #define GLAMOR_VERSION_MAJOR 0
 #define GLAMOR_VERSION_MINOR 1
@@ -68,13 +68,12 @@ glamor_identify(int flags)
 	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", glamor_name);
 }
 
-struct glamor_screen_private {
+struct glamor_egl_screen_private {
 	EGLDisplay display;
 	EGLContext context;
 	EGLImageKHR root;
 	EGLint major, minor;
         
-
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
 	int fd;
@@ -90,19 +89,15 @@ struct glamor_screen_private {
 
 int xf86GlamorEGLPrivateIndex = -1;
 
-static struct glamor_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn)
+static struct glamor_egl_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn)
 {
-        return (struct glamor_screen_private *)  scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
+        return (struct glamor_egl_screen_private *)  scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
 }
 
-static Bool
-_glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int stride)
+static EGLImageKHR
+_glamor_create_egl_image(struct glamor_egl_screen_private *glamor_egl, int width, int height, int stride, int name)
 {
-
-	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
-	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
 	EGLImageKHR image;
-	GLuint texture;
 	EGLint attribs[] = {
 		EGL_WIDTH,	0,
 		EGL_HEIGHT,	0,
@@ -113,64 +108,122 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str
 		EGL_NONE
 	};
 
-        if (glamor->root) {
-          eglDestroyImageKHR(glamor->display, glamor->root);
-	  glamor->root = EGL_NO_IMAGE_KHR;
-        }
-          
+         
 	attribs[1] = width;
 	attribs[3] = height;
         attribs[5] = stride / 4;
-        image = glamor->egl_create_image_khr (glamor->display, 
-                                              glamor->context,
-                                              EGL_DRM_BUFFER_MESA,
-                                              (void*)glamor->front_buffer_handle,
-                                              attribs);   
+        image = glamor_egl->egl_create_image_khr (glamor_egl->display, 
+                                                  glamor_egl->context,
+                                                  EGL_DRM_BUFFER_MESA,
+                                                  (void*)name,
+                                                  attribs);   
 	if (image == EGL_NO_IMAGE_KHR)
-		return FALSE;
+		return EGL_NO_IMAGE_KHR;
 
-	glamor->dispatch->glGenTextures(1, &texture);
-	glamor->dispatch->glBindTexture(GL_TEXTURE_2D, texture);
-	glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-	(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
+	return image;
+}
 
-	glamor_set_screen_pixmap_texture(screen, width, height, texture);
-	glamor->root = image;
-	return TRUE;
+static int
+glamor_get_flink_name(int fd, int handle, int *name)
+{
+        struct drm_gem_flink flink;
+        flink.handle = handle;
+        if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) 
+           return FALSE;
+        *name = flink.name;
+        return TRUE;
+}
+
+static Bool
+glamor_create_texture_from_image(struct glamor_egl_screen_private *glamor_egl, EGLImageKHR image, GLuint *texture)
+{
+	glamor_egl->dispatch->glGenTextures(1, texture);
+	glamor_egl->dispatch->glBindTexture(GL_TEXTURE_2D, *texture);
+	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glamor_egl->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	(glamor_egl->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
+        return TRUE;
 }
 
+
 Bool
 glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
-        struct drm_gem_flink flink;
-        flink.handle = handle;
+	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	EGLImageKHR image;
+	GLuint texture;
 
-        if (ioctl(glamor->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
-           xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+        if (!glamor_get_flink_name(glamor_egl->fd, handle, &glamor_egl->front_buffer_handle)) {
+          xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 	       "Couldn't flink front buffer handle\n");
-           return FALSE;
+          return FALSE;
+        }
+
+        if (glamor_egl->root) {
+          eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
+	  glamor_egl->root = EGL_NO_IMAGE_KHR;
+        }
+ 
+        image = _glamor_create_egl_image( glamor_egl, 
+                                          scrn->virtualX, 
+                                          scrn->virtualY, 
+                                          stride, 
+                                          glamor_egl->front_buffer_handle);
+        if (image == EGL_NO_IMAGE_KHR)
+          return FALSE;
+        
+        glamor_create_texture_from_image(glamor_egl, image, &texture);
+	glamor_set_screen_pixmap_texture(screen, scrn->virtualX, scrn->virtualY, texture);
+	glamor_egl->root = image;
+        return TRUE;
+}
+
+/*
+ * This function will be called from the dri buffer allocation.
+ * It is somehow very familiar with the create screen image.
+ */
+Bool
+glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	EGLImageKHR image;
+	GLuint texture;
+        int name;
+        if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
+          xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+	       "Couldn't flink pixmap handle\n");
+          return FALSE;
         }
 
-        glamor->front_buffer_handle = flink.name;
+        image = _glamor_create_egl_image( glamor_egl, 
+                                          pixmap->drawable.width, 
+                                          pixmap->drawable.height, 
+                                          stride, 
+                                          name);
+        if (image == EGL_NO_IMAGE_KHR)
+          return FALSE;
 
-        return _glamor_create_egl_screen_image(scrn, scrn->virtualX, scrn->virtualY, stride);
+        glamor_create_texture_from_image(glamor_egl, image, &texture);
+        glamor_set_pixmap_texture(pixmap, pixmap->drawable.width, pixmap->drawable.height, texture);
+        return TRUE;
 }
 
 Bool
 glamor_close_egl_screen(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
 	glamor_fini(screen);
 
-        eglDestroyImageKHR(glamor->display, glamor->root);
+        eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
 
 
-	glamor->root = EGL_NO_IMAGE_KHR;
+	glamor_egl->root = EGL_NO_IMAGE_KHR;
 
 	return TRUE;
 }
@@ -178,14 +231,14 @@ glamor_close_egl_screen(ScreenPtr screen)
 
 
 static Bool
-glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
+glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, char *extension)
 {
   const char *egl_extensions;
   char *pext;
   int  ext_len;
   ext_len = strlen(extension);
  
-  egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS);
+  egl_extensions = (const char*)eglQueryString(glamor_egl->display, EGL_EXTENSIONS);
   pext = (char*)egl_extensions;
  
   if (pext == NULL || extension == NULL)
@@ -201,7 +254,7 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
 
 Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
-	struct glamor_screen_private *glamor;
+	struct glamor_egl_screen_private *glamor_egl;
 	const char *version;
         EGLint config_attribs[] = {
 #ifdef GLAMOR_GLES2
@@ -211,30 +264,30 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
         };
 
         glamor_identify(0);
-        glamor = calloc(sizeof(*glamor), 1);
+        glamor_egl = calloc(sizeof(*glamor_egl), 1);
         if (xf86GlamorEGLPrivateIndex == -1) 
            xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex();      
 
-        scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor;
+        scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor_egl;
 
-        glamor->fd = fd;
-	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
+        glamor_egl->fd = fd;
+	glamor_egl->display = eglGetDRMDisplayMESA(glamor_egl->fd);
 #ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
 #else
 	eglBindAPI(EGL_OPENGL_ES_API);
 #endif
-	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
+	if (!eglInitialize(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglInitialize() failed\n");
 		return FALSE;
 	}
 
-	version = eglQueryString(glamor->display, EGL_VERSION);
+	version = eglQueryString(glamor_egl->display, EGL_VERSION);
 	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
 
 #define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
-        if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) {  \
+        if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) {  \
                ErrorF("EGL_" #EXT "required.\n");  \
                return FALSE;  \
         } 
@@ -247,37 +300,39 @@ Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
         GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
 #endif
 
-	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
+	glamor_egl->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
                                             eglGetProcAddress("eglExportDRMImageMESA");
-        glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
+        glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
                                        eglGetProcAddress("eglCreateImageKHR");
 
-	glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
+	glamor_egl->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
                                                  eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
-	if (!glamor->egl_create_image_khr 
-            || !glamor->egl_export_drm_image_mesa
-            || !glamor->egl_image_target_texture2d_oes) {
+	if (!glamor_egl->egl_create_image_khr 
+            || !glamor_egl->egl_export_drm_image_mesa
+            || !glamor_egl->egl_image_target_texture2d_oes) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglGetProcAddress() failed\n");
 		return FALSE;
 	}
 
-	glamor->context = eglCreateContext(glamor->display,
+	glamor_egl->context = eglCreateContext(glamor_egl->display,
 					   NULL, EGL_NO_CONTEXT, config_attribs);
-	if (glamor->context == EGL_NO_CONTEXT) {
+	if (glamor_egl->context == EGL_NO_CONTEXT) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to create EGL context\n");
 		return FALSE;
 	}
 
-	if (!eglMakeCurrent(glamor->display,
-			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) {
+	if (!eglMakeCurrent(glamor_egl->display,
+			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to make EGL context current\n");
 		return FALSE;
 	}
 
+        
+
         return TRUE;
 }
 
@@ -285,25 +340,27 @@ void
 glamor_free_egl_screen(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
-	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
 
-	if (glamor != NULL)
+	if (glamor_egl != NULL)
 	{
 	  if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
-            eglMakeCurrent(glamor->display,
+            eglMakeCurrent(glamor_egl->display,
                          EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
-	    eglTerminate(glamor->display);
+	    eglTerminate(glamor_egl->display);
           }
-	  free(glamor);
+	  free(glamor_egl);
 	}
 }
 
+/* egl version. */
+
 Bool
 glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	struct glamor_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+	struct glamor_egl_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
         if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
           return FALSE;
         glamor_egl->dispatch = dispatch; 
commit 2a9dfc963f610abfbf12d5efdf5ba5b3f55a4305
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Sep 8 15:14:43 2011 +0800

    glamor: Re-arrange some macros/definitions in header files.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glext.h b/glamor/glamor_glext.h
new file mode 100644
index 0000000..f734d13
--- /dev/null
+++ b/glamor/glamor_glext.h
@@ -0,0 +1,32 @@
+#ifdef GLAMOR_GLES2
+
+#define GL_BGRA                                 GL_BGRA_EXT
+#define GL_COLOR_INDEX                          0x1900
+#define GL_BITMAP                               0x1A00
+#define GL_UNSIGNED_INT_8_8_8_8                 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368
+#define GL_UNSIGNED_INT_10_10_10_2              0x8036
+#define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
+
+#define GL_PIXEL_PACK_BUFFER              0x88EB
+#define GL_PIXEL_UNPACK_BUFFER            0x88EC
+#define GL_CLAMP_TO_BORDER                0x812D
+
+#define GL_READ_WRITE                     0x88BA
+#define GL_READ_ONLY                      0x88B8
+#define GL_WRITE_ONLY                     0x88B9
+#define GL_STREAM_DRAW                    0x88E0
+#define GL_STREAM_READ                    0x88E1
+#define GL_PACK_ROW_LENGTH                      0x0D02
+#define GL_UNPACK_ROW_LENGTH                    0x0CF2
+
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+
+#define GL_PACK_INVERT_MESA               0x8758
+
+#endif
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0cbc258..5f82c78 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -35,89 +35,26 @@
 
 #include "glamor.h"
 
-#ifdef GLAMOR_GLES2
-#define GL_BGRA                                 GL_BGRA_EXT
-#define GL_COLOR_INDEX                          0x1900
-#define GL_BITMAP                               0x1A00
-#define GL_UNSIGNED_INT_8_8_8_8                 0x8035
-#define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367
-#define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368
-#define GL_UNSIGNED_INT_10_10_10_2              0x8036
-#define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
-
-#define GL_PIXEL_PACK_BUFFER              0x88EB
-#define GL_PIXEL_UNPACK_BUFFER            0x88EC
-#define GL_CLAMP_TO_BORDER                0x812D
-
-#define GL_READ_WRITE                     0x88BA
-#define GL_READ_ONLY                      0x88B8
-#define GL_WRITE_ONLY                     0x88B9
-#define GL_STREAM_DRAW                    0x88E0
-#define GL_STREAM_READ                    0x88E1
-#define GL_PACK_ROW_LENGTH                      0x0D02
-#define GL_UNPACK_ROW_LENGTH                    0x0CF2
-
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
-
-#define GL_PACK_INVERT_MESA               0x8758
-
-#define glMapBuffer(x, y)    NULL
-#define glUnmapBuffer(x)
-#define glRasterPos2i(x,y)
-#define glDrawPixels(x,y,z,a,b)
-
-#endif
-
 #define GL_GLEXT_PROTOTYPES
+
 #ifdef GLAMOR_GLES2
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#define GLAMOR_DEFAULT_PRECISION   \
-    "precision mediump float;\n" 
-
+#define GLAMOR_DEFAULT_PRECISION   "precision mediump float;\n" 
+#include "glamor_glext.h"
 #else
 #include <GL/gl.h>
 #include <GL/glext.h>
-
 #define GLAMOR_DEFAULT_PRECISION
 #endif
 
-
 #ifdef RENDER
 #include "glyphstr.h"
 #endif
 
-
 #include "glamor_debug.h"
 
-#define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
-                                                    && (_w_) < _glamor_->max_fbo_size  \
-                                                    && (_h_) < _glamor_->max_fbo_size)
-
-#define glamor_check_fbo_depth(_depth_) (			\
-                                         _depth_ == 8		\
-	                                 || _depth_ == 15	\
-                                         || _depth_ == 16	\
-                                         || _depth_ == 24	\
-                                         || _depth_ == 30	\
-                                         || _depth_ == 32)
-
-
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv->is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == 1)
-
-typedef struct glamor_transform_uniforms {
-  GLint x_bias;
-  GLint x_scale;
-  GLint y_bias;
-  GLint y_scale;
-} glamor_transform_uniforms;
-
 typedef struct glamor_composite_shader {
   GLuint prog;
   GLint dest_to_dest_uniform_location;
@@ -138,16 +75,6 @@ typedef struct {
   INT16 height;
 } glamor_composite_rect_t;
 
-#define GLAMOR_NUM_GLYPH_CACHES 4
-#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
-
-typedef struct {
-        PicturePtr picture;     /* Where the glyphs of the cache are stored */
-        GlyphPtr *glyphs;
-        uint16_t count;
-        uint16_t evict;
-} glamor_glyph_cache_t;
-
 
 enum glamor_vertex_type {
      GLAMOR_VERTEX_POS,
@@ -178,8 +105,6 @@ enum shader_in {
   SHADER_IN_COUNT,
 };
 
-#include "glamor_gl_dispatch.h"
-
 struct glamor_screen_private;
 struct glamor_pixmap_private;
 typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, 
@@ -191,6 +116,20 @@ enum glamor_gl_flavor {
 };
 
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
+
+#define GLAMOR_NUM_GLYPH_CACHES 4
+#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
+
+typedef struct {
+        PicturePtr picture;     /* Where the glyphs of the cache are stored */
+        GlyphPtr *glyphs;
+        uint16_t count;
+        uint16_t evict;
+} glamor_glyph_cache_t;
+
+
+#include "glamor_gl_dispatch.h"
+
 typedef struct glamor_screen_private {
   CloseScreenProcPtr saved_close_screen;
   CreateGCProcPtr saved_create_gc;
@@ -235,7 +174,6 @@ typedef struct glamor_screen_private {
 
   /* glamor_putimage */
   GLint put_image_xybitmap_prog;
-  glamor_transform_uniforms put_image_xybitmap_transform;
   GLint put_image_xybitmap_fg_uniform_location;
   GLint put_image_xybitmap_bg_uniform_location;
 
@@ -252,7 +190,6 @@ typedef struct glamor_screen_private {
 
   glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
   Bool glyph_cache_initialized;
-
   struct glamor_gl_dispatch dispatch; 
 } glamor_screen_private;
 
@@ -262,28 +199,6 @@ typedef enum glamor_access {
   GLAMOR_ACCESS_WO,
 } glamor_access_t;
 
-/*
- * glamor_pixmap_private - glamor pixmap's private structure.
- * @gl_fbo:  The pixmap is attached to a fbo originally.
- * @gl_tex:  The pixmap is in a gl texture originally.
- * @pbo_valid: The pbo has a valid copy of the pixmap's data.
- * @is_picture: The drawable is attached to a picture.
- * @tex:     attached texture.
- * @fb:      attached fbo.
- * @pbo:     attached pbo.
- * @access_mode: access mode during the prepare/finish pair.
- * @pict_format: the corresponding picture's format.
- * #pending_op: currently only support pending filling.
- * @container: The corresponding pixmap's pointer.
- **/
-
-#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
-	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
-	&& (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE))
-
-#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv)   \
-	(pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE)
-
 enum _glamor_pending_op_type{
     GLAMOR_PENDING_NONE,
     GLAMOR_PENDING_FILL
@@ -300,6 +215,20 @@ typedef union _glamor_pending_op {
     glamor_pending_fill fill;
 } glamor_pending_op;
 
+/*
+ * glamor_pixmap_private - glamor pixmap's private structure.
+ * @gl_fbo:  The pixmap is attached to a fbo originally.
+ * @gl_tex:  The pixmap is in a gl texture originally.
+ * @pbo_valid: The pbo has a valid copy of the pixmap's data.
+ * @is_picture: The drawable is attached to a picture.
+ * @tex:     attached texture.
+ * @fb:      attached fbo.
+ * @pbo:     attached pbo.
+ * @access_mode: access mode during the prepare/finish pair.
+ * @pict_format: the corresponding picture's format.
+ * #pending_op: currently only support pending filling.
+ * @container: The corresponding pixmap's pointer.
+ **/
 
 typedef struct glamor_pixmap_private {
   unsigned char gl_fbo:1;
@@ -316,15 +245,6 @@ typedef struct glamor_pixmap_private {
   glamor_screen_private *glamor_priv;
 } glamor_pixmap_private;
 
-#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \
-  { \
-      if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
-        _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \
-        _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
-                        _pixmap_priv_->pending_op.fill.color4fv); \
-      } \
-  } while(0)
- 
 /* 
  * Pixmap dynamic status, used by dynamic upload feature.
  *
@@ -356,347 +276,6 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
   return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
 }
 
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-
-/**
- * Borrow from uxa.
- */
-static inline CARD32
-format_for_depth(int depth)
-{
-  switch (depth) {
-  case 1: return PICT_a1;
-  case 4: return PICT_a4;
-  case 8: return PICT_a8;
-  case 15: return PICT_x1r5g5b5;
-  case 16: return PICT_r5g6b5;
-  default:
-  case 24: return PICT_x8r8g8b8;
-#if XORG_VERSION_CURRENT >= 10699900
-  case 30: return PICT_x2r10g10b10;
-#endif
-  case 32: return PICT_a8r8g8b8;
-  }
-}
-
-static inline CARD32
-format_for_pixmap(PixmapPtr pixmap)
-{
-  glamor_pixmap_private *pixmap_priv;
-  PictFormatShort pict_format;
-
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-    pict_format = pixmap_priv->pict_format;
-  else
-    pict_format = format_for_depth(pixmap->drawable.depth);
-
-  return pict_format;
-}
-
-/*
- * Map picture's format to the correct gl texture format and type.
- * no_alpha is used to indicate whehter we need to wire alpha to 1. 
- *
- * Return 0 if find a matched texture type. Otherwise return -1.
- **/
-#ifndef GLAMOR_GLES2
-static inline int 
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum *tex_format, 
-					   GLenum *tex_type,
-					   int *no_alpha,
-                                           int *no_revert)
-{
-  *no_alpha = 0;
-  *no_revert = 1;
-  switch (format) {
-  case PICT_a1:
-    *tex_format = GL_COLOR_INDEX;
-    *tex_type = GL_BITMAP;
-    break;
-  case PICT_b8g8r8x8:
-    *no_alpha = 1;
-  case PICT_b8g8r8a8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8;
-    break;
-
-  case PICT_x8r8g8b8:
-    *no_alpha = 1;
-  case PICT_a8r8g8b8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-    break;
-  case PICT_x8b8g8r8:
-    *no_alpha = 1;
-  case PICT_a8b8g8r8:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-    break;
-  case PICT_x2r10g10b10:
-    *no_alpha = 1;
-  case PICT_a2r10g10b10:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-    break;
-  case PICT_x2b10g10r10:
-    *no_alpha = 1;
-  case PICT_a2b10g10r10:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
-    break;
- 
-  case PICT_r5g6b5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    break;
-  case PICT_b5g6r5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
-    break;
-  case PICT_x1b5g5r5:
-    *no_alpha = 1;
-  case PICT_a1b5g5r5:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    break;
-               
-  case PICT_x1r5g5b5:
-    *no_alpha = 1;
-  case PICT_a1r5g5b5:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    break;
-  case PICT_a8:
-    *tex_format = GL_ALPHA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-  case PICT_x4r4g4b4:
-    *no_alpha = 1;
-  case PICT_a4r4g4b4:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    break;
-
-  case PICT_x4b4g4r4:
-    *no_alpha = 1;
-  case PICT_a4b4g4r4:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    break;
- 
-  default:
-    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
-    return -1;
-  }
-  return 0;
-}
-#else
-#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
-
-static inline int 
-glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
-					   GLenum *tex_format, 
-					   GLenum *tex_type,
-					   int *no_alpha,
-                                           int *no_revert)
-{
-  *no_alpha = 0;
-  *no_revert = IS_LITTLE_ENDIAN;
-
-  switch (format) {
-  case PICT_b8g8r8x8:
-    *no_alpha = 1;
-  case PICT_b8g8r8a8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    *no_revert = !IS_LITTLE_ENDIAN;
-    break;
-
-  case PICT_x8r8g8b8:
-    *no_alpha = 1;
-  case PICT_a8r8g8b8:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-
-  case PICT_x8b8g8r8:
-    *no_alpha = 1;
-  case PICT_a8b8g8r8:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    break;
-
-  case PICT_x2r10g10b10:
-    *no_alpha = 1;
-  case PICT_a2r10g10b10:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x2b10g10r10:
-    *no_alpha = 1;
-  case PICT_a2b10g10r10:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
-    *no_revert = TRUE;
-    break;
- 
-  case PICT_r5g6b5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_b5g6r5:
-    *tex_format = GL_RGB;
-    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
-    *no_revert = FALSE;
-    break;
-
-  case PICT_x1b5g5r5:
-    *no_alpha = 1;
-  case PICT_a1b5g5r5:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    *no_revert = TRUE;
-    break;
-               
-  case PICT_x1r5g5b5:
-    *no_alpha = 1;
-  case PICT_a1r5g5b5:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_a8:
-    *tex_format = GL_ALPHA;
-    *tex_type = GL_UNSIGNED_BYTE;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x4r4g4b4:
-    *no_alpha = 1;
-  case PICT_a4r4g4b4:
-    *tex_format = GL_BGRA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    *no_revert = TRUE;
-    break;
-
-  case PICT_x4b4g4r4:
-    *no_alpha = 1;
-  case PICT_a4b4g4r4:
-    *tex_format = GL_RGBA;
-    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-    *no_revert = TRUE;
-    break;
- 
-  default:
-    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
-    return -1;
-  }
-  return 0;
-}
-
-
-#endif
-
-
-static inline int 
-glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
-                                       GLenum *format, 
-                                       GLenum *type, 
-                                       int *no_alpha,
-                                       int *no_revert)
-{
-  glamor_pixmap_private *pixmap_priv;
-  PictFormatShort pict_format;
-
-  pixmap_priv = glamor_get_pixmap_private(pixmap);
-  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
-    pict_format = pixmap_priv->pict_format;
-  else
-    pict_format = format_for_depth(pixmap->drawable.depth);
-
-  return glamor_get_tex_format_type_from_pictformat(pict_format, 
-						    format, type, 
-                                                    no_alpha, no_revert);  
-}
-
-
-/* borrowed from uxa */
-static inline Bool
-glamor_get_rgba_from_pixel(CARD32 pixel,
-			   float * red,
-			   float * green,
-			   float * blue,
-			   float * alpha,
-			   CARD32 format)
-{
-  int rbits, bbits, gbits, abits;
-  int rshift, bshift, gshift, ashift;
-
-  rbits = PICT_FORMAT_R(format);
-  gbits = PICT_FORMAT_G(format);
-  bbits = PICT_FORMAT_B(format);
-  abits = PICT_FORMAT_A(format);
-
-  if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
-    rshift = gshift = bshift = ashift = 0;
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
-    bshift = 0;
-    gshift = bbits;
-    rshift = gshift + gbits;
-    ashift = rshift + rbits;
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
-    rshift = 0;
-    gshift = rbits;
-    bshift = gshift + gbits;
-    ashift = bshift + bbits;
-#if XORG_VERSION_CURRENT >= 10699900
-  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
-    ashift = 0;
-    rshift = abits;
-    if (abits == 0)
-      rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
-    gshift = rshift + rbits;
-    bshift = gshift + gbits;
-#endif
-  } else {
-    return FALSE;
-  }
-#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
-  *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
-    / (float)((1<<(_bits_)) - 1) 
-
-  if (rbits) 
-    COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
-  else
-    *red = 0;
-
-  if (gbits) 
-    COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
-  else
-    *green = 0;
-
-  if (bbits) 
-    COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
-  else
-    *blue = 0;
-
-  if (abits) 
-    COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
-  else
-    *alpha = 1;
-
-  return TRUE;
-}
-
 
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
@@ -775,10 +354,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
 
 void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
-void glamor_get_transform_uniform_locations(GLint prog,
-					    glamor_transform_uniforms *uniform_locations);
-void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
-				     glamor_transform_uniforms *uniform_locations);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 Bool glamor_gl_has_extension(char *extension);
@@ -977,6 +552,8 @@ glamor_upload_picture_to_texture(PicturePtr picture);
 void 
 glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv);
 
+#include"glamor_utils.h" 
+
 /* Dynamic pixmap upload to texture if needed. 
  * Sometimes, the target is a gl texture pixmap/picture,
  * but the source or mask is in cpu memory. In that case,
@@ -984,11 +561,9 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
  * fallback the whole process to cpu. Most of the time,
  * this will increase performance obviously. */
 
-
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
 #define GLAMOR_DELAYED_FILLING
 
 
-#include"glamor_utils.h" 
 
 #endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 30432cf..fe5bd4e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -159,4 +159,384 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
       boxes[i].y2 += dy;
     }
 }
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+
+#define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
+                                                    && (_w_) < _glamor_->max_fbo_size  \
+                                                    && (_h_) < _glamor_->max_fbo_size)
+
+#define glamor_check_fbo_depth(_depth_) (			\
+                                         _depth_ == 8		\
+	                                 || _depth_ == 15	\
+                                         || _depth_ == 16	\
+                                         || _depth_ == 24	\
+                                         || _depth_ == 30	\
+                                         || _depth_ == 32)
+
+
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv->is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == 1)
+
+#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
+	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
+	&& (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE))
+
+#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv)   \
+	(pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE)
+
+#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \
+  { \
+      if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
+        _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \
+        _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
+                        _pixmap_priv_->pending_op.fill.color4fv); \
+      } \
+  } while(0)
+ 
+
+/**
+ * Borrow from uxa.
+ */
+static inline CARD32
+format_for_depth(int depth)
+{
+  switch (depth) {
+  case 1: return PICT_a1;
+  case 4: return PICT_a4;
+  case 8: return PICT_a8;
+  case 15: return PICT_x1r5g5b5;
+  case 16: return PICT_r5g6b5;
+  default:
+  case 24: return PICT_x8r8g8b8;
+#if XORG_VERSION_CURRENT >= 10699900
+  case 30: return PICT_x2r10g10b10;
+#endif
+  case 32: return PICT_a8r8g8b8;
+  }
+}
+
+static inline CARD32
+format_for_pixmap(PixmapPtr pixmap)
+{
+  glamor_pixmap_private *pixmap_priv;
+  PictFormatShort pict_format;
+
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+    pict_format = pixmap_priv->pict_format;
+  else
+    pict_format = format_for_depth(pixmap->drawable.depth);
+
+  return pict_format;
+}
+
+/*
+ * Map picture's format to the correct gl texture format and type.
+ * no_alpha is used to indicate whehter we need to wire alpha to 1. 
+ *
+ * Return 0 if find a matched texture type. Otherwise return -1.
+ **/
+#ifndef GLAMOR_GLES2
+static inline int 
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+					   GLenum *tex_format, 
+					   GLenum *tex_type,
+					   int *no_alpha,
+                                           int *no_revert)
+{
+  *no_alpha = 0;
+  *no_revert = 1;
+  switch (format) {
+  case PICT_a1:
+    *tex_format = GL_COLOR_INDEX;
+    *tex_type = GL_BITMAP;
+    break;
+  case PICT_b8g8r8x8:
+    *no_alpha = 1;
+  case PICT_b8g8r8a8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+    break;
+
+  case PICT_x8r8g8b8:
+    *no_alpha = 1;
+  case PICT_a8r8g8b8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    break;
+  case PICT_x8b8g8r8:
+    *no_alpha = 1;
+  case PICT_a8b8g8r8:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    break;
+  case PICT_x2r10g10b10:
+    *no_alpha = 1;
+  case PICT_a2r10g10b10:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+    break;
+  case PICT_x2b10g10r10:
+    *no_alpha = 1;
+  case PICT_a2b10g10r10:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+    break;
+ 
+  case PICT_r5g6b5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    break;
+  case PICT_b5g6r5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+    break;
+  case PICT_x1b5g5r5:
+    *no_alpha = 1;
+  case PICT_a1b5g5r5:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    break;
+               
+  case PICT_x1r5g5b5:
+    *no_alpha = 1;
+  case PICT_a1r5g5b5:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    break;
+  case PICT_a8:
+    *tex_format = GL_ALPHA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+  case PICT_x4r4g4b4:
+    *no_alpha = 1;
+  case PICT_a4r4g4b4:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    break;
+
+  case PICT_x4b4g4r4:
+    *no_alpha = 1;
+  case PICT_a4b4g4r4:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    break;
+ 
+  default:
+    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
+    return -1;
+  }
+  return 0;
+}
+#else
+#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
+
+static inline int 
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+					   GLenum *tex_format, 
+					   GLenum *tex_type,
+					   int *no_alpha,
+                                           int *no_revert)
+{
+  *no_alpha = 0;
+  *no_revert = IS_LITTLE_ENDIAN;
+
+  switch (format) {
+  case PICT_b8g8r8x8:
+    *no_alpha = 1;
+  case PICT_b8g8r8a8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    *no_revert = !IS_LITTLE_ENDIAN;
+    break;
+
+  case PICT_x8r8g8b8:
+    *no_alpha = 1;
+  case PICT_a8r8g8b8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+
+  case PICT_x8b8g8r8:
+    *no_alpha = 1;
+  case PICT_a8b8g8r8:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+
+  case PICT_x2r10g10b10:
+    *no_alpha = 1;
+  case PICT_a2r10g10b10:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x2b10g10r10:
+    *no_alpha = 1;
+  case PICT_a2b10g10r10:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
+    *no_revert = TRUE;
+    break;
+ 
+  case PICT_r5g6b5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_b5g6r5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    *no_revert = FALSE;
+    break;
+
+  case PICT_x1b5g5r5:
+    *no_alpha = 1;
+  case PICT_a1b5g5r5:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    *no_revert = TRUE;
+    break;
+               
+  case PICT_x1r5g5b5:
+    *no_alpha = 1;
+  case PICT_a1r5g5b5:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_a8:
+    *tex_format = GL_ALPHA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x4r4g4b4:
+    *no_alpha = 1;
+  case PICT_a4r4g4b4:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x4b4g4r4:
+    *no_alpha = 1;
+  case PICT_a4b4g4r4:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    *no_revert = TRUE;
+    break;
+ 
+  default:
+    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
+    return -1;
+  }
+  return 0;
+}
+
+
+#endif
+
+
+static inline int 
+glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
+                                       GLenum *format, 
+                                       GLenum *type, 
+                                       int *no_alpha,
+                                       int *no_revert)
+{
+  glamor_pixmap_private *pixmap_priv;
+  PictFormatShort pict_format;
+
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+    pict_format = pixmap_priv->pict_format;
+  else
+    pict_format = format_for_depth(pixmap->drawable.depth);
+
+  return glamor_get_tex_format_type_from_pictformat(pict_format, 
+						    format, type, 
+                                                    no_alpha, no_revert);  
+}
+
+
+/* borrowed from uxa */
+static inline Bool
+glamor_get_rgba_from_pixel(CARD32 pixel,
+			   float * red,
+			   float * green,
+			   float * blue,
+			   float * alpha,
+			   CARD32 format)
+{
+  int rbits, bbits, gbits, abits;
+  int rshift, bshift, gshift, ashift;
+
+  rbits = PICT_FORMAT_R(format);
+  gbits = PICT_FORMAT_G(format);
+  bbits = PICT_FORMAT_B(format);
+  abits = PICT_FORMAT_A(format);
+
+  if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
+    rshift = gshift = bshift = ashift = 0;
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+    bshift = 0;
+    gshift = bbits;
+    rshift = gshift + gbits;
+    ashift = rshift + rbits;
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+    rshift = 0;
+    gshift = rbits;
+    bshift = gshift + gbits;
+    ashift = bshift + bbits;
+#if XORG_VERSION_CURRENT >= 10699900
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+    ashift = 0;
+    rshift = abits;
+    if (abits == 0)
+      rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
+    gshift = rshift + rbits;
+    bshift = gshift + gbits;
+#endif
+  } else {
+    return FALSE;
+  }
+#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
+  *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
+    / (float)((1<<(_bits_)) - 1) 
+
+  if (rbits) 
+    COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
+  else
+    *red = 0;
+
+  if (gbits) 
+    COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
+  else
+    *green = 0;
+
+  if (bbits) 
+    COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
+  else
+    *blue = 0;
+
+  if (abits) 
+    COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
+  else
+    *alpha = 1;
+
+  return TRUE;
+}
+
+
+
+
+
+
 #endif
commit 0dff23d65b8bcec615f4c7a49efa7a5bf220b299
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Sep 8 14:05:46 2011 +0800

    glamor: Don't direct call to any gl functions.
    
    Create a new structure glamor_gl_dispatch to hold all the
    gl function's pointer and initialize them at run time ,
    rather than use them directly. To do this is to avoid
    symbol conflicts.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index fcde765..8712e76 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -43,4 +43,5 @@ libglamor_la_SOURCES = \
         glamor_pixmap.c\
         glamor_picture.c\
 	glamor_window.c\
+        glamor_gl_dispatch.c\
 	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index c0f9d51..ea4099e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -59,7 +59,7 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 	return (PixmapPtr)drawable;
 }
 
-static void
+void
 glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
@@ -111,6 +111,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     int type = GLAMOR_PIXMAP_TEXTURE;
     glamor_pixmap_private *pixmap_priv;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
@@ -141,6 +142,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     pixmap_priv->container = pixmap;
+    pixmap_priv->glamor_priv = glamor_priv;
 
     if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
 	return pixmap;
@@ -160,11 +162,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     }
 
     /* Create the texture used to store the pixmap's data. */
-    glGenTextures(1, &tex);
-    glBindTexture(GL_TEXTURE_2D, tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+    dispatch->glGenTextures(1, &tex);
+    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                  format, GL_UNSIGNED_BYTE, NULL);
 
     glamor_set_pixmap_texture(pixmap, w, h, tex);
@@ -210,14 +212,16 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
 static Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     if (pixmap->refcnt == 1) {
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
         if (pixmap_priv->fb)
-	  glDeleteFramebuffers(1, &pixmap_priv->fb);
+	  dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
         if (pixmap_priv->tex)
-	  glDeleteTextures(1, &pixmap_priv->tex);
+	  dispatch->glDeleteTextures(1, &pixmap_priv->tex);
         if (pixmap_priv->pbo)
-          glDeleteBuffers(1, &pixmap_priv->pbo);
+          dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
         dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
     }
 
@@ -227,7 +231,8 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
 static void
 glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
-    glFlush();
+    glamor_gl_dispatch *dispatch = data;
+    dispatch->glFlush();
 }
 
 static void
@@ -295,6 +300,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         goto fail;
     }
 
+    glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version);
 
 #ifdef GLAMOR_GLES2
     if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
@@ -305,11 +311,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert");
     glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit");
-    glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); 
+    glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); 
 
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
-					NULL)) {
+					(void*)&glamor_priv->dispatch)) {
 	goto fail;
     }
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 7a0e899..e8719fb 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -52,10 +52,12 @@ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
 extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen);
+void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
 
 #ifdef GLAMOR_FOR_XORG
 extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
 extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
+extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride);
 extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
 extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
 #endif
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 3e6e6b9..ec57520 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -46,6 +46,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     glamor_pixmap_private *src_pixmap_priv;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
     if (!glamor_priv->has_fbo_blit) {
@@ -78,14 +79,14 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     }
     glamor_validate_pixmap(dst_pixmap);
 
-    glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
+    dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     src_y_off += dy;
 
     for (i = 0; i < nbox; i++) {
       if(glamor_priv->yInverted) {
-	glBlitFramebuffer((box[i].x1 + dx + src_x_off),
+	dispatch->glBlitFramebuffer((box[i].x1 + dx + src_x_off),
                              (box[i].y1 + src_y_off),
 			     (box[i].x2 + dx + src_x_off),
 			     (box[i].y2 + src_y_off),
@@ -101,7 +102,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
 	int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
 
-	glBlitFramebuffer(box[i].x1 + dx + src_x_off,
+	dispatch->glBlitFramebuffer(box[i].x1 + dx + src_x_off,
 			     flip_src_y1,
 			     box[i].x2 + dx + src_x_off,
 			     flip_src_y2,
@@ -129,6 +130,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 {
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(dst->pScreen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int i;
@@ -162,7 +164,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       flush_needed = 1;
 
     if (gc) {
-	glamor_set_alu(gc->alu);
+	glamor_set_alu(dispatch, gc->alu);
 	if (!glamor_set_planemask(dst_pixmap, gc->planemask))
 	  goto fail;
         if (gc->alu != GXcopy) {
@@ -181,10 +183,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 
 
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
                           2 * sizeof(float),
                           vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@@ -192,25 +194,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       dy += src_y_off;
       pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
-      glActiveTexture(GL_TEXTURE0);
-      glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+      dispatch->glActiveTexture(GL_TEXTURE0);
+      dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
 #ifndef GLAMOR_GLES2
-      glEnable(GL_TEXTURE_2D);
+      dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  
-      glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
+      dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
                             2 * sizeof(float),
                             texcoords);
-      glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-      glUseProgram(glamor_priv->finish_access_prog[0]);
-      glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
-      glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
+      dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+      dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+      dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
+      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
  
    } 
     else {
-      GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
+      GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
    }
  
     for (i = 0; i < nbox; i++) {
@@ -230,24 +232,24 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 				     glamor_priv->yInverted,
 				     texcoords);
 
-      glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+      dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-      glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+      dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-      glDisable(GL_TEXTURE_2D);
+      dispatch->glDisable(GL_TEXTURE_2D);
 #endif
     }
-    glUseProgram(0);
+    dispatch->glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
     if (flush_needed) 
-      glFlush();
+      dispatch->glFlush();
     return TRUE;
 
 fail:
-    glamor_set_alu(GXcopy);
+    glamor_set_alu(dispatch, GXcopy);
     glamor_set_planemask(dst_pixmap, ~0);
     return FALSE;
 }
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 3609600..2249ac8 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -54,49 +54,24 @@ glamor_get_drawable_location(const DrawablePtr drawable)
     return 'f';
 }
 
-
-void
-glamor_get_transform_uniform_locations(GLint prog,
-				       glamor_transform_uniforms *uniform_locations)
-{
-  uniform_locations->x_bias = glGetUniformLocation(prog, "x_bias");
-  uniform_locations->x_scale = glGetUniformLocation(prog, "x_scale");
-  uniform_locations->y_bias = glGetUniformLocation(prog, "y_bias");
-  uniform_locations->y_scale = glGetUniformLocation(prog, "y_scale");
-}
-
-/* We don't use a full matrix for our transformations because it's
- * wasteful when all we want is to rescale to NDC and possibly do a flip
- * if it's the front buffer.
- */
-void
-glamor_set_transform_for_pixmap(PixmapPtr pixmap,
-				glamor_transform_uniforms *uniform_locations)
-{
-  glUniform1f(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
-  glUniform1f(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
-  glUniform1f(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
-  glUniform1f(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
-}
-
 GLint
-glamor_compile_glsl_prog(GLenum type, const char *source)
+glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source)
 {
   GLint ok;
   GLint prog;
 
-  prog = glCreateShader(type);
-  glShaderSource(prog, 1, (const GLchar **)&source, NULL);
-  glCompileShader(prog);
-  glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
+  prog = dispatch->glCreateShader(type);
+  dispatch->glShaderSource(prog, 1, (const GLchar **)&source, NULL);
+  dispatch->glCompileShader(prog);
+  dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
   if (!ok) {
     GLchar *info;
     GLint size;
 
-    glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
+    dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
     info = malloc(size);
 
-    glGetShaderInfoLog(prog, size, NULL, info);
+    dispatch->glGetShaderInfoLog(prog, size, NULL, info);
     ErrorF("Failed to compile %s: %s\n",
 	   type == GL_FRAGMENT_SHADER ? "FS" : "VS",
 	   info);
@@ -108,20 +83,20 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
 }
 
 void
-glamor_link_glsl_prog(GLint prog)
+glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog)
 {
   GLint ok;
 
-  glLinkProgram(prog);
-  glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+  dispatch->glLinkProgram(prog);
+  dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
   if (!ok) {
     GLchar *info;
     GLint size;
 
-    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
+    dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
     info = malloc(size);
 
-    glGetProgramInfoLog(prog, size, NULL, info);
+    dispatch->glGetProgramInfoLog(prog, size, NULL, info);
     ErrorF("Failed to link: %s\n",
 	   info);
     FatalError("GLSL link failure\n");
@@ -140,6 +115,7 @@ void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   const char *vs_source =
     "attribute vec4 v_position;\n"
     "attribute vec4 v_texcoord0;\n"
@@ -200,51 +176,51 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
   GLint sampler_uniform_location;
 
-  glamor_priv->finish_access_prog[0] = glCreateProgram();
-  glamor_priv->finish_access_prog[1] = glCreateProgram();
+  glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
+  glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
 
-  vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-  fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
-  glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-  glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
+  vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+  fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source);
+  dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
+  dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
 
-  avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-  set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, set_alpha_source);
-  glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-  glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
+  avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
+  set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source);
+  dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
+  dispatch->glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
 
-  glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position");
-  glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
+  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position");
+  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[0]);
 
-  glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position");
-  glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
+  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position");
+  dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glamor_link_glsl_prog(dispatch, glamor_priv->finish_access_prog[1]);
 
   glamor_priv->finish_access_no_revert[0] = 
-    glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
 
   glamor_priv->finish_access_swap_rb[0] = 
-    glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
   sampler_uniform_location =
-    glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
-  glUseProgram(glamor_priv->finish_access_prog[0]);
-  glUniform1i(sampler_uniform_location, 0);
-  glUniform1i(glamor_priv->finish_access_no_revert[0],1);
-  glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
-  glUseProgram(0);
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
+  dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
+  dispatch->glUniform1i(sampler_uniform_location, 0);
+  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0],1);
+  dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
+  dispatch->glUseProgram(0);
 
   glamor_priv->finish_access_no_revert[1] = 
-    glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
   glamor_priv->finish_access_swap_rb[1] = 
-    glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
   sampler_uniform_location =
-    glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
-  glUseProgram(glamor_priv->finish_access_prog[1]);
-  glUniform1i(glamor_priv->finish_access_no_revert[1],1);
-  glUniform1i(sampler_uniform_location, 0);
-  glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
-  glUseProgram(0);
+    dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
+  dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
+  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1],1);
+  dispatch->glUniform1i(sampler_uniform_location, 0);
+  dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
+  dispatch->glUseProgram(0);
 
 }
 
@@ -254,6 +230,7 @@ glamor_finish_access(DrawablePtr drawable)
   PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
     return;
@@ -264,10 +241,10 @@ glamor_finish_access(DrawablePtr drawable)
 
   if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
     assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-    glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
-    glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
+    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+    dispatch->glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
     pixmap_priv->pbo_valid = FALSE;
-    glDeleteBuffers(1, &pixmap_priv->pbo);
+    dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
     pixmap_priv->pbo = 0;
   } else {
     free(pixmap->devPrivate.ptr);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index bdb2da7..773f90e 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -54,6 +54,7 @@
 #define GLAMOR_FOR_XORG
 
 #include <glamor.h>
+#include <glamor_gl_dispatch.h>
 
 #define GLAMOR_VERSION_MAJOR 0
 #define GLAMOR_VERSION_MINOR 1
@@ -84,6 +85,7 @@ struct glamor_screen_private {
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
         PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
+        struct glamor_gl_dispatch *dispatch;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
@@ -127,10 +129,10 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str
 	if (image == EGL_NO_IMAGE_KHR)
 		return FALSE;
 
-	glGenTextures(1, &texture);
-	glBindTexture(GL_TEXTURE_2D, texture);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glamor->dispatch->glGenTextures(1, &texture);
+	glamor->dispatch->glBindTexture(GL_TEXTURE_2D, texture);
+	glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 	(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
 
@@ -296,3 +298,14 @@ glamor_free_egl_screen(int scrnIndex, int flags)
 	  free(glamor);
 	}
 }
+
+Bool
+glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
+        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
+          return FALSE;
+        glamor_egl->dispatch = dispatch; 
+        return TRUE;
+}
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 0b3d5fd..7254167 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -105,6 +105,7 @@ void
 glamor_init_solid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     const char *solid_vs =
         "attribute vec4 v_position;"
 	"void main()\n"
@@ -120,17 +121,17 @@ glamor_init_solid_shader(ScreenPtr screen)
 	"}\n";
     GLint fs_prog, vs_prog;
 
-    glamor_priv->solid_prog = glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
-    glAttachShader(glamor_priv->solid_prog, vs_prog);
-    glAttachShader(glamor_priv->solid_prog, fs_prog);
+    glamor_priv->solid_prog = dispatch->glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs);
+    dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
     
-    glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position");
-    glamor_link_glsl_prog(glamor_priv->solid_prog);
+    dispatch->glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position");
+    glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
 
     glamor_priv->solid_color_uniform_location =
-	glGetUniformLocation(glamor_priv->solid_prog, "color");
+	dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color");
 }
 
 Bool
@@ -140,6 +141,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     int x1 = x;
     int x2 = x + width;
     int y1 = y;
@@ -151,7 +153,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
         glamor_fallback("dest %p has no fbo.\n", pixmap);
 	goto fail;
     }
-    glamor_set_alu(alu);
+    glamor_set_alu(dispatch, alu);
     if (!glamor_set_planemask(pixmap, planemask)) {
       glamor_fallback("Failedto set planemask  in glamor_solid.\n");
       goto fail;
@@ -178,24 +180,24 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
 
-    glUseProgram(glamor_priv->solid_prog);
+    dispatch->glUseProgram(glamor_priv->solid_prog);
  
-    glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
+    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
 
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float), vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
 
     glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
 				 glamor_priv->yInverted,
 				 vertices);
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glUseProgram(0);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(0);
     return TRUE;
 fail:
-    glamor_set_alu(GXcopy);
+    glamor_set_alu(dispatch, GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return FALSE;
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index ba409dc..224af1b 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -44,6 +44,7 @@ glamor_get_spans(DrawablePtr drawable,
     int no_alpha, no_revert;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     PixmapPtr temp_pixmap = NULL;
     int i;
     uint8_t *readpixels_dst = (uint8_t *)dst;
@@ -79,14 +80,14 @@ glamor_get_spans(DrawablePtr drawable,
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
     for (i = 0; i < count; i++) {
       if (glamor_priv->yInverted) {
-	glReadPixels(points[i].x + x_off,
+	dispatch->glReadPixels(points[i].x + x_off,
 		     (points[i].y + y_off),
 		     widths[i],
 		     1,
 		     format, type,
 		     readpixels_dst);
  	} else {
-	glReadPixels(points[i].x + x_off,
+	dispatch->glReadPixels(points[i].x + x_off,
 		     pixmap->drawable.height - 1 - (points[i].y + y_off),
 		     widths[i],
 		     1,
diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c
new file mode 100644
index 0000000..8232624
--- /dev/null
+++ b/glamor/glamor_gl_dispatch.c
@@ -0,0 +1,73 @@
+#include "glamor_priv.h"
+
+#define INIT_FUNC(dst,func_name,get)			\
+  dst->func_name = get(#func_name);			\
+  if (dst->func_name == NULL)				\
+    { ErrorF("Failed to get fun %s", #func_name);	\
+	goto fail; }
+
+Bool
+glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, 
+                             int gl_version, 
+                             void *(*get_proc_address)(const char*))
+{
+  INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
+  INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
+  INIT_FUNC(dispatch, glViewport, get_proc_address);
+  INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
+  INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
+  INIT_FUNC(dispatch, glReadPixels, get_proc_address);
+  INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
+  INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
+  INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
+  INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
+  INIT_FUNC(dispatch, glGenTextures, get_proc_address);
+  INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
+  INIT_FUNC(dispatch, glBindTexture, get_proc_address);
+  INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
+  INIT_FUNC(dispatch, glFlush, get_proc_address);
+  INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
+  INIT_FUNC(dispatch, glGetString, get_proc_address);
+  INIT_FUNC(dispatch, glScissor, get_proc_address);
+  INIT_FUNC(dispatch, glEnable, get_proc_address);
+  INIT_FUNC(dispatch, glDisable, get_proc_address);
+  INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
+  INIT_FUNC(dispatch, glLogicOp, get_proc_address);
+  INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
+  INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
+  INIT_FUNC(dispatch, glBufferData, get_proc_address);
+  INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
+  INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
+  INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
+  INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
+  INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
+  INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
+  INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
+  INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
+  INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
+  INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
+  INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
+  INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
+  INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
+  INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
+  INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
+  INIT_FUNC(dispatch, glShaderSource, get_proc_address);
+
+  INIT_FUNC(dispatch, glUseProgram, get_proc_address);
+  INIT_FUNC(dispatch, glUniform1i, get_proc_address);
+  INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+  INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
+  INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
+  INIT_FUNC(dispatch, glCreateShader, get_proc_address);
+  INIT_FUNC(dispatch, glCompileShader, get_proc_address);
+  INIT_FUNC(dispatch, glAttachShader, get_proc_address);
+  INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
+  INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
+  INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
+  INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
+  INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
+
+  return TRUE;
+fail:
+  return FALSE;
+}
diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h
new file mode 100644
index 0000000..c519667
--- /dev/null
+++ b/glamor/glamor_gl_dispatch.h
@@ -0,0 +1,101 @@
+typedef struct glamor_gl_dispatch {
+  /* Transformation functions */
+  void (*glMatrixMode)(GLenum mode);
+  void (*glLoadIdentity)(void);
+  void (*glViewport)( GLint x, GLint y,
+                      GLsizei width, GLsizei height );
+  /* Drawing functions */ 
+  void (*glRasterPos2i)( GLint x, GLint y );
+
+  /* Vertex Array */
+  void (*glDrawArrays)( GLenum mode, GLint first, GLsizei count );
+
+  /* Raster functions */
+  void (*glReadPixels)( GLint x, GLint y,
+                        GLsizei width, GLsizei height,
+                        GLenum format, GLenum type,
+                        GLvoid *pixels );
+
+  void (*glDrawPixels)( GLsizei width, GLsizei height,
+                        GLenum format, GLenum type,
+                        const GLvoid *pixels );
+  void (*glPixelStorei)( GLenum pname, GLint param ); 
+  /* Texture Mapping */
+
+  void (*glTexParameteri)( GLenum target, GLenum pname, GLint param );
+  void (*glTexImage2D)( GLenum target, GLint level,
+                        GLint internalFormat,
+                        GLsizei width, GLsizei height,
+                        GLint border, GLenum format, GLenum type,
+                        const GLvoid *pixels );
+  /* 1.1 */
+  void (*glGenTextures)( GLsizei n, GLuint *textures );
+  void (*glDeleteTextures)( GLsizei n, const GLuint *textures);
+  void (*glBindTexture)( GLenum target, GLuint texture );                                                                                                                         
+  void (*glTexSubImage2D)( GLenum target, GLint level,
+                           GLint xoffset, GLint yoffset,
+                           GLsizei width, GLsizei height,
+                           GLenum format, GLenum type,
+                           const GLvoid *pixels );
+  /* MISC */
+  void (*glFlush)( void );
+  void (*glGetIntegerv)( GLenum pname, GLint *params );
+  const GLubyte * (*glGetString)( GLenum name );
+  void (*glScissor)( GLint x, GLint y, GLsizei width, GLsizei height);
+  void (*glEnable)( GLenum cap );
+  void (*glDisable)( GLenum cap );
+  void (*glBlendFunc)( GLenum sfactor, GLenum dfactor );
+  void (*glLogicOp)( GLenum opcode );
+
+  /* 1.3 */
+  void (*glActiveTexture)( GLenum texture );
+
+  /* GL Extentions */
+  void (*glGenBuffers) (GLsizei n, GLuint *buffers);
+  void (*glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+  GLvoid* (*glMapBuffer) (GLenum target, GLenum access);
+  GLboolean (*glUnmapBuffer) (GLenum target);
+  void (*glBindBuffer) (GLenum target, GLuint buffer);
+  void (*glDeleteBuffers) (GLsizei n, const GLuint *buffers);        
+
+  void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+  void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
+  void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers);
+  void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers);          
+  GLenum (*glCheckFramebufferStatus) (GLenum target);
+  void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+  void (*glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+  void (*glDisableVertexAttribArray) (GLuint index);
+  void (*glEnableVertexAttribArray) (GLuint index);
+  void (*glBindAttribLocation) (GLuint program, GLuint index, const GLchar *name);
+
+  void (*glLinkProgram) (GLuint program);
+  void (*glShaderSource) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+  void (*glUseProgram) (GLuint program);
+  void (*glUniform1i) (GLint location, GLint v0);
+  void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+  void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat *value);
+  GLuint (*glCreateProgram) (void);
+  GLuint (*glCreateShader) (GLenum type);
+  void (*glCompileShader) (GLuint shader);
+  void (*glAttachShader) (GLuint program, GLuint shader);
+  void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint *params);
+  void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+  void (*glGetProgramiv) (GLuint program, GLenum pname, GLint *params);
+  void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+  GLint (*glGetUniformLocation) (GLuint program, const GLchar *name);
+
+}glamor_gl_dispatch;
+
+Bool
+glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
+                             int gl_version,
+                             void *(*get_proc_address)(const char*));
+
+
+Bool
+glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version);
+
+
+
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 15fc014..28ad57a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -31,12 +31,13 @@ static void
 _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, 
 				 glamor_pixmap_private *pixmap_priv)
 {
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     GLfloat vertices[8];
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float), vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glUseProgram(glamor_priv->solid_prog);
-    glUniform4fv(glamor_priv->solid_color_uniform_location, 
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(glamor_priv->solid_prog);
+    dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 
       1, pixmap_priv->pending_op.fill.color4fv);
     vertices[0] = -1;
     vertices[1] = -1;
@@ -46,9 +47,9 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
     vertices[5] = 1;
     vertices[6] = -1;
     vertices[7] = 1;
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glUseProgram(0);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(0);
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
 
@@ -83,14 +84,15 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
-  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
 #ifndef GLAMOR_GLES2
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();                                        
+  dispatch->glMatrixMode(GL_PROJECTION);
+  dispatch->glLoadIdentity();
+  dispatch->glMatrixMode(GL_MODELVIEW);
+  dispatch->glLoadIdentity();                                        
 #endif
-  glViewport(0, 0,
+  dispatch->glViewport(0, 0,
 	     pixmap_priv->container->drawable.width,
 	     pixmap_priv->container->drawable.height);
 
@@ -130,59 +132,59 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 
 
 void
-glamor_set_alu(unsigned char alu)
+glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
 {
 #ifndef GLAMOR_GLES2
   if (alu == GXcopy) {
-    glDisable(GL_COLOR_LOGIC_OP);
+    dispatch->glDisable(GL_COLOR_LOGIC_OP);
     return;
   }
-  glEnable(GL_COLOR_LOGIC_OP);
+  dispatch->glEnable(GL_COLOR_LOGIC_OP);
   switch (alu) {
   case GXclear:
-    glLogicOp(GL_CLEAR);
+    dispatch->glLogicOp(GL_CLEAR);
     break;
   case GXand:
-    glLogicOp(GL_AND);
+    dispatch->glLogicOp(GL_AND);
     break;
   case GXandReverse:
-    glLogicOp(GL_AND_REVERSE);
+    dispatch->glLogicOp(GL_AND_REVERSE);
     break;
   case GXandInverted:
-    glLogicOp(GL_AND_INVERTED);
+    dispatch->glLogicOp(GL_AND_INVERTED);
     break;
   case GXnoop:
-    glLogicOp(GL_NOOP);
+    dispatch->glLogicOp(GL_NOOP);
     break;
   case GXxor:
-    glLogicOp(GL_XOR);
+    dispatch->glLogicOp(GL_XOR);
     break;
   case GXor:
-    glLogicOp(GL_OR);
+    dispatch->glLogicOp(GL_OR);
     break;
   case GXnor:
-    glLogicOp(GL_NOR);
+    dispatch->glLogicOp(GL_NOR);
     break;
   case GXequiv:
-    glLogicOp(GL_EQUIV);
+    dispatch->glLogicOp(GL_EQUIV);
     break;
   case GXinvert:
-    glLogicOp(GL_INVERT);
+    dispatch->glLogicOp(GL_INVERT);
     break;
   case GXorReverse:
-    glLogicOp(GL_OR_REVERSE);
+    dispatch->glLogicOp(GL_OR_REVERSE);
     break;
   case GXcopyInverted:
-    glLogicOp(GL_COPY_INVERTED);
+    dispatch->glLogicOp(GL_COPY_INVERTED);
     break;
   case GXorInverted:
-    glLogicOp(GL_OR_INVERTED);
+    dispatch->glLogicOp(GL_OR_INVERTED);
     break;
   case GXnand:
-    glLogicOp(GL_NAND);
+    dispatch->glLogicOp(GL_NAND);
     break;
   case GXset:
-    glLogicOp(GL_SET);
+    dispatch->glLogicOp(GL_SET);
     break;
   default:
     FatalError("unknown logic op\n");
@@ -206,6 +208,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 {
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   unsigned int stride, row_length;
   void *texels;
   GLenum iformat;
@@ -231,24 +234,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
   stride = pixmap->devKind;
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
-  glBindTexture(GL_TEXTURE_2D, tex);
+  dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 
   if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
   } 
   else {
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
   }
 
   if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
     texels = NULL;
-    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
+    dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
   }
   else
     texels = pixmap->devPrivate.ptr;
 
-  glTexImage2D(GL_TEXTURE_2D, 
+  dispatch->glTexImage2D(GL_TEXTURE_2D, 
 	       0, 
 	       iformat,
 	       pixmap->drawable.width, 
@@ -271,6 +274,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   glamor_screen_private *glamor_priv =
     glamor_get_screen_private(pixmap->drawable.pScreen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   static float vertices[8] = {-1, -1,
 			      1, -1,
 			      1,  1,
@@ -303,41 +307,41 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
     ptexcoords = texcoords_inv;
 
   /* Slow path, we need to flip y or wire alpha to 1. */
-  glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         vertices);
-  glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-  glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         ptexcoords);
-  glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
   glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-  glGenTextures(1, &tex);
+  dispatch->glGenTextures(1, &tex);
 
   __glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, tex);
+  dispatch->glActiveTexture(GL_TEXTURE0);
+  dispatch->glBindTexture(GL_TEXTURE_2D, tex);
 
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 #ifndef GLAMOR_GLES2
-  glEnable(GL_TEXTURE_2D);
+  dispatch->glEnable(GL_TEXTURE_2D);
 #endif
-  glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-  glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0);
+  dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+  dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0);
 
-  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+  dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
 #ifndef GLAMOR_GLES2
-  glDisable(GL_TEXTURE_2D);
+  dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-  glUseProgram(0);
-  glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-  glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-  glDeleteTextures(1, &tex);
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+  dispatch->glUseProgram(0);
+  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+  dispatch->glDeleteTextures(1, &tex);
+  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
 void
@@ -345,16 +349,18 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
 {
   int status;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
+
   if (pixmap_priv->fb == 0)
-    glGenFramebuffers(1, &pixmap_priv->fb);
+    dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
   assert(pixmap_priv->tex != 0);
-  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-  glFramebufferTexture2D(GL_FRAMEBUFFER,
+  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+  dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
                          GL_COLOR_ATTACHMENT0,
 			 GL_TEXTURE_2D,
 			 pixmap_priv->tex,
 			 0);
-    status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
+    status = dispatch->glCheckFramebufferStatus (GL_FRAMEBUFFER);
     if (status != GL_FRAMEBUFFER_COMPLETE) {
         const char *str;
         switch (status) {
@@ -387,6 +393,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
   int need_fbo;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
   if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) 
       || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
@@ -404,13 +411,13 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
     need_fbo = 0;
 
   if (pixmap_priv->tex == 0) 
-    glGenTextures(1, &pixmap_priv->tex);
+    dispatch->glGenTextures(1, &pixmap_priv->tex);
 
   if (need_fbo) {
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
+    dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
 		 pixmap->drawable.height, 0,
 		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glamor_pixmap_ensure_fb(pixmap);
@@ -498,6 +505,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
     ScreenPtr screen;
     PixmapPtr temp_pixmap;
     glamor_pixmap_private *temp_pixmap_priv;
+    glamor_gl_dispatch *dispatch;
     static float vertices[8] = {-1, -1,
 			      1, -1,
 			      1,  1,
@@ -513,6 +521,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
 
     glamor_priv = glamor_get_screen_private(screen);
     source_priv = glamor_get_pixmap_private(source);
+    dispatch = &glamor_priv->dispatch;
     if (*format == GL_BGRA) {
       *format = GL_RGBA;
       swap_rb = 1;
@@ -527,36 +536,35 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
 
     temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 
-    glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
-    glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, 
+    dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, 
 		 source->drawable.height, 0,
 		 *format, *type, NULL);
     
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     
-    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         texcoords);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
 
     glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
 
-    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
 
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    glUseProgram(0);
-    glFlush();
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glUseProgram(0);
     return temp_pixmap; 
 }
  
@@ -583,6 +591,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   ScreenPtr screen;
   glamor_screen_private *glamor_priv =
     glamor_get_screen_private(pixmap->drawable.pScreen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   
   screen = pixmap->drawable.pScreen;
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -641,43 +650,43 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
   if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
   }
   else {
-    glPixelStorei(GL_PACK_ALIGNMENT, 4);
-  //  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+    dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+  //  dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   }
-
   if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
 
     if (!glamor_priv->yInverted) {
       assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); 
-      glPixelStorei(GL_PACK_INVERT_MESA, 1);
+      dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
     }
     
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
     if (pixmap_priv->pbo == 0)
-      glGenBuffers (1, &pixmap_priv->pbo);
-    glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
-    glBufferData (GL_PIXEL_PACK_BUFFER,
+      dispatch->glGenBuffers (1, &pixmap_priv->pbo);
+    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
+    dispatch->glBufferData (GL_PIXEL_PACK_BUFFER,
 		     stride * pixmap->drawable.height,
 		     NULL, gl_usage);
-    glReadPixels (0, 0,
+    dispatch->glReadPixels (0, 0,
                     row_length, pixmap->drawable.height,
                     format, type, 0);
-    data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
+    data = dispatch->glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
     pixmap_priv->pbo_valid = TRUE;
 
     if (!glamor_priv->yInverted) {
       assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
-      glPixelStorei(GL_PACK_INVERT_MESA, 0);
+      dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
     }
-    glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+    dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+
     } else {
     if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
       type = GL_UNSIGNED_SHORT_5_5_5_1;
-    glReadPixels (0, 0,
+    dispatch->glReadPixels (0, 0,
                     pixmap->drawable.width, pixmap->drawable.height,
                     format, type, data);
     }
@@ -686,32 +695,31 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     assert(data);
     if (access != GLAMOR_ACCESS_WO) {
       if (pixmap_priv->pbo == 0)
-	glGenBuffers(1, &pixmap_priv->pbo);
-      glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
-      glBufferData(GL_PIXEL_PACK_BUFFER,
+	dispatch->glGenBuffers(1, &pixmap_priv->pbo);
+      dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
+      dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
 		      stride * pixmap->drawable.height,
 		      NULL, GL_STREAM_READ);
-      glReadPixels (0, 0, row_length, pixmap->drawable.height,
+      dispatch->glReadPixels (0, 0, row_length, pixmap->drawable.height,
 		    format, type, 0);
-      read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
+      read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
 	  
       for (y = 0; y < pixmap->drawable.height; y++)
 	memcpy(data + y * stride,
 	       read + (pixmap->drawable.height - y - 1) * stride, stride);
-      glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
-      glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+      dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+      dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
       pixmap_priv->pbo_valid = FALSE;
-      glDeleteBuffers(1, &pixmap_priv->pbo);
+      dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
       pixmap_priv->pbo = 0;
     }
   }
 
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+  dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
 done:
   pixmap->devPrivate.ptr = data;
 
   if (temp_pixmap) { 
-      glFlush();
       (*screen->DestroyPixmap)(temp_pixmap);
   }
 
@@ -724,14 +732,15 @@ static void
 _glamor_destroy_upload_pixmap(PixmapPtr pixmap)
 {
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
 
   assert(pixmap_priv->gl_fbo == 0);
   if (pixmap_priv->fb)
-    glDeleteFramebuffers(1, &pixmap_priv->fb);
+    dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
   if (pixmap_priv->tex)
-    glDeleteTextures(1, &pixmap_priv->tex);
+    dispatch->glDeleteTextures(1, &pixmap_priv->tex);
   if (pixmap_priv->pbo)
-    glDeleteBuffers(1, &pixmap_priv->pbo);
+    dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
   pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
 
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 325fa43..0cbc258 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -178,6 +178,8 @@ enum shader_in {
   SHADER_IN_COUNT,
 };
 
+#include "glamor_gl_dispatch.h"
+
 struct glamor_screen_private;
 struct glamor_pixmap_private;
 typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, 
@@ -251,6 +253,7 @@ typedef struct glamor_screen_private {
   glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
   Bool glyph_cache_initialized;
 
+  struct glamor_gl_dispatch dispatch; 
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -310,18 +313,18 @@ typedef struct glamor_pixmap_private {
   PictFormatShort pict_format;
   glamor_pending_op pending_op;
   PixmapPtr container;
+  glamor_screen_private *glamor_priv;
 } glamor_pixmap_private;
 
-#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \
+#define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \
   { \
       if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
-        glUseProgram(_glamor_priv_->solid_prog); \
-        glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
+        _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \
+        _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
                         _pixmap_priv_->pending_op.fill.color4fv); \
       } \
   } while(0)
  
-
 /* 
  * Pixmap dynamic status, used by dynamic upload feature.
  *
@@ -752,8 +755,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    unsigned char alu, unsigned long planemask,
 		    unsigned long fg_pixel, unsigned long bg_pixel,
 		    int stipple_x, int stipple_y);
-GLint glamor_compile_glsl_prog(GLenum type, const char *source);
-void glamor_link_glsl_prog(GLint prog);
+GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source);
+void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 				    GLfloat *color);
 
@@ -770,7 +773,7 @@ PixmapPtr
 glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, 
                                GLenum *type, int no_alpha, int no_revert);
 
-void glamor_set_alu(unsigned char alu);
+void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 void glamor_get_transform_uniform_locations(GLint prog,
 					    glamor_transform_uniforms *uniform_locations);
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index a7a6186..cdcde5e 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -67,25 +67,25 @@ glamor_init_putimage_shaders(ScreenPtr screen)
     if (!GLEW_ARB_fragment_shader)
 	return;
 
-    prog = glCreateProgram();
+    prog = dispatch->glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
-    glAttachShader(prog, vs_prog);
-    glAttachShader(prog, fs_prog);
+    dispatch->glAttachShader(prog, vs_prog);
+    dispatch->glAttachShader(prog, fs_prog);
     glamor_link_glsl_prog(prog);
 
-    glUseProgram(prog);
-    sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler");
-    glUniform1i(sampler_uniform_location, 0);
+    dispatch->glUseProgram(prog);
+    sampler_uniform_location = dispatch->glGetUniformLocation(prog, "bitmap_sampler");
+    dispatch->glUniform1i(sampler_uniform_location, 0);
 
     glamor_priv->put_image_xybitmap_fg_uniform_location =
-	glGetUniformLocation(prog, "fg");
+	dispatch->glGetUniformLocation(prog, "fg");
     glamor_priv->put_image_xybitmap_bg_uniform_location =
-	glGetUniformLocation(prog, "bg");
+	dispatch->glGetUniformLocation(prog, "bg");
     glamor_get_transform_uniform_locations(prog,
 					   &glamor_priv->put_image_xybitmap_transform);
     glamor_priv->put_image_xybitmap_prog = prog;
-    glUseProgram(0);
+    dispatch->glUseProgram(0);
 #endif
 }
 
@@ -162,42 +162,42 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     if (!glamor_set_planemask(pixmap, gc->planemask))
 	goto fail;
 
-    glUseProgram(glamor_priv->put_image_xybitmap_prog);
+    dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
 
     glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
-    glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location,
+    dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location,
 		    1, fg);
     glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
-    glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location,
+    dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location,
 		    1, bg);
 
-    glGenTextures(1, &tex);
-    glActiveTexture(GL_TEXTURE0);
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
-    glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+    dispatch->glGenTextures(1, &tex);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glEnable(GL_TEXTURE_2D);
+    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
+    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
 		 w, h, 0,
 		 GL_COLOR_INDEX, GL_BITMAP, bits);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-    glEnable(GL_TEXTURE_2D);
+    dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    dispatch->glEnable(GL_TEXTURE_2D);
 
     /* Now that we've set up our bitmap texture and the shader, shove
      * the destination rectangle through the cliprects and run the
      * shader on the resulting fragments.
      */
-    glVertexPointer(2, GL_FLOAT, 0, dest_coords);
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
+    dispatch->glEnableClientState(GL_VERTEX_ARRAY);
+    dispatch->glClientActiveTexture(GL_TEXTURE0);
+    dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
+    dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-    glEnable(GL_SCISSOR_TEST);
+    dispatch->glEnable(GL_SCISSOR_TEST);
     clip = fbGetCompositeClip(gc);
     for (nbox = REGION_NUM_RECTS(clip),
 	 box = REGION_RECTS(clip);
@@ -220,20 +220,20 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	if (x1 >= x2 || y1 >= y2)
 	    continue;
 
-	glScissor(box->x1,
+	dispatch->glScissor(box->x1,
 		  y_flip(pixmap, box->y1),
 		  box->x2 - box->x1,
 		  box->y2 - box->y1);
-	glDrawArrays(GL_QUADS, 0, 4);
+	dispatch->glDrawArrays(GL_QUADS, 0, 4);
     }
 
-    glDisable(GL_SCISSOR_TEST);
+    dispatch->glDisable(GL_SCISSOR_TEST);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
-    glDeleteTextures(1, &tex);
-    glDisable(GL_TEXTURE_2D);
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    dispatch->glDeleteTextures(1, &tex);
+    dispatch->glDisable(GL_TEXTURE_2D);
+    dispatch->glDisableClientState(GL_VERTEX_ARRAY);
+    dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     return;
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
@@ -254,6 +254,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 {
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(drawable->pScreen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     GLenum type, format, iformat;
@@ -285,7 +286,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     if (!glamor_set_planemask(pixmap, gc->planemask)) {
 	goto fail;
     }
-    glamor_set_alu(gc->alu);
+    glamor_set_alu(dispatch, gc->alu);
 
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
@@ -301,29 +302,29 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     /* XXX consider to reuse a function to do the following work. */
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     
-    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         texcoords);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-      glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
+      dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
   		    pixmap->drawable.bitsPerPixel);
     }
     else {
-      glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-//      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+      dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+//      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     }
     
-    glGenTextures(1, &tex);
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, tex);
+    dispatch->glGenTextures(1, &tex);
+    dispatch->glActiveTexture(GL_TEXTURE0);
+    dispatch->glBindTexture(GL_TEXTURE_2D, tex);
     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
       iformat = format;
     } 
@@ -331,19 +332,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
       iformat = GL_RGBA;
     }
 
-    glTexImage2D(GL_TEXTURE_2D, 0, iformat,
+    dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
 		 w, h, 0,
 		 format, type, bits);
 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 #ifndef GLAMOR_GLES2
-    glEnable(GL_TEXTURE_2D);
+    dispatch->glEnable(GL_TEXTURE_2D);
 #endif
 
-    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-    glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
-      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
+    dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
 
     x += drawable->x;
     y += drawable->y;
@@ -388,19 +389,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 				      glamor_priv->yInverted,
 				      vertices);
 
-	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
 #ifndef GLAMOR_GLES2
-    glDisable(GL_TEXTURE_2D);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-    glUseProgram(0);
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    glDeleteTextures(1, &tex);
+    dispatch->glUseProgram(0);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDeleteTextures(1, &tex);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
-      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    glamor_set_alu(GXcopy);
+      dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glamor_set_alu(dispatch, GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return;
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 258a09b..d649c98 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -68,7 +68,7 @@ static struct blendinfo composite_op_info[] = {
 };
 
 static GLuint
-glamor_create_composite_fs(struct shader_key *key)
+glamor_create_composite_fs(glamor_gl_dispatch *dispatch, struct shader_key *key)
 {
   const char *source_solid_fetch =
     GLAMOR_DEFAULT_PRECISION
@@ -200,14 +200,14 @@ glamor_create_composite_fs(struct shader_key *key)
 	      in);
  
 
-  prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
+  prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
   free(source);
 
   return prog;
 }
 
 static GLuint
-glamor_create_composite_vs(struct shader_key *key)
+glamor_create_composite_vs(glamor_gl_dispatch *dispatch, struct shader_key *key)
 {
   const char *main_opening =
     "attribute vec4 v_position;\n"
@@ -242,7 +242,7 @@ glamor_create_composite_vs(struct shader_key *key)
 	      mask_coords_setup,
 	      main_closing);
 
-  prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source);
+  prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
   free(source);
 
   return prog;
@@ -254,45 +254,47 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 {
   GLuint vs, fs, prog;
   GLint source_sampler_uniform_location, mask_sampler_uniform_location;
+  glamor_screen_private *glamor = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor->dispatch;
 
-  vs = glamor_create_composite_vs(key);
+  vs = glamor_create_composite_vs(dispatch, key);
   if (vs == 0)
     return;
-  fs = glamor_create_composite_fs(key);
+  fs = glamor_create_composite_fs(dispatch, key);
   if (fs == 0)
     return;
 
-  prog = glCreateProgram();
-  glAttachShader(prog, vs);
-  glAttachShader(prog, fs);
+  prog = dispatch->glCreateProgram();
+  dispatch->glAttachShader(prog, vs);
+  dispatch->glAttachShader(prog, fs);
 
-  glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
-  glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
+  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
+  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
 
-  glamor_link_glsl_prog(prog);
+  glamor_link_glsl_prog(dispatch, prog);
 
   shader->prog = prog;
 
-  glUseProgram(prog);
+  dispatch->glUseProgram(prog);
 
   if (key->source == SHADER_SOURCE_SOLID) {
-    shader->source_uniform_location = glGetUniformLocation(prog,
+    shader->source_uniform_location = dispatch->glGetUniformLocation(prog,
 							      "source");
   } else {
-    source_sampler_uniform_location = glGetUniformLocation(prog,
+    source_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
 							      "source_sampler");
-    glUniform1i(source_sampler_uniform_location, 0);
+    dispatch->glUniform1i(source_sampler_uniform_location, 0);
   }
 
   if (key->mask != SHADER_MASK_NONE) {
     if (key->mask == SHADER_MASK_SOLID) {
-      shader->mask_uniform_location = glGetUniformLocation(prog,
+      shader->mask_uniform_location = dispatch->glGetUniformLocation(prog,
 							      "mask");
     } else {
-      mask_sampler_uniform_location = glGetUniformLocation(prog,
+      mask_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
 							      "mask_sampler");
-      glUniform1i(mask_sampler_uniform_location, 1);
+      dispatch->glUniform1i(mask_sampler_uniform_location, 1);
     }
   }
 }
@@ -336,6 +338,8 @@ glamor_set_composite_op(ScreenPtr screen,
 {
   GLenum source_blend, dest_blend;
   struct blendinfo *op_info;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
   if (op >= ARRAY_SIZE(composite_op_info)) {
     glamor_fallback("unsupported render op %d \n", op);
@@ -370,10 +374,10 @@ glamor_set_composite_op(ScreenPtr screen,
   }
 
   if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
-    glDisable(GL_BLEND);
+    dispatch->glDisable(GL_BLEND);
   } else {
-    glEnable(GL_BLEND);
-    glBlendFunc(source_blend, dest_blend);
+    dispatch->glEnable(GL_BLEND);
+    dispatch->glBlendFunc(source_blend, dest_blend);
   }
   return TRUE;
 }
@@ -382,50 +386,52 @@ static void
 glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
 			     glamor_pixmap_private *pixmap_priv)
 {
-  glActiveTexture(GL_TEXTURE0 + unit);
-  glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+  dispatch->glActiveTexture(GL_TEXTURE0 + unit);
+  dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
   switch (picture->repeatType) {
   case RepeatNone:
 #ifndef GLAMOR_GLES2
     /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 #endif
     break;
   case RepeatNormal:
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     break;
   case RepeatPad:
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     break;
   case RepeatReflect:
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+    dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
     break;
   }
 
   switch (picture->filter) {
   case PictFilterNearest:
-    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     break;
   case PictFilterBilinear:
   default:
-    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     break;
   }
 #ifndef GLAMOR_GLES2
-  glEnable(GL_TEXTURE_2D);
+  dispatch->glEnable(GL_TEXTURE_2D);
 #endif
 }
 
 static void
-glamor_set_composite_solid(float *color, GLint uniform_location)
+glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color, GLint uniform_location)
 {
-  glUniform4fv(uniform_location, 1, color);
+  dispatch->glUniform4fv(uniform_location, 1, color);
 }
 
 static int
@@ -525,6 +531,7 @@ static void
 glamor_setup_composite_vbo(ScreenPtr screen)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
   glamor_priv->vb_stride = 2 * sizeof(float);
   if (glamor_priv->has_source_coords)
@@ -532,27 +539,27 @@ glamor_setup_composite_vbo(ScreenPtr screen)
   if (glamor_priv->has_mask_coords)
     glamor_priv->vb_stride += 2 * sizeof(float);
 
-  glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+  dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 
-  glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
+  dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset));
-  glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+  dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
   if (glamor_priv->has_source_coords) {
-    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float)));
-    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
   }
 
   if (glamor_priv->has_mask_coords) {
-    glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, 
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset + 
 			       (glamor_priv->has_source_coords ? 4 : 2) *
                                sizeof(float)));
-    glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
   }
 }
 
@@ -586,13 +593,13 @@ static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   if (!glamor_priv->render_nr_verts)
     return;
-  glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
+  dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
 	    GL_STREAM_DRAW);
 
-  glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
+  dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
   glamor_reset_composite_vbo(screen);
 }
 
@@ -603,6 +610,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
 			   const float *dst_coords)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
   if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
       glamor_priv->vbo_size)
@@ -612,7 +620,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
 
   if (glamor_priv->vbo_offset == 0) {
     if (glamor_priv->vbo == 0)
-      glGenBuffers(1, &glamor_priv->vbo);
+      dispatch->glGenBuffers(1, &glamor_priv->vbo);
 
     glamor_setup_composite_vbo(screen);
   }
@@ -700,6 +708,7 @@ glamor_composite_with_shader(CARD8 op,
 {
   ScreenPtr screen = dest->pDrawable->pScreen;
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
   PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
   PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
   glamor_pixmap_private *source_pixmap_priv = NULL;
@@ -914,17 +923,17 @@ glamor_composite_with_shader(CARD8 op,
     goto fail;
   }
 
-  glUseProgram(shader->prog);
+  dispatch->glUseProgram(shader->prog);
 
 
   if (key.source == SHADER_SOURCE_SOLID) {
-    glamor_set_composite_solid(source_solid_color, shader->source_uniform_location);
+    glamor_set_composite_solid(dispatch, source_solid_color, shader->source_uniform_location);
   } else {
     glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
   }
   if (key.mask != SHADER_MASK_NONE) {
     if (key.mask == SHADER_MASK_SOLID) {
-      glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location);
+      glamor_set_composite_solid(dispatch, mask_solid_color, shader->mask_uniform_location);
     } else {
       glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
     }
@@ -1042,19 +1051,19 @@ glamor_composite_with_shader(CARD8 op,
   }
   glamor_flush_composite_rects(screen);
 
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-  glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-  glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+  dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
+  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+  dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
   REGION_UNINIT(dst->pDrawable->pScreen, &region);
-  glDisable(GL_BLEND);
+  dispatch->glDisable(GL_BLEND);
 #ifndef GLAMOR_GLES2
-  glActiveTexture(GL_TEXTURE0);
-  glDisable(GL_TEXTURE_2D);
-  glActiveTexture(GL_TEXTURE1);
-  glDisable(GL_TEXTURE_2D);
+  dispatch->glActiveTexture(GL_TEXTURE0);
+  dispatch->glDisable(GL_TEXTURE_2D);
+  dispatch->glActiveTexture(GL_TEXTURE1);
+  dispatch->glDisable(GL_TEXTURE_2D);
 #endif
-  glUseProgram(0);
+  dispatch->glUseProgram(0);
   if (saved_source_format) 
     source->format = saved_source_format;
   return TRUE;
@@ -1063,8 +1072,8 @@ glamor_composite_with_shader(CARD8 op,
   if (saved_source_format) 
     source->format = saved_source_format;
 
-  glDisable(GL_BLEND);
-  glUseProgram(0);
+  dispatch->glDisable(GL_BLEND);
+  dispatch->glUseProgram(0);
   return FALSE;
 }
 
@@ -1138,6 +1147,7 @@ glamor_composite(CARD8 op,
   int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
   glamor_composite_rect_t rect;
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
   x_temp_src = x_source;
   y_temp_src = y_source;
@@ -1257,8 +1267,8 @@ fail:
 		  dest->pDrawable->height,
 		  glamor_get_picture_location(dest));
 
-  glUseProgram(0);
-  glDisable(GL_BLEND);
+  dispatch->glUseProgram(0);
+  dispatch->glDisable(GL_BLEND);
   if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
     if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
       {
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 8b2676b..bb4bffd 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -36,7 +36,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 DDXPointPtr points, int *widths, int n, int sorted)
 {
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_screen_private *glamor_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     GLenum format, type;
     int no_alpha, no_revert, i;
     uint8_t *drawpixels_src = (uint8_t *)src;
@@ -44,8 +45,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     BoxRec *pbox;
     int x_off, y_off;
 
-    glamor_priv = glamor_get_screen_private(drawable->pScreen);
-
     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
       glamor_fallback("ES2 fallback.\n");
       goto fail;
@@ -69,7 +68,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     glamor_validate_pixmap(dest_pixmap);
     if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 	goto fail;
-    glamor_set_alu(gc->alu);
+    glamor_set_alu(dispatch, gc->alu);
     if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 	goto fail;
 
@@ -82,14 +81,14 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	while (n--) {
 	    if (pbox->y1 > points[i].y)
 		break;
-	    glScissor(pbox->x1,
+	    dispatch->glScissor(pbox->x1,
 		      points[i].y + y_off,
 		      pbox->x2 - pbox->x1,
 		      1);
-	    glEnable(GL_SCISSOR_TEST);
-	    glRasterPos2i(points[i].x + x_off,
+	    dispatch->glEnable(GL_SCISSOR_TEST);
+	    dispatch->glRasterPos2i(points[i].x + x_off,
 			  points[i].y + y_off);
-	    glDrawPixels(widths[i],
+	    dispatch->glDrawPixels(widths[i],
 			 1,
 			 format, type,
 			 drawpixels_src);
@@ -97,8 +96,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
     }
     glamor_set_planemask(dest_pixmap, ~0);
-    glamor_set_alu(GXcopy);
-    glDisable(GL_SCISSOR_TEST);
+    glamor_set_alu(dispatch, GXcopy);
+    dispatch->glDisable(GL_SCISSOR_TEST);
     return;
 fail:
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index c184dac..687cc6a 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -40,6 +40,7 @@ void
 glamor_init_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     const char *tile_vs =
         "attribute vec4 v_position;\n"
         "attribute vec4 v_texcoord0;\n"
@@ -60,21 +61,21 @@ glamor_init_tile_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
     GLint sampler_uniform_location;
 
-    glamor_priv->tile_prog = glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
-    glAttachShader(glamor_priv->tile_prog, vs_prog);
-    glAttachShader(glamor_priv->tile_prog, fs_prog);
+    glamor_priv->tile_prog = dispatch->glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
+    fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs);
+    dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
+    dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
 
-    glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position");
-    glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-    glamor_link_glsl_prog(glamor_priv->tile_prog);
+    dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position");
+    dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+    glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
 
     sampler_uniform_location =
-	glGetUniformLocation(glamor_priv->tile_prog, "sampler");
-    glUseProgram(glamor_priv->tile_prog);
-    glUniform1i(sampler_uniform_location, 0);
-    glUseProgram(0);
+	dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler");
+    dispatch->glUseProgram(glamor_priv->tile_prog);
+    dispatch->glUniform1i(sampler_uniform_location, 0);
+    dispatch->glUseProgram(0);
 }
 
 Bool
@@ -85,6 +86,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
     int x1 = x;
     int x2 = x + width;
     int y1 = y;
@@ -135,33 +137,33 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_validate_pixmap(pixmap);
     pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
 
-    glamor_set_alu(alu);
+    glamor_set_alu(dispatch, alu);
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-      glUseProgram(glamor_priv->tile_prog);
+      dispatch->glUseProgram(glamor_priv->tile_prog);
  
-      glActiveTexture(GL_TEXTURE0);
-      glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+      dispatch->glActiveTexture(GL_TEXTURE0);
+      dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+      dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 #ifndef GLAMOR_GLES2
-      glEnable(GL_TEXTURE_2D);
+      dispatch->glEnable(GL_TEXTURE_2D);
 #endif
       glamor_set_normalize_tcoords(src_xscale, src_yscale,
 				 tile_x1, tile_y1,
 				 tile_x2, tile_y2,
 				 glamor_priv->yInverted,
 				 source_texcoords);
-      glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+      dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                             2 * sizeof(float),
                             source_texcoords);
-      glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+      dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
    } 
    else {
-     GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
+     GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
    }
  
     glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
@@ -169,21 +171,21 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				 glamor_priv->yInverted,
 				 vertices);
 
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+    dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float),
                          vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #ifndef GLAMOR_GLES2
-    glDisable(GL_TEXTURE_2D);
+    dispatch->glDisable(GL_TEXTURE_2D);
 #endif
     }
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glUseProgram(0);
-    glamor_set_alu(GXcopy);
+    dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    dispatch->glUseProgram(0);
+    glamor_set_alu(dispatch, GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return TRUE;
 
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 9c9be89..90357d2 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -584,6 +584,18 @@ glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin)
    }
 }
 
+Bool
+glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
+{
+        ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+        struct glamor_screen_private *glamor_egl = glamor_get_screen_private(scrn);
+        if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
+          return FALSE;
+        glamor_egl->dispatch = dispatch;
+        return TRUE;
+}
+
+
 static XF86ModuleVersionInfo glamor_version_info = {
 	glamor_name,
 	MODULEVENDORSTRING,
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 6d9e410..2c14ca1 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -16,6 +16,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include "glamor_gl_dispatch.h"
 struct glamor_screen_private {
 	EGLDisplay display;
 	EGLContext context;
@@ -30,6 +31,7 @@ struct glamor_screen_private {
 	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
+        struct glamor_gl_dispatch *dispatch;
 };
 
 inline struct glamor_screen_private *
commit 7daf9af086624133d6c4857ed92d57ad2a492d86
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 31 17:43:46 2011 +0800

    glamor: Let GLAMOR_DDX implicit GLAMOR.
    
    If user only enable GLAMOR_DDX, he must also want GLAMOR.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index 82c845b..80daf82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1772,7 +1772,11 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 
 dnl glamor 
 
-AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes || test "x$GLAMOR" = xyes])
+if [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes] ; then
+   GLAMOR=yes
+fi
+
+AM_CONDITIONAL([GLAMOR], [test "x$GLAMOR" = xyes])
 AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes])
 AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes])
 
commit f08988455cd4f6339187e74df8edb5783b61f8fa
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 30 18:24:53 2011 +0800

    glamor: Route UnrealizeGlyph to glamor_glyph_unrealize.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 53fe71d..c0f9d51 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -359,6 +359,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     ps->CreatePicture = glamor_create_picture;
     glamor_priv->saved_destroy_picture = ps->DestroyPicture; 
     ps->DestroyPicture = glamor_destroy_picture;
+
+    glamor_priv->saved_unrealize_glyph = ps->UnrealizeGlyph;
+    ps->UnrealizeGlyph = glamor_glyph_unrealize;
 #endif
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 76e21ea..325fa43 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -205,6 +205,7 @@ typedef struct glamor_screen_private {
   TrianglesProcPtr saved_triangles;
   CreatePictureProcPtr saved_create_picture;
   DestroyPictureProcPtr saved_destroy_picture;
+  UnrealizeGlyphProcPtr saved_unrealize_glyph;
 
   int yInverted;
   int screen_fbo;
@@ -828,6 +829,8 @@ void glamor_glyphs(CARD8 op,
 		   INT16 xSrc,
 		   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
 
+void
+glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph);
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		      DDXPointPtr points, int *widths, int n, int sorted);
commit 16659622708db82caaeb12527ba09545ad15b4c3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 30 17:45:07 2011 +0800

    glamor: Improve glyphs cache mechanism.
    
    This commit applying the latest uxa's glyphs cache mechanism
    and give up the old hash based cache algorithm. And the cache
    picture now is much larger than the previous one also.
    
    This new algorithm can avoid the hash insert/remove and also
    the expensive sha1 checking. It could obtain about 10%
    performance gain when rendering glyphs.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 63ffd20..af6ec71 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -60,13 +60,16 @@
  * max texture size of the driver; this may need to actually come from
  * the driver.
  */
-#define CACHE_PICTURE_WIDTH 1024
 
 /* Maximum number of glyphs we buffer on the stack before flushing
  * rendering to the mask or destination surface.
  */
-#define GLYPH_BUFFER_SIZE 256
+#define GLYPH_BUFFER_SIZE 1024
 
+#define CACHE_PICTURE_SIZE  1024 
+#define GLYPH_MIN_SIZE 8
+#define GLYPH_MAX_SIZE 64
+#define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
 
 typedef struct {
     PicturePtr source;
@@ -74,76 +77,64 @@ typedef struct {
     int count;
 } glamor_glyph_buffer_t;
 
+struct glamor_glyph
+{
+  glamor_glyph_cache_t *cache;
+  uint16_t x, y;
+  uint16_t size, pos;
+};
+
 typedef enum {
     GLAMOR_GLYPH_SUCCESS,	/* Glyph added to render buffer */
     GLAMOR_GLYPH_FAIL,		/* out of memory, etc */
     GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
 } glamor_glyph_cache_result_t;
 
-void glamor_glyphs_init(ScreenPtr screen)
+
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+static DevPrivateKeyRec glamor_glyph_key;
+
+static inline struct glamor_glyph *
+glamor_glyph_get_private (GlyphPtr glyph)
 {
-    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
-    int i = 0;
-
-    memset(glamor_screen->glyph_caches, 0, sizeof(glamor_screen->glyph_caches));
-
-    glamor_screen->glyph_caches[i].format = PICT_a8;
-    glamor_screen->glyph_caches[i].glyph_width =
-	glamor_screen->glyph_caches[i].glyph_height = 16;
-    i++;
-    glamor_screen->glyph_caches[i].format = PICT_a8;
-    glamor_screen->glyph_caches[i].glyph_width =
-	glamor_screen->glyph_caches[i].glyph_height = 32;
-    i++;
-    glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8;
-    glamor_screen->glyph_caches[i].glyph_width =
-	glamor_screen->glyph_caches[i].glyph_height = 16;
-    i++;
-    glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8;
-    glamor_screen->glyph_caches[i].glyph_width =
-	glamor_screen->glyph_caches[i].glyph_height = 32;
-    i++;
-
-    assert(i == GLAMOR_NUM_GLYPH_CACHES);
-
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_screen->glyph_caches[i].columns =
-	    CACHE_PICTURE_WIDTH / glamor_screen->glyph_caches[i].glyph_width;
-	glamor_screen->glyph_caches[i].size = 256;
-	glamor_screen->glyph_caches[i].hash_size = 557;
-    }
+  return dixGetPrivate (&glyph->devPrivates, &glamor_glyph_key);
 }
 
-static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format)
+static inline void
+glamor_glyph_set_private (GlyphPtr glyph, struct glamor_glyph *priv)
 {
-    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
-    int i;
+  dixSetPrivate (&glyph->devPrivates, &glamor_glyph_key, priv);
+}
 
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
 
-	if (cache->format != format)
-	    continue;
+static void
+glamor_unrealize_glyph_caches (ScreenPtr pScreen)
+{
+  glamor_screen_private *glamor = glamor_get_screen_private (pScreen);
+  int i;
 
-	if (cache->picture) {
-	    FreePicture((pointer) cache->picture, (XID) 0);
-	    cache->picture = NULL;
-	}
+  if (!glamor->glyph_cache_initialized)
+    return;
 
-	if (cache->hash_entries) {
-	    free(cache->hash_entries);
-	    cache->hash_entries = NULL;
-	}
+  for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++)
+    {
+      glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
 
-	if (cache->glyphs) {
-	    free(cache->glyphs);
-	    cache->glyphs = NULL;
-	}
-	cache->glyph_count = 0;
+      if (cache->picture)
+	FreePicture (cache->picture, 0);
+
+      if (cache->glyphs)
+	free (cache->glyphs);
     }
+  glamor->glyph_cache_initialized = FALSE;
 }
 
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+void
+glamor_glyphs_fini (ScreenPtr pScreen)
+{
+  glamor_unrealize_glyph_caches (pScreen);
+}
 
 /* All caches for a single format share a single pixmap for glyph storage,
  * allowing mixing glyphs of different sizes without paying a penalty
@@ -154,730 +145,716 @@ static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format)
  * This function allocates the storage pixmap, and then fills in the
  * rest of the allocated structures for all caches with the given format.
  */
-static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format)
+static Bool
+glamor_realize_glyph_caches (ScreenPtr pScreen)
 {
-    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
-    int depth = PIXMAN_FORMAT_DEPTH(format);
-    PictFormatPtr pict_format;
-    PixmapPtr pixmap;
-    PicturePtr picture;
-    CARD32 component_alpha;
-    int height;
-    int i;
-    int error;
-
-    pict_format = PictureMatchFormat(screen, depth, format);
-    if (!pict_format)
-	return FALSE;
-
-    /* Compute the total vertical size needed for the format */
-
-    height = 0;
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
-	int rows;
-
-	if (cache->format != format)
-	    continue;
-
-	cache->y_offset = height;
+  glamor_screen_private *glamor = glamor_get_screen_private (pScreen);
+  unsigned int formats[] = {
+    PIXMAN_a8,
+    PIXMAN_a8r8g8b8,
+  };
+  int i;
+
+  if (glamor->glyph_cache_initialized)
+    return TRUE;
 
-	rows = (cache->size + cache->columns - 1) / cache->columns;
-	height += rows * cache->glyph_height;
+  glamor->glyph_cache_initialized = TRUE;
+  memset (glamor->glyphCaches, 0, sizeof (glamor->glyphCaches));
+
+  for (i = 0; i < sizeof (formats) / sizeof (formats[0]); i++)
+    {
+      glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
+      PixmapPtr pixmap;
+      PicturePtr picture;
+      CARD32 component_alpha;
+      int depth = PIXMAN_FORMAT_DEPTH (formats[i]);
+      int error;
+      PictFormatPtr pPictFormat =
+	PictureMatchFormat (pScreen, depth, formats[i]);
+      if (!pPictFormat)
+	goto bail;
+
+      /* Now allocate the pixmap and picture */
+      pixmap = pScreen->CreatePixmap (pScreen,
+				      CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
+				      depth, 0);
+      if (!pixmap)
+	goto bail;
+
+      component_alpha = NeedsComponent (pPictFormat->format);
+      picture = CreatePicture (0, &pixmap->drawable, pPictFormat,
+			       CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+
+      pScreen->DestroyPixmap (pixmap);
+      if (!picture)
+	goto bail;
+
+      ValidatePicture (picture);
+
+      cache->picture = picture;
+      cache->glyphs = calloc (sizeof (GlyphPtr), GLYPH_CACHE_SIZE);
+      if (!cache->glyphs)
+	goto bail;
+
+      cache->evict = rand () % GLYPH_CACHE_SIZE;
     }
+  assert (i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
 
-    /* Now allocate the pixmap and picture */
-
-    pixmap = screen->CreatePixmap(screen,
-				  CACHE_PICTURE_WIDTH,
-				  height, depth,
-				  0);
-    if (!pixmap)
-	return FALSE;
+  return TRUE;
 
-    component_alpha = NeedsComponent(pict_format->format);
-    picture = CreatePicture(0, &pixmap->drawable, pict_format,
-			    CPComponentAlpha, &component_alpha,
-			    serverClient, &error);
-
-    screen->DestroyPixmap(pixmap);	/* picture holds a refcount */
+bail:
+  glamor_unrealize_glyph_caches (pScreen);
+  return FALSE;
+}
 
-    if (!picture)
-	return FALSE;
 
-    /* And store the picture in all the caches for the format */
+Bool
+glamor_glyphs_init (ScreenPtr pScreen)
+{
+  if (!dixRegisterPrivateKey (&glamor_glyph_key, PRIVATE_GLYPH, 0))
+    return FALSE;
 
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
-	int j;
+  /* Skip pixmap creation if we don't intend to use it. */
 
-	if (cache->format != format)
-	    continue;
+  return glamor_realize_glyph_caches (pScreen);
+}
 
-	cache->picture = picture;
-	cache->picture->refcnt++;
-	cache->hash_entries = malloc(sizeof(int) * cache->hash_size);
-	cache->glyphs =
-	    malloc(sizeof(glamor_cached_glyph_t) * cache->size);
-	cache->glyph_count = 0;
+/* The most efficient thing to way to upload the glyph to the screen
+ * is to use CopyArea; glamor pixmaps are always offscreen.
+ */
+static void
+glamor_glyph_cache_upload_glyph (ScreenPtr screen,
+				 glamor_glyph_cache_t * cache,
+				 GlyphPtr glyph, int x, int y)
+{
+  PicturePtr pGlyphPicture = GlyphPicture (glyph)[screen->myNum];
+  PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
+  PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
+  PixmapPtr scratch;
+  GCPtr gc;
 
-	if (!cache->hash_entries || !cache->glyphs)
-	    goto bail;
+  gc = GetScratchGC (pCachePixmap->drawable.depth, screen);
+  if (!gc)
+    return;
 
-	for (j = 0; j < cache->hash_size; j++)
-	    cache->hash_entries[j] = -1;
+  ValidateGC (&pCachePixmap->drawable, gc);
 
-	cache->eviction_position = rand() % cache->size;
+  scratch = pGlyphPixmap;
+#if 0
+  /* Create a temporary bo to stream the updates to the cache */
+  if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth ||
+      !uxa_pixmap_is_offscreen (scratch))
+    {
+      scratch = screen->CreatePixmap (screen,
+				      glyph->info.width,
+				      glyph->info.height,
+				      pCachePixmap->drawable.depth, 0);
+      if (scratch)
+	{
+	  if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth)
+	    {
+	      PicturePtr picture;
+	      int error;
+
+	      picture = CreatePicture (0, &scratch->drawable,
+				       PictureMatchFormat (screen,
+							   pCachePixmap->
+							   drawable.depth,
+							   cache->picture->
+							   format), 0, NULL,
+				       serverClient, &error);
+	      if (picture)
+		{
+		  ValidatePicture (picture);
+		  uxa_composite (PictOpSrc, pGlyphPicture, NULL, picture,
+				 0, 0,
+				 0, 0,
+				 0, 0, glyph->info.width, glyph->info.height);
+		  FreePicture (picture, 0);
+		}
+	    }
+	  else
+	    {
+	      glamor_copy_area (&pGlyphPixmap->drawable,
+				&scratch->drawable,
+				gc,
+				0, 0,
+				glyph->info.width, glyph->info.height, 0, 0);
+	    }
+	}
+      else
+	{
+	  scratch = pGlyphPixmap;
+	}
     }
+#endif
+  glamor_copy_area (&scratch->drawable, &pCachePixmap->drawable, gc,
+		    0, 0, glyph->info.width, glyph->info.height, x, y);
 
-    /* Each cache references the picture individually */
-    FreePicture(picture, 0);
-    return TRUE;
+  if (scratch != pGlyphPixmap)
+    screen->DestroyPixmap (scratch);
 
- bail:
-    glamor_unrealize_glyph_caches(screen, format);
-    return FALSE;
+  FreeScratchGC (gc);
 }
 
-void glamor_glyphs_fini(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
-    int i;
-
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
 
-	if (cache->picture)
-	    glamor_unrealize_glyph_caches(screen, cache->format);
-    }
-}
-
-static int
-glamor_glyph_cache_hash_lookup(glamor_glyph_cache_t * cache, GlyphPtr glyph)
+void
+glamor_glyph_unrealize (ScreenPtr screen, GlyphPtr glyph)
 {
-    int slot;
+  struct glamor_glyph *priv;
 
-    slot = (*(CARD32 *) glyph->sha1) % cache->hash_size;
+  /* Use Lookup in case we have not attached to this glyph. */
+  priv = dixLookupPrivate (&glyph->devPrivates, &glamor_glyph_key);
+  if (priv == NULL)
+    return;
 
-    while (TRUE) {		/* hash table can never be full */
-	int entryPos = cache->hash_entries[slot];
-	if (entryPos == -1)
-	    return -1;
+  priv->cache->glyphs[priv->pos] = NULL;
 
-	if (memcmp(glyph->sha1, cache->glyphs[entryPos].sha1,
-		   sizeof(glyph->sha1)) == 0) {
-	    return entryPos;
-	}
-
-	slot--;
-	if (slot < 0)
-	    slot = cache->hash_size - 1;
-    }
+  glamor_glyph_set_private (glyph, NULL);
+  free (priv);
 }
 
+/* Cut and paste from render/glyph.c - probably should export it instead */
 static void
-glamor_glyph_cache_hash_insert(glamor_glyph_cache_t * cache, GlyphPtr glyph, int pos)
+glamor_glyph_extents (int nlist,
+		      GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
 {
-    int slot;
-
-    memcpy(cache->glyphs[pos].sha1, glyph->sha1, sizeof(glyph->sha1));
-
-    slot = (*(CARD32 *) glyph->sha1) % cache->hash_size;
-
-    while (TRUE) {		/* hash table can never be full */
-	if (cache->hash_entries[slot] == -1) {
-	    cache->hash_entries[slot] = pos;
-	    return;
+  int x1, x2, y1, y2;
+  int x, y, n;
+
+  x1 = y1 = MAXSHORT;
+  x2 = y2 = MINSHORT;
+  x = y = 0;
+  while (nlist--)
+    {
+      x += list->xOff;
+      y += list->yOff;
+      n = list->len;
+      list++;
+      while (n--)
+	{
+	  GlyphPtr glyph = *glyphs++;
+	  int v;
+
+	  v = x - glyph->info.x;
+	  if (v < x1)
+	    x1 = v;
+	  v += glyph->info.width;
+	  if (v > x2)
+	    x2 = v;
+
+	  v = y - glyph->info.y;
+	  if (v < y1)
+	    y1 = v;
+	  v += glyph->info.height;
+	  if (v > y2)
+	    y2 = v;
+
+	  x += glyph->info.xOff;
+	  y += glyph->info.yOff;
 	}
-
-	slot--;
-	if (slot < 0)
-	    slot = cache->hash_size - 1;
     }
-}
-
-static void glamor_glyph_cache_hash_remove(glamor_glyph_cache_t * cache, int pos)
-{
-    int slot;
-    int emptied_slot = -1;
-
-    slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hash_size;
-
-    while (TRUE) {		/* hash table can never be full */
-	int entryPos = cache->hash_entries[slot];
-
-	if (entryPos == -1)
-	    return;
-
-	if (entryPos == pos) {
-	    cache->hash_entries[slot] = -1;
-	    emptied_slot = slot;
-	} else if (emptied_slot != -1) {
-	    /* See if we can move this entry into the emptied slot,
-	     * we can't do that if if entry would have hashed
-	     * between the current position and the emptied slot.
-	     * (taking wrapping into account). Bad positions
-	     * are:
-	     *
-	     * |   XXXXXXXXXX             |
-	     *     i         j
-	     *
-	     * |XXX                   XXXX|
-	     *     j                  i
-	     *
-	     * i - slot, j - emptied_slot
-	     *
-	     * (Knuth 6.4R)
-	     */
-
-	    int entry_slot = (*(CARD32 *) cache->glyphs[entryPos].sha1) %
-		cache->hash_size;
-
-	    if (!((entry_slot >= slot && entry_slot < emptied_slot) ||
-		  (emptied_slot < slot
-		   && (entry_slot < emptied_slot
-		       || entry_slot >= slot)))) {
-		cache->hash_entries[emptied_slot] = entryPos;
-		cache->hash_entries[slot] = -1;
-		emptied_slot = slot;
-	    }
-	}
 
-	slot--;
-	if (slot < 0)
-	    slot = cache->hash_size - 1;
-    }
+  extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
+  extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
+  extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
+  extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
 }
 
-#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyph_width)
-#define CACHE_Y(pos) (cache->y_offset + ((pos) / cache->columns) * cache->glyph_height)
-
-/* The most efficient thing to way to upload the glyph to the screen
- * is to use CopyArea; glamor pixmaps are always offscreen.
+/**
+ * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
+ * bounding box, which appears to be good enough to catch most cases at least.
  */
 static Bool
-glamor_glyph_cache_upload_glyph(ScreenPtr screen,
-				glamor_glyph_cache_t * cache,
-				int pos, GlyphPtr glyph)
+glamor_glyphs_intersect (int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-    PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
-    PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
-    PixmapPtr cache_pixmap = (PixmapPtr) cache->picture->pDrawable;
-    PixmapPtr scratch;
-    GCPtr gc;
-
-    /* UploadToScreen only works if bpp match */
-    if (glyph_pixmap->drawable.bitsPerPixel !=
-	cache_pixmap->drawable.bitsPerPixel)
-	return FALSE;
+  int x1, x2, y1, y2;
+  int n;
+  int x, y;
+  BoxRec extents;
+  Bool first = TRUE;
+
+  x = 0;
+  y = 0;
+  extents.x1 = 0;
+  extents.y1 = 0;
+  extents.x2 = 0;
+  extents.y2 = 0;
+  while (nlist--)
+    {
+      x += list->xOff;
+      y += list->yOff;
+      n = list->len;
+      list++;
+      while (n--)
+	{
+	  GlyphPtr glyph = *glyphs++;
+
+	  if (glyph->info.width == 0 || glyph->info.height == 0)
+	    {
+	      x += glyph->info.xOff;
+	      y += glyph->info.yOff;
+	      continue;
+	    }
 
-    gc = GetScratchGC(cache_pixmap->drawable.depth, screen);
-    ValidateGC(&cache_pixmap->drawable, gc);
+	  x1 = x - glyph->info.x;
+	  if (x1 < MINSHORT)
+	    x1 = MINSHORT;
+	  y1 = y - glyph->info.y;
+	  if (y1 < MINSHORT)
+	    y1 = MINSHORT;
+	  x2 = x1 + glyph->info.width;
+	  if (x2 > MAXSHORT)
+	    x2 = MAXSHORT;
+	  y2 = y1 + glyph->info.height;
+	  if (y2 > MAXSHORT)
+	    y2 = MAXSHORT;
+
+	  if (first)
+	    {
+	      extents.x1 = x1;
+	      extents.y1 = y1;
+	      extents.x2 = x2;
+	      extents.y2 = y2;
+	      first = FALSE;
+	    }
+	  else
+	    {
+	      if (x1 < extents.x2 && x2 > extents.x1 &&
+		  y1 < extents.y2 && y2 > extents.y1)
+		{
+		  return TRUE;
+		}
 
-    /* Create a temporary bo to stream the updates to the cache */
-#if 0
-    scratch = screen->CreatePixmap(screen,
-				   glyph->info.width,
-				   glyph->info.height,
-				   glyph_pixmap->drawable.depth,
-				   0);
-    if (scratch) {
-	(void)glamor_copy_area(&glyph_pixmap->drawable,
-			       &scratch->drawable,
-			       gc,
-			       0, 0,
-			       glyph->info.width, glyph->info.height,
-			       0, 0);
-    } else {
-	scratch = glyph_pixmap;
+	      if (x1 < extents.x1)
+		extents.x1 = x1;
+	      if (x2 > extents.x2)
+		extents.x2 = x2;
+	      if (y1 < extents.y1)
+		extents.y1 = y1;
+	      if (y2 > extents.y2)
+		extents.y2 = y2;
+	    }
+	  x += glyph->info.xOff;
+	  y += glyph->info.yOff;
+	}
     }
-#endif
-    scratch = glyph_pixmap;
-    (void)glamor_copy_area(&scratch->drawable,
-			   &cache_pixmap->drawable,
-			   gc,
-			   0, 0, glyph->info.width, glyph->info.height,
-			   CACHE_X(pos), CACHE_Y(pos));
 
-    if (scratch != glyph_pixmap)
-	screen->DestroyPixmap(scratch);
+  return FALSE;
+}
 
-    FreeScratchGC(gc);
 
-    return TRUE;
+static inline unsigned int
+glamor_glyph_size_to_count (int size)
+{
+  size /= GLYPH_MIN_SIZE;
+  return size * size;
 }
 
-static glamor_glyph_cache_result_t
-glamor_glyph_cache_buffer_glyph(ScreenPtr screen,
-				glamor_glyph_cache_t * cache,
-				glamor_glyph_buffer_t * buffer,
-				GlyphPtr glyph, int x_glyph, int y_glyph)
+static inline unsigned int
+glamor_glyph_count_to_mask (int count)
 {
-    glamor_composite_rect_t *rect;
-    int pos;
+  return ~(count - 1);
+}
 
-    if (buffer->source && buffer->source != cache->picture)
-	return GLAMOR_GLYPH_NEED_FLUSH;
+static inline unsigned int
+glamor_glyph_size_to_mask (int size)
+{
+  return glamor_glyph_count_to_mask (glamor_glyph_size_to_count (size));
+}
 
-    if (!cache->picture) {
-	if (!glamor_realize_glyph_caches(screen, cache->format))
-	    return GLAMOR_GLYPH_FAIL;
+static PicturePtr
+glamor_glyph_cache (ScreenPtr screen, GlyphPtr glyph, int *out_x, int *out_y)
+{
+  glamor_screen_private *glamor = glamor_get_screen_private (screen);
+  PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum];
+  glamor_glyph_cache_t *cache =
+    &glamor->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0];
+  struct glamor_glyph *priv = NULL;
+  int size, mask, pos, s;
+
+  if (glyph->info.width > GLYPH_MAX_SIZE
+      || glyph->info.height > GLYPH_MAX_SIZE)
+    return NULL;
+
+  for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
+    if (glyph->info.width <= size && glyph->info.height <= size)
+      break;
+
+  s = glamor_glyph_size_to_count (size);
+  mask = glamor_glyph_count_to_mask (s);
+  pos = (cache->count + s - 1) & mask;
+  if (pos < GLYPH_CACHE_SIZE)
+    {
+      cache->count = pos + s;
     }
+  else
+    {
+      for (s = size; s <= GLYPH_MAX_SIZE; s *= 2)
+	{
+	  int i = cache->evict & glamor_glyph_size_to_mask (s);
+	  GlyphPtr evicted = cache->glyphs[i];
+	  if (evicted == NULL)
+	    continue;
 
-    DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n",
-		     cache->glyph_width, cache->glyph_height,
-		     cache->format == PICT_a8 ? "A" : "ARGB",
-		     (long)*(CARD32 *) glyph->sha1));
-
-    pos = glamor_glyph_cache_hash_lookup(cache, glyph);
-    if (pos != -1) {
-	DBG_GLYPH_CACHE(("  found existing glyph at %d\n", pos));
-    } else {
-	if (cache->glyph_count < cache->size) {
-	    /* Space remaining; we fill from the start */
-	    pos = cache->glyph_count;
-	    cache->glyph_count++;
-	    DBG_GLYPH_CACHE(("  storing glyph in free space at %d\n", pos));
-
-	    glamor_glyph_cache_hash_insert(cache, glyph, pos);
-
-	} else {
-	    /* Need to evict an entry. We have to see if any glyphs
-	     * already in the output buffer were at this position in
-	     * the cache
-	     */
-
-	    pos = cache->eviction_position;
-	    DBG_GLYPH_CACHE(("  evicting glyph at %d\n", pos));
-	    if (buffer->count) {
-		int x, y;
-		int i;
-
-		x = CACHE_X(pos);
-		y = CACHE_Y(pos);
-
-		for (i = 0; i < buffer->count; i++) {
-		    if (buffer->rects[i].x_src == x
-			&& buffer->rects[i].y_src == y) {
-			DBG_GLYPH_CACHE(("  must flush buffer\n"));
-			return GLAMOR_GLYPH_NEED_FLUSH;
-		    }
-		}
+	  priv = glamor_glyph_get_private (evicted);
+	  if (priv->size >= s)
+	    {
+	      cache->glyphs[i] = NULL;
+	      glamor_glyph_set_private (evicted, NULL);
+	      pos = cache->evict & glamor_glyph_size_to_mask (size);
 	    }
-
-	    /* OK, we're all set, swap in the new glyph */
-	    glamor_glyph_cache_hash_remove(cache, pos);
-	    glamor_glyph_cache_hash_insert(cache, glyph, pos);
-
-	    /* And pick a new eviction position */
-	    cache->eviction_position = rand() % cache->size;
+	  else
+	    priv = NULL;
+	  break;
 	}
-
-	/* Now actually upload the glyph into the cache picture; if
-	 * we can't do it with UploadToScreen (because the glyph is
-	 * offscreen, etc), we fall back to CompositePicture.
-	 */
-	if (!glamor_glyph_cache_upload_glyph(screen, cache, pos, glyph)) {
-	    CompositePicture(PictOpSrc,
-			     GlyphPicture(glyph)[screen->myNum],
-			     None,
-			     cache->picture,
-			     0, 0,
-			     0, 0,
-			     CACHE_X(pos),
-			     CACHE_Y(pos),
-			     glyph->info.width,
-			     glyph->info.height);
+      if (priv == NULL)
+	{
+	  int count = glamor_glyph_size_to_count (size);
+	  mask = glamor_glyph_count_to_mask (count);
+	  pos = cache->evict & mask;
+	  for (s = 0; s < count; s++)
+	    {
+	      GlyphPtr evicted = cache->glyphs[pos + s];
+	      if (evicted != NULL)
+		{
+		  if (priv != NULL)
+		    free (priv);
+
+		  priv = glamor_glyph_get_private (evicted);
+		  glamor_glyph_set_private (evicted, NULL);
+		  cache->glyphs[pos + s] = NULL;
+		}
+	    }
 	}
-
+      /* And pick a new eviction position */
+      cache->evict = rand () % GLYPH_CACHE_SIZE;
     }
 
-    buffer->source = cache->picture;
+  if (priv == NULL)
+    {
+      priv = malloc (sizeof (struct glamor_glyph));
+      if (priv == NULL)
+	return NULL;
+    }
 
-    rect = &buffer->rects[buffer->count];
-    rect->x_src = CACHE_X(pos);
-    rect->y_src = CACHE_Y(pos);
-    rect->x_dst = x_glyph - glyph->info.x;
-    rect->y_dst = y_glyph - glyph->info.y;
-    rect->width = glyph->info.width;
-    rect->height = glyph->info.height;
+  glamor_glyph_set_private (glyph, priv);
+  cache->glyphs[pos] = glyph;
+
+  priv->cache = cache;
+  priv->size = size;
+  priv->pos = pos;
+  s =
+    pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
+	   (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
+  priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
+  priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
+  for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2)
+    {
+      if (pos & 1)
+	priv->x += s;
+      if (pos & 2)
+	priv->y += s;
+      pos >>= 2;
+    }
 
-    buffer->count++;
+  glamor_glyph_cache_upload_glyph (screen, cache, glyph, priv->x, priv->y);
 
-    return GLAMOR_GLYPH_SUCCESS;
+  *out_x = priv->x;
+  *out_y = priv->y;
+  return cache->picture;
 }
 
-#undef CACHE_X
-#undef CACHE_Y
-
 static glamor_glyph_cache_result_t
-glamor_buffer_glyph(ScreenPtr screen,
-		    glamor_glyph_buffer_t *buffer,
-		    GlyphPtr glyph, int x_glyph, int y_glyph)
+glamor_buffer_glyph (ScreenPtr screen,
+		     glamor_glyph_buffer_t * buffer,
+		     GlyphPtr glyph, int x_glyph, int y_glyph)
 {
-    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
-    unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format;
-    int width = glyph->info.width;
-    int height = glyph->info.height;
-    glamor_composite_rect_t *rect;
-    PicturePtr source;
-    int i;
-
-    if (buffer->count == GLYPH_BUFFER_SIZE)
-	return GLAMOR_GLYPH_NEED_FLUSH;
-
-    if (PICT_FORMAT_BPP(format) == 1)
-	format = PICT_a8;
-
-    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
-	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
-
-	if (format == cache->format &&
-	    width <= cache->glyph_width &&
-	    height <= cache->glyph_height) {
-	    glamor_glyph_cache_result_t result =
-		glamor_glyph_cache_buffer_glyph(screen,
-						&glamor_screen->glyph_caches[i],
-						buffer,
-						glyph, x_glyph,
-						y_glyph);
-	    switch (result) {
-	    case GLAMOR_GLYPH_FAIL:
-		break;
-	    case GLAMOR_GLYPH_SUCCESS:
-	    case GLAMOR_GLYPH_NEED_FLUSH:
-		return result;
-	    }
+  glamor_screen_private *glamor_screen = glamor_get_screen_private (screen);
+  unsigned int format = (GlyphPicture (glyph)[screen->myNum])->format;
+  glamor_composite_rect_t *rect;
+  PicturePtr source;
+  struct glamor_glyph *priv;
+  int x, y;
+  PicturePtr glyph_picture = GlyphPicture (glyph)[screen->myNum];
+  glamor_glyph_cache_t *cache; 
+
+  if (PICT_FORMAT_BPP (format) == 1)
+    format = PICT_a8;
+
+  cache = &glamor_screen->glyphCaches[PICT_FORMAT_RGB (glyph_picture->format) != 0];
+
+  if (buffer->source && buffer->source != cache->picture)
+    return GLAMOR_GLYPH_NEED_FLUSH;
+
+  if (buffer->count == GLYPH_BUFFER_SIZE)
+    return GLAMOR_GLYPH_NEED_FLUSH;
+
+  priv = glamor_glyph_get_private (glyph);
+
+  if (priv)
+    {
+      rect = &buffer->rects[buffer->count++];
+      rect->x_src = priv->x;
+      rect->y_src = priv->y;
+      if (buffer->source == NULL) buffer->source = priv->cache->picture;
+    }
+  else
+    {
+      source = glamor_glyph_cache (screen, glyph, &x, &y);
+      if (source != NULL)
+	{
+	  rect = &buffer->rects[buffer->count++];
+	  rect->x_src = x;
+	  rect->y_src = y;
+          if (buffer->source == NULL) buffer->source = source;
+	}
+      else
+	{
+	  source = GlyphPicture (glyph)[screen->myNum];
+	  if (buffer->source && buffer->source != source)
+	    return GLAMOR_GLYPH_NEED_FLUSH;
+	  buffer->source = source;
+
+	  rect = &buffer->rects[buffer->count++];
+	  rect->x_src = 0;
+	  rect->y_src = 0;
 	}
     }
 
-    /* Couldn't find the glyph in the cache, use the glyph picture directly */
+  rect->x_dst = x_glyph - glyph->info.x;
+  rect->y_dst = y_glyph - glyph->info.y;
+  rect->width = glyph->info.width;
+  rect->height = glyph->info.height;
 
-    source = GlyphPicture(glyph)[screen->myNum];
-    if (buffer->source && buffer->source != source)
-	return GLAMOR_GLYPH_NEED_FLUSH;
+  /* Couldn't find the glyph in the cache, use the glyph picture directly */
 
-    buffer->source = source;
-
-    rect = &buffer->rects[buffer->count];
-    rect->x_src = 0;
-    rect->y_src = 0;
-    rect->x_dst = x_glyph - glyph->info.x;
-    rect->y_dst = y_glyph - glyph->info.y;
-    rect->width = glyph->info.width;
-    rect->height = glyph->info.height;
-
-    buffer->count++;
-
-    return GLAMOR_GLYPH_SUCCESS;
+  return GLAMOR_GLYPH_SUCCESS;
 }
 
-static void glamor_glyphs_to_mask(PicturePtr mask,
-				  glamor_glyph_buffer_t *buffer)
+
+static void
+glamor_glyphs_flush_mask (PicturePtr mask, glamor_glyph_buffer_t * buffer)
 {
 #ifdef RENDER
-    
-    glamor_composite_rects(PictOpAdd, buffer->source, mask,
-			   buffer->count, buffer->rects);
+  glamor_composite_rects (PictOpAdd, buffer->source, NULL, mask,
+			  buffer->count, buffer->rects);
 #endif
-
-    buffer->count = 0;
-    buffer->source = NULL;
+  buffer->count = 0;
+  buffer->source = NULL;
 }
 
 static void
-glamor_glyphs_to_dst(CARD8 op,
-		     PicturePtr src,
-		     PicturePtr dst,
-		     glamor_glyph_buffer_t *buffer,
-		     INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
+glamor_glyphs_via_mask (CARD8 op,
+			PicturePtr src,
+			PicturePtr dst,
+			PictFormatPtr mask_format,
+			INT16 x_src,
+			INT16 y_src,
+			int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-    int i;
-
-    for (i = 0; i < buffer->count; i++) {
-	glamor_composite_rect_t *rect = &buffer->rects[i];
-
-	CompositePicture(op,
-			 src,
-			 buffer->source,
-			 dst,
-			 x_src + rect->x_dst - x_dst,
-			 y_src + rect->y_dst - y_dst,
-			 rect->x_src,
-			 rect->y_src,
-			 rect->x_dst,
-			 rect->y_dst, rect->width, rect->height);
+  PixmapPtr mask_pixmap = 0;
+  PicturePtr mask;
+  ScreenPtr screen = dst->pDrawable->pScreen;
+  int width = 0, height = 0;
+  int x, y;
+  int x_dst = list->xOff, y_dst = list->yOff;
+  int n;
+  GlyphPtr glyph;
+  int error;
+  BoxRec extents = { 0, 0, 0, 0 };
+  CARD32 component_alpha;
+  glamor_glyph_buffer_t buffer;
+
+  GCPtr gc;
+
+  glamor_glyph_extents (nlist, list, glyphs, &extents);
+
+  if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+    return;
+  width = extents.x2 - extents.x1;
+  height = extents.y2 - extents.y1;
+
+  if (mask_format->depth == 1)
+    {
+      PictFormatPtr a8Format = PictureMatchFormat (screen, 8, PICT_a8);
+
+      if (a8Format)
+	mask_format = a8Format;
+    }
+
+  mask_pixmap = screen->CreatePixmap (screen, width, height,
+				      mask_format->depth,
+				      CREATE_PIXMAP_USAGE_SCRATCH);
+  if (!mask_pixmap)
+    return;
+  component_alpha = NeedsComponent (mask_format->format);
+  mask = CreatePicture (0, &mask_pixmap->drawable,
+			mask_format, CPComponentAlpha,
+			&component_alpha, serverClient, &error);
+  if (!mask)
+    {
+      screen->DestroyPixmap (mask_pixmap);
+      return;
     }
+  gc = GetScratchGC (mask_pixmap->drawable.depth, screen);
+  ValidateGC (&mask_pixmap->drawable, gc);
+  glamor_fill (&mask_pixmap->drawable, gc, 0, 0, width, height);
+  FreeScratchGC (gc);
+  x = -extents.x1;
+  y = -extents.y1;
+
+  buffer.count = 0;
+  buffer.source = NULL;
+  while (nlist--)
+    {
+      x += list->xOff;
+      y += list->yOff;
+      n = list->len;
+      while (n--)
+	{
+	  glyph = *glyphs++;
+
+	  if (glyph->info.width > 0 && glyph->info.height > 0 &&
+	      glamor_buffer_glyph (screen, &buffer, glyph, x,
+				   y) == GLAMOR_GLYPH_NEED_FLUSH)
+	    {
+
+	      glamor_glyphs_flush_mask (mask, &buffer);
+
+	      glamor_buffer_glyph (screen, &buffer, glyph, x, y);
+	    }
 
-    buffer->count = 0;
-    buffer->source = NULL;
+	  x += glyph->info.xOff;
+	  y += glyph->info.yOff;
+	}
+      list++;
+    }
+
+  if (buffer.count)
+      glamor_glyphs_flush_mask (mask, &buffer);
+
+  x = extents.x1;
+  y = extents.y1;
+  CompositePicture (op,
+		    src,
+		    mask,
+		    dst,
+		    x_src + x - x_dst,
+		    y_src + y - y_dst, 0, 0, x, y, width, height);
+  FreePicture (mask, 0);
+  screen->DestroyPixmap (mask_pixmap);
 }
 
-/* Cut and paste from render/glyph.c - probably should export it instead */
 static void
-glamor_glyph_extents(int nlist,
-		     GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents)
+glamor_glyphs_flush_dst (CARD8 op,
+			 PicturePtr src,
+			 PicturePtr dst,
+			 glamor_glyph_buffer_t * buffer,
+			 INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
 {
-    int x1, x2, y1, y2;
-    int n;
-    GlyphPtr glyph;
-    int x, y;
-
-    x = 0;
-    y = 0;
-    extents->x1 = MAXSHORT;
-    extents->x2 = MINSHORT;
-    extents->y1 = MAXSHORT;
-    extents->y2 = MINSHORT;
-    while (nlist--) {
-	x += list->xOff;
-	y += list->yOff;
-	n = list->len;
-	list++;
-	while (n--) {
-	    glyph = *glyphs++;
-	    x1 = x - glyph->info.x;
-	    if (x1 < MINSHORT)
-		x1 = MINSHORT;
-	    y1 = y - glyph->info.y;
-	    if (y1 < MINSHORT)
-		y1 = MINSHORT;
-	    x2 = x1 + glyph->info.width;
-	    if (x2 > MAXSHORT)
-		x2 = MAXSHORT;
-	    y2 = y1 + glyph->info.height;
-	    if (y2 > MAXSHORT)
-		y2 = MAXSHORT;
-	    if (x1 < extents->x1)
-		extents->x1 = x1;
-	    if (x2 > extents->x2)
-		extents->x2 = x2;
-	    if (y1 < extents->y1)
-		extents->y1 = y1;
-	    if (y2 > extents->y2)
-		extents->y2 = y2;
-	    x += glyph->info.xOff;
-	    y += glyph->info.yOff;
-	}
+  int i;
+  glamor_composite_rect_t *rect = &buffer->rects[0];
+  for (i = 0; i < buffer->count; i++, rect++)
+    {
+      rect->x_mask = rect->x_src;
+      rect->y_mask = rect->y_src;
+      rect->x_src = x_src + rect->x_dst - x_dst;
+      rect->y_src = y_src + rect->y_dst - y_dst;
     }
+
+  glamor_composite_rects (op, src, buffer->source, dst,
+			  buffer->count, &buffer->rects[0]);
+
+  buffer->count = 0;
+  buffer->source = NULL;
 }
 
-/**
- * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
- * bounding box, which appears to be good enough to catch most cases at least.
- */
-static Bool
-glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
+static void
+glamor_glyphs_to_dst (CARD8 op,
+		      PicturePtr src,
+		      PicturePtr dst,
+		      INT16 x_src,
+		      INT16 y_src,
+		      int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-    int x1, x2, y1, y2;
-    int n;
-    GlyphPtr glyph;
-    int x, y;
-    BoxRec extents;
-    Bool first = TRUE;
-
-    x = 0;
-    y = 0;
-    extents.x1 = 0;
-    extents.y1 = 0;
-    extents.x2 = 0;
-    extents.y2 = 0;
-    while (nlist--) {
-	x += list->xOff;
-	y += list->yOff;
-	n = list->len;
-	list++;
-	while (n--) {
-	    glyph = *glyphs++;
-
-	    if (glyph->info.width == 0 || glyph->info.height == 0) {
-		x += glyph->info.xOff;
-		y += glyph->info.yOff;
-		continue;
+  ScreenPtr screen = dst->pDrawable->pScreen;
+  int x = 0, y = 0;
+  int x_dst = list->xOff, y_dst = list->yOff;
+  int n;
+  GlyphPtr glyph;
+  glamor_glyph_buffer_t buffer;
+
+  buffer.count = 0;
+  buffer.source = NULL;
+  while (nlist--)
+    {
+      x += list->xOff;
+      y += list->yOff;
+      n = list->len;
+      while (n--)
+	{
+	  glyph = *glyphs++;
+
+	  if (glyph->info.width > 0 && glyph->info.height > 0 &&
+	      glamor_buffer_glyph (screen, &buffer, glyph, x,
+				   y) == GLAMOR_GLYPH_NEED_FLUSH)
+	    {
+	      glamor_glyphs_flush_dst (op, src, dst,
+				       &buffer, x_src, y_src, x_dst, y_dst);
+	      glamor_buffer_glyph (screen, &buffer, glyph, x, y);
 	    }
 
-	    x1 = x - glyph->info.x;
-	    if (x1 < MINSHORT)
-		x1 = MINSHORT;
-	    y1 = y - glyph->info.y;
-	    if (y1 < MINSHORT)
-		y1 = MINSHORT;
-	    x2 = x1 + glyph->info.width;
-	    if (x2 > MAXSHORT)
-		x2 = MAXSHORT;
-	    y2 = y1 + glyph->info.height;
-	    if (y2 > MAXSHORT)
-		y2 = MAXSHORT;
-
-	    if (first) {
-		extents.x1 = x1;
-		extents.y1 = y1;
-		extents.x2 = x2;
-		extents.y2 = y2;
-		first = FALSE;
-	    } else {
-		if (x1 < extents.x2 && x2 > extents.x1 &&
-		    y1 < extents.y2 && y2 > extents.y1) {
-		    return TRUE;
-		}
-
-		if (x1 < extents.x1)
-		    extents.x1 = x1;
-		if (x2 > extents.x2)
-		    extents.x2 = x2;
-		if (y1 < extents.y1)
-		    extents.y1 = y1;
-		if (y2 > extents.y2)
-		    extents.y2 = y2;
-	    }
-	    x += glyph->info.xOff;
-	    y += glyph->info.yOff;
+	  x += glyph->info.xOff;
+	  y += glyph->info.yOff;
 	}
+      list++;
     }
 
-    return FALSE;
+  if (buffer.count)
+      glamor_glyphs_flush_dst (op, src, dst, &buffer,
+			       x_src, y_src, x_dst, y_dst);
 }
 
 void
-glamor_glyphs(CARD8 op,
-	      PicturePtr src,
-	      PicturePtr dst,
-	      PictFormatPtr mask_format,
-	      INT16 x_src,
-	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+glamor_glyphs (CARD8 op,
+	       PicturePtr src,
+	       PicturePtr dst,
+	       PictFormatPtr mask_format,
+	       INT16 x_src,
+	       INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 {
-    PicturePtr picture;
-    PixmapPtr mask_pixmap = 0;
-    PicturePtr mask;
-    ScreenPtr screen = dst->pDrawable->pScreen;
-    int width = 0, height = 0;
-    int x, y;
-    int x_dst = list->xOff, y_dst = list->yOff;
-    int n;
-    GlyphPtr glyph;
-    int error;
-    BoxRec extents = { 0, 0, 0, 0 };
-    CARD32 component_alpha;
-    glamor_glyph_buffer_t buffer;
-
-    /* If we don't have a mask format but all the glyphs have the same format
-     * and don't intersect, use the glyph format as mask format for the full
-     * benefits of the glyph cache.
-     */
-    if (!mask_format) {
-	Bool same_format = TRUE;
-	int i;
-
-	mask_format = list[0].format;
-
-	for (i = 0; i < nlist; i++) {
-	    if (mask_format->format != list[i].format->format) {
-		same_format = FALSE;
-		break;
+  /* If we don't have a mask format but all the glyphs have the same format
+   * and don't intersect, use the glyph format as mask format for the full
+   * benefits of the glyph cache.
+   */
+  if (!mask_format)
+    {
+      Bool same_format = TRUE;
+      int i;
+
+      mask_format = list[0].format;
+
+      for (i = 0; i < nlist; i++)
+	{
+	  if (mask_format->format != list[i].format->format)
+	    {
+	      same_format = FALSE;
+	      break;
 	    }
 	}
 
-	if (!same_format || (mask_format->depth != 1 &&
-			     glamor_glyphs_intersect(nlist, list,
-						     glyphs))) {
-	    mask_format = NULL;
-	}
-    }
-
-    if (mask_format) {
-	GCPtr gc;
-	xRectangle rect;
-
-	glamor_glyph_extents(nlist, list, glyphs, &extents);
-
-	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
-	    return;
-	width = extents.x2 - extents.x1;
-	height = extents.y2 - extents.y1;
-
-	if (mask_format->depth == 1) {
-	    PictFormatPtr a8Format =
-		PictureMatchFormat(screen, 8, PICT_a8);
-
-	    if (a8Format)
-		mask_format = a8Format;
-	}
-
-	mask_pixmap = screen->CreatePixmap(screen, width, height,
-					   mask_format->depth,
-					   CREATE_PIXMAP_USAGE_SCRATCH);
-	if (!mask_pixmap)
-	    return;
-	component_alpha = NeedsComponent(mask_format->format);
-	mask = CreatePicture(0, &mask_pixmap->drawable,
-			      mask_format, CPComponentAlpha,
-			      &component_alpha, serverClient, &error);
-	if (!mask) {
-	    screen->DestroyPixmap(mask_pixmap);
-	    return;
+      if (!same_format || (mask_format->depth != 1 &&
+			   glamor_glyphs_intersect (nlist, list, glyphs)))
+	{
+	  mask_format = NULL;
 	}
-	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
-	ValidateGC(&mask_pixmap->drawable, gc);
-	rect.x = 0;
-	rect.y = 0;
-	rect.width = width;
-	rect.height = height;
-	gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &rect);
-	FreeScratchGC(gc);
-	x = -extents.x1;
-	y = -extents.y1;
-    } else {
-	mask = dst;
-	x = 0;
-	y = 0;
     }
-    buffer.count = 0;
-    buffer.source = NULL;
-    while (nlist--) {
-	x += list->xOff;
-	y += list->yOff;
-	n = list->len;
-	while (n--) {
-	    glyph = *glyphs++;
-	    picture = GlyphPicture(glyph)[screen->myNum];
-
-	    if (glyph->info.width > 0 && glyph->info.height > 0 &&
-		glamor_buffer_glyph(screen, &buffer, glyph, x,
-				    y) == GLAMOR_GLYPH_NEED_FLUSH) {
-		if (mask_format)
-		    glamor_glyphs_to_mask(mask, &buffer);
-		else
-		    glamor_glyphs_to_dst(op, src, dst,
-					 &buffer, x_src, y_src,
-					 x_dst, y_dst);
-
-		glamor_buffer_glyph(screen, &buffer, glyph, x, y);
-	    }
 
-	    x += glyph->info.xOff;
-	    y += glyph->info.yOff;
-	}
-	list++;
-    }
-
-    if (buffer.count) {
-	if (mask_format)
-	    glamor_glyphs_to_mask(mask, &buffer);
-	else
-	    glamor_glyphs_to_dst(op, src, dst, &buffer,
-				 x_src, y_src, x_dst, y_dst);
-    }
-
-    if (mask_format) {
-	x = extents.x1;
-	y = extents.y1;
-	CompositePicture(op,
-			 src,
-			 mask,
-			 dst,
-			 x_src + x - x_dst,
-			 y_src + y - y_dst, 0, 0, x, y, width, height);
-	FreePicture(mask, 0);
-	screen->DestroyPixmap(mask_pixmap);
-    }
+  if (mask_format)
+    glamor_glyphs_via_mask (op, src, dst, mask_format,
+			    x_src, y_src, nlist, list, glyphs);
+  else
+    glamor_glyphs_to_dst (op, src, dst, x_src, y_src, nlist, list, glyphs);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4feb004..76e21ea 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -138,38 +138,16 @@ typedef struct {
   INT16 height;
 } glamor_composite_rect_t;
 
-typedef struct {
-  unsigned char sha1[20];
-} glamor_cached_glyph_t;
+#define GLAMOR_NUM_GLYPH_CACHES 4
+#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
 typedef struct {
-  /* The identity of the cache, statically configured at initialization */
-  unsigned int format;
-  int glyph_width;
-  int glyph_height;
-
-  /* Size of cache; eventually this should be dynamically determined */
-  int size;
-
-  /* Hash table mapping from glyph sha1 to position in the glyph; we use
-   * open addressing with a hash table size determined based on size and large
-   * enough so that we always have a good amount of free space, so we can
-   * use linear probing. (Linear probing is preferrable to double hashing
-   * here because it allows us to easily remove entries.)
-   */
-  int *hash_entries;
-  int hash_size;
-
-  glamor_cached_glyph_t *glyphs;
-  int glyph_count;		/* Current number of glyphs */
-
-  PicturePtr picture;	/* Where the glyphs of the cache are stored */
-  int y_offset;		/* y location within the picture where the cache starts */
-  int columns;		/* Number of columns the glyphs are layed out in */
-  int eviction_position;	/* Next random position to evict a glyph */
+        PicturePtr picture;     /* Where the glyphs of the cache are stored */
+        GlyphPtr *glyphs;
+        uint16_t count;
+        uint16_t evict;
 } glamor_glyph_cache_t;
 
-#define GLAMOR_NUM_GLYPH_CACHES 4
 
 enum glamor_vertex_type {
      GLAMOR_VERTEX_POS,
@@ -268,6 +246,10 @@ typedef struct glamor_screen_private {
   glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
   char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
   int  delayed_fallback_pending;
+
+  glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
+  Bool glyph_cache_initialized;
+
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -838,7 +820,6 @@ glamor_get_spans(DrawablePtr drawable,
 		 char *dst_start);
 
 /* glamor_glyphs.c */
-void glamor_glyphs_init(ScreenPtr screen);
 void glamor_glyphs_fini(ScreenPtr screen);
 void glamor_glyphs(CARD8 op,
 		   PicturePtr pSrc,
@@ -888,7 +869,7 @@ void glamor_trapezoids(CARD8 op,
 		       int ntrap, xTrapezoid *traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
 void glamor_composite_rects(CARD8 op,
-			    PicturePtr src, PicturePtr dst,
+			    PicturePtr src, PicturePtr mask, PicturePtr dst,
 			    int nrect, glamor_composite_rect_t *rects);
 
 /* glamor_tile.c */
@@ -999,7 +980,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
 
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
-//#define GLAMOR_DELAYED_FILLING
+#define GLAMOR_DELAYED_FILLING
 
 
 #include"glamor_utils.h" 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index bc63478..258a09b 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1405,7 +1405,7 @@ glamor_trapezoids(CARD8 op,
 
 void
 glamor_composite_rects(CARD8 op,
-		       PicturePtr src, PicturePtr dst,
+		       PicturePtr src, PicturePtr mask, PicturePtr dst,
 		       int nrect, glamor_composite_rect_t *rects)
 {
   int n;
@@ -1414,7 +1414,7 @@ glamor_composite_rects(CARD8 op,
   ValidatePicture(src);
   ValidatePicture(dst);
 
-  if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects))
+  if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
     return;
 
   n = nrect;
@@ -1423,10 +1423,10 @@ glamor_composite_rects(CARD8 op,
   while (n--) {
     CompositePicture(op,
 		     src,
-		     NULL,
+		     mask,
 		     dst,
 		     r->x_src, r->y_src,
-		     0, 0,
+		     r->x_mask, r->y_mask,
 		     r->x_dst, r->y_dst,
 		     r->width, r->height);
     r++;
commit bf4cbbd4e9c8ee104293a3c4eb202c880a139b73
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 30 17:37:47 2011 +0800

    glamor: Move glamor_glyphs_init to create screen resources stage.
    
    As in glamor_glyphs_init, we may need to create pixmap. Thus it must
    be called after the pixmap resources allocation. Just move it to
    screen resource creation stage is good enough for mow.
    
    Also introduce a macro GLAMOR_FOR_XORG to glamor.h. As glamor may
    be used by Xephyr which doesn't don't have those xorg header files
    and also don't need the egl extension.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index cd261ac..53fe71d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -364,7 +364,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_init_tile_shader(screen);
     glamor_init_putimage_shaders(screen);
     glamor_init_finish_access_shaders(screen);
-    glamor_glyphs_init(screen);
     glamor_pixmap_init(screen);
 
 #ifdef GLAMOR_GLES2
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 3c74c72..7a0e899 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -29,7 +29,9 @@
 #define GLAMOR_H
 
 #include "scrnintstr.h"
+#ifdef GLAMOR_FOR_XORG
 #include "xf86str.h"
+#endif
 #include "pixmapstr.h"
 #include "windowstr.h"
 #include "gcstruct.h"
@@ -49,9 +51,11 @@
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
+extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen);
 
+#ifdef GLAMOR_FOR_XORG
 extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
 extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
 extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
 extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
-
+#endif
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 293e8de..bdb2da7 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -51,6 +51,8 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#define GLAMOR_FOR_XORG
+
 #include <glamor.h>
 
 #define GLAMOR_VERSION_MAJOR 0
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 4bead1f..e2cd7a4 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -684,6 +684,7 @@ ephyrInitScreen (ScreenPtr pScreen)
   return TRUE;
 }
 
+
 Bool
 ephyrFinishInitScreen (ScreenPtr pScreen)
 {
@@ -700,6 +701,7 @@ ephyrFinishInitScreen (ScreenPtr pScreen)
 
   return TRUE;
 }
+extern Bool ephyr_glamor;
 
 Bool
 ephyrCreateResources (ScreenPtr pScreen)
@@ -710,14 +712,16 @@ ephyrCreateResources (ScreenPtr pScreen)
 
   EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
             pScreen, pScreen->myNum, scrpriv->shadow);
-
   if (scrpriv->shadow) 
     return KdShadowSet (pScreen, 
 			scrpriv->randr, 
 			ephyrShadowUpdate, 
 			ephyrWindowLinear);
-  else
+  else {
+    if (ephyr_glamor)
+      if (!glamor_glyphs_init(pScreen)) return FALSE;
     return ephyrSetInternalDamage(pScreen); 
+  }
 }
 
 void
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 109477b..9c9be89 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -233,7 +233,8 @@ glamor_create_screen_resources_ddx(ScreenPtr screen)
 	screen->CreateScreenResources = glamor->CreateScreenResources;
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
-
+        if (!glamor_glyphs_init(screen))
+                return FALSE;
 
 	if (!xf86SetDesiredModes(scrn))
 		return FALSE;
commit ae38bd7c459982d3e05f6f672ee68d187e97421c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Aug 25 10:05:11 2011 +0800

    glamor: Change glamor_egl_init API.
    
    Slightly change the API glamor_egl_init,
    as this initialization is to initialize the display not
    the screen, we should call it in xxx_preinit rather
    than xxxScreenInit(). we change the input parameter as
    below, as in preInit, the screen may not be allocated
    at all. And in glamor_egl_init, it will not call
    glamor_init. Driver should call glamor_init at
    screen_init stage.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index ef13b7a..3c74c72 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -29,6 +29,7 @@
 #define GLAMOR_H
 
 #include "scrnintstr.h"
+#include "xf86str.h"
 #include "pixmapstr.h"
 #include "windowstr.h"
 #include "gcstruct.h"
@@ -49,7 +50,7 @@ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
 
-extern _X_EXPORT Bool glamor_egl_init(ScreenPtr screen, int fd);
+extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
 extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
 extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
 extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 7848c51..293e8de 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -195,9 +195,8 @@ glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
 }
 
 
-Bool glamor_egl_init(ScreenPtr screen, int fd)
+Bool glamor_egl_init(ScrnInfoPtr scrn, int fd)
 {
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_screen_private *glamor;
 	const char *version;
         EGLint config_attribs[] = {
@@ -275,11 +274,6 @@ Bool glamor_egl_init(ScreenPtr screen, int fd)
 		return FALSE;
 	}
 
-	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
-		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-			   "Failed to initialize glamor\n");
-		return FALSE;
-	}
         return TRUE;
 }
 
commit d4f4d1272e1745752840eb7e8ec04eb155ac38d1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 24 17:17:48 2011 +0800

    glamor-egl: Fix direct call for glEGLImageTargetTexture2DOES.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a92993b..7848c51 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -42,6 +42,7 @@
 
 #if GLAMOR_GLES2
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 #else
 #include <GL/gl.h>
 #endif
@@ -80,7 +81,7 @@ struct glamor_screen_private {
 	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
 	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
         PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
-
+	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
 };
 
 int xf86GlamorEGLPrivateIndex = -1;
@@ -128,7 +129,8 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str
 	glBindTexture(GL_TEXTURE_2D, texture);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); 
+
+	(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
 
 	glamor_set_screen_pixmap_texture(screen, width, height, texture);
 	glamor->root = image;
@@ -247,8 +249,12 @@ Bool glamor_egl_init(ScreenPtr screen, int fd)
         glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
                                        eglGetProcAddress("eglCreateImageKHR");
 
+	glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
+                                                 eglGetProcAddress("glEGLImageTargetTexture2DOES");
+
 	if (!glamor->egl_create_image_khr 
-            || !glamor->egl_export_drm_image_mesa) {
+            || !glamor->egl_export_drm_image_mesa
+            || !glamor->egl_image_target_texture2d_oes) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglGetProcAddress() failed\n");
 		return FALSE;
commit 6cb4abca697c24bdc644502cce8a2ca9bbf131e3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 24 17:13:35 2011 +0800

    glamor: Remove the version check for EGL/gles.
    
    As PVR's gles2 has different version number from mesa's,
    just simply remove the version check here to let both
    platform could build it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index 2a1c786..82c845b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -801,8 +801,8 @@ LIBUDEV="libudev >= 143"
 LIBSELINUX="libselinux >= 2.0.86"
 LIBDBUS="dbus-1 >= 1.0"
 LIBPIXMAN="pixman-1 >= 0.21.8"
-LIBEGL="egl >= 7.11.0"
-LIBGLESV2="glesv2 >= 7.11.0"
+LIBEGL="egl"
+LIBGLESV2="glesv2"
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
 PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
commit 60f14d60f6169272951d41d8ca9e0a294c2ca3d0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 24 16:54:32 2011 +0800

    glamor-egl: Move EGL surfaceless related code to dix module.
    
    The functions in glamor_egl.c could be shared by any egl back
    end drivers.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.h b/glamor/glamor.h
index 25f4506..ef13b7a 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -43,6 +43,14 @@
 #define GLAMOR_HOSTX            2
 #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX)
 
+#define GLAMOR_EGL_EXTERNAL_BUFFER 3
+
 extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
 extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
+
+extern _X_EXPORT Bool glamor_egl_init(ScreenPtr screen, int fd);
+extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
+extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
+extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
+
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
new file mode 100644
index 0000000..a92993b
--- /dev/null
+++ b/glamor/glamor_egl.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2010 Intel Corporation.
+ *
+ * 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 (including
+ * the next paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at linux.intel.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <xf86.h>
+#include <xf86drm.h>
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+#define EGL_DISPLAY_NO_X_MESA
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#define MESA_EGL_NO_X11_HEADERS
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <glamor.h>
+
+#define GLAMOR_VERSION_MAJOR 0
+#define GLAMOR_VERSION_MINOR 1
+#define GLAMOR_VERSION_PATCH 0
+
+static const char glamor_name[] = "glamor";
+
+static void
+glamor_identify(int flags)
+{
+	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver based.\n", glamor_name);
+}
+
+struct glamor_screen_private {
+	EGLDisplay display;
+	EGLContext context;
+	EGLImageKHR root;
+	EGLint major, minor;
+        
+
+	CreateScreenResourcesProcPtr CreateScreenResources;
+	CloseScreenProcPtr CloseScreen;
+	int fd;
+        int front_buffer_handle;
+	int cpp;
+
+	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
+	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
+        PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
+
+};
+
+int xf86GlamorEGLPrivateIndex = -1;
+
+static struct glamor_screen_private* glamor_get_egl_screen_private(ScrnInfoPtr scrn)
+{
+        return (struct glamor_screen_private *)  scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
+}
+
+static Bool
+_glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int stride)
+{
+
+	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+	EGLImageKHR image;
+	GLuint texture;
+	EGLint attribs[] = {
+		EGL_WIDTH,	0,
+		EGL_HEIGHT,	0,
+                EGL_DRM_BUFFER_STRIDE_MESA, 0,
+		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
+					EGL_DRM_BUFFER_USE_SCANOUT_MESA,
+		EGL_NONE
+	};
+
+        if (glamor->root) {
+          eglDestroyImageKHR(glamor->display, glamor->root);
+	  glamor->root = EGL_NO_IMAGE_KHR;
+        }
+          
+	attribs[1] = width;
+	attribs[3] = height;
+        attribs[5] = stride / 4;
+        image = glamor->egl_create_image_khr (glamor->display, 
+                                              glamor->context,
+                                              EGL_DRM_BUFFER_MESA,
+                                              (void*)glamor->front_buffer_handle,
+                                              attribs);   
+	if (image == EGL_NO_IMAGE_KHR)
+		return FALSE;
+
+	glGenTextures(1, &texture);
+	glBindTexture(GL_TEXTURE_2D, texture);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); 
+
+	glamor_set_screen_pixmap_texture(screen, width, height, texture);
+	glamor->root = image;
+	return TRUE;
+}
+
+Bool
+glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+        struct drm_gem_flink flink;
+        flink.handle = handle;
+
+        if (ioctl(glamor->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+           xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+	       "Couldn't flink front buffer handle\n");
+           return FALSE;
+        }
+
+        glamor->front_buffer_handle = flink.name;
+
+        return _glamor_create_egl_screen_image(scrn, scrn->virtualX, scrn->virtualY, stride);
+}
+
+Bool
+glamor_close_egl_screen(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+	glamor_fini(screen);
+
+        eglDestroyImageKHR(glamor->display, glamor->root);
+
+
+	glamor->root = EGL_NO_IMAGE_KHR;
+
+	return TRUE;
+}
+
+
+
+static Bool
+glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
+{
+  const char *egl_extensions;
+  char *pext;
+  int  ext_len;
+  ext_len = strlen(extension);
+ 
+  egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS);
+  pext = (char*)egl_extensions;
+ 
+  if (pext == NULL || extension == NULL)
+    return FALSE;
+  while((pext = strstr(pext, extension)) != NULL) {
+    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+      return TRUE;
+    pext += ext_len;
+  }
+  return FALSE;
+}
+
+
+Bool glamor_egl_init(ScreenPtr screen, int fd)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor;
+	const char *version;
+        EGLint config_attribs[] = {
+#ifdef GLAMOR_GLES2
+          EGL_CONTEXT_CLIENT_VERSION, 2, 
+#endif
+          EGL_NONE
+        };
+
+        glamor_identify(0);
+        glamor = calloc(sizeof(*glamor), 1);
+        if (xf86GlamorEGLPrivateIndex == -1) 
+           xf86GlamorEGLPrivateIndex = xf86AllocateScrnInfoPrivateIndex();      
+
+        scrn->privates[xf86GlamorEGLPrivateIndex].ptr = glamor;
+
+        glamor->fd = fd;
+	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
+#ifndef GLAMOR_GLES2
+	eglBindAPI(EGL_OPENGL_API);
+#else
+	eglBindAPI(EGL_OPENGL_ES_API);
+#endif
+	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "eglInitialize() failed\n");
+		return FALSE;
+	}
+
+	version = eglQueryString(glamor->display, EGL_VERSION);
+	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
+
+#define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
+        if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) {  \
+               ErrorF("EGL_" #EXT "required.\n");  \
+               return FALSE;  \
+        } 
+
+        GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
+#ifdef GLAMOR_GLES2
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
+#else
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
+#endif
+
+	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)
+                                            eglGetProcAddress("eglExportDRMImageMESA");
+        glamor->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
+                                       eglGetProcAddress("eglCreateImageKHR");
+
+	if (!glamor->egl_create_image_khr 
+            || !glamor->egl_export_drm_image_mesa) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "eglGetProcAddress() failed\n");
+		return FALSE;
+	}
+
+	glamor->context = eglCreateContext(glamor->display,
+					   NULL, EGL_NO_CONTEXT, config_attribs);
+	if (glamor->context == EGL_NO_CONTEXT) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to create EGL context\n");
+		return FALSE;
+	}
+
+	if (!eglMakeCurrent(glamor->display,
+			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to make EGL context current\n");
+		return FALSE;
+	}
+
+	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to initialize glamor\n");
+		return FALSE;
+	}
+        return TRUE;
+}
+
+void
+glamor_free_egl_screen(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_screen_private *glamor = glamor_get_egl_screen_private(scrn);
+
+	if (glamor != NULL)
+	{
+	  if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) {
+            eglMakeCurrent(glamor->display,
+                         EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+	    eglTerminate(glamor->display);
+          }
+	  free(glamor);
+	}
+}
diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index 84c909b..ba4aeb4 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -34,6 +34,7 @@ INCLUDES = @XORG_INCS@ \
            -I$(top_srcdir)/hw/xfree86/loader \
            -I$(top_srcdir)/miext/shadow \
            -I$(top_srcdir)/glx
+           
 
 libdbe_la_LDFLAGS = -avoid-version
 libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
@@ -41,8 +42,8 @@ libdbe_la_SOURCES = dbemodule.c
 if GLAMOR
 libglamor_dix_la_LDFLAGS = -avoid-version
 libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la
-libglamor_dix_la_SOURCES = glamor_module.c
-libglamor_dix_la_CFLAGS = $(AM_CFLAGS)
+libglamor_dix_la_SOURCES = glamor_module.c $(top_srcdir)/glamor/glamor_egl.c
+libglamor_dix_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/glamor $(LIBDRM_CFLAGS)
 endif
 libfb_la_LDFLAGS = -avoid-version
 libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
commit 3854409e9ad25418c6188f491410bb05eaf92fc6
Author: Zhenyu Wang <zhenyuw at linux.intel.com>
Date:   Mon Aug 22 23:27:24 2011 -0700

    glamor: Fix direct call for glEGLImageTargetTexture2DOES
    
    Follow extension call rule to call glEGLImageTargetTexture2DOES.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 3ac003d..109477b 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -35,19 +35,6 @@
 #include <errno.h>
 #include <xf86drm.h>
 
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
-#define EGL_DISPLAY_NO_X_MESA
-
-#if GLAMOR_GLES2
-#include <GLES2/gl2.h>
-#else
-#include <GL/gl.h>
-#endif
-
-#define MESA_EGL_NO_X11_HEADERS
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
 
 #include "../../../mi/micmap.h"
 #include <xf86Crtc.h>
@@ -70,27 +57,6 @@ glamor_identify(int flags)
 	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name);
 }
 
-struct glamor_screen_private {
-	EGLDisplay display;
-	EGLContext context;
-	EGLImageKHR root;
-	EGLint major, minor;
-
-	CreateScreenResourcesProcPtr CreateScreenResources;
-	CloseScreenProcPtr CloseScreen;
-	int fd;
-	int cpp;
-
-	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
-	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
-
-};
-
-static inline struct glamor_screen_private *
-glamor_get_screen_private(ScrnInfoPtr scrn)
-{
-	return (struct glamor_screen_private *) (scrn->driverPrivate);
-}
 
 Bool
 glamor_resize(ScrnInfoPtr scrn, int width, int height)
@@ -122,7 +88,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	glBindTexture(GL_TEXTURE_2D, texture);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); 
+	(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); 
 
 	glamor_set_screen_pixmap_texture(screen, width, height, texture);
 	glamor->root = image;
@@ -394,8 +360,10 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 
 	glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA");
 	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA");
+	glamor->egl_image_target_texture2d_oes = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
 
-	if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) {
+	if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa ||
+			!glamor->egl_image_target_texture2d_oes) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglGetProcAddress() failed\n");
 		return FALSE;
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 9592013..ef6ee29 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -478,6 +478,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	ScrnInfoPtr scrn = crtc->scrn;
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 
 	if (drmmode_crtc->cursor == NULL)
 	{
@@ -490,7 +491,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 				GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 		glTexParameteri(GL_TEXTURE_2D,
 				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor);
+		(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, drmmode_crtc->cursor);
 	}
 	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
 #ifdef GLAMOR_GLES2
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 0e164d3..6d9e410 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -1,6 +1,43 @@
 #ifndef GLAMOR_DDX_H
 #define GLAMOR_DDX_H
 
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+#define EGL_DISPLAY_NO_X_MESA
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#define MESA_EGL_NO_X11_HEADERS
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+struct glamor_screen_private {
+	EGLDisplay display;
+	EGLContext context;
+	EGLImageKHR root;
+	EGLint major, minor;
+
+	CreateScreenResourcesProcPtr CreateScreenResources;
+	CloseScreenProcPtr CloseScreen;
+	int fd;
+	int cpp;
+
+	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
+	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
+	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
+};
+
+inline struct glamor_screen_private *
+glamor_get_screen_private(ScrnInfoPtr scrn)
+{
+	return (struct glamor_screen_private *) (scrn->driverPrivate);
+}
+
 Bool glamor_resize(ScrnInfoPtr scrn, int width, int height);
 void glamor_frontbuffer_handle(ScrnInfoPtr scrn,
 			       uint32_t *handle, uint32_t *pitch);
commit 54c91079d2bd21d3fd97b6d5fa3ba5c4a86b6337
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 23 14:04:07 2011 +0800

    glamor-gles2: Add explicit precision qualifiers for gles2.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index d4588e2..3609600 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -151,10 +151,11 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "}\n";
 
   const char *fs_source =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 source_texture;\n"
     "uniform sampler2D sampler;\n"
-    "uniform int no_revert;"
-    "uniform int swap_rb;"
+    "uniform int no_revert;\n"
+    "uniform int swap_rb;\n"
     "void main()\n"
     "{\n"
     "   if (no_revert == 1) \n"
@@ -174,10 +175,11 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "}\n";
     
   const char *set_alpha_source =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 source_texture;\n"
     "uniform sampler2D sampler;\n"
-    "uniform int no_revert;"
-    "uniform int swap_rb;"
+    "uniform int no_revert;\n"
+    "uniform int swap_rb;\n"
     "void main()\n"
     "{\n"
     "   if (no_revert == 1) \n"
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index cbd2b59..0b3d5fd 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -112,6 +112,7 @@ glamor_init_solid_shader(ScreenPtr screen)
         "       gl_Position = v_position;\n"
 	"}\n";
     const char *solid_fs =
+        GLAMOR_DEFAULT_PRECISION
 	"uniform vec4 color;\n"
 	"void main()\n"
 	"{\n"
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1f3e8c4..4feb004 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -36,7 +36,6 @@
 #include "glamor.h"
 
 #ifdef GLAMOR_GLES2
-
 #define GL_BGRA                                 GL_BGRA_EXT
 #define GL_COLOR_INDEX                          0x1900
 #define GL_BITMAP                               0x1A00
@@ -77,9 +76,15 @@
 #ifdef GLAMOR_GLES2
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+
+#define GLAMOR_DEFAULT_PRECISION   \
+    "precision mediump float;\n" 
+
 #else
 #include <GL/gl.h>
 #include <GL/glext.h>
+
+#define GLAMOR_DEFAULT_PRECISION
 #endif
 
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index cec6c8d..bc63478 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -71,12 +71,14 @@ static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
   const char *source_solid_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "uniform vec4 source;\n"
     "vec4 get_source()\n"
     "{\n"
     "	return source;\n"
     "}\n";
   const char *source_alpha_pixmap_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 source_texture;\n"
     "uniform sampler2D source_sampler;\n"
     "vec4 get_source()\n"
@@ -84,6 +86,7 @@ glamor_create_composite_fs(struct shader_key *key)
     "	return texture2D(source_sampler, source_texture);\n"
     "}\n";
   const char *source_pixmap_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 source_texture;\n"
     "uniform sampler2D source_sampler;\n"
     "vec4 get_source()\n"
@@ -91,12 +94,14 @@ glamor_create_composite_fs(struct shader_key *key)
     "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
     "}\n";
   const char *mask_solid_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "uniform vec4 mask;\n"
     "vec4 get_mask()\n"
     "{\n"
     "	return mask;\n"
     "}\n";
   const char *mask_alpha_pixmap_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 mask_texture;\n"
     "uniform sampler2D mask_sampler;\n"
     "vec4 get_mask()\n"
@@ -104,6 +109,7 @@ glamor_create_composite_fs(struct shader_key *key)
     "	return texture2D(mask_sampler, mask_texture);\n"
     "}\n";
   const char *mask_pixmap_fetch =
+    GLAMOR_DEFAULT_PRECISION
     "varying vec2 mask_texture;\n"
     "uniform sampler2D mask_sampler;\n"
     "vec4 get_mask()\n"
@@ -111,21 +117,25 @@ glamor_create_composite_fs(struct shader_key *key)
     "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
     "}\n";
   const char *in_source_only =
+    GLAMOR_DEFAULT_PRECISION
     "void main()\n"
     "{\n"
     "	gl_FragColor = get_source();\n"
     "}\n";
   const char *in_normal =
+    GLAMOR_DEFAULT_PRECISION
     "void main()\n"
     "{\n"
     "	gl_FragColor = get_source() * get_mask().a;\n"
     "}\n";
   const char *in_ca_source =
+    GLAMOR_DEFAULT_PRECISION
     "void main()\n"
     "{\n"
     "	gl_FragColor = get_source() * get_mask();\n"
     "}\n";
   const char *in_ca_alpha =
+    GLAMOR_DEFAULT_PRECISION
     "void main()\n"
     "{\n"
     "	gl_FragColor = get_source().a * get_mask();\n"
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 8fe4b38..c184dac 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -50,6 +50,7 @@ glamor_init_tile_shader(ScreenPtr screen)
         "       tile_texture = v_texcoord0.xy;\n"
 	"}\n";
     const char *tile_fs =
+        GLAMOR_DEFAULT_PRECISION
         "varying vec2 tile_texture;\n"
 	"uniform sampler2D sampler;\n"
 	"void main()\n"
commit b4f265c7f9bcb7824df19ea915ab32fe84d9ec53
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 23 13:30:54 2011 +0800

    glamor: Fallback to software fb when repeat is needed.
    
    Need to be fixed latter. We should not need any fallback here.
    But currently, the implementation for repeating tiling is
    broken.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 25ad635..8fe4b38 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -98,10 +98,14 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_pixmap_private *src_pixmap_priv;
     glamor_pixmap_private *dst_pixmap_priv;
 
-
     src_pixmap_priv = glamor_get_pixmap_private(tile);
     dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
 
+    if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
+         || ((tile_y != 0) && (tile_y + height > tile->drawable.height)))  {
+       ErrorF("tile_x = %d tile_y = %d \n", tile_x, tile_y);
+       goto fail;
+    }
     if (glamor_priv->tile_prog == 0) {
 	glamor_fallback("Tiling unsupported\n");
 	goto fail;
commit bd0ea43f3999e29ae5953ca5257b1795916dd5e7
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 23 13:27:48 2011 +0800

    glamor: Change to use the original drawable in glamor_fill.
    
    As glamor_fill may fallback to software rasterization, we'd
    better to use the original drawable as input paramter.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 873f383..cbd2b59 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -41,12 +41,15 @@ glamor_fill(DrawablePtr drawable,
 	    int height)
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
+    int off_x, off_y;
+
+    glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
 
     switch (gc->fillStyle) {
     case FillSolid:
 	if (!glamor_solid(dst_pixmap,
-                         x,
-                         y,
+                         x + off_x,
+                         y + off_y,
 		         width,
 		         height,
 		         gc->alu,
@@ -58,8 +61,8 @@ glamor_fill(DrawablePtr drawable,
     case FillOpaqueStippled:
 	if (!glamor_stipple(dst_pixmap,
 		       gc->stipple,
-		       x,
-		       y,
+		       x + off_x,
+		       y + off_y,
 		       width,
 		       height,
 		       gc->alu,
@@ -74,14 +77,14 @@ glamor_fill(DrawablePtr drawable,
     case FillTiled:
 	if (!glamor_tile(dst_pixmap,
 		    gc->tile.pixmap,
-		    x,
-		    y,
+		    x + off_x,
+		    y + off_y,
 		    width,
 		    height,
 		    gc->alu,
 		    gc->planemask,
-		    drawable->x + x - gc->patOrg.x,
-		    drawable->y + y - gc->patOrg.y))
+		    drawable->x + x + off_x - gc->patOrg.x,
+		    drawable->y + y + off_y - gc->patOrg.y))
 	goto fail;
 	break;
     }
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index b1f79a9..9a97da2 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -42,15 +42,11 @@ glamor_fill_spans(DrawablePtr drawable,
     int nbox;
     BoxPtr pbox;
     int x1, x2, y;
-    int off_x, off_y;
     RegionPtr pClip = fbGetCompositeClip(gc);
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
 
     if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) 
 	goto fail;
 
-    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
 	ppt = points;
         while (n--) {
                 x1 = ppt->x;
@@ -74,7 +70,7 @@ glamor_fill_spans(DrawablePtr drawable,
                         if (x2 <= x1)
                                 continue;
                         glamor_fill (drawable,gc,
-                                     x1 + off_x, y + off_y,
+                                     x1, y,
                                      x2 - x1 ,  1);
                         pbox++;
                 }
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 218c308..3cc4b52 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -47,16 +47,13 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     int		    xorg, yorg;
     int		    n;
     register BoxPtr pbox;
-    int off_x, off_y;
     RegionPtr pClip = fbGetCompositeClip(gc);
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
 	goto fail;
     }
 
     xorg = drawable->x;
     yorg = drawable->y;
-    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
 
         while (nrect--) {
                 fullX1 = prect->x + xorg;
@@ -92,8 +89,8 @@ glamor_poly_fill_rect(DrawablePtr drawable,
                                 continue;
 	                glamor_fill(drawable,
 			            gc,
-				    x1 + off_x,
-				    y1 + off_y,
+				    x1,
+				    y1,
 				    x2 - x1,
                                     y2 - y1);
                 }
commit 65812b538f23bfccc32a7bbc0b2c4e93e1cd8fe8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 23 10:31:50 2011 +0800

    glamor-dix: Make a glamor dix module.
    
    And modify the header file to export three APIs to the
    ddx driver.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index 25e9dd3..2a1c786 100644
--- a/configure.ac
+++ b/configure.ac
@@ -646,7 +646,7 @@ AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest serv
 AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
 AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
 AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
-#AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor server (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
+AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor dix module (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
 AC_ARG_ENABLE(glamor-ddx,     AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no])
 dnl kdrive and its subsystems
 AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
@@ -1772,12 +1772,10 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 
 dnl glamor 
 
-AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes])
+AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes || test "x$GLAMOR" = xyes])
 AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes])
 AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes])
 
-GLAMOR=yes
-
 if test "x$GLAMOR" = xyes; then 
    AC_DEFINE(GLAMOR,1,[Build Glamor])
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 2c1b241..25f4506 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -43,6 +43,6 @@
 #define GLAMOR_HOSTX            2
 #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX)
 
-Bool glamor_init(ScreenPtr screen, unsigned int flags);
-void glamor_fini(ScreenPtr screen);
-void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
+extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
+extern _X_EXPORT void glamor_fini(ScreenPtr screen);
+extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index 6dc63ce..84c909b 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -14,10 +14,14 @@ if RECORD
 RECORDMOD = librecord.la
 endif
 
+if GLAMOR
+LIBGLAMOR_DIX = libglamor_dix.la
+endif
+
 module_LTLIBRARIES = libfb.la \
                      libwfb.la \
                      libshadow.la \
-                     libglamor_dix.la
+                     $(LIBGLAMOR_DIX)
 
 extsmoduledir = $(moduledir)/extensions
 extsmodule_LTLIBRARIES = $(RECORDMOD) \
@@ -34,12 +38,12 @@ INCLUDES = @XORG_INCS@ \
 libdbe_la_LDFLAGS = -avoid-version
 libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
 libdbe_la_SOURCES = dbemodule.c
-
+if GLAMOR
 libglamor_dix_la_LDFLAGS = -avoid-version
 libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la
-libglamor_dix_la_SOURCES = 
+libglamor_dix_la_SOURCES = glamor_module.c
 libglamor_dix_la_CFLAGS = $(AM_CFLAGS)
-
+endif
 libfb_la_LDFLAGS = -avoid-version
 libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
 libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
diff --git a/hw/xfree86/dixmods/glamor_module.c b/hw/xfree86/dixmods/glamor_module.c
new file mode 100644
index 0000000..ee2dba8
--- /dev/null
+++ b/hw/xfree86/dixmods/glamor_module.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc.  All Rights Reserved.
+ *
+ * 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
+ * XFREE86 PROJECT 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.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo VersRec =
+{
+	"glamor_dix",
+	MODULEVENDORSTRING,
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XORG_VERSION_CURRENT,
+	1, 0, 0,
+	ABI_CLASS_ANSIC,		/* Only need the ansic layer */
+	ABI_ANSIC_VERSION,
+	MOD_CLASS_NONE,
+	{0,0,0,0}       /* signature, to be patched into the file by a tool */
+};
+
+_X_EXPORT XF86ModuleData glamor_dixModuleData = { &VersRec, NULL, NULL };
commit ef3ea0f46bf1b688249cd37d54cfa67ec55041b0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Aug 19 11:06:56 2011 +0800

    glamor: Don't need to check status when set the target.
    
    As we already checked the status when create the fbo.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 1e17069..15fc014 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -83,9 +83,7 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
-//  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-
-  glamor_pixmap_ensure_fb(pixmap_priv->container);
+  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
 #ifndef GLAMOR_GLES2
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
commit 52cce9333fed2035da9623f338428a5d220b577d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Aug 19 11:05:21 2011 +0800

    glamor:  egl version 7.11 should be ok for us.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index d67e7cb..25e9dd3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -801,7 +801,7 @@ LIBUDEV="libudev >= 143"
 LIBSELINUX="libselinux >= 2.0.86"
 LIBDBUS="dbus-1 >= 1.0"
 LIBPIXMAN="pixman-1 >= 0.21.8"
-LIBEGL="egl >= 7.12.0"
+LIBEGL="egl >= 7.11.0"
 LIBGLESV2="glesv2 >= 7.11.0"
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
commit 3648e35b5d0ffcb2ea5d40c842a7f8dd39b27b50
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Aug 19 10:53:44 2011 +0800

    glamor-ddx: Add code to check required egl extensions.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 317342b..3ac003d 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -304,6 +304,31 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
 	return TRUE;
 }
 
+
+
+static Bool
+glamor_egl_has_extension(struct glamor_screen_private *glamor, char *extension)
+{
+  const char *egl_extensions;
+  char *pext;
+  int  ext_len;
+  ext_len = strlen(extension);
+ 
+  egl_extensions = (const char*)eglQueryString(glamor->display, EGL_EXTENSIONS);
+  pext = (char*)egl_extensions;
+ 
+  if (pext == NULL || extension == NULL)
+    return FALSE;
+  while((pext = strstr(pext, extension)) != NULL) {
+    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+      return TRUE;
+    pext += ext_len;
+  }
+  return FALSE;
+}
+
+
+
 static Bool
 glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
@@ -353,6 +378,20 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	version = eglQueryString(glamor->display, EGL_VERSION);
 	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
 
+#define GLAMOR_CHECK_EGL_EXTENSION(EXT)  \
+        if (!glamor_egl_has_extension(glamor, "EGL_" #EXT)) {  \
+               ErrorF("EGL_" #EXT "required.\n");  \
+               return FALSE;  \
+        } 
+
+        GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_gl_renderbuffer_image);
+#ifdef GLAMOR_GLES2
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_gles2);
+#else
+        GLAMOR_CHECK_EGL_EXTENSION(KHR_surfaceless_opengl);
+#endif
+
 	glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA");
 	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA");
 
commit eaa07998c432f68485423c4d108220ce1d72e7b6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 16 14:05:25 2011 +0800

    glamor: Add device independent glamor to the installation package.
    
    Other ddx driver may link libglamor_dix to utilize glamor.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/configure.ac b/configure.ac
index 69b1ac3..d67e7cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -801,7 +801,8 @@ LIBUDEV="libudev >= 143"
 LIBSELINUX="libselinux >= 2.0.86"
 LIBDBUS="dbus-1 >= 1.0"
 LIBPIXMAN="pixman-1 >= 0.21.8"
-
+LIBEGL="egl >= 7.12.0"
+LIBGLESV2="glesv2 >= 7.11.0"
 dnl Pixman is always required, but we separate it out so we can link
 dnl specific modules against it
 PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
@@ -1779,14 +1780,21 @@ GLAMOR=yes
 
 if test "x$GLAMOR" = xyes; then 
    AC_DEFINE(GLAMOR,1,[Build Glamor])
+
    if test "x$GLAMOR_GLES2" = xyes; then
       AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2])
+      PKG_CHECK_MODULES(GLESV2, $LIBGLESV2)
+      REQUIRED_LIBS="$REQUIRED_LIBS $LIBGLESV2"
    else 
       AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL])
+      PKG_CHECK_MODULES(GL, $LIBGL)
+      REQUIRED_LIBS="$REQUIRED_LIBS $LIBGL"
    fi
 
    if test "x$GLAMOR_DDX" = xyes; then
      AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver])
+     PKG_CHECK_MODULES(EGL, $LIBEGL)
+     REQUIRED_LIBS="$REQUIRED_LIBS $LIBEGL"
    fi
 fi
 
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index ec38ac4..fcde765 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -9,13 +9,20 @@ sdk_HEADERS = glamor.h
 endif
 
 if GLAMOR_GLES2
-GLAMOR_GLES2_CFLAGS = -DGLAMOR_GLES2
+libglamor_la_LIBADD = $(GLESV2_LIBS)
+else
+libglamor_la_LIBADD = $(GL_LIBS)
+endif
+
+if XORG
+sdk_HEADERS = glamor.h
 endif
 
 INCLUDES = \
 	$(XORG_INCS)
 
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) $(LIBDRM_CFLAGS)
+
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
@@ -37,4 +44,3 @@ libglamor_la_SOURCES = \
         glamor_picture.c\
 	glamor_window.c\
 	glamor.h
-
diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index 1a162ab..6dc63ce 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -16,7 +16,8 @@ endif
 
 module_LTLIBRARIES = libfb.la \
                      libwfb.la \
-                     libshadow.la
+                     libshadow.la \
+                     libglamor_dix.la
 
 extsmoduledir = $(moduledir)/extensions
 extsmodule_LTLIBRARIES = $(RECORDMOD) \
@@ -34,6 +35,11 @@ libdbe_la_LDFLAGS = -avoid-version
 libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la
 libdbe_la_SOURCES = dbemodule.c
 
+libglamor_dix_la_LDFLAGS = -avoid-version
+libglamor_dix_la_LIBADD = $(top_builddir)/glamor/libglamor.la
+libglamor_dix_la_SOURCES = 
+libglamor_dix_la_CFLAGS = $(AM_CFLAGS)
+
 libfb_la_LDFLAGS = -avoid-version
 libfb_la_LIBADD = $(top_builddir)/fb/libfb.la
 libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index dcd44b2..8432645 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -13,15 +13,11 @@ glamor_la_CFLAGS =					\
 
 if GLAMOR_GLES2
 glamor_la_CFLAGS+=-DGLAMOR_GLES2
-GLAMOR_GL_LIB = -lGLESv2
-else
-GLAMOR_GL_LIB = -lGL
 endif
 
-glamor_la_LDFLAGS =				 \
-	-module -avoid-version -L$(libdir) -lEGL \
-        $(top_builddir)/glamor/libglamor.la      \
-        -L$(libdir)/../lib64 $(GLAMOR_GL_LIB)
+glamor_la_LDFLAGS = -module -avoid-version \
+                    $(top_builddir)/glamor/libglamor.la  \
+                     $(EGL_LIBS)
 
 glamor_ladir = $(moduledir)/drivers
 glamor_la_SOURCES =				\
commit 1658454dea4330144ebc0b02e1b42feed6db4f41
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:33:35 2011 +0800

    glamor: Fix the copy of overlaped region in one pixmap.
    
    Originaly, we use fbo blit to handle overlaped region copy.
    But GLES2 doesn't support that, just simply copy the needed
    region to another texture can fix this problem.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 1e160ac..3e6e6b9 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -124,7 +124,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 			      BoxPtr box,
 			      int nbox,
 			      int dx,
-			      int dy)
+			      int dy
+                              )
 {
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(dst->pScreen);
@@ -193,7 +194,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
       glActiveTexture(GL_TEXTURE0);
       glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+#ifndef GLAMOR_GLES2
       glEnable(GL_TEXTURE_2D);
+#endif
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  
@@ -202,6 +205,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
                             texcoords);
       glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
       glUseProgram(glamor_priv->finish_access_prog[0]);
+      glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
+      glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
  
    } 
     else {
@@ -231,7 +236,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#ifndef GLAMOR_GLES2
       glDisable(GL_TEXTURE_2D);
+#endif
     }
     glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
@@ -308,23 +315,29 @@ glamor_copy_n_to_n(DrawablePtr src,
 #endif
     glamor_calculate_boxes_bound(&bound, box, nbox);
 
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) 
+    /*  Overlaped indicate the src and dst are the same pixmap. */
+    if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) 
 	&& ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
-	    * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height)) {
+	    * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height))) {
 
       temp_pixmap = (*screen->CreatePixmap)(screen,
 					 bound.x2 - bound.x1,
 					 bound.y2 - bound.y1,
 					 src_pixmap->drawable.depth,
-					 GLAMOR_CREATE_PIXMAP_CPU);
+					 overlaped ? 0 : GLAMOR_CREATE_PIXMAP_CPU);
       if (!temp_pixmap)
 	goto fail;
       glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
       temp_src = &temp_pixmap->drawable;
-      fbCopyNtoN(src, temp_src, gc, box, nbox,
-		 temp_dx + bound.x1, temp_dy + bound.y1, 
-		 reverse, upsidedown, bitplane,
-		 closure);
+
+      if (overlaped)
+        glamor_copy_n_to_n_textured(src, temp_src, gc, box, nbox, 
+                                    temp_dx + bound.x1, temp_dy + bound.y1); 
+      else
+        fbCopyNtoN(src, temp_src, gc, box, nbox,
+	  	   temp_dx + bound.x1, temp_dy + bound.y1, 
+		   reverse, upsidedown, bitplane,
+		   closure);
       glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
       temp_dx = -bound.x1;
       temp_dy = -bound.y1;
commit 1f129c491bfc825465c3bc0e9b745b7f66dea720
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:32:57 2011 +0800

    glamor: Convert pixmap to supported format before getspans.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index e1a20ba..ba409dc 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -41,9 +41,10 @@ glamor_get_spans(DrawablePtr drawable,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    int no_alpha;
+    int no_alpha, no_revert;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    PixmapPtr temp_pixmap = NULL;
     int i;
     uint8_t *readpixels_dst = (uint8_t *)dst;
     int x_off, y_off;
@@ -56,7 +57,8 @@ glamor_get_spans(DrawablePtr drawable,
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
                                                &type, 
-                                               &no_alpha
+                                               &no_alpha,
+                                               &no_revert
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
@@ -65,7 +67,15 @@ glamor_get_spans(DrawablePtr drawable,
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
- 
+
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+    /* XXX prepare whole pixmap is not efficient. */
+      temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, 
+                                                   &type, no_alpha, no_revert);
+      pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+      glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    }
+
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
     for (i = 0; i < count; i++) {
       if (glamor_priv->yInverted) {
@@ -85,6 +95,8 @@ glamor_get_spans(DrawablePtr drawable,
 	}
        readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
     }
+    if (temp_pixmap) 
+     pixmap->drawable.pScreen->DestroyPixmap(temp_pixmap);
     return;
 
 fail:
commit 67da52ec13a87846201a99d5a31db28668d9fdfd
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:21:09 2011 +0800

    glamor: Add color conversion support by using new shader.
    
    There are two places we need to do color conversion.
    
    1. When upload a image data to a texture.
    2. When download a texture to a memory buffer.
    
    As the color format may not be supported in GLES2. We may
    need to do the following two operations to convert dat.
    
    a. revert argb to bgra / abgr to rgba.
    b. swap argb to abgr / bgra to rgba.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 9f04573..d4588e2 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -133,7 +133,6 @@ Bool
 glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
   PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
   return glamor_download_pixmap_to_cpu(pixmap, access);
 }
 
@@ -154,17 +153,47 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   const char *fs_source =
     "varying vec2 source_texture;\n"
     "uniform sampler2D sampler;\n"
+    "uniform int no_revert;"
+    "uniform int swap_rb;"
     "void main()\n"
     "{\n"
-    "	gl_FragColor = texture2D(sampler, source_texture);\n"
+    "   if (no_revert == 1) \n"
+    "    { \n"
+    "     if (swap_rb == 1)   \n"
+    "	  gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+    "     else \n"
+    "	  gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+    "    } \n"
+    "   else \n"
+    "    { \n"
+    "     if (swap_rb == 1)   \n"
+    "	    gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+    "     else \n"
+    "	    gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+    "    } \n"
     "}\n";
     
   const char *set_alpha_source =
     "varying vec2 source_texture;\n"
     "uniform sampler2D sampler;\n"
+    "uniform int no_revert;"
+    "uniform int swap_rb;"
     "void main()\n"
     "{\n"
-    " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+    "   if (no_revert == 1) \n"
+    "    { \n"
+    "     if (swap_rb == 1)   \n"
+    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+    "     else \n"
+    "	  gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+    "    } \n"
+    "   else \n"
+    "    { \n"
+    "     if (swap_rb == 1)   \n"
+    "	  gl_FragColor = vec4(1,  texture2D(sampler, source_texture).rgb);\n"
+    "     else \n"
+    "	  gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+    "    } \n"
     "}\n";
   GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
   GLint sampler_uniform_location;
@@ -190,17 +219,31 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
 
+  glamor_priv->finish_access_no_revert[0] = 
+    glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
+
+  glamor_priv->finish_access_swap_rb[0] = 
+    glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
   sampler_uniform_location =
     glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
   glUseProgram(glamor_priv->finish_access_prog[0]);
   glUniform1i(sampler_uniform_location, 0);
+  glUniform1i(glamor_priv->finish_access_no_revert[0],1);
+  glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
   glUseProgram(0);
 
+  glamor_priv->finish_access_no_revert[1] = 
+    glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
+  glamor_priv->finish_access_swap_rb[1] = 
+    glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
   sampler_uniform_location =
     glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
   glUseProgram(glamor_priv->finish_access_prog[1]);
+  glUniform1i(glamor_priv->finish_access_no_revert[1],1);
   glUniform1i(sampler_uniform_location, 0);
+  glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
   glUseProgram(0);
+
 }
 
 void
@@ -224,8 +267,9 @@ glamor_finish_access(DrawablePtr drawable)
     pixmap_priv->pbo_valid = FALSE;
     glDeleteBuffers(1, &pixmap_priv->pbo);
     pixmap_priv->pbo = 0;
-  } else
+  } else {
     free(pixmap->devPrivate.ptr);
+  }
 
   pixmap->devPrivate.ptr = NULL;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 660ffe0..873f383 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -143,7 +143,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     GLfloat color[4];
     float vertices[8];
     GLfloat xscale, yscale;
-    
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
         glamor_fallback("dest %p has no fbo.\n", pixmap);
 	goto fail;
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 1dc1ee9..1e17069 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -83,12 +83,15 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
-  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+//  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+
+  glamor_pixmap_ensure_fb(pixmap_priv->container);
 #ifndef GLAMOR_GLES2
-  glMatrixMode(GL_PROJECTION);                                                                                                                                                                  glLoadIdentity();
-  glMatrixMode(GL_MODELVIEW);                                                                                                                                                                   glLoadIdentity();                                        
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();                                        
 #endif
-
   glViewport(0, 0,
 	     pixmap_priv->container->drawable.width,
 	     pixmap_priv->container->drawable.height);
@@ -199,7 +202,7 @@ glamor_set_alu(unsigned char alu)
  * Upload pixmap to a specified texture.
  * This texture may not be the one attached to it.
  **/
-
+int in_restore = 0;
 static void 
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex)
 {
@@ -225,7 +228,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 
   if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
     iformat = format;
-    type = GL_UNSIGNED_BYTE;
   }
 
   stride = pixmap->devKind;
@@ -264,7 +266,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 
 static void
 _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, 
-                                 GLenum type, int no_alpha, int flip)
+                                 GLenum type, int no_alpha, int no_revert, 
+                                 int flip)
 {
 
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -290,8 +293,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
   /* Try fast path firstly, upload the pixmap to the texture attached
    * to the fbo directly. */
-
-  if (no_alpha == 0 && !need_flip) {
+  if (no_alpha == 0 && no_revert == 1 && !need_flip) {
     __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex);
     return;
   }
@@ -303,14 +305,6 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
     ptexcoords = texcoords_inv;
 
   /* Slow path, we need to flip y or wire alpha to 1. */
-#if 0
-  glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-  glEnableClientState(GL_VERTEX_ARRAY);
-
-  glClientActiveTexture(GL_TEXTURE0);
-  glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
-  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
   glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         vertices);
@@ -319,10 +313,8 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
                         2 * sizeof(float),
                         ptexcoords);
   glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
-  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-  glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
 
+  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
   glGenTextures(1, &tex);
 
   __glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
@@ -331,12 +323,18 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
 
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#ifndef GLAMOR_GLES2
   glEnable(GL_TEXTURE_2D);
+#endif
   glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+  glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0);
 
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
+#ifndef GLAMOR_GLES2
   glDisable(GL_TEXTURE_2D);
+#endif
   glUseProgram(0);
   glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
   glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -386,7 +384,7 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
  * 2. no_alpha != 0, we need to wire the alpha.
  * */
 static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
 {
   int need_fbo;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -402,7 +400,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha)
   if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 
     return 0; 
 
-  if (no_alpha != 0 || !glamor_priv->yInverted)
+  if (no_alpha != 0 || no_revert == 0 || !glamor_priv->yInverted)
     need_fbo = 1;
   else
     need_fbo = 0;
@@ -427,16 +425,17 @@ enum glamor_pixmap_status
 glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 {
   GLenum format, type;
-  int no_alpha;
+  int no_alpha, no_revert;
 
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format, 
 					     &type, 
-					     &no_alpha)) {
+					     &no_alpha,
+                                             &no_revert)) {
     glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     return GLAMOR_UPLOAD_FAILED;
   }
-  if (glamor_pixmap_upload_prepare(pixmap, no_alpha))
+  if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
     return GLAMOR_UPLOAD_FAILED;
   glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
 		      "Uploading pixmap %p  %dx%d depth%d.\n", 
@@ -444,7 +443,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 		      pixmap->drawable.width, 
 		      pixmap->drawable.height,
 		      pixmap->drawable.depth);
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1);
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1);
   return GLAMOR_UPLOAD_DONE;
 }
 
@@ -468,18 +467,101 @@ void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
   GLenum format, type;
-  int no_alpha;
+  int no_alpha, no_revert;
 
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format, 
 					     &type, 
-					     &no_alpha)) {
+					     &no_alpha, 
+                                             &no_revert)) {
     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     assert(0);
   }
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1);
+
+  in_restore = 1;
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, no_revert, 1);
+  in_restore = 0;
 }
 
+/* 
+ * as gles2 only support a very small set of color format and
+ * type when do glReadPixel,  
+ * Before we use glReadPixels to get back a textured pixmap, 
+ * Use shader to convert it to a supported format and thus
+ * get a new temporary pixmap returned.
+ * */
+
+PixmapPtr
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, 
+                               GLenum *type, int no_alpha, int no_revert)
+{
+    glamor_pixmap_private *source_priv;
+    glamor_screen_private *glamor_priv;
+    ScreenPtr screen;
+    PixmapPtr temp_pixmap;
+    glamor_pixmap_private *temp_pixmap_priv;
+    static float vertices[8] = {-1, -1,
+			      1, -1,
+			      1,  1,
+			      -1,  1};
+    static float texcoords[8] = {0, 0,
+				   1, 0,
+				   1, 1,
+				   0, 1};
+
+    int swap_rb = 0;
+
+    screen = source->drawable.pScreen;
+
+    glamor_priv = glamor_get_screen_private(screen);
+    source_priv = glamor_get_pixmap_private(source);
+    if (*format == GL_BGRA) {
+      *format = GL_RGBA;
+      swap_rb = 1;
+    }
+
+
+    temp_pixmap = (*screen->CreatePixmap)(screen,
+			                  source->drawable.width,
+					  source->drawable.height,
+					  source->drawable.depth,
+					  0);
+
+    temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+
+    glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, 
+		 source->drawable.height, 0,
+		 *format, *type, NULL);
+    
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, source_priv->tex);
+
+    glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
+
+    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glUseProgram(0);
+    glFlush();
+    return temp_pixmap; 
+}
+ 
 
 /**
  * Move a pixmap to CPU memory.
@@ -497,18 +579,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   unsigned int stride, row_length, y;
   GLenum format, type, gl_access, gl_usage;
-  int no_alpha;
+  int no_alpha, no_revert;
   uint8_t *data = NULL, *read;
+  PixmapPtr temp_pixmap = NULL;
+  ScreenPtr screen;
   glamor_screen_private *glamor_priv =
     glamor_get_screen_private(pixmap->drawable.pScreen);
-
-
+  
+  screen = pixmap->drawable.pScreen;
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
     return TRUE;
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format,
 					     &type, 
-					     &no_alpha)) {
+					     &no_alpha,
+                                             &no_revert)) {
     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     assert(0);  // Should never happen.
     return FALSE;
@@ -521,13 +606,21 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		      pixmap->drawable.width, 
 		      pixmap->drawable.height,
 		      pixmap->drawable.depth);
- 
+
   stride = pixmap->devKind;
+
   glamor_set_destination_pixmap_priv_nc(pixmap_priv);
   /* XXX we may don't need to validate it on GPU here,
    * we can just validate it on CPU. */
   glamor_validate_pixmap(pixmap); 
-  switch (access) {
+ 
+  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+    && ((format != GL_RGBA && format != GL_RGB && format != GL_ALPHA) || no_revert != 1)) {
+    
+    temp_pixmap = glamor_es2_pixmap_read_prepare(pixmap, &format, &type, no_alpha, no_revert);
+
+  } 
+ switch (access) {
   case GLAMOR_ACCESS_RO:
     gl_access = GL_READ_ONLY;
     gl_usage = GL_STREAM_READ;
@@ -544,9 +637,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     ErrorF("Glamor: Invalid access code. %d\n", access);
     assert(0);
   }
-  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
     data = malloc(stride * pixmap->drawable.height);
+  }
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
   if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
     glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
@@ -582,8 +677,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     }
     glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
     } else {
+    if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
+      type = GL_UNSIGNED_SHORT_5_5_5_1;
     glReadPixels (0, 0,
-                    row_length, pixmap->drawable.height,
+                    pixmap->drawable.width, pixmap->drawable.height,
                     format, type, data);
     }
   } else {
@@ -614,6 +711,12 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
 done:
   pixmap->devPrivate.ptr = data;
+
+  if (temp_pixmap) { 
+      glFlush();
+      (*screen->DestroyPixmap)(temp_pixmap);
+  }
+
   return TRUE;
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4009885..1f3e8c4 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -43,6 +43,7 @@
 #define GL_UNSIGNED_INT_8_8_8_8                 0x8035
 #define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367
 #define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368
+#define GL_UNSIGNED_INT_10_10_10_2              0x8036
 #define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364
 #define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
 #define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
@@ -236,6 +237,8 @@ typedef struct glamor_screen_private {
 
   /* glamor_finishaccess */
   GLint finish_access_prog[2];
+  GLint finish_access_no_revert[2];
+  GLint finish_access_swap_rb[2];
 
   /* glamor_solid */
   GLint solid_prog;
@@ -408,13 +411,16 @@ format_for_pixmap(PixmapPtr pixmap)
  *
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
+#ifndef GLAMOR_GLES2
 static inline int 
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 					   GLenum *tex_format, 
 					   GLenum *tex_type,
-					   int *no_alpha)
+					   int *no_alpha,
+                                           int *no_revert)
 {
   *no_alpha = 0;
+  *no_revert = 1;
   switch (format) {
   case PICT_a1:
     *tex_format = GL_COLOR_INDEX;
@@ -497,13 +503,125 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
   }
   return 0;
 }
+#else
+#define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
+
+static inline int 
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+					   GLenum *tex_format, 
+					   GLenum *tex_type,
+					   int *no_alpha,
+                                           int *no_revert)
+{
+  *no_alpha = 0;
+  *no_revert = IS_LITTLE_ENDIAN;
+
+  switch (format) {
+  case PICT_b8g8r8x8:
+    *no_alpha = 1;
+  case PICT_b8g8r8a8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    *no_revert = !IS_LITTLE_ENDIAN;
+    break;
+
+  case PICT_x8r8g8b8:
+    *no_alpha = 1;
+  case PICT_a8r8g8b8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+
+  case PICT_x8b8g8r8:
+    *no_alpha = 1;
+  case PICT_a8b8g8r8:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+
+  case PICT_x2r10g10b10:
+    *no_alpha = 1;
+  case PICT_a2r10g10b10:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x2b10g10r10:
+    *no_alpha = 1;
+  case PICT_a2b10g10r10:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_10_10_10_2;
+    *no_revert = TRUE;
+    break;
+ 
+  case PICT_r5g6b5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_b5g6r5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    *no_revert = FALSE;
+    break;
+
+  case PICT_x1b5g5r5:
+    *no_alpha = 1;
+  case PICT_a1b5g5r5:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    *no_revert = TRUE;
+    break;
+               
+  case PICT_x1r5g5b5:
+    *no_alpha = 1;
+  case PICT_a1r5g5b5:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_a8:
+    *tex_format = GL_ALPHA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x4r4g4b4:
+    *no_alpha = 1;
+  case PICT_a4r4g4b4:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    *no_revert = TRUE;
+    break;
+
+  case PICT_x4b4g4r4:
+    *no_alpha = 1;
+  case PICT_a4b4g4r4:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    *no_revert = TRUE;
+    break;
+ 
+  default:
+    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
+    return -1;
+  }
+  return 0;
+}
+
+
+#endif
 
 
 static inline int 
 glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
                                        GLenum *format, 
                                        GLenum *type, 
-                                       int *ax)
+                                       int *no_alpha,
+                                       int *no_revert)
 {
   glamor_pixmap_private *pixmap_priv;
   PictFormatShort pict_format;
@@ -515,7 +633,8 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
     pict_format = format_for_depth(pixmap->drawable.depth);
 
   return glamor_get_tex_format_type_from_pictformat(pict_format, 
-						    format, type, ax);  
+						    format, type, 
+                                                    no_alpha, no_revert);  
 }
 
 
@@ -658,6 +777,11 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
  * */
 void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
 
+
+PixmapPtr
+glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, 
+                               GLenum *type, int no_alpha, int no_revert);
+
 void glamor_set_alu(unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 void glamor_get_transform_uniform_locations(GLint prog,
@@ -870,7 +994,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
 
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
-#define GLAMOR_DELAYED_FILLING
+//#define GLAMOR_DELAYED_FILLING
 
 
 #include"glamor_utils.h" 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index addfdf2..a7a6186 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     float vertices[8], texcoords[8];
     GLfloat xscale, yscale, txscale, tyscale;
     GLuint tex;
-    int no_alpha;
+    int no_alpha, no_revert;
     if (image_format == XYBitmap) {
 	assert(depth == 1);
         goto fail;
@@ -290,7 +290,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
                                                &type, 
-                                               &no_alpha
+                                               &no_alpha,
+                                               &no_revert
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
@@ -300,14 +301,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     /* XXX consider to reuse a function to do the following work. */
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
-#if 0
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                         2 * sizeof(float),
                         vertices);
@@ -317,7 +310,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
                         2 * sizeof(float),
                         texcoords);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
 
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -333,20 +325,25 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
     if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
-      type = GL_UNSIGNED_BYTE;
       iformat = format;
     } 
     else {
       iformat = GL_RGBA;
     }
+
     glTexImage2D(GL_TEXTURE_2D, 0, iformat,
 		 w, h, 0,
 		 format, type, bits);
+
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#ifndef GLAMOR_GLES2
     glEnable(GL_TEXTURE_2D);
+#endif
 
     glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+    glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
+      glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
 
     x += drawable->x;
     y += drawable->y;
@@ -394,7 +391,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
+#ifndef GLAMOR_GLES2
     glDisable(GL_TEXTURE_2D);
+#endif
     glUseProgram(0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -409,9 +408,9 @@ fail:
     glamor_set_planemask(pixmap, ~0);
     glamor_fallback("to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
-	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format,
+    if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
+	fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format,
 		   bits);
-	glamor_finish_access(drawable);
+	glamor_finish_access(&pixmap->drawable);
     }
 }
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index a1d5dc1..8b2676b 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -38,7 +38,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_screen_private *glamor_priv;
     GLenum format, type;
-    int no_alpha, i;
+    int no_alpha, no_revert, i;
     uint8_t *drawpixels_src = (uint8_t *)src;
     RegionPtr clip = fbGetCompositeClip(gc);
     BoxRec *pbox;
@@ -46,18 +46,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 
     glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
-    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+      glamor_fallback("ES2 fallback.\n");
       goto fail;
+    }
 
     if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
                                                &format, 
                                                &type, 
-                                               &no_alpha
+                                               &no_alpha,
+                                               &no_revert
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
       goto fail;
     }
+
+
     if (glamor_set_destination_pixmap(dest_pixmap))
 	goto fail;
 
commit 0eea084db54fb88b9933fd1326a2b0b059b3f9d7
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:20:01 2011 +0800

    glamor: GLES2 doesn't support glEnable/Disable Texture 2D.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 5104f0b..25ad635 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -140,9 +140,11 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
       glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+#ifndef GLAMOR_GLES2
       glEnable(GL_TEXTURE_2D);
+#endif
       glamor_set_normalize_tcoords(src_xscale, src_yscale,
 				 tile_x1, tile_y1,
 				 tile_x2, tile_y2,
@@ -170,7 +172,9 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#ifndef GLAMOR_GLES2
     glDisable(GL_TEXTURE_2D);
+#endif
     }
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glUseProgram(0);
commit 504e03c0b59f4dc3b8058abdce79706a72cd0dde
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:17:58 2011 +0800

    glamor:  GLES2 doesn't support GL_CLAMP_TO_BORDER.
    
    Simply comments it out. Need revisit latter.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6099af7..cec6c8d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -376,11 +376,11 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
   glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
   switch (picture->repeatType) {
   case RepeatNone:
-#ifdef GLAMOR_GLES2
-    assert(1);
-#endif
+#ifndef GLAMOR_GLES2
+    /* XXX  GLES2 doesn't support GL_CLAMP_TO_BORDER. */
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+#endif
     break;
   case RepeatNormal:
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -407,8 +407,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     break;
   }
-
+#ifndef GLAMOR_GLES2
   glEnable(GL_TEXTURE_2D);
+#endif
 }
 
 static void
@@ -1037,10 +1038,12 @@ glamor_composite_with_shader(CARD8 op,
   glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
   REGION_UNINIT(dst->pDrawable->pScreen, &region);
   glDisable(GL_BLEND);
+#ifndef GLAMOR_GLES2
   glActiveTexture(GL_TEXTURE0);
   glDisable(GL_TEXTURE_2D);
   glActiveTexture(GL_TEXTURE1);
   glDisable(GL_TEXTURE_2D);
+#endif
   glUseProgram(0);
   if (saved_source_format) 
     source->format = saved_source_format;
commit f84cc8b84b2944b60eb2a8225e3c44a1cdfb228d
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 16 00:09:38 2011 +0800

    glamor-ddx: Hardware cursor's format should be GL_RGBA.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 5c2b5c1..9592013 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -494,9 +494,14 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 	}
 	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
 #ifdef GLAMOR_GLES2
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0,
-	  GL_BGRA,  GL_UNSIGNED_BYTE, image);
+       /* XXX Actually, the image is BGRA not RGBA, so the r and b
+        * should be swapped. But as normally, they are the same value
+        * ignore this currently, don't want to let CPU to do the swizzle.
+        * considering to put this function to the glamor rendering directory.
+        * Thus we can reuse the shader to do this.*/
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
+	  GL_RGBA,  GL_UNSIGNED_BYTE, image);
 #else
 	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
commit 23c1fba5e5a5fe8dd18c4c8a9b5a958ce4671160
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sat Aug 13 15:41:18 2011 -0400

    glamor: Remove glu3 which is unnecessary.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/configure.ac b/configure.ac
index 737aa84..69b1ac3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2163,7 +2163,6 @@ Xi/Makefile
 xfixes/Makefile
 exa/Makefile
 glamor/Makefile
-glamor/glu3/Makefile
 hw/Makefile
 hw/xfree86/Makefile
 hw/xfree86/common/Makefile
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2df76bd..ec38ac4 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -4,8 +4,6 @@ noinst_LTLIBRARIES = libglamor.la
 # built (in hw/xfree86/os-support/solaris) until after glamor is built
 SOLARIS_ASM_CFLAGS=""
 
-SUBDIRS = glu3
-
 if XORG
 sdk_HEADERS = glamor.h
 endif
@@ -39,5 +37,4 @@ libglamor_la_SOURCES = \
         glamor_picture.c\
 	glamor_window.c\
 	glamor.h
-libglamor_la_LIBADD = \
-	glu3/libglu3.la
+
diff --git a/glamor/glu3/Makefile.am b/glamor/glu3/Makefile.am
deleted file mode 100644
index 7d141a7..0000000
--- a/glamor/glu3/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-noinst_LTLIBRARIES = libglu3.la
-
-# Override these since glu3 doesn't need them and the needed files aren't
-# built (in hw/xfree86/os-support/solaris) until after glu3 is built
-SOLARIS_ASM_CFLAGS=""
-
-INCLUDES = \
-	$(XORG_INCS)
-
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
-
-libglu3_la_SOURCES = \
-	matrix.c \
-	glu3.h \
-	glu3_scalar.h
diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h
deleted file mode 100644
index 0a698cc..0000000
--- a/glamor/glu3/glu3.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright © 2009 Ian D. Romanick
- *
- * 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 (including the next
- * paragraph) 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.
- */
-
-#ifndef __glu3_h__
-#define __glu3_h__
-
-#include <GL/gl.h>
-
-#define GLU_VERSION_3_0
-
-struct GLUmat4;
-
-struct GLUvec4 {
-	GLfloat values[4];
-
-#ifdef __cplusplus
-	inline GLUvec4(void)
-	{
-	}
-
-	inline GLUvec4(GLfloat x , GLfloat y, GLfloat z, GLfloat w)
-	{
-		values[0] = x;
-		values[1] = y;
-		values[2] = z;
-		values[3] = w;
-	}
-
-	inline GLUvec4(const GLUvec4 &v)
-	{
-		values[0] = v.values[0];
-		values[1] = v.values[1];
-		values[2] = v.values[2];
-		values[3] = v.values[3];
-	}
-
-	GLUvec4 operator *(const GLUmat4 &) const;
-	GLUvec4 operator *(const GLUvec4 &) const;
-	GLUvec4 operator *(GLfloat) const;
-
-	GLUvec4 operator +(const GLUvec4 &) const;
-	GLUvec4 operator -(const GLUvec4 &) const;
-#endif /* __cplusplus */
-};
-
-
-struct GLUmat4 {
-	struct GLUvec4 col[4];
-
-#ifdef __cplusplus
-	inline GLUmat4(void)
-	{
-	}
-
-	inline GLUmat4(const GLUvec4 & c0, const GLUvec4 & c1,
-		       const GLUvec4 & c2, const GLUvec4 & c3)
-	{
-		col[0] = c0;
-		col[1] = c1;
-		col[2] = c2;
-		col[3] = c3;
-	}
-
-	inline GLUmat4(const GLUmat4 &m)
-	{
-		col[0] = m.col[0];
-		col[1] = m.col[1];
-		col[2] = m.col[2];
-		col[3] = m.col[3];
-	}
-
-
-	GLUvec4 operator *(const GLUvec4 &) const;
-	GLUmat4 operator *(const GLUmat4 &) const;
-	GLUmat4 operator *(GLfloat) const;
-
-	GLUmat4 operator +(const GLUmat4 &) const;
-	GLUmat4 operator -(const GLUmat4 &) const;
-#endif	/* __cplusplus */
-};
-
-#define GLU_MAX_STACK_DEPTH 32
-
-struct GLUmat4Stack {
-	struct GLUmat4 stack[GLU_MAX_STACK_DEPTH];
-	unsigned top;
-
-#ifdef __cplusplus
-	GLUmat4Stack() : top(0)
-	{
-		/* empty */
-	}
-#endif	/* __cplusplus */
-};
-
-#ifndef __cplusplus
-typedef struct GLUvec4 GLUvec4;
-typedef struct GLUmat4 GLUmat4;
-typedef struct GLUmat4Stack GLUmat4Stack;
-#endif /*  __cplusplus */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void gluScale4v(GLUmat4 *result, const GLUvec4 *);
-void gluTranslate4v(GLUmat4 *result, const GLUvec4 *);
-void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle);
-void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center,
-		 const GLUvec4 *up);
-void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect,
-		      GLfloat near, GLfloat far);
-void gluFrustum6f(GLUmat4 *result,
-		  GLfloat left, GLfloat right,
-		  GLfloat bottom, GLfloat top,
-		  GLfloat near, GLfloat far);
-void gluOrtho6f(GLUmat4 *result,
-		GLfloat left, GLfloat right,
-		GLfloat bottom, GLfloat top,
-		GLfloat near, GLfloat far);
-extern const GLUmat4 gluIdentityMatrix;
-
-#ifdef __cplusplus
-};
-#endif
-
-#ifdef __cplusplus
-GLfloat gluDot4(const GLUvec4 &, const GLUvec4 &);
-GLfloat gluDot3(const GLUvec4 &, const GLUvec4 &);
-GLfloat gluDot2(const GLUvec4 &, const GLUvec4 &);
-
-GLUvec4 gluCross(const GLUvec4 &, const GLUvec4 &);
-GLUvec4 gluNormalize(const GLUvec4 &);
-GLfloat gluLength(const GLUvec4 &);
-GLfloat gluLengthSqr(const GLUvec4 &);
-#endif /* __cplusplus */
-
-#include "glu3_scalar.h"
-
-#endif /* __glu3_h__ */
diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h
deleted file mode 100644
index 00592f0..0000000
--- a/glamor/glu3/glu3_scalar.h
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright © 2009 Ian D. Romanick
- *
- * 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 (including the next
- * paragraph) 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.
- */
-
-#include <math.h>
-#include <string.h>
-
-static inline void gluMult4v_4v(GLUvec4 *result,
-				const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	result->values[0] = v1->values[0] * v2->values[0];
-	result->values[1] = v1->values[1] * v2->values[1];
-	result->values[2] = v1->values[2] * v2->values[2];
-	result->values[3] = v1->values[3] * v2->values[3];
-}
-
-
-static inline void gluDiv4v_4v(GLUvec4 *result,
-			       const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	result->values[0] = v1->values[0] / v2->values[0];
-	result->values[1] = v1->values[1] / v2->values[1];
-	result->values[2] = v1->values[2] / v2->values[2];
-	result->values[3] = v1->values[3] / v2->values[3];
-}
-
-
-static inline void gluAdd4v_4v(GLUvec4 *result,
-			       const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	result->values[0] = v1->values[0] + v2->values[0];
-	result->values[1] = v1->values[1] + v2->values[1];
-	result->values[2] = v1->values[2] + v2->values[2];
-	result->values[3] = v1->values[3] + v2->values[3];
-}
-
-
-static inline void gluSub4v_4v(GLUvec4 *result,
-			       const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	result->values[0] = v1->values[0] - v2->values[0];
-	result->values[1] = v1->values[1] - v2->values[1];
-	result->values[2] = v1->values[2] - v2->values[2];
-	result->values[3] = v1->values[3] - v2->values[3];
-}
-
-
-static inline void gluMult4v_f(GLUvec4 *result,
-			       const GLUvec4 *v1, GLfloat f)
-{
-	result->values[0] = v1->values[0] * f;
-	result->values[1] = v1->values[1] * f;
-	result->values[2] = v1->values[2] * f;
-	result->values[3] = v1->values[3] * f;
-}
-
-
-static inline void gluDiv4v_f(GLUvec4 *result,
-			      const GLUvec4 *v1, GLfloat f)
-{
-	result->values[0] = v1->values[0] / f;
-	result->values[1] = v1->values[1] / f;
-	result->values[2] = v1->values[2] / f;
-	result->values[3] = v1->values[3] / f;
-}
-
-
-static inline void gluAdd4v_f(GLUvec4 *result,
-			      const GLUvec4 *v1, GLfloat f)
-{
-	result->values[0] = v1->values[0] + f;
-	result->values[1] = v1->values[1] + f;
-	result->values[2] = v1->values[2] + f;
-	result->values[3] = v1->values[3] + f;
-}
-
-
-static inline void gluSub4v_f(GLUvec4 *result,
-			      const GLUvec4 *v1, GLfloat f)
-{
-	result->values[0] = v1->values[0] - f;
-	result->values[1] = v1->values[1] - f;
-	result->values[2] = v1->values[2] - f;
-	result->values[3] = v1->values[3] - f;
-}
-
-
-static inline void gluMult4m_f(GLUmat4 *result,
-			       const GLUmat4 *m, GLfloat f)
-{
-	GLUmat4 temp;
-
-	gluMult4v_f(& temp.col[0], & m->col[0], f);
-	gluMult4v_f(& temp.col[1], & m->col[1], f);
-	gluMult4v_f(& temp.col[2], & m->col[2], f);
-	gluMult4v_f(& temp.col[3], & m->col[3], f);
-	*result = temp;
-}
-
-
-static inline void gluMult4m_4v(GLUvec4 *result,
-				const GLUmat4 *m, const GLUvec4 *v)
-{
-	GLUvec4 temp[6];
-	unsigned i;
-
-	for (i = 0; i < 4; i++) {
-		gluMult4v_f(& temp[i], & m->col[i], v->values[i]);
-	}
-
-	gluAdd4v_4v(& temp[4], & temp[0], & temp[1]);
-	gluAdd4v_4v(& temp[5], & temp[2], & temp[3]);
-	gluAdd4v_4v(result,    & temp[4], & temp[5]);
-}
-
-
-static inline void gluAdd4m_4m(GLUmat4 *result,
-			       const GLUmat4 *m1, const GLUmat4 *m2)
-{
-	GLUmat4 temp;
-
-	gluAdd4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]);
-	gluAdd4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]);
-	gluAdd4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]);
-	gluAdd4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]);
-	*result = temp;
-}
-
-static inline void gluSub4m_4m(GLUmat4 *result,
-			       const GLUmat4 *m1, const GLUmat4 *m2)
-{
-	GLUmat4 temp;
-
-	gluSub4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]);
-	gluSub4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]);
-	gluSub4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]);
-	gluSub4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]);
-	*result = temp;
-}
-
-static inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	return v1->values[0] * v2->values[0]
-		+ v1->values[1] * v2->values[1]
-		+ v1->values[2] * v2->values[2]
-		+ v1->values[3] * v2->values[3];
-}
-
-
-static inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	return v1->values[0] * v2->values[0]
-		+ v1->values[1] * v2->values[1]
-		+ v1->values[2] * v2->values[2];
-}
-
-
-static inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	return v1->values[0] * v2->values[0]
-		+ v1->values[1] * v2->values[1];
-}
-
-
-static inline void gluCross4v(GLUvec4 *result,
-			      const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	GLUvec4 temp;
-
-	temp.values[0] = (v1->values[1] * v2->values[2]) 
-		- (v1->values[2] * v2->values[1]);
-	temp.values[1] = (v1->values[2] * v2->values[0]) 
-		- (v1->values[0] * v2->values[2]);
-	temp.values[2] = (v1->values[0] * v2->values[1]) 
-		- (v1->values[1] * v2->values[0]);
-	temp.values[3] = 0.0;
-	*result = temp;
-}
-
-
-static inline void gluOuter4v(GLUmat4 *result,
-			      const GLUvec4 *v1, const GLUvec4 *v2)
-{
-	GLUmat4 temp;
-
-	gluMult4v_f(& temp.col[0], v1, v2->values[0]);
-	gluMult4v_f(& temp.col[1], v1, v2->values[1]);
-	gluMult4v_f(& temp.col[2], v1, v2->values[2]);
-	gluMult4v_f(& temp.col[3], v1, v2->values[3]);
-	*result = temp;
-}
-
-
-static inline GLfloat gluLengthSqr4v(const GLUvec4 *v)
-{
-	return gluDot4_4v(v, v);
-}
-
-
-static inline GLfloat gluLength4v(const GLUvec4 *v)
-{
-	return sqrt(gluLengthSqr4v(v));
-}
-
-
-static inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v)
-{
-	gluDiv4v_f(result, v, gluLength4v(v));
-}
-
-
-
-static inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m)
-{
-	unsigned i;
-	unsigned j;
-	GLUmat4 temp;
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < 4; j++) {
-			temp.col[i].values[j] = m->col[j].values[i];
-		}
-	}
-
-	*result = temp;
-}
-
-
-static inline void gluMult4m_4m(GLUmat4 *result,
-				const GLUmat4 *m1, const GLUmat4 *m2)
-{
-	GLUmat4 temp;
-	unsigned i;
-
-	for (i = 0; i < 4; i++) {
-		gluMult4m_4v(& temp.col[i], m1, & m2->col[i]);
-	}
-
-	*result = temp;
-}
-
-
-
-static inline void gluTranslate3f(GLUmat4 *result,
-				  GLfloat x, GLfloat y, GLfloat z)
-{
-	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
-	result->col[3].values[0] = x;
-	result->col[3].values[1] = y;
-	result->col[3].values[2] = z;
-}
-
-
-#ifdef __cplusplus
-static inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2)
-{
-	return v1.values[0] * v2.values[0]
-		+ v1.values[1] * v2.values[1]
-		+ v1.values[2] * v2.values[2]
-		+ v1.values[3] * v2.values[3];
-}
-
-
-static inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2)
-{
-	return v1.values[0] * v2.values[0]
-		+ v1.values[1] * v2.values[1]
-		+ v1.values[2] * v2.values[2];
-}
-
-
-static inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2)
-{
-	return v1.values[0] * v2.values[0]
-		+ v1.values[1] * v2.values[1];
-}
-
-
-inline GLUvec4 GLUvec4::operator+(const GLUvec4 &v) const
-{
-	return GLUvec4(values[0] + v.values[0],
-		       values[1] + v.values[1],
-		       values[2] + v.values[2],
-		       values[3] + v.values[3]);
-}
-
-
-inline GLUvec4 GLUvec4::operator-(const GLUvec4 &v) const
-{
-	return GLUvec4(values[0] - v.values[0],
-		       values[1] - v.values[1],
-		       values[2] - v.values[2],
-		       values[3] - v.values[3]);
-}
-
-
-inline GLUvec4 GLUvec4::operator*(const GLUvec4 &v) const
-{
-	return GLUvec4(values[0] * v.values[0],
-		       values[1] * v.values[1],
-		       values[2] * v.values[2],
-		       values[3] * v.values[3]);
-}
-
-
-inline GLUvec4 GLUvec4::operator*(GLfloat f) const
-{
-	return GLUvec4(values[0] * f,
-		       values[1] * f,
-		       values[2] * f,
-		       values[3] * f);
-}
-
-
-inline GLUvec4 GLUvec4::operator*(const GLUmat4 &m) const
-{
-	return GLUvec4(gluDot4(*this, m.col[0]),
-		       gluDot4(*this, m.col[1]),
-		       gluDot4(*this, m.col[2]),
-		       gluDot4(*this, m.col[3]));
-}
-
-
-inline GLUmat4 GLUmat4::operator+(const GLUmat4 &m) const
-{
-	GLUmat4 temp;
-
-	gluAdd4m_4m(& temp, this, &m);
-	return temp;
-}
-
-
-inline GLUmat4 GLUmat4::operator-(const GLUmat4 &m) const
-{
-	return GLUmat4(col[0] - m.col[0],
-		       col[1] - m.col[1],
-		       col[2] - m.col[2],
-		       col[3] - m.col[3]);
-}
-
-
-inline GLUmat4 GLUmat4::operator*(GLfloat f) const
-{
-	GLUmat4 temp;
-
-	gluMult4m_f(& temp, this, f);
-	return temp;
-}
-
-
-inline GLUvec4 GLUmat4::operator*(const GLUvec4 &v) const
-{
-	return (col[0] * v.values[0])
-		+ (col[1] * v.values[1])
-		+ (col[2] * v.values[2])
-		+ (col[3] * v.values[3]);
-}
-
-
-inline GLUmat4 GLUmat4::operator*(const GLUmat4 &m) const
-{
-	GLUmat4 temp;
-
-	gluMult4m_4m(& temp, this, &m);
-	return temp;
-}
-
-
-#endif /* __cplusplus */
diff --git a/glamor/glu3/matrix.c b/glamor/glu3/matrix.c
deleted file mode 100644
index b3d5819..0000000
--- a/glamor/glu3/matrix.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright © 2009 Ian D. Romanick
- *
- * 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 (including the next
- * paragraph) 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.
- */
-
-#include <string.h>
-#include "glu3.h"
-
-#define DEG2RAD(d) ((d) * M_PI / 180.0)
-
-const GLUmat4 gluIdentityMatrix = {
-	{
-		{ { 1.0f, 0.0f,  0.0f,  0.0f } },
-		{ { 0.0f, 1.0f,  0.0f,  0.0f } },
-		{ { 0.0f, 0.0f,  1.0f,  0.0f } },
-		{ { 0.0f, 0.0f,  0.0f,  1.0f } }
-	}
-};
-
-
-void gluTranslate4v(GLUmat4 *result, const GLUvec4 *t)
-{
-	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
-	result->col[3] = *t;
-	result->col[3].values[3] = 1.0f;
-}
-
-
-void gluScale4v(GLUmat4 *result, const GLUvec4 *t)
-{
-	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
-	result->col[0].values[0] = t->values[0];
-	result->col[1].values[1] = t->values[1];
-	result->col[2].values[2] = t->values[2];
-}
-
-
-void gluLookAt4v(GLUmat4 *result,
-		 const GLUvec4 *_eye,
-		 const GLUvec4 *_center,
-		 const GLUvec4 *_up)
-{
-	static const GLUvec4 col3 = { { 0.0f, 0.0f, 0.0f, 1.0f } };
-	const GLUvec4 e = { 
-		{ -_eye->values[0], -_eye->values[1], -_eye->values[2], 0.0f }
-	};
-	GLUmat4  translate;
-	GLUmat4  rotate;
-	GLUmat4  rotateT;
-	GLUvec4  f;
-	GLUvec4  s;
-	GLUvec4  u;
-	GLUvec4  center, up;
-
-	center = *_center;
-	center.values[3] = 0;
-	up = *_up;
-	up.values[3] = 0;
-
-	gluAdd4v_4v(& f, &center, &e);
-	gluNormalize4v(& f, & f);
-
-	gluNormalize4v(& u, &up);
-
-	gluCross4v(& s, & f, & u);
-	gluCross4v(& u, & s, & f);
-
-	rotate.col[0] = s;
-	rotate.col[1] = u;
-	rotate.col[2].values[0] = -f.values[0];
-	rotate.col[2].values[1] = -f.values[1];
-	rotate.col[2].values[2] = -f.values[2];
-	rotate.col[2].values[3] = 0.0f;
-	rotate.col[3] = col3;
-	gluTranspose4m(& rotateT, & rotate);
-
-	gluTranslate4v(& translate, & e);
-	gluMult4m_4m(result, & rotateT, & translate);
-}
-
-
-void gluRotate4v(GLUmat4 *result, const GLUvec4 *_axis, GLfloat angle)
-{
-	GLUvec4 axis;
-	const float c = cos(angle);
-	const float s = sin(angle);
-	const float one_c = 1.0 - c;
-
-	float xx;
-	float yy;
-	float zz;
-
-	float xs;
-	float ys;
-	float zs;
-
-	float xy;
-	float xz;
-	float yz;
-
-	/* Only normalize the 3-component axis.  A gluNormalize3v might be
-	 * appropriate to save us some computation.
-	 */
-	axis = *_axis;
-	axis.values[3] = 0;
-	gluNormalize4v(&axis, &axis);
-
-	xx = axis.values[0] * axis.values[0];
-	yy = axis.values[1] * axis.values[1];
-	zz = axis.values[2] * axis.values[2];
-
-	xs = axis.values[0] * s;
-	ys = axis.values[1] * s;
-	zs = axis.values[2] * s;
-
-	xy = axis.values[0] * axis.values[1];
-	xz = axis.values[0] * axis.values[2];
-	yz = axis.values[1] * axis.values[2];
-
-
-	result->col[0].values[0] = (one_c * xx) + c;
-	result->col[0].values[1] = (one_c * xy) + zs;
-	result->col[0].values[2] = (one_c * xz) - ys;
-	result->col[0].values[3] = 0.0;
-
-	result->col[1].values[0] = (one_c * xy) - zs;
-	result->col[1].values[1] = (one_c * yy) + c;
-	result->col[1].values[2] = (one_c * yz) + xs;
-	result->col[1].values[3] = 0.0;
-
-
-	result->col[2].values[0] = (one_c * xz) + ys;
-	result->col[2].values[1] = (one_c * yz) - xs;
-	result->col[2].values[2] = (one_c * zz) + c;
-	result->col[2].values[3] = 0.0;
-
-	result->col[3].values[0] = 0.0;
-	result->col[3].values[1] = 0.0;
-	result->col[3].values[2] = 0.0;
-	result->col[3].values[3] = 1.0;
-}
-
-
-void
-gluPerspective4f(GLUmat4 *result,
-		 GLfloat fovy, GLfloat aspect, GLfloat near, GLfloat far)
-{
-	const double sine = sin(DEG2RAD(fovy / 2.0));
-	const double cosine = cos(DEG2RAD(fovy / 2.0));
-	const double sine_aspect = sine * aspect;
-	const double dz = far - near;
-
-
-	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
-	if ((sine == 0.0) || (dz == 0.0) || (sine_aspect == 0.0)) {
-		return;
-	}
-
-	result->col[0].values[0] = cosine / sine_aspect;
-	result->col[1].values[1] = cosine / sine;
-	result->col[2].values[2] = -(far + near) / dz;
-	result->col[2].values[3] = -1.0;
-	result->col[3].values[2] = -2.0 * near * far / dz;
-	result->col[3].values[3] =  0.0;
-}
-
-void gluFrustum6f(GLUmat4 *result,
-		  GLfloat left, GLfloat right,
-		  GLfloat bottom, GLfloat top,
-		  GLfloat near, GLfloat far)
-{
-	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
-
-	result->col[0].values[0] = (2.0 * near) / (right - left);
-	result->col[1].values[1] = (2.0 * near) / (top - bottom);
-	result->col[2].values[0] = (right + left) / (right - left);
-	result->col[2].values[1] = (top + bottom) / (top - bottom);
-	result->col[2].values[2] = -(far + near) / (far - near);
-	result->col[2].values[3] = -1.0;
-	result->col[3].values[2] = -2.0 * near * far / (far - near);
-	result->col[3].values[3] =  0.0;
-}
-
-void gluOrtho6f(GLUmat4 *result,
-		GLfloat left, GLfloat right,
-		GLfloat bottom, GLfloat top,
-		GLfloat near, GLfloat far)
-{
-	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
-
-	result->col[0].values[0] = 2.0f / (right - left);
-	result->col[3].values[0] = -(right + left) / (right - left);
-
-	result->col[1].values[1] = 2.0f / (top - bottom);
-	result->col[3].values[1] = -(top + bottom) / (top - bottom);
-
-	result->col[2].values[2] = -2.0f / (far - near);
-	result->col[3].values[2] = -(far + near) / (far - near);
-}
commit a228effbeb339ae6f0b73c633022b3ec9981148f
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:56:02 2011 -0400

    glamor: Remove useless glVertexPointer related code.
    
    As glVertexPointer is not supported by GLES2, I totally
    replaced it by VertexAttribArray. This commit remove those
    old code.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index dca7160..1e160ac 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -180,15 +180,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
 
 
-#if 0
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
                           2 * sizeof(float),
                           vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@@ -201,19 +196,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glEnable(GL_TEXTURE_2D);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-#if 0
-      glClientActiveTexture(GL_TEXTURE0);
-      glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
-      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-      glUseProgram(glamor_priv->finish_access_prog[0]);
-#else
  
       glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
                             2 * sizeof(float),
                             texcoords);
       glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-      glUseProgram(glamor_priv->finish_access_prog[2]);
-#endif
+      glUseProgram(glamor_priv->finish_access_prog[0]);
  
    } 
     else {
@@ -240,19 +228,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-#if 0
-    glDisableClientState(GL_VERTEX_ARRAY);
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-      glDisable(GL_TEXTURE_2D);
-    }
-#else
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
       glDisable(GL_TEXTURE_2D);
     }
-#endif
     glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
     if (flush_needed) 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 09851a0..9f04573 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -141,30 +141,7 @@ void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-#ifndef GLAMOR_GLES2
   const char *vs_source =
-    "void main()\n"
-    "{\n"
-    "	gl_Position = gl_Vertex;\n"
-    "	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
-    "}\n";
-  const char *fs_source =
-    "varying vec2 texcoords;\n"
-    "uniform sampler2D sampler;\n"
-    "void main()\n"
-    "{\n"
-    "	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
-    "}\n";
-
-  const char *aswizzle_source =
-    "varying vec2 texcoords;\n"
-    "uniform sampler2D sampler;\n"
-    "void main()\n"
-    "{\n"
-    " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
-    "}\n";
-#endif
-  const char *es_vs_source =
     "attribute vec4 v_position;\n"
     "attribute vec4 v_texcoord0;\n"
     "varying vec2 source_texture;\n"
@@ -174,7 +151,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "	source_texture = v_texcoord0.xy;\n"
     "}\n";
 
-  const char *es_fs_source =
+  const char *fs_source =
     "varying vec2 source_texture;\n"
     "uniform sampler2D sampler;\n"
     "void main()\n"
@@ -182,62 +159,37 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "	gl_FragColor = texture2D(sampler, source_texture);\n"
     "}\n";
     
-  const char *es_aswizzle_source =
+  const char *set_alpha_source =
     "varying vec2 source_texture;\n"
-    "varying vec2 texcoords;\n"
     "uniform sampler2D sampler;\n"
     "void main()\n"
     "{\n"
     " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
     "}\n";
-
-
-
-  GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
-  GLint es_fs_prog, es_vs_prog, es_avs_prog, es_aswizzle_prog;
+  GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
+  GLint sampler_uniform_location;
 
   glamor_priv->finish_access_prog[0] = glCreateProgram();
   glamor_priv->finish_access_prog[1] = glCreateProgram();
-  glamor_priv->finish_access_prog[2] = glCreateProgram();
-  glamor_priv->finish_access_prog[3] = glCreateProgram();
 
-#ifndef GLAMOR_GLES2
   vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
   fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
   glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
   glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
 
   avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-  aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
+  set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, set_alpha_source);
   glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-  glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
-#endif
-  es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
-  es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source);
-  glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog);
-  glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog);
-
-  es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
-  es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source);
-  glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog);
-  glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog);
- 
+  glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
 
-
-#ifndef GLAMOR_GLES2
+  glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position");
+  glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
-  glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
-#endif
-  glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position");
-  glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]);
 
-  glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_POS, "v_position");
-  glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
-  glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]);
+  glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position");
+  glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
 
-  GLint sampler_uniform_location;
-#ifndef GLAMOR_GLES2
   sampler_uniform_location =
     glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
   glUseProgram(glamor_priv->finish_access_prog[0]);
@@ -249,19 +201,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   glUseProgram(glamor_priv->finish_access_prog[1]);
   glUniform1i(sampler_uniform_location, 0);
   glUseProgram(0);
-#endif
-  sampler_uniform_location =
-    glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler");
-  glUseProgram(glamor_priv->finish_access_prog[2]);
-  glUniform1i(sampler_uniform_location, 0);
-  glUseProgram(0);
-
-  sampler_uniform_location =
-    glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler");
-  glUseProgram(glamor_priv->finish_access_prog[3]);
-  glUniform1i(sampler_uniform_location, 0);
-  glUseProgram(0);
- 
 }
 
 void
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 556ff34..660ffe0 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -102,33 +102,11 @@ void
 glamor_init_solid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    const char *solid_vs_only =
-#if 0
-#else
-        "attribute vec4 v_position;"
-#endif
-	"uniform vec4 color;\n"
-	"void main()\n"
-	"{\n"
-#if 0
-	"	gl_Position = gl_Vertex;\n"
-#else
-        "       gl_Position = v_position;\n"
-#endif
-	"	gl_Color = color;\n"
-	"}\n";
     const char *solid_vs =
-#if 0
-#else
         "attribute vec4 v_position;"
-#endif
 	"void main()\n"
 	"{\n"
-#if 0
-	"	gl_Position = gl_Vertex;\n"
-#else
         "       gl_Position = v_position;\n"
-#endif
 	"}\n";
     const char *solid_fs =
 	"uniform vec4 color;\n"
@@ -201,25 +179,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
  
     glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
 
-#if 0
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float), vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
 
     glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
 				 glamor_priv->yInverted,
 				 vertices);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-#if 0
-    glDisableClientState(GL_VERTEX_ARRAY);
-#else
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     glUseProgram(0);
     return TRUE;
 fail:
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 8ca1318..1dc1ee9 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -32,14 +32,9 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
 				 glamor_pixmap_private *pixmap_priv)
 {
     GLfloat vertices[8];
-#if 0
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float), vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     glUseProgram(glamor_priv->solid_prog);
     glUniform4fv(glamor_priv->solid_color_uniform_location, 
       1, pixmap_priv->pending_op.fill.color4fv);
@@ -52,11 +47,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
     vertices[6] = -1;
     vertices[7] = 1;
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-#if 0
-    glDisableClientState(GL_VERTEX_ARRAY);
-#else
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     glUseProgram(0);
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
@@ -341,23 +332,14 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glEnable(GL_TEXTURE_2D);
-#if 0
   glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-#else
-  glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]);
-#endif
 
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
   glDisable(GL_TEXTURE_2D);
   glUseProgram(0);
-#if 0
-  glDisableClientState(GL_VERTEX_ARRAY);
-  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
   glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
   glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
   glDeleteTextures(1, &tex);
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
@@ -516,7 +498,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   unsigned int stride, row_length, y;
   GLenum format, type, gl_access, gl_usage;
   int no_alpha;
-  uint8_t *data, *read;
+  uint8_t *data = NULL, *read;
   glamor_screen_private *glamor_priv =
     glamor_get_screen_private(pixmap->drawable.pScreen);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2c2bf22..4009885 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -235,7 +235,7 @@ typedef struct glamor_screen_private {
   int max_fbo_size;
 
   /* glamor_finishaccess */
-  GLint finish_access_prog[4];
+  GLint finish_access_prog[2];
 
   /* glamor_solid */
   GLint solid_prog;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 38da796..addfdf2 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -35,8 +35,8 @@
 void
 glamor_init_putimage_shaders(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 #if 0
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *xybitmap_vs =
 	"uniform float x_bias;\n"
 	"uniform float x_scale;\n"
@@ -346,11 +346,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glEnable(GL_TEXTURE_2D);
 
-#if 0
     glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
-#else
-    glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]);
-#endif
 
     x += drawable->x;
     y += drawable->y;
@@ -400,13 +396,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
     glDisable(GL_TEXTURE_2D);
     glUseProgram(0);
-#if 0
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
     glDeleteTextures(1, &tex);
     if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 12b0924..6099af7 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -523,47 +523,25 @@ glamor_setup_composite_vbo(ScreenPtr screen)
 
   glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 
-#if 0
-  glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-		  (void *)((long)glamor_priv->vbo_offset));
-  glEnableClientState(GL_VERTEX_ARRAY);
-#else
   glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset));
   glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
 
   if (glamor_priv->has_source_coords) {
-#if 0
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-		      (void *)(glamor_priv->vbo_offset + 2 * sizeof(float)));
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float)));
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
   }
 
   if (glamor_priv->has_mask_coords) {
-#if 0
-    glClientActiveTexture(GL_TEXTURE1);
-    glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-		      (void *)(glamor_priv->vbo_offset +
-			       (glamor_priv->has_source_coords ? 4 : 2) *
-			       sizeof(float)));
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, 
                         glamor_priv->vb_stride,
                        (void *)((long)glamor_priv->vbo_offset + 
 			       (glamor_priv->has_source_coords ? 4 : 2) *
                                sizeof(float)));
     glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
-#endif
   }
 }
 
@@ -1054,17 +1032,9 @@ glamor_composite_with_shader(CARD8 op,
   glamor_flush_composite_rects(screen);
 
   glBindBuffer(GL_ARRAY_BUFFER, 0);
-#if 0
-  glClientActiveTexture(GL_TEXTURE0);
-  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-  glClientActiveTexture(GL_TEXTURE1);
-  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-  glDisableClientState(GL_VERTEX_ARRAY);
-#else
   glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
   glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
   glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
-#endif
   REGION_UNINIT(dst->pDrawable->pScreen, &region);
   glDisable(GL_BLEND);
   glActiveTexture(GL_TEXTURE0);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index cb23552..5104f0b 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -41,35 +41,20 @@ glamor_init_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *tile_vs =
-#if 0
-#else
         "attribute vec4 v_position;\n"
         "attribute vec4 v_texcoord0;\n"
         "varying vec2 tile_texture;\n"
-#endif
 	"void main()\n"
 	"{\n"
-#if 0
-	"	gl_Position = gl_Vertex;\n"
-	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
-#else
         "       gl_Position = v_position;\n"
         "       tile_texture = v_texcoord0.xy;\n"
-#endif
 	"}\n";
     const char *tile_fs =
-#if 0
-#else
         "varying vec2 tile_texture;\n"
-#endif
 	"uniform sampler2D sampler;\n"
 	"void main()\n"
 	"{\n"
-#if 0
-	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
-#else
 	"	gl_FragColor = texture2D(sampler, tile_texture);\n"
-#endif
 	"}\n";
     GLint fs_prog, vs_prog;
     GLint sampler_uniform_location;
@@ -163,16 +148,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				 tile_x2, tile_y2,
 				 glamor_priv->yInverted,
 				 source_texcoords);
-#if 0
-      glClientActiveTexture(GL_TEXTURE0);
-      glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
-      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#else
       glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
                             2 * sizeof(float),
                             source_texcoords);
       glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-#endif
    } 
    else {
      GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
@@ -183,31 +162,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				 glamor_priv->yInverted,
 				 vertices);
 
-#if 0
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-#else
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
                           2 * sizeof(float),
                          vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
-#if 0
-    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
-    glClientActiveTexture(GL_TEXTURE0);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glDisable(GL_TEXTURE_2D);
-    }
-    glDisableClientState(GL_VERTEX_ARRAY);
-#else
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glDisable(GL_TEXTURE_2D);
     }
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-#endif
     glUseProgram(0);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
commit 5cbb2a4ca05f696d2af9a2e50bf106b6f2acd1c6
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:35:26 2011 -0400

    glamor: Only fallbac glamor_setspan when we are using gles2.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index d08be13..a1d5dc1 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -36,6 +36,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 DDXPointPtr points, int *widths, int n, int sorted)
 {
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_screen_private *glamor_priv;
     GLenum format, type;
     int no_alpha, i;
     uint8_t *drawpixels_src = (uint8_t *)src;
@@ -43,8 +44,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     BoxRec *pbox;
     int x_off, y_off;
 
+    glamor_priv = glamor_get_screen_private(drawable->pScreen);
 
-    goto fail;
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+      goto fail;
 
     if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
                                                &format, 
commit 667d65534d64df30146cfa0d32522bced51e0697
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:27:12 2011 -0400

    glamor:  Unify the variable name which used to indicate no alpha.
    
    The original code use different name and the name is vague.
    Now change it to no_alpha.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 237c1e7..e1a20ba 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -41,7 +41,7 @@ glamor_get_spans(DrawablePtr drawable,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    int ax;
+    int no_alpha;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     int i;
@@ -56,7 +56,7 @@ glamor_get_spans(DrawablePtr drawable,
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
                                                &type, 
-                                               &ax
+                                               &no_alpha
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 5ac62f4..8ca1318 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -272,7 +272,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
  * */
 
 static void
-_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, int ax, int flip)
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, 
+                                 GLenum type, int no_alpha, int flip)
 {
 
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -299,7 +300,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   /* Try fast path firstly, upload the pixmap to the texture attached
    * to the fbo directly. */
 
-  if (ax == 0 && !need_flip) {
+  if (no_alpha == 0 && !need_flip) {
     __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex);
     return;
   }
@@ -341,9 +342,9 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glEnable(GL_TEXTURE_2D);
 #if 0
-  glUseProgram(glamor_priv->finish_access_prog[ax]);
+  glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 #else
-  glUseProgram(glamor_priv->finish_access_prog[ax + 2]);
+  glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]);
 #endif
 
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -397,13 +398,13 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
 
 /*  
  * Prepare to upload a pixmap to texture memory.
- * ax 1 means the format needs to wire alpha to 1.
+ * no_alpha equals 1 means the format needs to wire alpha to 1.
  * Two condtion need to setup a fbo for a pixmap
  * 1. !yInverted, we need to do flip if we are not yInverted.
- * 2. ax != 0, we need to wire the alpha.
+ * 2. no_alpha != 0, we need to wire the alpha.
  * */
 static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha)
 {
   int need_fbo;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -419,7 +420,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
   if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 
     return 0; 
 
-  if (ax != 0 || !glamor_priv->yInverted)
+  if (no_alpha != 0 || !glamor_priv->yInverted)
     need_fbo = 1;
   else
     need_fbo = 0;
@@ -444,16 +445,16 @@ enum glamor_pixmap_status
 glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 {
   GLenum format, type;
-  int ax;
+  int no_alpha;
 
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format, 
 					     &type, 
-					     &ax)) {
+					     &no_alpha)) {
     glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     return GLAMOR_UPLOAD_FAILED;
   }
-  if (glamor_pixmap_upload_prepare(pixmap, ax))
+  if (glamor_pixmap_upload_prepare(pixmap, no_alpha))
     return GLAMOR_UPLOAD_FAILED;
   glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
 		      "Uploading pixmap %p  %dx%d depth%d.\n", 
@@ -461,7 +462,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 		      pixmap->drawable.width, 
 		      pixmap->drawable.height,
 		      pixmap->drawable.depth);
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1);
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1);
   return GLAMOR_UPLOAD_DONE;
 }
 
@@ -485,16 +486,16 @@ void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
 {
   GLenum format, type;
-  int ax;
+  int no_alpha;
 
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format, 
 					     &type, 
-					     &ax)) {
+					     &no_alpha)) {
     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     assert(0);
   }
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1);
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha, 1);
 }
 
 
@@ -514,7 +515,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   unsigned int stride, row_length, y;
   GLenum format, type, gl_access, gl_usage;
-  int ax;
+  int no_alpha;
   uint8_t *data, *read;
   glamor_screen_private *glamor_priv =
     glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -522,12 +523,10 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
     return TRUE;
-  /* XXX we may don't need to validate it on GPU here,
-   * we can just validate it on CPU. */
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format,
 					     &type, 
-					     &ax)) {
+					     &no_alpha)) {
     ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
     assert(0);  // Should never happen.
     return FALSE;
@@ -543,6 +542,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
  
   stride = pixmap->devKind;
   glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+  /* XXX we may don't need to validate it on GPU here,
+   * we can just validate it on CPU. */
   glamor_validate_pixmap(pixmap); 
   switch (access) {
   case GLAMOR_ACCESS_RO:
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 69590a5..2c2bf22 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -404,7 +404,7 @@ format_for_pixmap(PixmapPtr pixmap)
 
 /*
  * Map picture's format to the correct gl texture format and type.
- * xa is used to indicate whehter we need to wire alpha to 1. 
+ * no_alpha is used to indicate whehter we need to wire alpha to 1. 
  *
  * Return 0 if find a matched texture type. Otherwise return -1.
  **/
@@ -412,41 +412,41 @@ static inline int
 glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 					   GLenum *tex_format, 
 					   GLenum *tex_type,
-					   int *xa)
+					   int *no_alpha)
 {
-  *xa = 0;
+  *no_alpha = 0;
   switch (format) {
   case PICT_a1:
     *tex_format = GL_COLOR_INDEX;
     *tex_type = GL_BITMAP;
     break;
   case PICT_b8g8r8x8:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_b8g8r8a8:
     *tex_format = GL_BGRA;
     *tex_type = GL_UNSIGNED_INT_8_8_8_8;
     break;
 
   case PICT_x8r8g8b8:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a8r8g8b8:
     *tex_format = GL_BGRA;
     *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
     break;
   case PICT_x8b8g8r8:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a8b8g8r8:
     *tex_format = GL_RGBA;
     *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
     break;
   case PICT_x2r10g10b10:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a2r10g10b10:
     *tex_format = GL_BGRA;
     *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
     break;
   case PICT_x2b10g10r10:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a2b10g10r10:
     *tex_format = GL_RGBA;
     *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
@@ -461,14 +461,14 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
     break;
   case PICT_x1b5g5r5:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a1b5g5r5:
     *tex_format = GL_RGBA;
     *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
     break;
                
   case PICT_x1r5g5b5:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a1r5g5b5:
     *tex_format = GL_BGRA;
     *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
@@ -478,14 +478,14 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
     *tex_type = GL_UNSIGNED_BYTE;
     break;
   case PICT_x4r4g4b4:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a4r4g4b4:
     *tex_format = GL_BGRA;
     *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
     break;
 
   case PICT_x4b4g4r4:
-    *xa = 1;
+    *no_alpha = 1;
   case PICT_a4b4g4r4:
     *tex_format = GL_RGBA;
     *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index a6aadce..38da796 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     float vertices[8], texcoords[8];
     GLfloat xscale, yscale, txscale, tyscale;
     GLuint tex;
-    int ax = 0;
+    int no_alpha;
     if (image_format == XYBitmap) {
 	assert(depth == 1);
         goto fail;
@@ -290,7 +290,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
                                                &type, 
-                                               &ax
+                                               &no_alpha
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
@@ -347,9 +347,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glEnable(GL_TEXTURE_2D);
 
 #if 0
-    glUseProgram(glamor_priv->finish_access_prog[ax]);
+    glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
 #else
-    glUseProgram(glamor_priv->finish_access_prog[ax + 2]);
+    glUseProgram(glamor_priv->finish_access_prog[no_alpha + 2]);
 #endif
 
     x += drawable->x;
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index af26643..d08be13 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -37,18 +37,19 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 {
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    int ax, i;
+    int no_alpha, i;
     uint8_t *drawpixels_src = (uint8_t *)src;
     RegionPtr clip = fbGetCompositeClip(gc);
     BoxRec *pbox;
     int x_off, y_off;
 
+
     goto fail;
 
     if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
                                                &format, 
                                                &type, 
-                                               &ax
+                                               &no_alpha
                                                )) {
       glamor_fallback("unknown depth. %d \n", 
                      drawable->depth);
commit 5e7fdbb498c47b6e89280b8354f0ebaaf61d0646
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:08:12 2011 -0400

    glamor: Disable ALPHA8 fbo.
    
    As some platform doesn't support to use ALPHA8 texture as
    draw target, we have to disable it. It seems there is no
    easy way to check that.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 06103ac..cd261ac 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -146,9 +146,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return pixmap;
 
     switch (depth) {
+#if 0
     case 8:
         format = GL_ALPHA;
         break;
+#endif
     case 24:
         format = GL_RGB;
         break; 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index b105916..5ac62f4 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -219,9 +219,11 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
   GLenum iformat;
 
   switch (pixmap->drawable.depth) {
+#if 0
     case 8:
         iformat = GL_ALPHA;
         break;
+#endif
     case 24:
         iformat = GL_RGB;
         break; 
commit 172e8cfcd411b1abeaf8ede2e3882d6198cee5b8
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:05:02 2011 -0400

    glamor: Remove GLEW dependency.
    
    Glamor doesn't need to use GLEW. We can parse the extension by
    ourself. This patch also fix the fbo size checking from a hard
    coded style to a dynamic checking style.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/README b/README
index fd31d99..c240ac7 100644
--- a/README
+++ b/README
@@ -2,48 +2,6 @@
 
 1. Prerequirement.
 Please install makedepend and libudev-devel firstly. 
-Glamor need patch glew-1.5.8, here is the patch:
-
-
-diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile
---- ../Downloads/glew-1.5.8/Makefile    2011-01-31 22:17:27.000000000 +0800
-+++ glew-1.5.8/Makefile 2011-06-28 10:13:54.147700479 +0800
-@@ -63,8 +63,12 @@
- else
- OPT = $(POPT)
- endif
--INCLUDE = -Iinclude
-+
-+INCLUDE = -Iinclude
- CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA)
-+ifeq ($(NO_GLX), 1)
-+CFLAGS += -D_NO_GLX_
-+endif
-
- LIB.SRCS = src/glew.c
- LIB.OBJS = $(LIB.SRCS:.c=.o)
-diff -ur ../Downloads/glew-1.5.8/src/glew.c glew-1.5.8/src/glew.c
---- ../Downloads/glew-1.5.8/src/glew.c  2011-01-31 22:17:27.000000000 +0800
-+++ glew-1.5.8/src/glew.c       2011-06-28 10:06:45.952700777 +0800
-@@ -11379,6 +11379,10 @@
- {
-   GLenum r;
-   if ( (r = glewContextInit()) ) return r;
-+#if defined(_NO_GLX_)
-+  return r;
-+#endif
-+
- #if defined(_WIN32)
-   return wglewContextInit();
- #elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */
-
-
-As xserver's glx extension code has conflicts with glew's glx related
-initialization, we have to disable it in glew currently. Please apply the
-above patch to glew and then build the glew as follow which will 
-workaround the problem.
-
-glew-1.5.8# NO_GLX=1 make
 
 2. Build xserver-glamor.
 
diff --git a/configure.ac b/configure.ac
index a94cd00..737aa84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2036,15 +2036,6 @@ if test "$KDRIVE" = yes; then
         AC_MSG_ERROR([Xephyr dependencies missing])
     fi
 
-    AC_CHECK_LIB(GLEW, glewInit, [
-      AC_CHECK_HEADER(GL/glew.h, [], [
-        AC_MSG_ERROR([requires glew http://glew.sourceforge.net/])
-      ])
-    ], [
-      AC_MSG_ERROR([requires glew http://glew.sourceforge.net/])
-    ])
-    XEPHYR_LIBS="$XEPHYR_LIBS -lGLEW"
-
     # Xephyr needs nanosleep() which is in librt on Solaris
     AC_CHECK_FUNC([nanosleep], [],
         AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
diff --git a/glamor/glamor.c b/glamor/glamor.c
index dd0d69d..06103ac 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -110,10 +110,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     GLuint tex;
     int type = GLAMOR_PIXMAP_TEXTURE;
     glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    if (!glamor_check_fbo_width_height(w,h)
+    if (!glamor_check_fbo_size(glamor_priv, w,h)
 	|| !glamor_check_fbo_depth(depth) 
 	|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
 	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
@@ -249,6 +250,7 @@ Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
 {
     glamor_screen_private *glamor_priv;
+    int gl_version;
 
 #ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
@@ -271,7 +273,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	LogMessage(X_WARNING,
 		   "glamor%d: Failed to allocate screen private\n",
 		   screen->myNum);
-        return FALSE;
+        goto fail;
     }
 
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
@@ -281,36 +283,27 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         LogMessage(X_WARNING,
                    "glamor%d: Failed to allocate pixmap private\n",
                    screen->myNum);
-        return FALSE;
+        goto fail;;
     }
 
+    gl_version = glamor_gl_get_version();
 
-#ifndef GLAMOR_GLES2
-    glewInit();
-    if (!GLEW_EXT_framebuffer_object) {
-	ErrorF("GL_EXT_framebuffer_object required\n");
-	goto fail;
-    }
-    if (!GLEW_ARB_shader_objects) {
-	ErrorF("GL_ARB_shader_objects required\n");
-	goto fail;
-    }
-    if (!GLEW_ARB_vertex_shader) {
-	ErrorF("GL_ARB_vertex_shader required\n");
-	goto fail;
+    if (gl_version < GLAMOR_GL_VERSION_ENCODE(1,3))  {
+        ErrorF("Require Opengl 1.3 or latter.\n");
+        goto fail;
     }
 
-    if (!GLEW_ARB_pixel_buffer_object) {
-	ErrorF("GL_ARB_pixel_buffer_object required\n");
-	goto fail;
-    }
- 
-    if (!GLEW_EXT_bgra) {
-	ErrorF("GL_EXT_bgra required\n");
+
+#ifdef GLAMOR_GLES2
+    if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
+	ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
 	goto fail;
     }
 #endif
 
+    glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert");
+    glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit");
+    glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); 
 
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 7a84adb..dca7160 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -48,7 +48,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
-    if (!GLEW_EXT_framebuffer_blit) {
+    if (!glamor_priv->has_fbo_blit) {
 	glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
 	return FALSE;
     }
@@ -85,7 +85,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 
     for (i = 0; i < nbox; i++) {
       if(glamor_priv->yInverted) {
-	glBlitFramebufferEXT((box[i].x1 + dx + src_x_off),
+	glBlitFramebuffer((box[i].x1 + dx + src_x_off),
                              (box[i].y1 + src_y_off),
 			     (box[i].x2 + dx + src_x_off),
 			     (box[i].y2 + src_y_off),
@@ -101,7 +101,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
 	int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
 
-	glBlitFramebufferEXT(box[i].x1 + dx + src_x_off,
+	glBlitFramebuffer(box[i].x1 + dx + src_x_off,
 			     flip_src_y1,
 			     box[i].x2 + dx + src_x_off,
 			     flip_src_y2,
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 096e40b..09851a0 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -201,35 +201,27 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   glamor_priv->finish_access_prog[2] = glCreateProgram();
   glamor_priv->finish_access_prog[3] = glCreateProgram();
 
-  if (GLEW_ARB_fragment_shader) {
 #ifndef GLAMOR_GLES2
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
-    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
-
-    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-    aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
-    glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
+  vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+  fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
+  glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
+  glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
+
+  avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+  aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
+  glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
+  glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
 #endif
-    es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
-    es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source);
-    glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog);
-
-    es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
-    es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source);
-    glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog);
-    glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog);
+  es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
+  es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source);
+  glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog);
+  glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog);
+
+  es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
+  es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source);
+  glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog);
+  glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog);
  
-  } else {
-#ifndef GLAMOR_GLES2
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
-    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
-    ErrorF("Lack of framgment shader support.\n");
-#endif
-  }
 
 
 #ifndef GLAMOR_GLES2
@@ -244,34 +236,32 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]);
 
-  if (GLEW_ARB_fragment_shader) {
-    GLint sampler_uniform_location;
+  GLint sampler_uniform_location;
 #ifndef GLAMOR_GLES2
-    sampler_uniform_location =
-      glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[0]);
-    glUniform1i(sampler_uniform_location, 0);
-    glUseProgram(0);
-
-    sampler_uniform_location =
-      glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[1]);
-    glUniform1i(sampler_uniform_location, 0);
-    glUseProgram(0);
+  sampler_uniform_location =
+    glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
+  glUseProgram(glamor_priv->finish_access_prog[0]);
+  glUniform1i(sampler_uniform_location, 0);
+  glUseProgram(0);
+
+  sampler_uniform_location =
+    glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
+  glUseProgram(glamor_priv->finish_access_prog[1]);
+  glUniform1i(sampler_uniform_location, 0);
+  glUseProgram(0);
 #endif
-    sampler_uniform_location =
-      glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[2]);
-    glUniform1i(sampler_uniform_location, 0);
-    glUseProgram(0);
-
-    sampler_uniform_location =
-      glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler");
-    glUseProgram(glamor_priv->finish_access_prog[3]);
-    glUniform1i(sampler_uniform_location, 0);
-    glUseProgram(0);
+  sampler_uniform_location =
+    glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler");
+  glUseProgram(glamor_priv->finish_access_prog[2]);
+  glUniform1i(sampler_uniform_location, 0);
+  glUseProgram(0);
+
+  sampler_uniform_location =
+    glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler");
+  glUseProgram(glamor_priv->finish_access_prog[3]);
+  glUniform1i(sampler_uniform_location, 0);
+  glUseProgram(0);
  
-  }
 }
 
 void
@@ -494,3 +484,50 @@ glamor_bitmap_to_region(PixmapPtr pixmap)
   glamor_finish_access(&pixmap->drawable);
   return ret;
 }
+
+/* Borrow from cairo. */
+Bool
+glamor_gl_has_extension(char *extension)
+{
+  const char *gl_extensions;
+  char *pext;
+  int  ext_len;
+  ext_len = strlen(extension);
+ 
+  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
+  pext = (char*)gl_extensions;
+ 
+  if (pext == NULL || extension == NULL)
+    return FALSE;
+
+  while((pext = strstr(pext, extension)) != NULL) {
+    if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
+      return TRUE;
+    pext += ext_len;
+  }
+  return FALSE;
+}
+
+int
+glamor_gl_get_version (void)
+{
+    int major, minor;
+    const char *version = (const char *) glGetString (GL_VERSION);
+    const char *dot = version == NULL ? NULL : strchr (version, '.');
+    const char *major_start = dot;
+
+    /* Sanity check */
+    if (dot == NULL || dot == version || *(dot + 1) == '\0') {
+        major = 0;
+        minor = 0;
+    } else {
+        /* Find the start of the major version in the string */
+        while (major_start > version && *major_start != ' ')
+            --major_start;
+        major = strtol (major_start, NULL, 10);
+        minor = strtol (dot + 1, NULL, 10);
+    }
+
+    return GLAMOR_GL_VERSION_ENCODE (major, minor);
+}
+
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index bfa30b2..556ff34 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -139,15 +139,10 @@ glamor_init_solid_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv->solid_prog = glCreateProgram();
-    if (GLEW_ARB_fragment_shader) {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
-	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
-	glAttachShader(glamor_priv->solid_prog, vs_prog);
-	glAttachShader(glamor_priv->solid_prog, fs_prog);
-    } else {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only);
-	glAttachShader(glamor_priv->solid_prog, vs_prog);
-    }
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
+    glAttachShader(glamor_priv->solid_prog, vs_prog);
+    glAttachShader(glamor_priv->solid_prog, fs_prog);
     
     glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position");
     glamor_link_glsl_prog(glamor_priv->solid_prog);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index d747ade..b105916 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -407,7 +407,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
-  if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) 
+  if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) 
       || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
     glamor_fallback("upload failed reason: bad size or depth %d x %d @depth %d \n",
 		    pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth);
@@ -571,7 +571,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   //  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   }
 
-  if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
+  if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
 
     if (!glamor_priv->yInverted) {
       assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index bf032b1..69590a5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -37,8 +37,6 @@
 
 #ifdef GLAMOR_GLES2
 
-#define GLEW_ES_ONLY 1
-
 #define GL_BGRA                                 GL_BGRA_EXT
 #define GL_COLOR_INDEX                          0x1900
 #define GL_BITMAP                               0x1A00
@@ -49,7 +47,6 @@
 #define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
 #define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
 
-#define GLEW_ARB_fragment_shader                1
 #define GL_PIXEL_PACK_BUFFER              0x88EB
 #define GL_PIXEL_UNPACK_BUFFER            0x88EC
 #define GL_CLAMP_TO_BORDER                0x812D
@@ -66,7 +63,6 @@
 #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
 
-#define GLEW_MESA_pack_invert             0
 #define GL_PACK_INVERT_MESA               0x8758
 
 #define glMapBuffer(x, y)    NULL
@@ -76,12 +72,13 @@
 
 #endif
 
-#ifdef GLAMOR_GLES2
 #define GL_GLEXT_PROTOTYPES
+#ifdef GLAMOR_GLES2
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #else
-#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glext.h>
 #endif
 
 
@@ -90,19 +87,11 @@
 #endif
 
 
-#ifndef MAX_WIDTH
-#define MAX_WIDTH 4096
-#endif
-
-#ifndef MAX_HEIGHT
-#define MAX_HEIGHT 4096
-#endif
-
 #include "glamor_debug.h"
 
-#define glamor_check_fbo_width_height(_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
-                                                    && (_w_) < MAX_WIDTH   \
-                                                    && (_h_) < MAX_HEIGHT)
+#define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
+                                                    && (_w_) < _glamor_->max_fbo_size  \
+                                                    && (_h_) < _glamor_->max_fbo_size)
 
 #define glamor_check_fbo_depth(_depth_) (			\
                                          _depth_ == 8		\
@@ -241,6 +230,9 @@ typedef struct glamor_screen_private {
   char *vb;
   int vb_stride;
   enum glamor_gl_flavor gl_flavor;
+  int has_pack_invert;
+  int has_fbo_blit;
+  int max_fbo_size;
 
   /* glamor_finishaccess */
   GLint finish_access_prog[4];
@@ -674,6 +666,15 @@ void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				     glamor_transform_uniforms *uniform_locations);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
+Bool glamor_gl_has_extension(char *extension);
+int  glamor_gl_get_version(void);
+
+#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
+          ((major) * 256)                       \
+        + ((minor) *   1))
+
+
+
 
 /* glamor_fill.c */
 void glamor_fill(DrawablePtr drawable,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 0567f67..12b0924 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1154,6 +1154,7 @@ glamor_composite(CARD8 op,
   PicturePtr temp_src = source, temp_mask = mask;
   int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
   glamor_composite_rect_t rect;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
   x_temp_src = x_source;
   y_temp_src = y_source;
@@ -1181,7 +1182,7 @@ glamor_composite(CARD8 op,
 	  && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) 
 	  && ((width * height * 4 
 	       < (source_pixmap->drawable.width * source_pixmap->drawable.height))
-	      || !(glamor_check_fbo_width_height(source_pixmap->drawable.width,
+	      || !(glamor_check_fbo_size(glamor_priv, source_pixmap->drawable.width,
 						 source_pixmap->drawable.height))))) {
     temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height);
     if (!temp_src) {
@@ -1197,7 +1198,7 @@ glamor_composite(CARD8 op,
 	      && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
 	      && ((width * height * 4 
 		   < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))
-		  || !(glamor_check_fbo_width_height(mask_pixmap->drawable.width,
+		  || !(glamor_check_fbo_size(glamor_priv, mask_pixmap->drawable.width,
 						     mask_pixmap->drawable.height)))))) {
     /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
      * to do reduce one convertion. */
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index cdb0611..cb23552 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -74,9 +74,6 @@ glamor_init_tile_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
     GLint sampler_uniform_location;
 
-    if (!GLEW_ARB_fragment_shader)
-	return;
-
     glamor_priv->tile_prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 7e10d6b..744604e 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -66,6 +66,12 @@ libxephyr_la_SOURCES = $(XEPHYR_SRCS)
 Xephyr_SOURCES = \
 	ephyrinit.c
 
+if GLAMOR_GLES2
+GLAMOR_GL_LIB = -lGLESv2
+else
+GLAMOR_GL_LIB = -lGL
+endif
+
 Xephyr_LDADD = 						\
 	libxephyr.la					\
 	libxephyr-hostx.la				\
@@ -74,7 +80,8 @@ Xephyr_LDADD = 						\
 	$(top_builddir)/exa/libexa.la			\
 	$(top_builddir)/glamor/libglamor.la		\
 	@KDRIVE_LIBS@					\
-	@XEPHYR_LIBS@
+	@XEPHYR_LIBS@                                   \
+        $(GLAMOR_GL_LIB)
 
 Xephyr_DEPENDENCIES =	\
 	libxephyr.la					\
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index a00f08a..dcd44b2 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -15,7 +15,7 @@ if GLAMOR_GLES2
 glamor_la_CFLAGS+=-DGLAMOR_GLES2
 GLAMOR_GL_LIB = -lGLESv2
 else
-GLAMOR_GL_LIB = -L$(libdir)/../lib64 -lGLEW
+GLAMOR_GL_LIB = -lGL
 endif
 
 glamor_la_LDFLAGS =				 \
commit 2146a25bac4392c47ef06ecddbf12db184926b7e
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 15:03:48 2011 -0400

    glamor-ddx: Silence one warning.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index e7ee956..317342b 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -353,8 +353,8 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	version = eglQueryString(glamor->display, EGL_VERSION);
 	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
 
-	glamor->egl_create_drm_image_mesa = eglGetProcAddress("eglCreateDRMImageMESA");
-	glamor->egl_export_drm_image_mesa = eglGetProcAddress("eglExportDRMImageMESA");
+	glamor->egl_create_drm_image_mesa = (PFNEGLCREATEDRMIMAGEMESA)eglGetProcAddress("eglCreateDRMImageMESA");
+	glamor->egl_export_drm_image_mesa = (PFNEGLEXPORTDRMIMAGEMESA)eglGetProcAddress("eglExportDRMImageMESA");
 
 	if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
commit d66bd9714e1e1af4267fb4eb208143a070e65ee3
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Thu Aug 11 09:54:28 2011 -0400

    glamor: Concentrate FBO's creation to one function.
    
    And add status checking for it.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index eeb85f2..dd0d69d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -74,14 +74,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
      */
     pixmap_priv->gl_fbo = 1;
     pixmap_priv->gl_tex = 1;
-    glGenFramebuffers(1, &pixmap_priv->fb);
-    glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-    glFramebufferTexture2D(GL_FRAMEBUFFER,
-                             GL_COLOR_ATTACHMENT0,
-                             GL_TEXTURE_2D,
-                             pixmap_priv->tex,
-                             0);
-
+    glamor_pixmap_ensure_fb(pixmap);
     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 5dd5975..d747ade 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -359,6 +359,39 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
+void
+glamor_pixmap_ensure_fb(PixmapPtr pixmap)
+{
+  int status;
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  if (pixmap_priv->fb == 0)
+    glGenFramebuffers(1, &pixmap_priv->fb);
+  assert(pixmap_priv->tex != 0);
+  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+  glFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+			 GL_TEXTURE_2D,
+			 pixmap_priv->tex,
+			 0);
+    status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
+    if (status != GL_FRAMEBUFFER_COMPLETE) {
+        const char *str;
+        switch (status) {
+        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str= "incomplete attachment"; break;
+        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str= "incomplete/missing attachment"; break;
+        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str= "incomplete draw buffer"; break;
+        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str= "incomplete read buffer"; break;
+        case GL_FRAMEBUFFER_UNSUPPORTED: str= "unsupported"; break;
+        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str= "incomplete multiple"; break;
+        default: str = "unknown error"; break;
+        }
+
+        LogMessageVerb(X_INFO, 0,
+                 "destination is framebuffer incomplete: %s [%#x]\n",
+                 str, status);
+        assert(0);
+    }
+}
 
 /*  
  * Prepare to upload a pixmap to texture memory.
@@ -393,21 +426,13 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
     glGenTextures(1, &pixmap_priv->tex);
 
   if (need_fbo) {
-    if (pixmap_priv->fb == 0) 
-      glGenFramebuffers(1, &pixmap_priv->fb);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
 		 pixmap->drawable.height, 0,
 		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
-    glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
-    glFramebufferTexture2D(GL_FRAMEBUFFER,
-			      GL_COLOR_ATTACHMENT0,
-			      GL_TEXTURE_2D,
-			      pixmap_priv->tex,
-			      0);
+    glamor_pixmap_ensure_fb(pixmap);
   }
  
   return 0;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c04e118..bf032b1 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -62,6 +62,10 @@
 #define GL_PACK_ROW_LENGTH                      0x0D02
 #define GL_UNPACK_ROW_LENGTH                    0x0CF2
 
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+
 #define GLEW_MESA_pack_invert             0
 #define GL_PACK_INVERT_MESA               0x8758
 
@@ -802,6 +806,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
  **/
 void
 glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
+/**
+ * Ensure to have a fbo attached to the pixmap. 
+ * If the pixmap already has one fbo then do nothing.
+ * Otherwise, it will generate a new fbo, and bind
+ * the pixmap's texture to the fbo. 
+ * The pixmap must has a valid texture before call this
+ * API, othersie, it will trigger a assert.
+ */
+void
+glamor_pixmap_ensure_fb(PixmapPtr pixmap);
 
 /**
  * Upload a pixmap to gl texture. Used by dynamic pixmap
commit b2bff334ce4f36352497f1c1d4e9f0e5b3336136
Author: Zhenyu Wang <zhenyuw at linux.intel.com>
Date:   Tue Aug 9 19:37:17 2011 -0700

    glamor: Require libdrm CFLAGS for building
    
    Need to depend on libdrm CFLAGS for glamor building.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 97b677a..2df76bd 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -17,7 +17,7 @@ endif
 INCLUDES = \
 	$(XORG_INCS)
 
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS)
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS) $(LIBDRM_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index 71d4914..a00f08a 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -1,7 +1,7 @@
 glamor_la_LTLIBRARIES = glamor.la
 glamor_la_CFLAGS =					\
 	-DHAVE_XORG_CONFIG_H				\
-	@DIX_CFLAGS@ @XORG_CFLAGS@			\
+	@DIX_CFLAGS@ @XORG_CFLAGS@ @LIBDRM_CFLAGS@	\
 	-I$(top_srcdir)/hw/xfree86/common		\
 	-I$(top_srcdir)/hw/xfree86/os-support/bus	\
 	-I$(top_srcdir)/hw/xfree86/parser		\
@@ -9,8 +9,7 @@ glamor_la_CFLAGS =					\
 	-I$(top_srcdir)/hw/xfree86/ddc			\
 	-I$(top_srcdir)/hw/xfree86/ramdac		\
 	-I$(top_srcdir)/hw/xfree86/i2c			\
-	-I$(top_srcdir)/glamor				\
-	-I/usr/include/drm
+	-I$(top_srcdir)/glamor
 
 if GLAMOR_GLES2
 glamor_la_CFLAGS+=-DGLAMOR_GLES2
commit 41b13fbd264594f88905b1cf8dcb2f14e7ee5b69
Author: Zhenyu Wang <zhenyuw at linux.intel.com>
Date:   Wed Aug 10 01:42:26 2011 -0700

    glamor: Use function pointer to get extenstion calls
    
    This is the formal usage for extension functions.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 82ebeeb..e7ee956 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -45,6 +45,7 @@
 #include <GL/gl.h>
 #endif
 
+#define MESA_EGL_NO_X11_HEADERS
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
@@ -79,6 +80,10 @@ struct glamor_screen_private {
 	CloseScreenProcPtr CloseScreen;
 	int fd;
 	int cpp;
+
+	PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
+	PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
+
 };
 
 static inline struct glamor_screen_private *
@@ -109,7 +114,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 
 	attribs[1] = width;
 	attribs[3] = height;
-	image =	 eglCreateDRMImageMESA(glamor->display, attribs);  
+	image =	 (glamor->egl_create_drm_image_mesa)(glamor->display, attribs);  
 	if (image == EGL_NO_IMAGE_KHR)
 		return FALSE;
 
@@ -131,7 +136,7 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	EGLint name;
-	eglExportDRMImageMESA (glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch);
+	(glamor->egl_export_drm_image_mesa)(glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch);
 }
 
 EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
@@ -148,7 +153,7 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 
 	attribs[1] = width;
 	attribs[3] = height;
-	return	eglCreateDRMImageMESA(glamor->display, attribs); 
+	return	(glamor->egl_create_drm_image_mesa)(glamor->display, attribs); 
 }
 
 void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor)
@@ -162,7 +167,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	EGLint name;
-	eglExportDRMImageMESA (glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch);
+	(glamor->egl_export_drm_image_mesa)(glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch);
 	ErrorF("cursor stride: %d\n", *pitch);
 }
 
@@ -346,7 +351,16 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	}
 
 	version = eglQueryString(glamor->display, EGL_VERSION);
-	xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version);
+	xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
+
+	glamor->egl_create_drm_image_mesa = eglGetProcAddress("eglCreateDRMImageMESA");
+	glamor->egl_export_drm_image_mesa = eglGetProcAddress("eglExportDRMImageMESA");
+
+	if (!glamor->egl_create_drm_image_mesa || !glamor->egl_export_drm_image_mesa) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "eglGetProcAddress() failed\n");
+		return FALSE;
+	}
 
 	glamor->context = eglCreateContext(glamor->display,
 					   NULL, EGL_NO_CONTEXT, config_attribs);
commit 7aecfa245facf754ff8e09d6ef1ad0ab802156fc
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 9 10:01:39 2011 -0400

    glamor-es2: Add --enable-glamor-gles2 to build system.
    
    Now, to build a gles2 version of glamor server, we could
    use ./autogen.sh --enable-glamor-ddx --enable-glamor-gles2
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/configure.ac b/configure.ac
index 73c1bea..a94cd00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1772,6 +1772,8 @@ AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 dnl glamor 
 
 AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes])
+AM_CONDITIONAL([GLAMOR_GLES2], [test "x$GLAMOR_GLES2" = xyes])
+AM_CONDITIONAL([GLAMOR_DDX], [test "x$GLAMOR_DDX" = xyes])
 
 GLAMOR=yes
 
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index e2678f0..97b677a 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -10,10 +10,14 @@ if XORG
 sdk_HEADERS = glamor.h
 endif
 
+if GLAMOR_GLES2
+GLAMOR_GLES2_CFLAGS = -DGLAMOR_GLES2
+endif
+
 INCLUDES = \
 	$(XORG_INCS)
 
-AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(GLAMOR_GLES2_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f585d6a..096e40b 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -141,6 +141,7 @@ void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+#ifndef GLAMOR_GLES2
   const char *vs_source =
     "void main()\n"
     "{\n"
@@ -154,7 +155,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "{\n"
     "	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
     "}\n";
-    
+
   const char *aswizzle_source =
     "varying vec2 texcoords;\n"
     "uniform sampler2D sampler;\n"
@@ -162,6 +163,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "{\n"
     " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
     "}\n";
+#endif
   const char *es_vs_source =
     "attribute vec4 v_position;\n"
     "attribute vec4 v_texcoord0;\n"
@@ -200,6 +202,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
   glamor_priv->finish_access_prog[3] = glCreateProgram();
 
   if (GLEW_ARB_fragment_shader) {
+#ifndef GLAMOR_GLES2
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
     glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
@@ -209,7 +212,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
     glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
     glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
-
+#endif
     es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
     es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source);
     glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog);
@@ -221,16 +224,18 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog);
  
   } else {
+#ifndef GLAMOR_GLES2
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
     glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
     ErrorF("Lack of framgment shader support.\n");
+#endif
   }
 
 
-
+#ifndef GLAMOR_GLES2
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
-
+#endif
   glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position");
   glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]);
@@ -241,7 +246,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 
   if (GLEW_ARB_fragment_shader) {
     GLint sampler_uniform_location;
-
+#ifndef GLAMOR_GLES2
     sampler_uniform_location =
       glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
     glUseProgram(glamor_priv->finish_access_prog[0]);
@@ -253,7 +258,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     glUseProgram(glamor_priv->finish_access_prog[1]);
     glUniform1i(sampler_uniform_location, 0);
     glUseProgram(0);
-
+#endif
     sampler_uniform_location =
       glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler");
     glUseProgram(glamor_priv->finish_access_prog[2]);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2176008..c04e118 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -60,10 +60,16 @@
 #define GL_STREAM_DRAW                    0x88E0
 #define GL_STREAM_READ                    0x88E1
 #define GL_PACK_ROW_LENGTH                      0x0D02
+#define GL_UNPACK_ROW_LENGTH                    0x0CF2
 
 #define GLEW_MESA_pack_invert             0
 #define GL_PACK_INVERT_MESA               0x8758
 
+#define glMapBuffer(x, y)    NULL
+#define glUnmapBuffer(x)
+#define glRasterPos2i(x,y)
+#define glDrawPixels(x,y,z,a,b)
+
 #endif
 
 #ifdef GLAMOR_GLES2
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 4b2215a..a6aadce 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -36,6 +36,7 @@ void
 glamor_init_putimage_shaders(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+#if 0
     const char *xybitmap_vs =
 	"uniform float x_bias;\n"
 	"uniform float x_scale;\n"
@@ -85,6 +86,7 @@ glamor_init_putimage_shaders(ScreenPtr screen)
 					   &glamor_priv->put_image_xybitmap_transform);
     glamor_priv->put_image_xybitmap_prog = prog;
     glUseProgram(0);
+#endif
 }
 
 
@@ -254,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	glamor_get_screen_private(drawable->pScreen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    GLenum type, format;
+    GLenum type, format, iformat;
     RegionPtr clip;
     BoxPtr pbox;
     int nbox;
@@ -317,17 +319,27 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #endif
 
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-#ifndef GLAMOR_GLES2
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
-		  pixmap->drawable.bitsPerPixel);
-#endif
-
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+      glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
+  		    pixmap->drawable.bitsPerPixel);
+    }
+    else {
+      glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+//      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    }
     
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+    if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+      type = GL_UNSIGNED_BYTE;
+      iformat = format;
+    } 
+    else {
+      iformat = GL_RGBA;
+    }
+    glTexImage2D(GL_TEXTURE_2D, 0, iformat,
 		 w, h, 0,
 		 format, type, bits);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -396,9 +408,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 #endif
     glDeleteTextures(1, &tex);
-#ifndef GLAMOR_GLES2
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-#endif
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6b8c760..0567f67 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -377,7 +377,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
   switch (picture->repeatType) {
   case RepeatNone:
 #ifdef GLAMOR_GLES2
-    assert(0);
+    assert(1);
 #endif
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 14a2437..af26643 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -43,6 +43,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     BoxRec *pbox;
     int x_off, y_off;
 
+    goto fail;
+
     if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
                                                &format, 
                                                &type, 
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index c031d4b..173d765 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -89,4 +89,10 @@ if LNXACPI
 XORG_CFLAGS += -DHAVE_ACPI
 endif
 
-AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
+if GLAMOR_DDX
+GLAMOR_DDX_CFLAGS = -DGLAMOR_DDX
+endif
+
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_DDX_CFLAGS)
+
+
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 663e70a..7ab3f28 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1118,7 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev,
             } else if (dev->device_id == 0x8108) {
                 break; /* "hooray" for poulsbo */
 	    } else {
-#if GLAMOR_DDX
+#ifdef GLAMOR_DDX
 	      driverList[0] = "glamor";
 #else
 	      driverList[0] = "intel";
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index d9dc8a9..71d4914 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -12,10 +12,17 @@ glamor_la_CFLAGS =					\
 	-I$(top_srcdir)/glamor				\
 	-I/usr/include/drm
 
+if GLAMOR_GLES2
+glamor_la_CFLAGS+=-DGLAMOR_GLES2
+GLAMOR_GL_LIB = -lGLESv2
+else
+GLAMOR_GL_LIB = -L$(libdir)/../lib64 -lGLEW
+endif
+
 glamor_la_LDFLAGS =				 \
 	-module -avoid-version -L$(libdir) -lEGL \
         $(top_builddir)/glamor/libglamor.la      \
-        -L$(libdir)/../lib64 -lGLEW
+        -L$(libdir)/../lib64 $(GLAMOR_GL_LIB)
 
 glamor_ladir = $(moduledir)/drivers
 glamor_la_SOURCES =				\
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index a1128da..82ebeeb 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -306,6 +306,13 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	const char *version;
 	VisualPtr visual;
+        EGLint config_attribs[] = {
+#ifdef GLAMOR_GLES2
+        EGL_CONTEXT_CLIENT_VERSION, 2, 
+#endif
+          EGL_NONE
+    };
+
 
 	/* If serverGeneration != 1 then fd was closed during the last
 	 time closing screen, actually in eglTerminate(). */
@@ -327,7 +334,11 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 
 
 	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
+#ifndef GLAMOR_GLES2
 	eglBindAPI(EGL_OPENGL_API);
+#else
+	eglBindAPI(EGL_OPENGL_ES_API);
+#endif
 	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglInitialize() failed\n");
@@ -338,7 +349,7 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version);
 
 	glamor->context = eglCreateContext(glamor->display,
-					   NULL, EGL_NO_CONTEXT, NULL);
+					   NULL, EGL_NO_CONTEXT, config_attribs);
 	if (glamor->context == EGL_NO_CONTEXT) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to create EGL context\n");
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index d2f98fb..5c2b5c1 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -493,7 +493,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor);
 	}
 	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
-#if GLAMOR_GLES2
+#ifdef GLAMOR_GLES2
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0,
 	  GL_BGRA,  GL_UNSIGNED_BYTE, image);
 #else
commit 36a93f62c7830af088a54514eab6bf4d92423df6
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 9 09:59:56 2011 -0400

    glamor_gles2: Use gl_flavor to determine which version of GL.
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7acfc98..eeb85f2 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -379,6 +379,12 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_glyphs_init(screen);
     glamor_pixmap_init(screen);
 
+#ifdef GLAMOR_GLES2
+    glamor_priv->gl_flavor = GLAMOR_GL_ES2;
+#else
+    glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
+#endif
+
     return TRUE;
 
 fail:
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index ce4ca00..5dd5975 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -213,6 +213,7 @@ static void
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex)
 {
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
   unsigned int stride, row_length;
   void *texels;
   GLenum iformat;
@@ -229,15 +230,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
         break;
     }
 
+  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+    iformat = format;
+    type = GL_UNSIGNED_BYTE;
+  }
 
   stride = pixmap->devKind;
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
   glBindTexture(GL_TEXTURE_2D, tex);
-  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-#ifndef GLAMOR_GLES2
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-#endif
+
+  if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+  } 
+  else {
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+  }
+
   if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
     texels = NULL;
     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
@@ -524,15 +534,26 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     ErrorF("Glamor: Invalid access code. %d\n", access);
     assert(0);
   }
- 
+  if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
+    data = malloc(stride * pixmap->drawable.height);
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-  glPixelStorei(GL_PACK_ALIGNMENT, 1);
-  glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+  if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+  }
+  else {
+    glPixelStorei(GL_PACK_ALIGNMENT, 4);
+  //  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+  }
 
   if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
 
-    if (!glamor_priv->yInverted) 
+    if (!glamor_priv->yInverted) {
+      assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); 
       glPixelStorei(GL_PACK_INVERT_MESA, 1);
+    }
+    
+    if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
     if (pixmap_priv->pbo == 0)
       glGenBuffers (1, &pixmap_priv->pbo);
     glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
@@ -545,9 +566,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
     pixmap_priv->pbo_valid = TRUE;
 
-    if (!glamor_priv->yInverted) 
+    if (!glamor_priv->yInverted) {
+      assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
       glPixelStorei(GL_PACK_INVERT_MESA, 0);
+    }
     glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+    } else {
+    glReadPixels (0, 0,
+                    row_length, pixmap->drawable.height,
+                    format, type, data);
+    }
   } else {
     data = malloc(stride * pixmap->drawable.height);
     assert(data);
@@ -588,7 +616,7 @@ _glamor_destroy_upload_pixmap(PixmapPtr pixmap)
 
   assert(pixmap_priv->gl_fbo == 0);
   if (pixmap_priv->fb)
-    glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
+    glDeleteFramebuffers(1, &pixmap_priv->fb);
   if (pixmap_priv->tex)
     glDeleteTextures(1, &pixmap_priv->tex);
   if (pixmap_priv->pbo)
commit 29e358f6b3838a56b53ec809665f2e7be1731722
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue Aug 9 09:59:08 2011 -0400

    glamor: Fix one typo error in README.
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/README b/README
index 05effbe..fd31d99 100644
--- a/README
+++ b/README
@@ -14,7 +14,7 @@ diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile
  endif
 -INCLUDE = -Iinclude
 +
-+NCLUDE = -Iinclude
++INCLUDE = -Iinclude
  CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA)
 +ifeq ($(NO_GLX), 1)
 +CFLAGS += -D_NO_GLX_
commit ee33c947aac10b2b1ec2c5b070fbd81cef1773c6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 3 16:52:19 2011 +0800

    glamor-es: Use glVertexAttribPointer to replace glVertexPointer.
    
    As GLES2 doesn't support glVertexPointer.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 4b4a335..7a84adb 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -176,29 +176,46 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
-
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
 
 
+
+#if 0
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
+                          2 * sizeof(float),
+                          vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
       dx += src_x_off;
       dy += src_y_off;
       pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+
       glActiveTexture(GL_TEXTURE0);
       glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
       glEnable(GL_TEXTURE_2D);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
+#if 0
       glClientActiveTexture(GL_TEXTURE0);
       glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       glUseProgram(glamor_priv->finish_access_prog[0]);
-    } 
+#else
+ 
+      glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
+                            2 * sizeof(float),
+                            texcoords);
+      glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+      glUseProgram(glamor_priv->finish_access_prog[2]);
+#endif
+ 
+   } 
     else {
       GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
    }
@@ -223,13 +240,20 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    glUseProgram(0);
-
+#if 0
     glDisableClientState(GL_VERTEX_ARRAY);
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       glDisable(GL_TEXTURE_2D);
     }
+#else
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+      glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+      glDisable(GL_TEXTURE_2D);
+    }
+#endif
+    glUseProgram(0);
     /* The source texture is bound to a fbo, we have to flush it here. */
     if (flush_needed) 
       glFlush();
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f337628..f585d6a 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -162,11 +162,42 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     "{\n"
     " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
     "}\n";
+  const char *es_vs_source =
+    "attribute vec4 v_position;\n"
+    "attribute vec4 v_texcoord0;\n"
+    "varying vec2 source_texture;\n"
+    "void main()\n"
+    "{\n"
+    "	gl_Position = v_position;\n"
+    "	source_texture = v_texcoord0.xy;\n"
+    "}\n";
+
+  const char *es_fs_source =
+    "varying vec2 source_texture;\n"
+    "uniform sampler2D sampler;\n"
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = texture2D(sampler, source_texture);\n"
+    "}\n";
+    
+  const char *es_aswizzle_source =
+    "varying vec2 source_texture;\n"
+    "varying vec2 texcoords;\n"
+    "uniform sampler2D sampler;\n"
+    "void main()\n"
+    "{\n"
+    " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+    "}\n";
+
+
 
   GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
+  GLint es_fs_prog, es_vs_prog, es_avs_prog, es_aswizzle_prog;
 
   glamor_priv->finish_access_prog[0] = glCreateProgram();
   glamor_priv->finish_access_prog[1] = glCreateProgram();
+  glamor_priv->finish_access_prog[2] = glCreateProgram();
+  glamor_priv->finish_access_prog[3] = glCreateProgram();
 
   if (GLEW_ARB_fragment_shader) {
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
@@ -178,15 +209,36 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
     glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
     glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
+
+    es_vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
+    es_fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_fs_source);
+    glAttachShader(glamor_priv->finish_access_prog[2], es_vs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[2], es_fs_prog);
+
+    es_avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, es_vs_source);
+    es_aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, es_aswizzle_source);
+    glAttachShader(glamor_priv->finish_access_prog[3], es_avs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[3], es_aswizzle_prog);
+ 
   } else {
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
     glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
     ErrorF("Lack of framgment shader support.\n");
   }
 
+
+
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
   glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
 
+  glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_POS, "v_position");
+  glBindAttribLocation(glamor_priv->finish_access_prog[2], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glamor_link_glsl_prog(glamor_priv->finish_access_prog[2]);
+
+  glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_POS, "v_position");
+  glBindAttribLocation(glamor_priv->finish_access_prog[3], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glamor_link_glsl_prog(glamor_priv->finish_access_prog[3]);
+
   if (GLEW_ARB_fragment_shader) {
     GLint sampler_uniform_location;
 
@@ -201,6 +253,19 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     glUseProgram(glamor_priv->finish_access_prog[1]);
     glUniform1i(sampler_uniform_location, 0);
     glUseProgram(0);
+
+    sampler_uniform_location =
+      glGetUniformLocation(glamor_priv->finish_access_prog[2], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[2]);
+    glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(0);
+
+    sampler_uniform_location =
+      glGetUniformLocation(glamor_priv->finish_access_prog[3], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[3]);
+    glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(0);
+ 
   }
 }
 
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 14cce0c..bfa30b2 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -103,16 +103,32 @@ glamor_init_solid_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *solid_vs_only =
+#if 0
+#else
+        "attribute vec4 v_position;"
+#endif
 	"uniform vec4 color;\n"
 	"void main()\n"
 	"{\n"
+#if 0
 	"	gl_Position = gl_Vertex;\n"
+#else
+        "       gl_Position = v_position;\n"
+#endif
 	"	gl_Color = color;\n"
 	"}\n";
     const char *solid_vs =
+#if 0
+#else
+        "attribute vec4 v_position;"
+#endif
 	"void main()\n"
 	"{\n"
+#if 0
 	"	gl_Position = gl_Vertex;\n"
+#else
+        "       gl_Position = v_position;\n"
+#endif
 	"}\n";
     const char *solid_fs =
 	"uniform vec4 color;\n"
@@ -132,6 +148,8 @@ glamor_init_solid_shader(ScreenPtr screen)
 	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only);
 	glAttachShader(glamor_priv->solid_prog, vs_prog);
     }
+    
+    glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position");
     glamor_link_glsl_prog(glamor_priv->solid_prog);
 
     glamor_priv->solid_color_uniform_location =
@@ -188,17 +206,25 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
  
     glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
 
+#if 0
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
-
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
 
     glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
 				 glamor_priv->yInverted,
 				 vertices);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
+#if 0
     glDisableClientState(GL_VERTEX_ARRAY);
+#else
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     glUseProgram(0);
     return TRUE;
 fail:
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 34fc408..ce4ca00 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -32,9 +32,14 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
 				 glamor_pixmap_private *pixmap_priv)
 {
     GLfloat vertices[8];
-//    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+#if 0
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float), vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     glUseProgram(glamor_priv->solid_prog);
     glUniform4fv(glamor_priv->solid_color_uniform_location, 
       1, pixmap_priv->pending_op.fill.color4fv);
@@ -47,7 +52,11 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
     vertices[6] = -1;
     vertices[7] = 1;
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+#if 0
     glDisableClientState(GL_VERTEX_ARRAY);
+#else
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     glUseProgram(0);
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
@@ -84,8 +93,10 @@ void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
   glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+#ifndef GLAMOR_GLES2
   glMatrixMode(GL_PROJECTION);                                                                                                                                                                  glLoadIdentity();
   glMatrixMode(GL_MODELVIEW);                                                                                                                                                                   glLoadIdentity();                                        
+#endif
 
   glViewport(0, 0,
 	     pixmap_priv->container->drawable.width,
@@ -129,6 +140,7 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
 void
 glamor_set_alu(unsigned char alu)
 {
+#ifndef GLAMOR_GLES2
   if (alu == GXcopy) {
     glDisable(GL_COLOR_LOGIC_OP);
     return;
@@ -183,6 +195,10 @@ glamor_set_alu(unsigned char alu)
   default:
     FatalError("unknown logic op\n");
   }
+#else
+ if (alu != GXcopy)
+  ErrorF("unsupported alu %x \n", alu);
+#endif
 }
 
 
@@ -219,8 +235,9 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 
   glBindTexture(GL_TEXTURE_2D, tex);
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#ifndef GLAMOR_GLES2
   glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-
+#endif
   if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
     texels = NULL;
     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
@@ -282,12 +299,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
     ptexcoords = texcoords_inv;
 
   /* Slow path, we need to flip y or wire alpha to 1. */
+#if 0
   glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
   glEnableClientState(GL_VERTEX_ARRAY);
 
   glClientActiveTexture(GL_TEXTURE0);
   glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+  glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        vertices);
+  glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+  glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        ptexcoords);
+  glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
   glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
   glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
 
@@ -300,14 +328,23 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glEnable(GL_TEXTURE_2D);
+#if 0
   glUseProgram(glamor_priv->finish_access_prog[ax]);
+#else
+  glUseProgram(glamor_priv->finish_access_prog[ax + 2]);
+#endif
 
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
   glDisable(GL_TEXTURE_2D);
   glUseProgram(0);
+#if 0
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+  glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+  glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
   glDeleteTextures(1, &tex);
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ac51a72..2176008 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -166,6 +166,12 @@ typedef struct {
 
 #define GLAMOR_NUM_GLYPH_CACHES 4
 
+enum glamor_vertex_type {
+     GLAMOR_VERTEX_POS,
+     GLAMOR_VERTEX_SOURCE,
+     GLAMOR_VERTEX_MASK
+};
+
 enum shader_source {
   SHADER_SOURCE_SOLID,
   SHADER_SOURCE_TEXTURE,
@@ -227,7 +233,7 @@ typedef struct glamor_screen_private {
   enum glamor_gl_flavor gl_flavor;
 
   /* glamor_finishaccess */
-  GLint finish_access_prog[2];
+  GLint finish_access_prog[4];
 
   /* glamor_solid */
   GLint solid_prog;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 65e7cfd..4b2215a 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -298,17 +298,30 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     /* XXX consider to reuse a function to do the following work. */
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
+#if 0
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
     glClientActiveTexture(GL_TEXTURE0);
     glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+    
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                        2 * sizeof(float),
+                        texcoords);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#ifndef GLAMOR_GLES2
     glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
+#endif
 
     
     glGenTextures(1, &tex);
@@ -321,8 +334,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glEnable(GL_TEXTURE_2D);
 
-    assert(GLEW_ARB_fragment_shader);
+#if 0
     glUseProgram(glamor_priv->finish_access_prog[ax]);
+#else
+    glUseProgram(glamor_priv->finish_access_prog[ax + 2]);
+#endif
 
     x += drawable->x;
     y += drawable->y;
@@ -372,11 +388,17 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
     glDisable(GL_TEXTURE_2D);
     glUseProgram(0);
+#if 0
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
     glDeleteTextures(1, &tex);
+#ifndef GLAMOR_GLES2
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+#endif
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 224ae27..6b8c760 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -36,7 +36,7 @@
 #include "mipict.h"
 #include "fbpict.h"
 
-#include "glu3/glu3.h"
+//#include "glu3/glu3.h"
 
 struct shader_key {
   enum shader_source source;
@@ -77,16 +77,18 @@ glamor_create_composite_fs(struct shader_key *key)
     "	return source;\n"
     "}\n";
   const char *source_alpha_pixmap_fetch =
+    "varying vec2 source_texture;\n"
     "uniform sampler2D source_sampler;\n"
     "vec4 get_source()\n"
     "{\n"
-    "	return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
+    "	return texture2D(source_sampler, source_texture);\n"
     "}\n";
   const char *source_pixmap_fetch =
+    "varying vec2 source_texture;\n"
     "uniform sampler2D source_sampler;\n"
     "vec4 get_source()\n"
     "{\n"
-    "       return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb, 1);\n"
+    "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
     "}\n";
   const char *mask_solid_fetch =
     "uniform vec4 mask;\n"
@@ -95,16 +97,18 @@ glamor_create_composite_fs(struct shader_key *key)
     "	return mask;\n"
     "}\n";
   const char *mask_alpha_pixmap_fetch =
+    "varying vec2 mask_texture;\n"
     "uniform sampler2D mask_sampler;\n"
     "vec4 get_mask()\n"
     "{\n"
-    "	return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
+    "	return texture2D(mask_sampler, mask_texture);\n"
     "}\n";
   const char *mask_pixmap_fetch =
+    "varying vec2 mask_texture;\n"
     "uniform sampler2D mask_sampler;\n"
     "vec4 get_mask()\n"
     "{\n"
-    "       return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, 1);\n"
+    "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
     "}\n";
   const char *in_source_only =
     "void main()\n"
@@ -196,13 +200,18 @@ static GLuint
 glamor_create_composite_vs(struct shader_key *key)
 {
   const char *main_opening =
+    "attribute vec4 v_position;\n"
+    "attribute vec4 v_texcoord0;\n"
+    "attribute vec4 v_texcoord1;\n"
+    "varying vec2 source_texture;\n"
+    "varying vec2 mask_texture;\n"
     "void main()\n"
     "{\n"
-    "	gl_Position = gl_Vertex;\n";
+    "	gl_Position = v_position;\n";
   const char *source_coords =
-    "	gl_TexCoord[0] = gl_MultiTexCoord0;\n";
+    "	source_texture = v_texcoord0.xy;\n";
   const char *mask_coords =
-    "	gl_TexCoord[1] = gl_MultiTexCoord1;\n";
+    "	mask_texture = v_texcoord1.xy;\n";
   const char *main_closing =
     "}\n";
   const char *source_coords_setup = "";
@@ -246,6 +255,11 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
   prog = glCreateProgram();
   glAttachShader(prog, vs);
   glAttachShader(prog, fs);
+
+  glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
+  glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
+  glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
+
   glamor_link_glsl_prog(prog);
 
   shader->prog = prog;
@@ -508,24 +522,48 @@ glamor_setup_composite_vbo(ScreenPtr screen)
     glamor_priv->vb_stride += 2 * sizeof(float);
 
   glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
+
+#if 0
   glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
 		  (void *)((long)glamor_priv->vbo_offset));
   glEnableClientState(GL_VERTEX_ARRAY);
+#else
+  glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 
+                        glamor_priv->vb_stride,
+                       (void *)((long)glamor_priv->vbo_offset));
+  glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
 
   if (glamor_priv->has_source_coords) {
+#if 0
     glClientActiveTexture(GL_TEXTURE0);
     glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
 		      (void *)(glamor_priv->vbo_offset + 2 * sizeof(float)));
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 
+                        glamor_priv->vb_stride,
+                       (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float)));
+    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
   }
 
   if (glamor_priv->has_mask_coords) {
+#if 0
     glClientActiveTexture(GL_TEXTURE1);
     glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
 		      (void *)(glamor_priv->vbo_offset +
 			       (glamor_priv->has_source_coords ? 4 : 2) *
 			       sizeof(float)));
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, 
+                        glamor_priv->vb_stride,
+                       (void *)((long)glamor_priv->vbo_offset + 
+			       (glamor_priv->has_source_coords ? 4 : 2) *
+                               sizeof(float)));
+    glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
+#endif
   }
 }
 
@@ -888,6 +926,8 @@ glamor_composite_with_shader(CARD8 op,
   }
 
   glUseProgram(shader->prog);
+
+
   if (key.source == SHADER_SOURCE_SOLID) {
     glamor_set_composite_solid(source_solid_color, shader->source_uniform_location);
   } else {
@@ -1014,12 +1054,17 @@ glamor_composite_with_shader(CARD8 op,
   glamor_flush_composite_rects(screen);
 
   glBindBuffer(GL_ARRAY_BUFFER, 0);
+#if 0
   glClientActiveTexture(GL_TEXTURE0);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glClientActiveTexture(GL_TEXTURE1);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glDisableClientState(GL_VERTEX_ARRAY);
-
+#else
+  glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+  glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+  glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
+#endif
   REGION_UNINIT(dst->pDrawable->pScreen, &region);
   glDisable(GL_BLEND);
   glActiveTexture(GL_TEXTURE0);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 436e769..cdb0611 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -41,16 +41,35 @@ glamor_init_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *tile_vs =
+#if 0
+#else
+        "attribute vec4 v_position;\n"
+        "attribute vec4 v_texcoord0;\n"
+        "varying vec2 tile_texture;\n"
+#endif
 	"void main()\n"
 	"{\n"
+#if 0
 	"	gl_Position = gl_Vertex;\n"
 	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+#else
+        "       gl_Position = v_position;\n"
+        "       tile_texture = v_texcoord0.xy;\n"
+#endif
 	"}\n";
     const char *tile_fs =
+#if 0
+#else
+        "varying vec2 tile_texture;\n"
+#endif
 	"uniform sampler2D sampler;\n"
 	"void main()\n"
 	"{\n"
+#if 0
 	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
+#else
+	"	gl_FragColor = texture2D(sampler, tile_texture);\n"
+#endif
 	"}\n";
     GLint fs_prog, vs_prog;
     GLint sampler_uniform_location;
@@ -63,6 +82,9 @@ glamor_init_tile_shader(ScreenPtr screen)
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
     glAttachShader(glamor_priv->tile_prog, vs_prog);
     glAttachShader(glamor_priv->tile_prog, fs_prog);
+
+    glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position");
+    glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glamor_link_glsl_prog(glamor_priv->tile_prog);
 
     sampler_uniform_location =
@@ -144,9 +166,16 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				 tile_x2, tile_y2,
 				 glamor_priv->yInverted,
 				 source_texcoords);
+#if 0
       glClientActiveTexture(GL_TEXTURE0);
       glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
+      glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+                            2 * sizeof(float),
+                            source_texcoords);
+      glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+#endif
    } 
    else {
      GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
@@ -157,18 +186,31 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				 glamor_priv->yInverted,
 				 vertices);
 
+#if 0
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
-
+#else
+    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+                          2 * sizeof(float),
+                         vertices);
+    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
+#if 0
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
     glClientActiveTexture(GL_TEXTURE0);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDisable(GL_TEXTURE_2D);
     }
     glDisableClientState(GL_VERTEX_ARRAY);
-
+#else
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+    glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+    glDisable(GL_TEXTURE_2D);
+    }
+    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+#endif
     glUseProgram(0);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
commit 94d884a198b97ed2e78a38ce5a71955bdbf893f8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Aug 3 10:49:18 2011 +0800

    glamor-es2: Fix some non-es2 functions.
    
    ES2.0 doesn't support QUADS and also doesn't support
    some EXT APIs. Fix some of them in this commit.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b678984..7acfc98 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -291,9 +291,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         return FALSE;
     }
 
-    glewInit();
 
 #ifndef GLAMOR_GLES2
+    glewInit();
     if (!GLEW_EXT_framebuffer_object) {
 	ErrorF("GL_EXT_framebuffer_object required\n");
 	goto fail;
@@ -306,17 +306,19 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	ErrorF("GL_ARB_vertex_shader required\n");
 	goto fail;
     }
-    if (!GLEW_EXT_bgra) {
-	ErrorF("GL_EXT_bgra required\n");
-	goto fail;
-    }
-#endif
 
     if (!GLEW_ARB_pixel_buffer_object) {
 	ErrorF("GL_ARB_pixel_buffer_object required\n");
 	goto fail;
     }
  
+    if (!GLEW_EXT_bgra) {
+	ErrorF("GL_EXT_bgra required\n");
+	goto fail;
+    }
+#endif
+
+
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
 					NULL)) {
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index acd1edc..4b4a335 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -31,6 +31,7 @@
  *
  * GC CopyArea implementation
  */
+#ifndef GLAMOR_GLES2
 static Bool
 glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 			    DrawablePtr dst,
@@ -51,7 +52,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
 	return FALSE;
     }
-
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
     if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) 
@@ -77,8 +77,8 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 	return FALSE;
     }
     glamor_validate_pixmap(dst_pixmap);
-    glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
 
+    glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     src_y_off += dy;
@@ -115,6 +115,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     }
     return TRUE;
 }
+#endif
 
 static Bool
 glamor_copy_n_to_n_textured(DrawablePtr src,
@@ -293,13 +294,14 @@ glamor_copy_n_to_n(DrawablePtr src,
     }
     /* XXX need revisit to handle overlapped area copying. */
 
+#ifndef GLAMOR_GLES2
     if ((overlaped 
           || !src_pixmap_priv->gl_tex  || !dst_pixmap_priv->gl_tex )
         && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
         goto done;
 	return;
     }
-
+#endif
     glamor_calculate_boxes_bound(&bound, box, nbox);
 
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index d99560f..f337628 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -88,15 +88,15 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
   prog = glCreateShader(type);
   glShaderSource(prog, 1, (const GLchar **)&source, NULL);
   glCompileShader(prog);
-  glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
+  glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
   if (!ok) {
     GLchar *info;
     GLint size;
 
-    glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+    glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
     info = malloc(size);
 
-    glGetInfoLogARB(prog, size, NULL, info);
+    glGetShaderInfoLog(prog, size, NULL, info);
     ErrorF("Failed to compile %s: %s\n",
 	   type == GL_FRAGMENT_SHADER ? "FS" : "VS",
 	   info);
@@ -113,15 +113,15 @@ glamor_link_glsl_prog(GLint prog)
   GLint ok;
 
   glLinkProgram(prog);
-  glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
+  glGetProgramiv(prog, GL_LINK_STATUS, &ok);
   if (!ok) {
     GLchar *info;
     GLint size;
 
-    glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
     info = malloc(size);
 
-    glGetInfoLogARB(prog, size, NULL, info);
+    glGetProgramInfoLog(prog, size, NULL, info);
     ErrorF("Failed to link: %s\n",
 	   info);
     FatalError("GLSL link failure\n");
@@ -209,6 +209,7 @@ glamor_finish_access(DrawablePtr drawable)
 {
   PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
     
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
     return;
@@ -218,8 +219,9 @@ glamor_finish_access(DrawablePtr drawable)
   }
 
   if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
-    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0);
-    glBindBuffer (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+    assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+    glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+    glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
     pixmap_priv->pbo_valid = FALSE;
     glDeleteBuffers(1, &pixmap_priv->pbo);
     pixmap_priv->pbo = 0;
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0f13f09..34fc408 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -46,7 +46,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
     vertices[5] = 1;
     vertices[6] = -1;
     vertices[7] = 1;
-    glDrawArrays(GL_QUADS, 0, 4);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     glDisableClientState(GL_VERTEX_ARRAY);
     glUseProgram(0);
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
@@ -83,7 +83,7 @@ glamor_validate_pixmap(PixmapPtr pixmap)
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
   glMatrixMode(GL_PROJECTION);                                                                                                                                                                  glLoadIdentity();
   glMatrixMode(GL_MODELVIEW);                                                                                                                                                                   glLoadIdentity();                                        
 
@@ -223,7 +223,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 
   if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
     texels = NULL;
-    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
   }
   else
     texels = pixmap->devPrivate.ptr;
@@ -288,7 +288,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glClientActiveTexture(GL_TEXTURE0);
   glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+  glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
   glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
 
   glGenTextures(1, &tex);
@@ -309,7 +309,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glDeleteTextures(1, &tex);
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+  glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
 
@@ -347,7 +347,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
 
   if (need_fbo) {
     if (pixmap_priv->fb == 0) 
-      glGenFramebuffersEXT(1, &pixmap_priv->fb);
+      glGenFramebuffers(1, &pixmap_priv->fb);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -355,9 +355,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
 		 pixmap->drawable.height, 0,
 		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-			      GL_COLOR_ATTACHMENT0_EXT,
+    glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+    glFramebufferTexture2D(GL_FRAMEBUFFER,
+			      GL_COLOR_ATTACHMENT0,
 			      GL_TEXTURE_2D,
 			      pixmap_priv->tex,
 			      0);
@@ -498,45 +498,45 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
       glPixelStorei(GL_PACK_INVERT_MESA, 1);
     if (pixmap_priv->pbo == 0)
       glGenBuffers (1, &pixmap_priv->pbo);
-    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-    glBufferData (GL_PIXEL_PACK_BUFFER_EXT,
+    glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
+    glBufferData (GL_PIXEL_PACK_BUFFER,
 		     stride * pixmap->drawable.height,
 		     NULL, gl_usage);
     glReadPixels (0, 0,
                     row_length, pixmap->drawable.height,
                     format, type, 0);
-    data = glMapBuffer (GL_PIXEL_PACK_BUFFER_EXT, gl_access);
+    data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
     pixmap_priv->pbo_valid = TRUE;
 
     if (!glamor_priv->yInverted) 
       glPixelStorei(GL_PACK_INVERT_MESA, 0);
-    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
   } else {
     data = malloc(stride * pixmap->drawable.height);
     assert(data);
     if (access != GLAMOR_ACCESS_WO) {
       if (pixmap_priv->pbo == 0)
 	glGenBuffers(1, &pixmap_priv->pbo);
-      glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-      glBufferData(GL_PIXEL_PACK_BUFFER_EXT,
+      glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
+      glBufferData(GL_PIXEL_PACK_BUFFER,
 		      stride * pixmap->drawable.height,
 		      NULL, GL_STREAM_READ);
       glReadPixels (0, 0, row_length, pixmap->drawable.height,
 		    format, type, 0);
-      read = glMapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY);
+      read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
 	  
       for (y = 0; y < pixmap->drawable.height; y++)
 	memcpy(data + y * stride,
 	       read + (pixmap->drawable.height - y - 1) * stride, stride);
-      glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT);
-      glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0);
+      glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+      glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
       pixmap_priv->pbo_valid = FALSE;
       glDeleteBuffers(1, &pixmap_priv->pbo);
       pixmap_priv->pbo = 0;
     }
   }
 
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+  glBindFramebuffer(GL_FRAMEBUFFER, 0);
 done:
   pixmap->devPrivate.ptr = data;
   return TRUE;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6005a2c..ac51a72 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -49,9 +49,31 @@
 #define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
 #define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
 
+#define GLEW_ARB_fragment_shader                1
+#define GL_PIXEL_PACK_BUFFER              0x88EB
+#define GL_PIXEL_UNPACK_BUFFER            0x88EC
+#define GL_CLAMP_TO_BORDER                0x812D
+
+#define GL_READ_WRITE                     0x88BA
+#define GL_READ_ONLY                      0x88B8
+#define GL_WRITE_ONLY                     0x88B9
+#define GL_STREAM_DRAW                    0x88E0
+#define GL_STREAM_READ                    0x88E1
+#define GL_PACK_ROW_LENGTH                      0x0D02
+
+#define GLEW_MESA_pack_invert             0
+#define GL_PACK_INVERT_MESA               0x8758
+
 #endif
 
+#ifdef GLAMOR_GLES2
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
 #include <GL/glew.h>
+#endif
+
 
 #ifdef RENDER
 #include "glyphstr.h"
@@ -171,6 +193,12 @@ struct glamor_screen_private;
 struct glamor_pixmap_private;
 typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, 
 					          struct glamor_pixmap_private*);
+
+enum glamor_gl_flavor {
+   GLAMOR_GL_DESKTOP,        // OPENGL API
+   GLAMOR_GL_ES2             // OPENGL ES2.0 API
+};
+
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
 typedef struct glamor_screen_private {
   CloseScreenProcPtr saved_close_screen;
@@ -196,6 +224,7 @@ typedef struct glamor_screen_private {
   int vbo_size;
   char *vb;
   int vb_stride;
+  enum glamor_gl_flavor gl_flavor;
 
   /* glamor_finishaccess */
   GLint finish_access_prog[2];
@@ -287,8 +316,8 @@ typedef struct glamor_pixmap_private {
 #define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \
   { \
       if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
-        glUseProgramObjectARB(_glamor_priv_->solid_prog); \
-        glUniform4fvARB(_glamor_priv_->solid_color_uniform_location, 1,  \
+        glUseProgram(_glamor_priv_->solid_prog); \
+        glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1,  \
                         _pixmap_priv_->pending_op.fill.color4fv); \
       } \
   } while(0)
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index dbb6081..224ae27 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -362,6 +362,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
   glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
   switch (picture->repeatType) {
   case RepeatNone:
+#ifdef GLAMOR_GLES2
+    assert(0);
+#endif
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
     break;
@@ -562,7 +565,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
   glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
 	    GL_STREAM_DRAW);
 
-  glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
+  glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
   glamor_reset_composite_vbo(screen);
 }
 
@@ -574,7 +577,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
 {
   glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-  if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
+  if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
       glamor_priv->vbo_size)
     {
       glamor_flush_composite_rects(screen);
@@ -590,6 +593,8 @@ glamor_emit_composite_rect(ScreenPtr screen,
   glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
   glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
   glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
   glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3);
 }
 
commit 68c3c6eb0cafd5eb2c208dd76a3a65187256700c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 2 15:54:15 2011 +0800

    glamor-es2: Add gles2 option.
    
    First commit to enable gles2 support. --enable-glamor-ddx
    --enable-glamor-gles2 will set thwo MACROs GLAMOR_DDX and
    GLAMOR_GLES2.
    
    Currently, the gles2 support is still incomplete.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/Makefile.am b/Makefile.am
index 0c70163..632258e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,10 @@ if RECORD
 RECORD_DIR=record
 endif
 
+if GLAMOR
+GLAMOR_DIR=glamor
+endif
+
 SUBDIRS = \
 	doc \
 	man \
@@ -38,7 +42,7 @@ SUBDIRS = \
 	$(COMPOSITE_DIR) \
 	$(GLX_DIR) \
 	exa \
-	glamor \
+	$(GLAMOR_DIR) \
 	config \
 	hw \
 	test
diff --git a/configure.ac b/configure.ac
index caefc46..73c1bea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -646,6 +646,8 @@ AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest serv
 AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
 AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
 AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
+#AC_ARG_ENABLE(glamor,         AS_HELP_STRING([--enable-glamor], [Build glamor server (default: no)]), [GLAMOR=$enableval], [GLAMOR=no])
+AC_ARG_ENABLE(glamor-ddx,     AS_HELP_STRING([--enable-glamor-ddx], [Build glamor ddx (default: no)]), [GLAMOR_DDX=$enableval], [GLAMOR_DDX=no])
 dnl kdrive and its subsystems
 AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
 AC_ARG_ENABLE(xephyr,         AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
@@ -655,6 +657,8 @@ dnl kdrive options
 AC_ARG_ENABLE(kdrive-kbd,     AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
 AC_ARG_ENABLE(kdrive-mouse,   AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
 AC_ARG_ENABLE(kdrive-evdev,   AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
+dnl glamor options
+AC_ARG_ENABLE(glamor-gles2,         AS_HELP_STRING([--enable-glamor-gles2], [Build glamor based on gles2 (default: no)]), [GLAMOR_GLES2=$enableval], [GLAMOR_GLES2=no])
 
 
 dnl chown/chmod to be setuid root as part of build
@@ -1765,6 +1769,25 @@ AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
 AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
 AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
 
+dnl glamor 
+
+AM_CONDITIONAL([GLAMOR], [test "x$XEPHYR" = xyes || test "x$GLAMOR_DDX" = xyes])
+
+GLAMOR=yes
+
+if test "x$GLAMOR" = xyes; then 
+   AC_DEFINE(GLAMOR,1,[Build Glamor])
+   if test "x$GLAMOR_GLES2" = xyes; then
+      AC_DEFINE(GLAMOR_GLES2,1,[Build glamor over GLES2])
+   else 
+      AC_DEFINE(GLAMOR_GL,1,[Build glamor over GL])
+   fi
+
+   if test "x$GLAMOR_DDX" = xyes; then
+     AC_DEFINE(GLAMOR_DDX,1,[Enable glamor ddx driver])
+   fi
+fi
+
 dnl XWin DDX
 
 AC_MSG_CHECKING([whether to build XWin DDX])
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b7fcfbd..6005a2c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -29,10 +29,28 @@
 
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
+#include <xorg-config.h>
 #endif
 
 
 #include "glamor.h"
+
+#ifdef GLAMOR_GLES2
+
+#define GLEW_ES_ONLY 1
+
+#define GL_BGRA                                 GL_BGRA_EXT
+#define GL_COLOR_INDEX                          0x1900
+#define GL_BITMAP                               0x1A00
+#define GL_UNSIGNED_INT_8_8_8_8                 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV             0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV          0x8368
+#define GL_UNSIGNED_SHORT_5_6_5_REV             0x8364
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV           0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV           0x8365
+
+#endif
+
 #include <GL/glew.h>
 
 #ifdef RENDER
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 830f17a..f76a361 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -27,12 +27,16 @@ if INT10MODULE
 INT10_SUBDIR = int10
 endif
 
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw glamor os-support parser \
+if GLAMOR
+GLAMOR_DIR=glamor
+endif
+
+SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw $(GLAMOR_DIR) os-support parser \
 	  ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
 	  loader dixmods exa modes \
 	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
 
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw glamor os-support \
+DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw $(GLAMOR_DIR) os-support \
                parser ramdac shadowfb vbe vgahw xaa \
                loader dixmods dri dri2 exa modes \
 	       utils doc man
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 56fb62f..663e70a 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1118,7 +1118,11 @@ videoPtrToDriverList(struct pci_device *dev,
             } else if (dev->device_id == 0x8108) {
                 break; /* "hooray" for poulsbo */
 	    } else {
+#if GLAMOR_DDX
 	      driverList[0] = "glamor";
+#else
+	      driverList[0] = "intel";
+#endif
 	    }
 	    break;
 	case 0x102b:		    driverList[0] = "mga";	break;
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index d691009..d9dc8a9 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -12,8 +12,11 @@ glamor_la_CFLAGS =					\
 	-I$(top_srcdir)/glamor				\
 	-I/usr/include/drm
 
-glamor_la_LDFLAGS =							\
-	-module -avoid-version -L$(libdir) -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW
+glamor_la_LDFLAGS =				 \
+	-module -avoid-version -L$(libdir) -lEGL \
+        $(top_builddir)/glamor/libglamor.la      \
+        -L$(libdir)/../lib64 -lGLEW
+
 glamor_ladir = $(moduledir)/drivers
 glamor_la_SOURCES =				\
 	glamor.c				\
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 1da7eb2..a1128da 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -38,7 +38,13 @@
 #define GL_GLEXT_PROTOTYPES
 #define EGL_EGLEXT_PROTOTYPES
 #define EGL_DISPLAY_NO_X_MESA
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#else
 #include <GL/gl.h>
+#endif
+
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
@@ -322,7 +328,6 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 
 	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
 	eglBindAPI(EGL_OPENGL_API);
-        LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB));
 	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglInitialize() failed\n");
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index cf49402..d2f98fb 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -53,7 +53,17 @@
 #define GL_GLEXT_PROTOTYPES
 #define EGL_EGLEXT_PROTOTYPES
 #define EGL_DISPLAY_NO_X_MESA
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#ifndef GL_BGRA
+#define GL_BGRA GL_BGRA_EXT
+#endif
+#else
 #include <GL/gl.h>
+#endif
+
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
@@ -482,11 +492,15 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor);
 	}
-
-	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
 	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
+#if GLAMOR_GLES2
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64, 0,
+	  GL_BGRA,  GL_UNSIGNED_BYTE, image);
+#else
+	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
 	  GL_BGRA,  GL_UNSIGNED_INT_8_8_8_8_REV, image);
+#endif
 
 }
 
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index 0d1ea91..c9760b0 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -139,4 +139,15 @@
 /* Build with libdrm support */
 #undef WITH_LIBDRM
 
+
+/* Build GLAMOR */
+#undef GLAMOR
+
+/* Build GLAMOR over GLES2*/
+#undef GLAMOR_GLES2
+
+/* Build GLAMOR ddx*/
+#undef GLAMOR_DDX
+
+
 #endif /* _XORG_CONFIG_H_ */
commit 98f8ef5f991e3c9d4b434af9003c466ad1edc23e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Aug 2 15:51:46 2011 +0800

    glamor: Change to use official APIs rather than ARB version function.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index f3a83fa..b678984 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -74,10 +74,10 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
      */
     pixmap_priv->gl_fbo = 1;
     pixmap_priv->gl_tex = 1;
-    glGenFramebuffersEXT(1, &pixmap_priv->fb);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-                             GL_COLOR_ATTACHMENT0_EXT,
+    glGenFramebuffers(1, &pixmap_priv->fb);
+    glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
+    glFramebufferTexture2D(GL_FRAMEBUFFER,
+                             GL_COLOR_ATTACHMENT0,
                              GL_TEXTURE_2D,
                              pixmap_priv->tex,
                              0);
@@ -217,11 +217,11 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
     if (pixmap->refcnt == 1) {
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
         if (pixmap_priv->fb)
-	  glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
+	  glDeleteFramebuffers(1, &pixmap_priv->fb);
         if (pixmap_priv->tex)
 	  glDeleteTextures(1, &pixmap_priv->tex);
         if (pixmap_priv->pbo)
-          glDeleteBuffersARB(1, &pixmap_priv->pbo);
+          glDeleteBuffers(1, &pixmap_priv->pbo);
         dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
     }
 
@@ -293,6 +293,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glewInit();
 
+#ifndef GLAMOR_GLES2
     if (!GLEW_EXT_framebuffer_object) {
 	ErrorF("GL_EXT_framebuffer_object required\n");
 	goto fail;
@@ -305,14 +306,17 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	ErrorF("GL_ARB_vertex_shader required\n");
 	goto fail;
     }
-    if (!GLEW_ARB_pixel_buffer_object) {
-	ErrorF("GL_ARB_pixel_buffer_object required\n");
-	goto fail;
-    }
     if (!GLEW_EXT_bgra) {
 	ErrorF("GL_EXT_bgra required\n");
 	goto fail;
     }
+#endif
+
+    if (!GLEW_ARB_pixel_buffer_object) {
+	ErrorF("GL_ARB_pixel_buffer_object required\n");
+	goto fail;
+    }
+ 
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
 					NULL)) {
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index c7d0d21..acd1edc 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -196,7 +196,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glClientActiveTexture(GL_TEXTURE0);
       glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-      glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
+      glUseProgram(glamor_priv->finish_access_prog[0]);
     } 
     else {
       GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
@@ -222,7 +222,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
 
     glDisableClientState(GL_VERTEX_ARRAY);
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index da8b90b..d99560f 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -59,10 +59,10 @@ void
 glamor_get_transform_uniform_locations(GLint prog,
 				       glamor_transform_uniforms *uniform_locations)
 {
-  uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
-  uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
-  uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
-  uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
+  uniform_locations->x_bias = glGetUniformLocation(prog, "x_bias");
+  uniform_locations->x_scale = glGetUniformLocation(prog, "x_scale");
+  uniform_locations->y_bias = glGetUniformLocation(prog, "y_bias");
+  uniform_locations->y_scale = glGetUniformLocation(prog, "y_scale");
 }
 
 /* We don't use a full matrix for our transformations because it's
@@ -73,10 +73,10 @@ void
 glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				glamor_transform_uniforms *uniform_locations)
 {
-  glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
-  glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
-  glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
-  glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
+  glUniform1f(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
+  glUniform1f(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
+  glUniform1f(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
+  glUniform1f(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
 }
 
 GLint
@@ -85,9 +85,9 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
   GLint ok;
   GLint prog;
 
-  prog = glCreateShaderObjectARB(type);
-  glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
-  glCompileShaderARB(prog);
+  prog = glCreateShader(type);
+  glShaderSource(prog, 1, (const GLchar **)&source, NULL);
+  glCompileShader(prog);
   glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
   if (!ok) {
     GLchar *info;
@@ -165,22 +165,22 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 
   GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
 
-  glamor_priv->finish_access_prog[0] = glCreateProgramObjectARB();
-  glamor_priv->finish_access_prog[1] = glCreateProgramObjectARB();
+  glamor_priv->finish_access_prog[0] = glCreateProgram();
+  glamor_priv->finish_access_prog[1] = glCreateProgram();
 
   if (GLEW_ARB_fragment_shader) {
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
-    glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog);
-    glAttachObjectARB(glamor_priv->finish_access_prog[0], fs_prog);
-
-    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-    aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source);
-    glAttachObjectARB(glamor_priv->finish_access_prog[1], avs_prog);
-    glAttachObjectARB(glamor_priv->finish_access_prog[1], aswizzle_prog);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source);
+    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
+
+    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+    aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, aswizzle_source);
+    glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
+    glAttachShader(glamor_priv->finish_access_prog[1], aswizzle_prog);
   } else {
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-    glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog);
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source);
+    glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
     ErrorF("Lack of framgment shader support.\n");
   }
 
@@ -191,16 +191,16 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     GLint sampler_uniform_location;
 
     sampler_uniform_location =
-      glGetUniformLocationARB(glamor_priv->finish_access_prog[0], "sampler");
-    glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
-    glUniform1iARB(sampler_uniform_location, 0);
-    glUseProgramObjectARB(0);
+      glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[0]);
+    glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(0);
 
     sampler_uniform_location =
-      glGetUniformLocationARB(glamor_priv->finish_access_prog[1], "sampler");
-    glUseProgramObjectARB(glamor_priv->finish_access_prog[1]);
-    glUniform1iARB(sampler_uniform_location, 0);
-    glUseProgramObjectARB(0);
+      glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
+    glUseProgram(glamor_priv->finish_access_prog[1]);
+    glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(0);
   }
 }
 
@@ -218,10 +218,10 @@ glamor_finish_access(DrawablePtr drawable)
   }
 
   if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
-    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
-    glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glBindBuffer (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
     pixmap_priv->pbo_valid = FALSE;
-    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+    glDeleteBuffers(1, &pixmap_priv->pbo);
     pixmap_priv->pbo = 0;
   } else
     free(pixmap->devPrivate.ptr);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 393f651..14cce0c 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -122,20 +122,20 @@ glamor_init_solid_shader(ScreenPtr screen)
 	"}\n";
     GLint fs_prog, vs_prog;
 
-    glamor_priv->solid_prog = glCreateProgramObjectARB();
+    glamor_priv->solid_prog = glCreateProgram();
     if (GLEW_ARB_fragment_shader) {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs);
-	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs);
-	glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
-	glAttachObjectARB(glamor_priv->solid_prog, fs_prog);
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
+	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
+	glAttachShader(glamor_priv->solid_prog, vs_prog);
+	glAttachShader(glamor_priv->solid_prog, fs_prog);
     } else {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only);
-	glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs_only);
+	glAttachShader(glamor_priv->solid_prog, vs_prog);
     }
     glamor_link_glsl_prog(glamor_priv->solid_prog);
 
     glamor_priv->solid_color_uniform_location =
-	glGetUniformLocationARB(glamor_priv->solid_prog, "color");
+	glGetUniformLocation(glamor_priv->solid_prog, "color");
 }
 
 Bool
@@ -184,9 +184,9 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glamor_validate_pixmap(pixmap);
 
-    glUseProgramObjectARB(glamor_priv->solid_prog);
+    glUseProgram(glamor_priv->solid_prog);
  
-    glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
+    glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
@@ -199,7 +199,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     glDisableClientState(GL_VERTEX_ARRAY);
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
     return TRUE;
 fail:
     glamor_set_alu(GXcopy);
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 0f85d96..0f13f09 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -35,8 +35,8 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
 //    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
-    glUseProgramObjectARB(glamor_priv->solid_prog);
-    glUniform4fvARB(glamor_priv->solid_color_uniform_location, 
+    glUseProgram(glamor_priv->solid_prog);
+    glUniform4fv(glamor_priv->solid_color_uniform_location, 
       1, pixmap_priv->pending_op.fill.color4fv);
     vertices[0] = -1;
     vertices[1] = -1;
@@ -48,7 +48,7 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
     vertices[7] = 1;
     glDrawArrays(GL_QUADS, 0, 4);
     glDisableClientState(GL_VERTEX_ARRAY);
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
 
@@ -223,7 +223,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
 
   if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
     texels = NULL;
-    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
   }
   else
     texels = pixmap->devPrivate.ptr;
@@ -300,12 +300,12 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glEnable(GL_TEXTURE_2D);
-  glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]);
+  glUseProgram(glamor_priv->finish_access_prog[ax]);
 
   glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
   glDisable(GL_TEXTURE_2D);
-  glUseProgramObjectARB(0);
+  glUseProgram(0);
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glDeleteTextures(1, &tex);
@@ -472,16 +472,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   glamor_validate_pixmap(pixmap); 
   switch (access) {
   case GLAMOR_ACCESS_RO:
-    gl_access = GL_READ_ONLY_ARB;
-    gl_usage = GL_STREAM_READ_ARB;
+    gl_access = GL_READ_ONLY;
+    gl_usage = GL_STREAM_READ;
     break;
   case GLAMOR_ACCESS_WO:
     data = malloc(stride * pixmap->drawable.height);
     goto done;
     break;
   case GLAMOR_ACCESS_RW:
-    gl_access = GL_READ_WRITE_ARB;
-    gl_usage = GL_DYNAMIC_DRAW_ARB;
+    gl_access = GL_READ_WRITE;
+    gl_usage = GL_DYNAMIC_DRAW;
     break;
   default:
     ErrorF("Glamor: Invalid access code. %d\n", access);
@@ -497,41 +497,41 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     if (!glamor_priv->yInverted) 
       glPixelStorei(GL_PACK_INVERT_MESA, 1);
     if (pixmap_priv->pbo == 0)
-      glGenBuffersARB (1, &pixmap_priv->pbo);
-    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-    glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT,
+      glGenBuffers (1, &pixmap_priv->pbo);
+    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+    glBufferData (GL_PIXEL_PACK_BUFFER_EXT,
 		     stride * pixmap->drawable.height,
 		     NULL, gl_usage);
     glReadPixels (0, 0,
                     row_length, pixmap->drawable.height,
                     format, type, 0);
-    data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access);
+    data = glMapBuffer (GL_PIXEL_PACK_BUFFER_EXT, gl_access);
     pixmap_priv->pbo_valid = TRUE;
 
     if (!glamor_priv->yInverted) 
       glPixelStorei(GL_PACK_INVERT_MESA, 0);
-    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glBindBuffer (GL_PIXEL_PACK_BUFFER_EXT, 0);
   } else {
     data = malloc(stride * pixmap->drawable.height);
     assert(data);
     if (access != GLAMOR_ACCESS_WO) {
       if (pixmap_priv->pbo == 0)
-	glGenBuffersARB(1, &pixmap_priv->pbo);
-      glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-      glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
+	glGenBuffers(1, &pixmap_priv->pbo);
+      glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+      glBufferData(GL_PIXEL_PACK_BUFFER_EXT,
 		      stride * pixmap->drawable.height,
-		      NULL, GL_STREAM_READ_ARB);
+		      NULL, GL_STREAM_READ);
       glReadPixels (0, 0, row_length, pixmap->drawable.height,
 		    format, type, 0);
-      read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB);
+      read = glMapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY);
 	  
       for (y = 0; y < pixmap->drawable.height; y++)
 	memcpy(data + y * stride,
 	       read + (pixmap->drawable.height - y - 1) * stride, stride);
-      glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
-      glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
+      glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT);
+      glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0);
       pixmap_priv->pbo_valid = FALSE;
-      glDeleteBuffersARB(1, &pixmap_priv->pbo);
+      glDeleteBuffers(1, &pixmap_priv->pbo);
       pixmap_priv->pbo = 0;
     }
   }
@@ -555,7 +555,7 @@ _glamor_destroy_upload_pixmap(PixmapPtr pixmap)
   if (pixmap_priv->tex)
     glDeleteTextures(1, &pixmap_priv->tex);
   if (pixmap_priv->pbo)
-    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+    glDeleteBuffers(1, &pixmap_priv->pbo);
   pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
 
 }
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 0a91050..65e7cfd 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -66,25 +66,25 @@ glamor_init_putimage_shaders(ScreenPtr screen)
     if (!GLEW_ARB_fragment_shader)
 	return;
 
-    prog = glCreateProgramObjectARB();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, xybitmap_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, xybitmap_fs);
-    glAttachObjectARB(prog, vs_prog);
-    glAttachObjectARB(prog, fs_prog);
+    prog = glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
+    glAttachShader(prog, vs_prog);
+    glAttachShader(prog, fs_prog);
     glamor_link_glsl_prog(prog);
 
-    glUseProgramObjectARB(prog);
-    sampler_uniform_location = glGetUniformLocationARB(prog, "bitmap_sampler");
-    glUniform1iARB(sampler_uniform_location, 0);
+    glUseProgram(prog);
+    sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler");
+    glUniform1i(sampler_uniform_location, 0);
 
     glamor_priv->put_image_xybitmap_fg_uniform_location =
-	glGetUniformLocationARB(prog, "fg");
+	glGetUniformLocation(prog, "fg");
     glamor_priv->put_image_xybitmap_bg_uniform_location =
-	glGetUniformLocationARB(prog, "bg");
+	glGetUniformLocation(prog, "bg");
     glamor_get_transform_uniform_locations(prog,
 					   &glamor_priv->put_image_xybitmap_transform);
     glamor_priv->put_image_xybitmap_prog = prog;
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
 }
 
 
@@ -160,13 +160,13 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     if (!glamor_set_planemask(pixmap, gc->planemask))
 	goto fail;
 
-    glUseProgramObjectARB(glamor_priv->put_image_xybitmap_prog);
+    glUseProgram(glamor_priv->put_image_xybitmap_prog);
 
     glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
-    glUniform4fvARB(glamor_priv->put_image_xybitmap_fg_uniform_location,
+    glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location,
 		    1, fg);
     glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
-    glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location,
+    glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location,
 		    1, bg);
 
     glGenTextures(1, &tex);
@@ -322,7 +322,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glEnable(GL_TEXTURE_2D);
 
     assert(GLEW_ARB_fragment_shader);
-    glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]);
+    glUseProgram(glamor_priv->finish_access_prog[ax]);
 
     x += drawable->x;
     y += drawable->y;
@@ -371,7 +371,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     }
 
     glDisable(GL_TEXTURE_2D);
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tex);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a901578..dbb6081 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -186,7 +186,7 @@ glamor_create_composite_fs(struct shader_key *key)
 	      in);
  
 
-  prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
+  prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
   free(source);
 
   return prog;
@@ -223,7 +223,7 @@ glamor_create_composite_vs(struct shader_key *key)
 	      mask_coords_setup,
 	      main_closing);
 
-  prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
+  prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source);
   free(source);
 
   return prog;
@@ -243,30 +243,30 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
   if (fs == 0)
     return;
 
-  prog = glCreateProgramObjectARB();
-  glAttachObjectARB(prog, vs);
-  glAttachObjectARB(prog, fs);
+  prog = glCreateProgram();
+  glAttachShader(prog, vs);
+  glAttachShader(prog, fs);
   glamor_link_glsl_prog(prog);
 
   shader->prog = prog;
 
-  glUseProgramObjectARB(prog);
+  glUseProgram(prog);
 
   if (key->source == SHADER_SOURCE_SOLID) {
-    shader->source_uniform_location = glGetUniformLocationARB(prog,
+    shader->source_uniform_location = glGetUniformLocation(prog,
 							      "source");
   } else {
-    source_sampler_uniform_location = glGetUniformLocationARB(prog,
+    source_sampler_uniform_location = glGetUniformLocation(prog,
 							      "source_sampler");
     glUniform1i(source_sampler_uniform_location, 0);
   }
 
   if (key->mask != SHADER_MASK_NONE) {
     if (key->mask == SHADER_MASK_SOLID) {
-      shader->mask_uniform_location = glGetUniformLocationARB(prog,
+      shader->mask_uniform_location = glGetUniformLocation(prog,
 							      "mask");
     } else {
-      mask_sampler_uniform_location = glGetUniformLocationARB(prog,
+      mask_sampler_uniform_location = glGetUniformLocation(prog,
 							      "mask_sampler");
       glUniform1i(mask_sampler_uniform_location, 1);
     }
@@ -397,7 +397,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
 static void
 glamor_set_composite_solid(float *color, GLint uniform_location)
 {
-  glUniform4fvARB(uniform_location, 1, color);
+  glUniform4fv(uniform_location, 1, color);
 }
 
 static int
@@ -504,7 +504,7 @@ glamor_setup_composite_vbo(ScreenPtr screen)
   if (glamor_priv->has_mask_coords)
     glamor_priv->vb_stride += 2 * sizeof(float);
 
-  glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
+  glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
   glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
 		  (void *)((long)glamor_priv->vbo_offset));
   glEnableClientState(GL_VERTEX_ARRAY);
@@ -559,8 +559,8 @@ glamor_flush_composite_rects(ScreenPtr screen)
 
   if (!glamor_priv->render_nr_verts)
     return;
-  glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_offset, glamor_priv->vb,
-	    GL_STREAM_DRAW_ARB);
+  glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
+	    GL_STREAM_DRAW);
 
   glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
   glamor_reset_composite_vbo(screen);
@@ -582,7 +582,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
 
   if (glamor_priv->vbo_offset == 0) {
     if (glamor_priv->vbo == 0)
-      glGenBuffersARB(1, &glamor_priv->vbo);
+      glGenBuffers(1, &glamor_priv->vbo);
 
     glamor_setup_composite_vbo(screen);
   }
@@ -882,7 +882,7 @@ glamor_composite_with_shader(CARD8 op,
     goto fail;
   }
 
-  glUseProgramObjectARB(shader->prog);
+  glUseProgram(shader->prog);
   if (key.source == SHADER_SOURCE_SOLID) {
     glamor_set_composite_solid(source_solid_color, shader->source_uniform_location);
   } else {
@@ -1008,7 +1008,7 @@ glamor_composite_with_shader(CARD8 op,
   }
   glamor_flush_composite_rects(screen);
 
-  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+  glBindBuffer(GL_ARRAY_BUFFER, 0);
   glClientActiveTexture(GL_TEXTURE0);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   glClientActiveTexture(GL_TEXTURE1);
@@ -1021,7 +1021,7 @@ glamor_composite_with_shader(CARD8 op,
   glDisable(GL_TEXTURE_2D);
   glActiveTexture(GL_TEXTURE1);
   glDisable(GL_TEXTURE_2D);
-  glUseProgramObjectARB(0);
+  glUseProgram(0);
   if (saved_source_format) 
     source->format = saved_source_format;
   return TRUE;
@@ -1031,7 +1031,7 @@ glamor_composite_with_shader(CARD8 op,
     source->format = saved_source_format;
 
   glDisable(GL_BLEND);
-  glUseProgramObjectARB(0);
+  glUseProgram(0);
   return FALSE;
 }
 
@@ -1223,7 +1223,7 @@ fail:
 		  dest->pDrawable->height,
 		  glamor_get_picture_location(dest));
 
-  glUseProgramObjectARB(0);
+  glUseProgram(0);
   glDisable(GL_BLEND);
   if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
     if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index a78c301..436e769 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -58,18 +58,18 @@ glamor_init_tile_shader(ScreenPtr screen)
     if (!GLEW_ARB_fragment_shader)
 	return;
 
-    glamor_priv->tile_prog = glCreateProgramObjectARB();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, tile_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, tile_fs);
-    glAttachObjectARB(glamor_priv->tile_prog, vs_prog);
-    glAttachObjectARB(glamor_priv->tile_prog, fs_prog);
+    glamor_priv->tile_prog = glCreateProgram();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
+    glAttachShader(glamor_priv->tile_prog, vs_prog);
+    glAttachShader(glamor_priv->tile_prog, fs_prog);
     glamor_link_glsl_prog(glamor_priv->tile_prog);
 
     sampler_uniform_location =
-	glGetUniformLocationARB(glamor_priv->tile_prog, "sampler");
-    glUseProgramObjectARB(glamor_priv->tile_prog);
-    glUniform1iARB(sampler_uniform_location, 0);
-    glUseProgramObjectARB(0);
+	glGetUniformLocation(glamor_priv->tile_prog, "sampler");
+    glUseProgram(glamor_priv->tile_prog);
+    glUniform1i(sampler_uniform_location, 0);
+    glUseProgram(0);
 }
 
 Bool
@@ -130,7 +130,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
     if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
       pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-      glUseProgramObjectARB(glamor_priv->tile_prog);
+      glUseProgram(glamor_priv->tile_prog);
  
       glActiveTexture(GL_TEXTURE0);
       glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
@@ -169,7 +169,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     }
     glDisableClientState(GL_VERTEX_ARRAY);
 
-    glUseProgramObjectARB(0);
+    glUseProgram(0);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return TRUE;
commit 0ef1698be22750fb14418bd418114fc63039db0c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 21 16:18:48 2011 +0800

    glamor: Fix one bug for Xephyr.
    
    Xephyr doesn't has a bounded valid texture. It seems that we can't
    load texture 0 directly sometimes. Especially in the copyarea, function
    if that is the case, we prefer to use fbo blit to read the screen pixmap
    rather than load the bound texture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 33a33d6..f3a83fa 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -200,7 +200,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
     pixmap_priv = glamor_get_pixmap_private(pixmap);
     pixmap_priv->tex = 0; 
     pixmap_priv->gl_fbo = 1;
-    pixmap_priv->gl_tex = 1;
+    pixmap_priv->gl_tex = 0;
     pixmap_priv->container = pixmap;
     pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
     
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index c8ccaae..c7d0d21 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -293,7 +293,8 @@ glamor_copy_n_to_n(DrawablePtr src,
     }
     /* XXX need revisit to handle overlapped area copying. */
 
-    if ( overlaped  
+    if ((overlaped 
+          || !src_pixmap_priv->gl_tex  || !dst_pixmap_priv->gl_tex )
         && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
         goto done;
 	return;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f0a6e88..a901578 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -765,7 +765,11 @@ glamor_composite_with_shader(CARD8 op,
       glamor_fallback("source == dest\n");
       goto fail;
     }
-    if (!source_pixmap_priv || source_pixmap_priv->gl_tex == 0) {
+    if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
+    /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
+     * equal to zero when the pixmap is screen pixmap. Then we may
+     * refer the tex zero directly latter in the composition. 
+     * It seems that it works fine, but it may have potential problem*/
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
       source_status = GLAMOR_UPLOAD_PENDING;
 #else
@@ -786,7 +790,7 @@ glamor_composite_with_shader(CARD8 op,
       glamor_fallback("mask == dest\n");
       goto fail;
     }
-    if (!mask_pixmap_priv || mask_pixmap_priv->gl_tex == 0) {
+    if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) {
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
       mask_status = GLAMOR_UPLOAD_PENDING;
 #else
commit 9b667ffd564910ff7373547ce2f8d4a7c5d71137
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 20 14:33:00 2011 +0800

    glamor: Use small internal texture format if possible.
    
    Reduce some texture memory requirement and also save
    some bandwidth.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6952308..33a33d6 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -151,10 +151,10 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
 	return pixmap;
 
-    /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
-     * FBOs, which EXT_fbo forgot to do.
-     */
     switch (depth) {
+    case 8:
+        format = GL_ALPHA;
+        break;
     case 24:
         format = GL_RGB;
         break; 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 924a173..0f85d96 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -199,7 +199,20 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
   unsigned int stride, row_length;
   void *texels;
-  GLenum iformat = GL_RGBA;
+  GLenum iformat;
+
+  switch (pixmap->drawable.depth) {
+    case 8:
+        iformat = GL_ALPHA;
+        break;
+    case 24:
+        iformat = GL_RGB;
+        break; 
+    default:
+        iformat = GL_RGBA;
+        break;
+    }
+
 
   stride = pixmap->devKind;
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
commit 01489f9da9aa357c59799d4d41c7ca96b4cbd1d8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 20 14:02:15 2011 +0800

    glamor: Add simple introduction of how to setup glamor xserver.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/README b/README
index b2499a0..05effbe 100644
--- a/README
+++ b/README
@@ -1,4 +1,83 @@
-					X Server
+			Glamor setup
+
+1. Prerequirement.
+Please install makedepend and libudev-devel firstly. 
+Glamor need patch glew-1.5.8, here is the patch:
+
+
+diff -ur ../Downloads/glew-1.5.8/Makefile glew-1.5.8/Makefile
+--- ../Downloads/glew-1.5.8/Makefile    2011-01-31 22:17:27.000000000 +0800
++++ glew-1.5.8/Makefile 2011-06-28 10:13:54.147700479 +0800
+@@ -63,8 +63,12 @@
+ else
+ OPT = $(POPT)
+ endif
+-INCLUDE = -Iinclude
++
++NCLUDE = -Iinclude
+ CFLAGS = $(OPT) $(WARN) $(INCLUDE) $(CFLAGS.EXTRA)
++ifeq ($(NO_GLX), 1)
++CFLAGS += -D_NO_GLX_
++endif
+
+ LIB.SRCS = src/glew.c
+ LIB.OBJS = $(LIB.SRCS:.c=.o)
+diff -ur ../Downloads/glew-1.5.8/src/glew.c glew-1.5.8/src/glew.c
+--- ../Downloads/glew-1.5.8/src/glew.c  2011-01-31 22:17:27.000000000 +0800
++++ glew-1.5.8/src/glew.c       2011-06-28 10:06:45.952700777 +0800
+@@ -11379,6 +11379,10 @@
+ {
+   GLenum r;
+   if ( (r = glewContextInit()) ) return r;
++#if defined(_NO_GLX_)
++  return r;
++#endif
++
+ #if defined(_WIN32)
+   return wglewContextInit();
+ #elif !defined(__APPLE__) || defined(GLEW_APPLE_GLX) /* _UNIX */
+
+
+As xserver's glx extension code has conflicts with glew's glx related
+initialization, we have to disable it in glew currently. Please apply the
+above patch to glew and then build the glew as follow which will 
+workaround the problem.
+
+glew-1.5.8# NO_GLX=1 make
+
+2. Build xserver-glamor.
+
+Then do the following steps one by one.
+2.1. get latest glamor at github.
+
+2.2 Setup xorg development environment, use xserver-glamor to 
+    replace the official xserver. 
+ Here is the link of how to setup xorg development environment: 
+ http://www.x.org/wiki/ModularDevelopersGuide
+ 
+ For most of the packages, we prefer latest git version. Especially
+ for the mesa package.
+
+ When build mesa, use the following parameters: (assume you want to 
+ install the experimental xorg to /opt/gfx-test) 
+#mesa/./autogen.sh --prefix=/opt/gfx-test --with-egl-platforms=drm --disable-gallium  --disable-gallium-egl
+
+ build xserver-glamor as below:
+#xserver-glamor/./autogen.sh --disable-glx --enable-kdrive --enable-xephyr
+
+ Once you finish all the building process, you can have a try as below:
+xserver-glamor#startx -- `pwd`/hw/xfree86/Xorg If you can find the 
+ following messages on the console, then everything should work correctly.
+Mesa: Initializing x86-64 optimizations
+
+
+3. Restrictions:
+
+Currently, glamor doesn't support glx extension, will be fixed in the future.
+
+Glamor setup done.
+
+				X Server
 
 The X server accepts requests from client applications to create windows,
 which are (normally rectangular) "virtual screens" that the client program
commit 1f3f3baf1469e74767474ddb383e92502384de80
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 20 13:35:25 2011 +0800

    glamor: Avoid 2D bitblit if possible.
    
    It turns out that the use of fbo blit is one of the root cause
    which lead to slow drawing, especially slow filling rects.
    
    We guess there should be a performance bug in the mesa driver
    or even in the kernel drm driver. Currently, the only thing
    glamor can do is to avoid calling those functions.
    
    We check whether the copy source and destination has overlapped
    region, if it has, we have to call fbo blit function. If it has
    not, we can load the source texture directly and draw it to the
    target texture. We totally don't need the glCopyPixels here, so
    remove it.
    
    By apply this patch, the rendering time of firefox-planet-gnome
    decrease to 10.4 seconds. At the same platform, uxa driver get 13
    seconds. This is the first time we get better performance than
    uxa driver.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 4cbb3c6..c8ccaae 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -47,15 +47,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
-    if (src == dst) {
-	glamor_delayed_fallback(screen,"src == dest\n");
-	return FALSE;
-    }
-
     if (!GLEW_EXT_framebuffer_blit) {
 	glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
 	return FALSE;
-   }
+    }
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
@@ -122,78 +117,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 }
 
 static Bool
-glamor_copy_n_to_n_copypixels(DrawablePtr src,
-			      DrawablePtr dst,
-			      GCPtr gc,
-			      BoxPtr box,
-			      int nbox,
-			      int dx,
-			      int dy)
-{
-    ScreenPtr screen = dst->pScreen;
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv;
-    int x_off, y_off, i;
-    if (src != dst) {
-	glamor_delayed_fallback(screen, "src != dest\n");
-	return FALSE;
-    }
-
-    if (gc) {
-	if (gc->alu != GXcopy) {
-	    glamor_delayed_fallback(screen,"non-copy ALU\n");
-	    return FALSE;
-	}
-	if (!glamor_pm_is_solid(dst, gc->planemask)) {
-	    glamor_delayed_fallback(screen,"non-solid planemask\n");
-	    return FALSE;
-	}
-    }
-
-    pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
-    if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) 
-      return TRUE;
-    if (glamor_set_destination_pixmap(dst_pixmap)) {
-        glamor_delayed_fallback(screen, "dst has no fbo.\n");
-	return FALSE;
-    }
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    glOrtho(0, dst_pixmap->drawable.width,
-	    0, dst_pixmap->drawable.height,
-	    -1, 1);
-
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-
-    glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
-
-    for (i = 0; i < nbox; i++) {
-      if(glamor_priv->yInverted) {
-	glRasterPos2i(box[i].x1 + x_off,
-		      box[i].y1 + y_off);
-	glCopyPixels(box[i].x1 + dx + x_off,
-		     box[i].y1 + dy + y_off,
-		     box[i].x2 - box[i].x1,
-		     box[i].y2 - box[i].y1,
-		     GL_COLOR);
-	} else {
-	int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off;
-	glRasterPos2i(box[i].x1 + x_off,
-		      flip_y1);
-	glCopyPixels(box[i].x1 + dx + x_off,
-		     flip_y1 - dy,
-		     box[i].x2 - box[i].x1,
-		     box[i].y2 - box[i].y1,
-		     GL_COLOR);
-	}
-    }
-    return TRUE;
-}
-
-static Bool
 glamor_copy_n_to_n_textured(DrawablePtr src,
 			      DrawablePtr dst,
 			      GCPtr gc,
@@ -213,21 +136,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
     enum glamor_pixmap_status src_status = GLAMOR_NONE;
     GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+    int flush_needed = 0;
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
     dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
-    if (src == dst) {
-	glamor_delayed_fallback(dst->pScreen, "same src/dst\n");
-	goto fail;
-    }
-
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
         glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
         goto fail;
     }
 
-    if (!src_pixmap_priv->gl_tex) {
+    if (!src_pixmap_priv->gl_fbo) {
 #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 	glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
 	goto fail;
@@ -237,6 +156,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	goto fail;
 #endif
     }
+    else
+      flush_needed = 1;
 
     if (gc) {
 	glamor_set_alu(gc->alu);
@@ -246,7 +167,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
           glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
           glamor_validate_pixmap(src_pixmap);
         }
- 
     }
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
@@ -283,6 +203,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
    }
  
     for (i = 0; i < nbox; i++) {
+
       glamor_set_normalize_vcoords(dst_xscale, dst_yscale, 
 				   box[i].x1 + dst_x_off,
 				   box[i].y1 + dst_y_off,
@@ -308,6 +229,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       glDisable(GL_TEXTURE_2D);
     }
+    /* The source texture is bound to a fbo, we have to flush it here. */
+    if (flush_needed) 
+      glFlush();
     return TRUE;
 
 fail:
@@ -337,8 +261,14 @@ glamor_copy_n_to_n(DrawablePtr src,
     ScreenPtr screen;
     int temp_dx = dx;
     int temp_dy = dy;
+    int src_x_off, src_y_off, dst_x_off, dst_y_off;
+    int i;
+    int overlaped = 0;
+    
     dst_pixmap = glamor_get_drawable_pixmap(dst);
     dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    src_pixmap = glamor_get_drawable_pixmap(src);
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
     screen = dst_pixmap->drawable.pScreen;
 
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
@@ -346,18 +276,28 @@ glamor_copy_n_to_n(DrawablePtr src,
       goto fail;
     }
 
-    if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
-        goto done;
-	return;
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+
+    if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
+      int x_shift = abs(src_x_off - dx - dst_x_off);
+      int y_shift = abs(src_y_off - dy - dst_y_off);
+      for ( i = 0; i < nbox; i++)
+        {
+         if (x_shift < abs(box[i].x2 - box[i].x1) 
+            && y_shift < abs(box[i].y2 - box[i].y1)) {
+           overlaped = 1;
+           break;
+         }
+        }
     }
+    /* XXX need revisit to handle overlapped area copying. */
 
-    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)){
+    if ( overlaped  
+        && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
         goto done;
 	return;
-     }
-
-    src_pixmap = glamor_get_drawable_pixmap(src);
-    src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    }
 
     glamor_calculate_boxes_bound(&bound, box, nbox);
 
@@ -370,7 +310,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 					 bound.y2 - bound.y1,
 					 src_pixmap->drawable.depth,
 					 GLAMOR_CREATE_PIXMAP_CPU);
-      if (!temp_src)
+      if (!temp_pixmap)
 	goto fail;
       glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
       temp_src = &temp_pixmap->drawable;
@@ -391,6 +331,7 @@ glamor_copy_n_to_n(DrawablePtr src,
     if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
         goto done;
     }
+
     
  fail:
     glamor_report_delayed_fallbacks(src->pScreen);
@@ -406,7 +347,8 @@ glamor_copy_n_to_n(DrawablePtr src,
       dst_access = GLAMOR_ACCESS_WO;
 
     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
-	if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+	if (dst == src 
+            || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
 	    fbCopyNtoN(src, dst, gc, box, nbox,
 		       dx, dy, reverse, upsidedown, bitplane,
 		       closure);
@@ -428,34 +370,10 @@ RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		 int srcx, int srcy, int width, int height, int dstx, int dsty)
 {
-#if 0
-    ScreenPtr screen = dst->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
-#endif
     RegionPtr region;
-
     region = miDoCopy(src, dst, gc,
 		      srcx, srcy, width, height,
 		      dstx, dsty, glamor_copy_n_to_n, 0, NULL);
 
     return region;
-
-#if 0
-fail:
-    glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst,
-		    glamor_get_drawable_location(src),
-		    glamor_get_drawable_location(dst));
-    region = NULL;
-    if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
-	if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
-	    region = fbCopyArea(src, dst, gc, srcx, srcy, width, height,
-				dstx, dsty);
-	    glamor_finish_access(src);
-	}
-	glamor_finish_access(dst);
-    }
-    return region;
-#endif
 }
commit 5c4d53c5126bb9f603d04dac6874280b527319f5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 20 13:06:23 2011 +0800

    glamor: Implement delayed solid filling.
    
    When we need to solid fill an entire pixmap with a specific color,
    we do not need to draw it immediately. We can defer it to the
    following occasions:
    
    1. The pixmap will be used as source, then we can just use a shader
       to instead of one copyarea.
    2. The pixmap will be used as target, then we can do the filling
       just before drawing new pixel onto it. The filling and drawing
       will have the same target texture, we can save one time of
       fbo context switching.
    
    Actually, for the 2nd case, we have opportunity to further optimize
    it. We can just fill the untouched region.
    
    By applying this patch, the cairo-trace for the firefox-planet-gnome's
    rendering time decrease to 14seconds from 16 seconds.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 2eec6f5..6952308 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -98,6 +98,7 @@ glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int te
 
   glamor_set_pixmap_texture(pixmap, w, h, tex);
   glamor_priv->screen_fbo = pixmap_priv->fb;
+  pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
 }
 
 
@@ -119,7 +120,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    if (!glamor_check_fbo_width_height(w,h) 
+    if (!glamor_check_fbo_width_height(w,h)
 	|| !glamor_check_fbo_depth(depth) 
 	|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
 	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
@@ -201,6 +202,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
     pixmap_priv->gl_fbo = 1;
     pixmap_priv->gl_tex = 1;
     pixmap_priv->container = pixmap;
+    pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
     
     screen->CreatePixmap = glamor_create_pixmap;
     return pixmap;
@@ -369,6 +371,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_init_putimage_shaders(screen);
     glamor_init_finish_access_shaders(screen);
     glamor_glyphs_init(screen);
+    glamor_pixmap_init(screen);
 
     return TRUE;
 
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 9e2be12..4cbb3c6 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -59,6 +59,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
+    if (src_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) 
+      return FALSE;
+
     if (gc) {
 	if (gc->alu != GXcopy) {
 	    glamor_delayed_fallback(screen, "non-copy ALU\n");
@@ -78,6 +81,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     if (glamor_set_destination_pixmap(dst_pixmap)) {
 	return FALSE;
     }
+    glamor_validate_pixmap(dst_pixmap);
     glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
@@ -130,6 +134,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(screen);
+    glamor_pixmap_private *pixmap_priv;
     int x_off, y_off, i;
     if (src != dst) {
 	glamor_delayed_fallback(screen, "src != dest\n");
@@ -147,6 +152,9 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 	}
     }
 
+    pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) 
+      return TRUE;
     if (glamor_set_destination_pixmap(dst_pixmap)) {
         glamor_delayed_fallback(screen, "dst has no fbo.\n");
 	return FALSE;
@@ -234,37 +242,47 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	glamor_set_alu(gc->alu);
 	if (!glamor_set_planemask(dst_pixmap, gc->planemask))
 	  goto fail;
+        if (gc->alu != GXcopy) {
+          glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
+          glamor_validate_pixmap(src_pixmap);
+        }
+ 
     }
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    glamor_validate_pixmap(dst_pixmap);
+
     pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
-    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
-    dx += src_x_off;
-    dy += src_y_off;
 
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
-    glEnable(GL_TEXTURE_2D);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-    assert(GLEW_ARB_fragment_shader);
-    glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
-   
-
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+      glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+      dx += src_x_off;
+      dy += src_y_off;
+      pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+      glActiveTexture(GL_TEXTURE0);
+      glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+      glEnable(GL_TEXTURE_2D);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+      glClientActiveTexture(GL_TEXTURE0);
+      glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+      glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
+    } 
+    else {
+      GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
+   }
+ 
     for (i = 0; i < nbox; i++) {
-
       glamor_set_normalize_vcoords(dst_xscale, dst_yscale, 
 				   box[i].x1 + dst_x_off,
 				   box[i].y1 + dst_y_off,
@@ -273,11 +291,12 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 				   glamor_priv->yInverted,
 				   vertices);
 
-      glamor_set_normalize_tcoords(src_xscale, src_yscale,
-				   box[i].x1 + dx, box[i].y1 + dy,
-				   box[i].x2 + dx, box[i].y2 + dy,
-				   glamor_priv->yInverted,
-				   texcoords);
+      if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv))
+        glamor_set_normalize_tcoords(src_xscale, src_yscale,
+	  			     box[i].x1 + dx, box[i].y1 + dy,
+				     box[i].x2 + dx, box[i].y2 + dy,
+				     glamor_priv->yInverted,
+				     texcoords);
 
       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
@@ -285,8 +304,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glUseProgramObjectARB(0);
 
     glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glDisable(GL_TEXTURE_2D);
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+      glDisable(GL_TEXTURE_2D);
+    }
     return TRUE;
 
 fail:
@@ -352,6 +373,7 @@ glamor_copy_n_to_n(DrawablePtr src,
       if (!temp_src)
 	goto fail;
       glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
+      temp_src = &temp_pixmap->drawable;
       fbCopyNtoN(src, temp_src, gc, box, nbox,
 		 temp_dx + bound.x1, temp_dy + bound.y1, 
 		 reverse, upsidedown, bitplane,
@@ -359,7 +381,6 @@ glamor_copy_n_to_n(DrawablePtr src,
       glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
       temp_dx = -bound.x1;
       temp_dy = -bound.y1;
-      temp_src = &temp_pixmap->drawable;
     }
     else {
       temp_dx = dx;
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index a41837b..393f651 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -154,7 +154,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     GLfloat xscale, yscale;
     
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-        glamor_fallback("dest has no fbo.\n");
+        glamor_fallback("dest %p has no fbo.\n", pixmap);
 	goto fail;
     }
     glamor_set_alu(alu);
@@ -163,15 +163,29 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
       goto fail;
     } 
 
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-    glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_rgba_from_pixel(fg_pixel, 
                               &color[0], 
                               &color[1], 
                               &color[2], 
                               &color[3],
                               format_for_pixmap(pixmap));
+#ifdef GLAMOR_DELAYED_FILLING
+    if (x == 0 && y == 0 
+        && width == pixmap->drawable.width 
+        && height == pixmap->drawable.height 
+        && pixmap_priv->fb != glamor_priv->screen_fbo ) {
+      pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
+      memcpy(&pixmap_priv->pending_op.fill.color4fv,
+	     color, 4*sizeof(GLfloat));
+      pixmap_priv->pending_op.fill.colori = fg_pixel;
+      return TRUE;
+    }
+#endif
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_validate_pixmap(pixmap);
+
+    glUseProgramObjectARB(glamor_priv->solid_prog);
+ 
     glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 7fe05f9..237c1e7 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -64,6 +64,7 @@ glamor_get_spans(DrawablePtr drawable,
     }
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_validate_pixmap(pixmap);
  
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
     for (i = 0; i < count; i++) {
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index c76920a..924a173 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -26,14 +26,71 @@ glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
   *y = 0;
 }
 
+
+static void 
+_glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, 
+				 glamor_pixmap_private *pixmap_priv)
+{
+    GLfloat vertices[8];
+//    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glUseProgramObjectARB(glamor_priv->solid_prog);
+    glUniform4fvARB(glamor_priv->solid_color_uniform_location, 
+      1, pixmap_priv->pending_op.fill.color4fv);
+    vertices[0] = -1;
+    vertices[1] = -1;
+    vertices[2] = 1;
+    vertices[3] = -1;
+    vertices[4] = 1;
+    vertices[5] = 1;
+    vertices[6] = -1;
+    vertices[7] = 1;
+    glDrawArrays(GL_QUADS, 0, 4);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glUseProgramObjectARB(0);
+    pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
+}
+
+
+glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
+  NULL,
+  _glamor_pixmap_validate_filling
+};
+
+void
+glamor_pixmap_init(ScreenPtr screen)
+{
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
+}
+
+void
+glamor_validate_pixmap(PixmapPtr pixmap)
+{
+  glamor_pixmap_validate_function_t validate_op;
+  glamor_screen_private *glamor_priv =
+    glamor_get_screen_private(pixmap->drawable.pScreen);
+  glamor_pixmap_private *pixmap_priv = 
+    glamor_get_pixmap_private(pixmap);
+
+  validate_op = glamor_priv->pixmap_validate_funcs[pixmap_priv->pending_op.type];
+  if (validate_op) { 
+    (*validate_op)(glamor_priv, pixmap_priv);
+  }
+}
+
 void
 glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
 {
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+  glMatrixMode(GL_PROJECTION);                                                                                                                                                                  glLoadIdentity();
+  glMatrixMode(GL_MODELVIEW);                                                                                                                                                                   glLoadIdentity();                                        
 
   glViewport(0, 0,
 	     pixmap_priv->container->drawable.width,
 	     pixmap_priv->container->drawable.height);
+
 }
 
 int
@@ -49,9 +106,11 @@ glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
 int
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
+  int err;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-  return glamor_set_destination_pixmap_priv(pixmap_priv);
+  err = glamor_set_destination_pixmap_priv(pixmap_priv);
+  return err;
 }
 
 Bool
@@ -376,7 +435,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
     return TRUE;
-
+  /* XXX we may don't need to validate it on GPU here,
+   * we can just validate it on CPU. */
   if (glamor_get_tex_format_type_from_pixmap(pixmap, 
 					     &format,
 					     &type, 
@@ -395,7 +455,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		      pixmap->drawable.depth);
  
   stride = pixmap->devKind;
- 
+  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+  glamor_validate_pixmap(pixmap); 
   switch (access) {
   case GLAMOR_ACCESS_RO:
     gl_access = GL_READ_ONLY_ARB;
@@ -415,7 +476,6 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   }
  
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
   glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 4b00373..b7fcfbd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -149,6 +149,10 @@ enum shader_in {
   SHADER_IN_COUNT,
 };
 
+struct glamor_screen_private;
+struct glamor_pixmap_private;
+typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, 
+					          struct glamor_pixmap_private*);
 #define GLAMOR_CREATE_PIXMAP_CPU  0x100
 typedef struct glamor_screen_private {
   CloseScreenProcPtr saved_close_screen;
@@ -197,7 +201,7 @@ typedef struct glamor_screen_private {
   [SHADER_IN_COUNT];
   Bool has_source_coords, has_mask_coords;
   int render_nr_verts;
-
+  glamor_pixmap_validate_function_t *pixmap_validate_funcs;
   glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
   char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
   int  delayed_fallback_pending;
@@ -220,9 +224,34 @@ typedef enum glamor_access {
  * @pbo:     attached pbo.
  * @access_mode: access mode during the prepare/finish pair.
  * @pict_format: the corresponding picture's format.
+ * #pending_op: currently only support pending filling.
  * @container: The corresponding pixmap's pointer.
  **/
 
+#define GLAMOR_PIXMAP_PRIV_NEED_VALIDATE(pixmap_priv)  \
+	(GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) \
+	&& (pixmap_priv->pending_op.type != GLAMOR_PENDING_NONE))
+
+#define GLAMOR_PIXMAP_PRIV_NO_PENDING(pixmap_priv)   \
+	(pixmap_priv->pending_op.type == GLAMOR_PENDING_NONE)
+
+enum _glamor_pending_op_type{
+    GLAMOR_PENDING_NONE,
+    GLAMOR_PENDING_FILL
+};
+
+typedef struct _glamor_pending_fill {
+    unsigned int type;
+    GLfloat color4fv[4];
+    CARD32  colori;
+} glamor_pending_fill;
+
+typedef union _glamor_pending_op {
+    unsigned int type;
+    glamor_pending_fill fill;
+} glamor_pending_op;
+
+
 typedef struct glamor_pixmap_private {
   unsigned char gl_fbo:1;
   unsigned char gl_tex:1;
@@ -233,9 +262,20 @@ typedef struct glamor_pixmap_private {
   GLuint pbo;                
   glamor_access_t access_mode;
   PictFormatShort pict_format;
+  glamor_pending_op pending_op;
   PixmapPtr container;
 } glamor_pixmap_private;
 
+#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \
+  { \
+      if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
+        glUseProgramObjectARB(_glamor_priv_->solid_prog); \
+        glUniform4fvARB(_glamor_priv_->solid_color_uniform_location, 1,  \
+                        _pixmap_priv_->pending_op.fill.color4fv); \
+      } \
+  } while(0)
+ 
+
 /* 
  * Pixmap dynamic status, used by dynamic upload feature.
  *
@@ -678,6 +718,8 @@ glamor_triangles (CARD8	    op,
 
 /* glamor_pixmap.c */
 
+void
+glamor_pixmap_init(ScreenPtr screen);
 /** 
  * Download a pixmap's texture to cpu memory. If success,
  * One copy of current pixmap's texture will be put into
@@ -724,7 +766,8 @@ glamor_upload_picture_to_texture(PicturePtr picture);
 void
 glamor_destroy_upload_pixmap(PixmapPtr pixmap);
 
-
+void
+glamor_validate_pixmap(PixmapPtr pixmap);
 
 int
 glamor_create_picture(PicturePtr picture);
@@ -753,6 +796,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
 
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
+#define GLAMOR_DELAYED_FILLING
 
 
 #include"glamor_utils.h" 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index e61425d..0a91050 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -296,6 +296,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     }
 
     /* XXX consider to reuse a function to do the following work. */
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+    glamor_validate_pixmap(pixmap);
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
@@ -303,7 +305,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 41ee46b..f0a6e88 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -395,16 +395,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
 }
 
 static void
-glamor_set_composite_solid(PicturePtr picture, GLint uniform_location)
+glamor_set_composite_solid(float *color, GLint uniform_location)
 {
-  CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */
-  float color[4]; /* rgba */
-
-  color[0] = ((c >> 16) & 0xff) / 255.0;
-  color[1] = ((c >> 8) & 0xff) / 255.0;
-  color[2] = ((c >> 0) & 0xff) / 255.0;
-  color[3] = ((c >> 24) & 0xff) / 255.0;
-
   glUniform4fvARB(uniform_location, 1, color);
 }
 
@@ -696,6 +688,7 @@ glamor_composite_with_shader(CARD8 op,
   enum glamor_pixmap_status mask_status = GLAMOR_NONE;
   PictFormatShort saved_source_format = 0; 
   float src_matrix[9], mask_matrix[9];
+  GLfloat source_solid_color[4], mask_solid_color[4];
 
   dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
@@ -707,6 +700,12 @@ glamor_composite_with_shader(CARD8 op,
   if (!source->pDrawable) {
     if (source->pSourcePict->type == SourcePictTypeSolidFill) {
       key.source = SHADER_SOURCE_SOLID;
+      glamor_get_rgba_from_pixel(source->pSourcePict->solidFill.color,
+				 &source_solid_color[0], 
+				 &source_solid_color[1], 
+				 &source_solid_color[2], 
+				 &source_solid_color[3], 
+				 PICT_a8r8g8b8);
     } else {
       glamor_fallback("gradient source\n");
       goto fail;
@@ -718,6 +717,12 @@ glamor_composite_with_shader(CARD8 op,
     if (!mask->pDrawable) {
       if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
 	key.mask = SHADER_MASK_SOLID;
+        glamor_get_rgba_from_pixel(mask->pSourcePict->solidFill.color,
+				 &mask_solid_color[0], 
+				 &mask_solid_color[1], 
+				 &mask_solid_color[2], 
+				 &mask_solid_color[3], 
+				 PICT_a8r8g8b8);
       } else {
 	glamor_fallback("gradient mask\n");
 	goto fail;
@@ -767,6 +772,10 @@ glamor_composite_with_shader(CARD8 op,
       glamor_fallback("no texture in source\n");
       goto fail;
 #endif
+    } 
+    else if (source_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
+      key.source = SHADER_SOURCE_SOLID;
+      memcpy(source_solid_color, source_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
     }
   }
   if (key.mask == SHADER_MASK_TEXTURE ||
@@ -785,6 +794,10 @@ glamor_composite_with_shader(CARD8 op,
       goto fail;
 #endif
     }
+    else if (mask_pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) {
+      key.mask = SHADER_MASK_SOLID;
+      memcpy(mask_solid_color, mask_pixmap_priv->pending_op.fill.color4fv, 4 * sizeof(float));
+    }
   }
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
   if (source_status == GLAMOR_UPLOAD_PENDING 
@@ -853,10 +866,11 @@ glamor_composite_with_shader(CARD8 op,
     }
   }
 #endif
+  glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+  glamor_validate_pixmap(dest_pixmap);
   if (!glamor_set_composite_op(screen, op, dest, mask)) {
     goto fail;
   }
-  glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 
   shader = glamor_lookup_composite_shader(screen, &key);
   if (shader->prog == 0) {
@@ -866,13 +880,13 @@ glamor_composite_with_shader(CARD8 op,
 
   glUseProgramObjectARB(shader->prog);
   if (key.source == SHADER_SOURCE_SOLID) {
-    glamor_set_composite_solid(source, shader->source_uniform_location);
+    glamor_set_composite_solid(source_solid_color, shader->source_uniform_location);
   } else {
     glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
   }
   if (key.mask != SHADER_MASK_NONE) {
     if (key.mask == SHADER_MASK_SOLID) {
-      glamor_set_composite_solid(mask, shader->mask_uniform_location);
+      glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location);
     } else {
       glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
     }
@@ -888,14 +902,14 @@ glamor_composite_with_shader(CARD8 op,
 
 
 
-  if (source_pixmap) {
+  if (glamor_priv->has_source_coords) {
     glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
 			       &source_x_off, &source_y_off);
     pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
     glamor_picture_get_matrixf(source, src_matrix);
   }
 
-  if (mask_pixmap) {
+  if (glamor_priv->has_mask_coords) {
     glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
 			       &mask_x_off, &mask_y_off);
     pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
@@ -944,14 +958,14 @@ glamor_composite_with_shader(CARD8 op,
     y_source += source_y_off;
     x_mask += mask_x_off;
     y_mask += mask_y_off;
-
+   
     box = REGION_RECTS(&region);
     for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
       int vx1 = box[i].x1 + dest_x_off;
       int vx2 = box[i].x2 + dest_x_off;
       int vy1 = box[i].y1 + dest_y_off;
       int vy2 = box[i].y2 + dest_y_off;
-      glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, 
+     glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, 
 				   glamor_priv->yInverted, vertices);
 
       if (key.source != SHADER_SOURCE_SOLID) {
@@ -1260,7 +1274,7 @@ glamor_create_mask_picture(ScreenPtr screen,
 
   pixmap = screen->CreatePixmap(screen, 0, 0,
 				pict_format->depth,
-				0);
+				GLAMOR_CREATE_PIXMAP_CPU);
   if (!pixmap)
     return 0;
   picture = CreatePicture(0, &pixmap->drawable, pict_format,
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 9bc7d15..14a2437 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -52,9 +52,10 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
                      drawable->depth);
       goto fail;
     }
-
     if (glamor_set_destination_pixmap(dest_pixmap))
 	goto fail;
+
+    glamor_validate_pixmap(dest_pixmap);
     if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 	goto fail;
     glamor_set_alu(gc->alu);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 5bfdd73..a78c301 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -107,7 +107,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
       glamor_fallback("dest has no fbo.\n");
       goto fail;
     }
-
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
       /* XXX dynamic uploading candidate. */
       glamor_fallback("Non-texture tile pixmap\n");
@@ -118,48 +117,59 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         glamor_fallback("unsupported planemask %lx\n", planemask);
 	goto fail;
     }
-
+    if (alu != GXcopy) {
+      glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
+      glamor_validate_pixmap(tile);
+    }
+ 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    glamor_validate_pixmap(pixmap);
     pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
-    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
     glamor_set_alu(alu);
-    glUseProgramObjectARB(glamor_priv->tile_prog);
-
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    glEnable(GL_TEXTURE_2D);
-
-    glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
-				 x1, y1,x2, y2,
-				 glamor_priv->yInverted,
-				 vertices);
 
-    glamor_set_normalize_tcoords(src_xscale, src_yscale,
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
+      pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+      glUseProgramObjectARB(glamor_priv->tile_prog);
+ 
+      glActiveTexture(GL_TEXTURE0);
+      glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+      glEnable(GL_TEXTURE_2D);
+      glamor_set_normalize_tcoords(src_xscale, src_yscale,
 				 tile_x1, tile_y1,
 				 tile_x2, tile_y2,
 				 glamor_priv->yInverted,
 				 source_texcoords);
+      glClientActiveTexture(GL_TEXTURE0);
+      glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
+      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+   } 
+   else {
+     GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv);
+   }
+ 
+    glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+				 x1, y1,x2, y2,
+				 glamor_priv->yInverted,
+				 vertices);
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
+    if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
     glClientActiveTexture(GL_TEXTURE0);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisable(GL_TEXTURE_2D);
+    }
     glDisableClientState(GL_VERTEX_ARRAY);
 
     glUseProgramObjectARB(0);
-    glDisable(GL_TEXTURE_2D);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return TRUE;
commit 1caf741a4a41ef46a43980ba0be897770fea13db
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jul 20 13:02:28 2011 +0800

    glamor: Fixed a bug when computing the bounds of boxes.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 2c65632..30432cf 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -134,11 +134,11 @@ glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
       if (x_min > boxes[i].x1)
         x_min = boxes[i].x1;
       if (y_min > boxes[i].y1)
-        x_min = boxes[i].y1;
+        y_min = boxes[i].y1;
 
       if (x_max < boxes[i].x2)
         x_max = boxes[i].x2;
-      if (y_max > boxes[i].y2)
+      if (y_max < boxes[i].y2)
         y_max = boxes[i].y2;
     }
   bound->x1 = x_min;
commit fe0a6a29300055f8288c9d1f470fd3e24f5bb3bb
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 7 16:54:18 2011 +0800

    glamor: Should return when done gl drawing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 253f203..9bc7d15 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -84,10 +84,11 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	}
 	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
     }
-fail:
-    glDisable(GL_SCISSOR_TEST);
     glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
+    glDisable(GL_SCISSOR_TEST);
+    return;
+fail:
 
     glamor_fallback("to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
commit 7fbdc60fd4eb94c02b0b89d05cfe0243c3562ec1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 7 15:32:39 2011 +0800

    glamor: comment out the message when creating a system memory pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 6bab8c1..2eec6f5 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -130,9 +130,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
                               NULL);
+#if 0
       if (usage != GLAMOR_CREATE_PIXMAP_CPU)
 	glamor_fallback("choose cpu memory for pixmap %p ,"
 			" %d x %d depth %d\n", pixmap, w, h, depth);
+#endif
    } else 
       pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
commit f961390db6fa0707895effb2e7672edda575f8ec
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 7 15:31:35 2011 +0800

    glamor: Don't need to pad the tile image if pixmap is ni texture.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 31734be..da8b90b 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -242,12 +242,10 @@ Bool
 glamor_prepare_access_gc(GCPtr gc)
 {
   if (gc->stipple) {
-    glamor_fallback("has stipple %p\n", gc->stipple);
     if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
       return FALSE;
   }
   if (gc->fillStyle == FillTiled) {
-    glamor_fallback("has tile pixmap %p\n", gc->tile.pixmap);
     if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
 				GLAMOR_ACCESS_RO)) {
       if (gc->stipple)
@@ -353,16 +351,20 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
   }
 #endif
   if (changes & GCTile) {
-    if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width *
-				       drawable->bitsPerPixel))
-      {
-	glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap);
-	if (glamor_prepare_access(&gc->tile.pixmap->drawable,
+    if (!gc->tileIsPixel) {
+      glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap);
+      if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+         && FbEvenTile(gc->tile.pixmap->drawable.width *
+	  			       drawable->bitsPerPixel))
+        {
+	  glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap);
+	  if (glamor_prepare_access(&gc->tile.pixmap->drawable,
 				  GLAMOR_ACCESS_RW)) {
 	  fbPadPixmap(gc->tile.pixmap);
 	  glamor_finish_access(&gc->tile.pixmap->drawable);
-	}
-      }
+	  }
+        }
+    }
     /* Mask out the GCTile change notification, now that we've done FB's
      * job for it.
      */
@@ -373,7 +375,6 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
     /* We can't inline stipple handling like we do for GCTile because
      * it sets fbgc privates.
      */
-    glamor_fallback("GC %p stipple changed %p.\n", gc, gc->stipple);
     if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
       fbValidateGC(gc, changes, drawable);
       glamor_finish_access(&gc->stipple->drawable);
commit 77ecd366933bbe726a4a7e57e35b1510b675df8d
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 7 15:30:19 2011 +0800

    glamor: We don't need to check format in compositing.
    
    We already handle all format checking in pixmap uploading and
    converting, don't need to do that again.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 30cc507..41ee46b 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -501,53 +501,6 @@ glamor_composite_with_copy(CARD8 op,
   return TRUE;
 }
 
-static Bool
-good_source_format(PicturePtr picture)
-{
-  switch (picture->format) {
-  case PICT_a1:
-  case PICT_a8:
-  case PICT_a8r8g8b8:
-  case PICT_x8r8g8b8:
-    return TRUE;
-  default:
-    return TRUE;
-    glamor_fallback("Bad source format 0x%08x\n", picture->format);
-    return FALSE;
-  }
-}
-
-static Bool
-good_mask_format(PicturePtr picture)
-{
-  switch (picture->format) {
-  case PICT_a1:
-  case PICT_a8:
-  case PICT_a8r8g8b8:
-  case PICT_x8r8g8b8:
-    return TRUE;
-  default:
-    return TRUE;
-    glamor_fallback("Bad mask format 0x%08x\n", picture->format);
-    return FALSE;
-  }
-}
-
-static Bool
-good_dest_format(PicturePtr picture)
-{
-  switch (picture->format) {
-  case PICT_a8:
-  case PICT_a8r8g8b8:
-  case PICT_x8r8g8b8:
-    return TRUE;
-  default:
-    return TRUE;
-    glamor_fallback("Bad dest format 0x%08x\n", picture->format);
-    return FALSE;
-  }
-}
-
 static void
 glamor_setup_composite_vbo(ScreenPtr screen)
 {
@@ -815,10 +768,6 @@ glamor_composite_with_shader(CARD8 op,
       goto fail;
 #endif
     }
-    if ((source_status != GLAMOR_UPLOAD_PENDING) 
-	&& !good_source_format(source)) {
-      goto fail;
-    }
   }
   if (key.mask == SHADER_MASK_TEXTURE ||
       key.mask == SHADER_MASK_TEXTURE_ALPHA) {
@@ -836,13 +785,6 @@ glamor_composite_with_shader(CARD8 op,
       goto fail;
 #endif
     }
-    if ((mask_status != GLAMOR_UPLOAD_PENDING) 
-	&& !good_mask_format(mask)) {
-      goto fail;
-    }
-  }
-  if (!good_dest_format(dest)) {
-    goto fail;
   }
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
   if (source_status == GLAMOR_UPLOAD_PENDING 
commit 477a54bc9ed8f252b3a42af8ac01ef1da7b5ab6b
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jul 7 14:47:51 2011 +0800

    glamor: Fixed two unintialized warnings.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 2408e3a..9e2be12 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -309,7 +309,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 void		*closure)
 {
     glamor_access_t dst_access;
-    PixmapPtr dst_pixmap, src_pixmap, temp_pixmap;
+    PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
     DrawablePtr temp_src = src;
     glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
     BoxRec bound;
@@ -361,6 +361,11 @@ glamor_copy_n_to_n(DrawablePtr src,
       temp_dy = -bound.y1;
       temp_src = &temp_pixmap->drawable;
     }
+    else {
+      temp_dx = dx;
+      temp_dy = dy;
+      temp_src = src;
+    }
 
     if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
         goto done;
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 3fdb264..d93b602 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -55,7 +55,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     int y_max = MINSHORT;
     DrawablePtr temp_dest;
     PixmapPtr temp_pixmap;
-    GCPtr temp_gc;
+    GCPtr temp_gc = NULL;
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0) {
 	/* This ends up in miSetSpans, which is accelerated as well as we
commit d49d48257917a4a900c84dae111d3f5e761a8d89
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sat Jul 2 14:47:38 2011 +0800

    glamor: Fix multiple crtc setup.
    
    Now, support dual crtc configuration.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 1f0396d..cf49402 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -1352,10 +1352,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 
 		if (!crtc->enabled)
 			continue;
-#if 0
 		drmmode_set_mode_major(crtc, &crtc->mode,
 				       crtc->rotation, crtc->x, crtc->y);
-#endif
 	}
 
 	return TRUE;
commit fc23334e54b0b90d2f00b017a03cf47b70dc71aa
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Fri Jul 1 23:51:42 2011 +0800

    glamor: Optimize fallback case for the polylines.
    
    When fallback to cpu for the polylines procedure, we can just download
    required region to CPU rather than to download the whole pixmap. This
    significant improve the performance if we have to fallback, for example
     do non-solid filling in the game Mines.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 9149611..3fdb264 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -49,6 +49,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     xRectangle *rects;
     int x1, x2, y1, y2;
     int i;
+    int x_min = MAXSHORT;
+    int x_max = MINSHORT;
+    int y_min = MAXSHORT;
+    int y_max = MINSHORT;
+    DrawablePtr temp_dest;
+    PixmapPtr temp_pixmap;
+    GCPtr temp_gc;
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0) {
 	/* This ends up in miSetSpans, which is accelerated as well as we
@@ -103,16 +110,70 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     return;
 
 fail:
+   for(i = 0; i < n; i++)
+      {
+        if (x_min > points[i].x)
+          x_min = points[i].x;
+        if (x_max < points[i].x)
+          x_max = points[i].x;
+
+        if (y_min > points[i].y)
+          y_min = points[i].y;
+        if (y_max < points[i].y)
+          y_max = points[i].y;
+      }
+
+    temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
+                                                  x_max - x_min + 1, y_max - y_min + 1,
+                                                  drawable->depth,
+                                                  0);
+    if (temp_pixmap) {
+      temp_dest = &temp_pixmap->drawable;
+      temp_gc = GetScratchGC(temp_dest->depth, temp_dest->pScreen);
+      ValidateGC(temp_dest, temp_gc);
+      for(i = 0; i < n; i++)
+        {
+           points[i].x -= x_min;
+           points[i].y -= y_min;
+        }
+      (void)glamor_copy_area(drawable,
+			     temp_dest,
+		             temp_gc,
+			     x_min, y_min,
+			     x_max - x_min + 1, y_max - y_min + 1,
+			     0, 0);
+    
+    } 
+    else 
+      temp_dest = drawable;
+
     if (gc->lineWidth == 0) {
-	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
 	    if (glamor_prepare_access_gc(gc)) {
-		fbPolyLine(drawable, gc, mode, n, points);
+		fbPolyLine(temp_dest, gc, mode, n, points);
 		glamor_finish_access_gc(gc);
 	    }
-	    glamor_finish_access(drawable);
+	    glamor_finish_access(temp_dest);
 	}
-	return;
-    }
+    } 
+    else {
     /* fb calls mi functions in the lineWidth != 0 case. */
-    fbPolyLine(drawable, gc, mode, n, points);
+      fbPolyLine(drawable, gc, mode, n, points);
+    }
+    if (temp_dest != drawable) {
+      (void)glamor_copy_area(temp_dest,
+			     drawable,
+		             temp_gc,
+			     0, 0,
+			     x_max - x_min + 1, y_max - y_min + 1,
+			     x_min, y_min);
+      drawable->pScreen->DestroyPixmap(temp_pixmap);
+      for(i = 0; i < n; i++)
+        {
+           points[i].x += x_min;
+           points[i].y += y_min;
+        }
+ 
+      FreeScratchGC(temp_gc);
+    }
 }
commit da66a76f276eccee90855bc0cb28092c3755ed7b
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Fri Jul 1 23:48:21 2011 +0800

    Revert "glamor: Don't need to read dest if op is SRC or CLEAR."
    
    This reverts commit eb16fe0b7c8ea27b5cf9122d02e48bf585495228.
    As currently glamor_prepare_access/finish_access will touch
    the whole pixmap, not just the request region, then write only
    mode will not work correctly. We may need to revisit all fallback
    case, and convert the image to the right size before do the
    prepare/finish processing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 72e0f83..30cc507 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1144,7 +1144,6 @@ glamor_composite(CARD8 op,
   PicturePtr temp_src = source, temp_mask = mask;
   int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
   glamor_composite_rect_t rect;
-  glamor_access_t dest_access;
 
   x_temp_src = x_source;
   y_temp_src = y_source;
@@ -1266,12 +1265,7 @@ fail:
 
   glUseProgramObjectARB(0);
   glDisable(GL_BLEND);
-
-  if (op == PictOpSrc || op == PictOpClear)
-    dest_access = GLAMOR_ACCESS_WO;
-  else
-    dest_access = GLAMOR_ACCESS_RW;
-  if (glamor_prepare_access_picture(dest, dest_access)) {
+  if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
     if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
       {
 	if (!mask ||
commit cb3b34ec53e00c6ca212891b314f473ee2f80a40
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Fri Jul 1 22:54:45 2011 +0800

    glamor-ddx: Add missed drmmode_crtc_destroy function.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index aba9b2c..1f0396d 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -613,6 +613,20 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc,
 	drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 			    size, red, green, blue);
 }
+static void
+drmmode_crtc_destroy(xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	ScrnInfoPtr scrn = crtc->scrn;
+        if (drmmode_crtc->cursor) {
+          drmmode_hide_cursor(crtc);
+          glDeleteTextures(1, &drmmode_crtc->cursor_tex);
+	  glamor_destroy_cursor(scrn, drmmode_crtc->cursor);
+        }
+        free(drmmode_crtc->cursor);
+        crtc->driver_private = NULL;
+}
 
 static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 	.dpms = drmmode_crtc_dpms,
@@ -629,7 +643,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 	.shadow_destroy = drmmode_crtc_shadow_destroy,
 #endif
 	.gamma_set = drmmode_crtc_gamma_set,
-	.destroy = NULL, /* XXX */
+	.destroy = drmmode_crtc_destroy
 };
 
 
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 6f8de11..0e164d3 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -9,6 +9,7 @@ Bool glamor_load_cursor(ScrnInfoPtr scrn,
 
 void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch);
 EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height);
+void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor);
 
 Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
 void drmmode_closefb(ScrnInfoPtr scrn);
commit c68fb6ed723d7268a3c4950b40c20ddf9b4b9ca5
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Fri Jul 1 22:36:31 2011 +0800

    glamor-ddx: Reinit crtc if we need to reopen the card.
    
    As the eglTerminate will close the card when close screen, we may
    need to reopen it at next time create a screen resource. and thus
    we need to re initialize the drmmode crtc also. Otherwise , the
    cursor handling will be broken as it has the wrong fd.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index d0432b3..1da7eb2 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -145,6 +145,12 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 	return	eglCreateDRMImageMESA(glamor->display, attribs); 
 }
 
+void glamor_destroy_cursor(ScrnInfoPtr scrn, EGLImageKHR cursor)
+{
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+        eglDestroyImageKHR(glamor->display, cursor);
+}
+
 void
 glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch)
 {
@@ -191,7 +197,7 @@ glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags)
 	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Kernel modesetting setup failed\n");
-	  goto fail;
+         goto fail;
 	}
 
 	scrn->currentMode = scrn->modes;
@@ -272,6 +278,8 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
 
 	glamor_fini(screen);
 
+        eglDestroyImageKHR(glamor->display, glamor->root);
+
 	eglMakeCurrent(glamor->display,
 		       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 	eglTerminate(glamor->display);
@@ -279,6 +287,7 @@ glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
 	drmmode_closefb(scrn);
 	
 	glamor->fd = -1;
+
 	glamor->root = EGL_NO_IMAGE_KHR;
 
 	return TRUE;
@@ -301,8 +310,16 @@ glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	    ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
 	    return FALSE;
 	  }
+	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Kernel modesetting setup failed\n");
+            return FALSE;
 	}
 
+	}
+
+
+
 	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
 	eglBindAPI(EGL_OPENGL_API);
         LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB));
commit ca614860fa2a56d469064b5e05070d8201597728
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jul 1 17:02:10 2011 +0800

    glamor: convert if too large source or mask .
    
    Some strange web page has 20000*1 png picture, and actually only use
    partial of it. We force to convert it to a actuall size rather than
    its original size,if it is the case. Then to avoid latter's failure
    uploading.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 9599d97..72e0f83 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1170,8 +1170,10 @@ glamor_composite(CARD8 op,
   if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill))
       || (source->pDrawable 
 	  && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) 
-	  && (width * height * 4 
-	      < (source_pixmap->drawable.width * source_pixmap->drawable.height)))){
+	  && ((width * height * 4 
+	       < (source_pixmap->drawable.width * source_pixmap->drawable.height))
+	      || !(glamor_check_fbo_width_height(source_pixmap->drawable.width,
+						 source_pixmap->drawable.height))))) {
     temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height);
     if (!temp_src) {
       temp_src = source;
@@ -1184,8 +1186,10 @@ glamor_composite(CARD8 op,
       && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill))
 	  || (mask->pDrawable 
 	      && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
-	      && (width * height * 4 
-		  < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))))) {
+	      && ((width * height * 4 
+		   < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))
+		  || !(glamor_check_fbo_width_height(mask_pixmap->drawable.width,
+						     mask_pixmap->drawable.height)))))) {
     /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
      * to do reduce one convertion. */
     temp_mask = glamor_convert_gradient_picture(screen, mask, x_mask, y_mask, width, height);
commit 1444fed4a8030ec59f4448b490f2f77db86f0b86
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:53:24 2011 +0800

    glamor: silence compilation warnings.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 1c4c1b3..9599d97 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1137,9 +1137,10 @@ glamor_composite(CARD8 op,
 		 CARD16 height)
 {
   ScreenPtr screen = dest->pDrawable->pScreen;
-  glamor_pixmap_private *dest_pixmap_priv, *source_pixmap_priv, *mask_pixmap_priv;
+  glamor_pixmap_private *dest_pixmap_priv;
+  glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
   PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-  PixmapPtr source_pixmap, mask_pixmap;
+  PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
   PicturePtr temp_src = source, temp_mask = mask;
   int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
   glamor_composite_rect_t rect;
commit 734b10e9f7e729fc300ed432bd3c81e1ea7483f3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:50:23 2011 +0800

    glamor: Fix one typo bug in glamor_tile.
    
    It will return when the destination pixmap has a fbo but will continue
    when it doesn't have a fbo.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index c62392c..5bfdd73 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -103,7 +103,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	goto fail;
     }
 
-    if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {      
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {      
       glamor_fallback("dest has no fbo.\n");
       goto fail;
     }
commit 2eb40a37920132d53e3b48830704f92d4c695f4c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:49:40 2011 +0800

    glamor: Remove one extra area copy in glamor_glyph.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 26e0847..63ffd20 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -375,6 +375,7 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
     ValidateGC(&cache_pixmap->drawable, gc);
 
     /* Create a temporary bo to stream the updates to the cache */
+#if 0
     scratch = screen->CreatePixmap(screen,
 				   glyph->info.width,
 				   glyph->info.height,
@@ -390,7 +391,8 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
     } else {
 	scratch = glyph_pixmap;
     }
-
+#endif
+    scratch = glyph_pixmap;
     (void)glamor_copy_area(&scratch->drawable,
 			   &cache_pixmap->drawable,
 			   gc,
commit 61e1ad39724e5baaed4f30ff3c86782e701f19fb
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:40:32 2011 +0800

    glamor: Reduce source or mask picture size if possible.
    
    If we only need a short part of the source or mask's drawable
    pixmap, we can convert it to a new small picture before
    call to the low level compositing function. Then it will only
    upload the smaller picture latter.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e7a886c..1c4c1b3 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1075,6 +1075,53 @@ glamor_composite_with_shader(CARD8 op,
   return FALSE;
 }
 
+static PicturePtr
+glamor_convert_gradient_picture(ScreenPtr screen,
+                                PicturePtr source,
+                                int x_source,
+                                int y_source,
+                                int width,
+                                int height)
+{
+  PixmapPtr pixmap;
+  PicturePtr dst;
+  int error;
+  PictFormatShort format;
+
+  if (!source->pDrawable)
+    format = PICT_a8r8g8b8;
+  else
+    format = source->format;
+
+  pixmap = screen->CreatePixmap(screen, 
+                                width, 
+                                height, 
+                                PIXMAN_FORMAT_DEPTH(format),
+                                GLAMOR_CREATE_PIXMAP_CPU);
+
+  if (!pixmap)
+    return NULL;
+  
+  dst = CreatePicture(0, 
+                      &pixmap->drawable,
+                      PictureMatchFormat(screen,
+                                         PIXMAN_FORMAT_DEPTH(format),
+                                         format),
+                      0, 
+                      0, 
+                      serverClient, 
+                      &error);
+  screen->DestroyPixmap(pixmap);
+  if (!dst)
+     return NULL;
+
+  ValidatePicture(dst);
+
+  fbComposite(PictOpSrc, source, NULL, dst, x_source, y_source,
+              0, 0, 0, 0, width, height);
+  return dst;
+}
+
 void
 glamor_composite(CARD8 op,
 		 PicturePtr source,
@@ -1089,27 +1136,84 @@ glamor_composite(CARD8 op,
 		 CARD16 width,
 		 CARD16 height)
 {
+  ScreenPtr screen = dest->pDrawable->pScreen;
+  glamor_pixmap_private *dest_pixmap_priv, *source_pixmap_priv, *mask_pixmap_priv;
+  PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+  PixmapPtr source_pixmap, mask_pixmap;
+  PicturePtr temp_src = source, temp_mask = mask;
+  int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
   glamor_composite_rect_t rect;
   glamor_access_t dest_access;
 
+  x_temp_src = x_source;
+  y_temp_src = y_source;
+  x_temp_mask = x_mask;
+  y_temp_mask = y_mask;
+
+  dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+  /* Currently. Always fallback to cpu if destination is in CPU memory. */
+  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+    goto fail;
+  }
+
+  if (source->pDrawable) {
+    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+  }
+
+  if (mask && mask->pDrawable) {
+    mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+    mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+  }
+
+  if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill))
+      || (source->pDrawable 
+	  && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) 
+	  && (width * height * 4 
+	      < (source_pixmap->drawable.width * source_pixmap->drawable.height)))){
+    temp_src = glamor_convert_gradient_picture(screen, source, x_source, y_source, width, height);
+    if (!temp_src) {
+      temp_src = source;
+      goto fail; 
+    }
+    x_temp_src = y_temp_src = 0;
+  }
+
+  if (mask 
+      && ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill))
+	  || (mask->pDrawable 
+	      && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
+	      && (width * height * 4 
+		  < (mask_pixmap->drawable.width * mask_pixmap->drawable.height))))) {
+    /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
+     * to do reduce one convertion. */
+    temp_mask = glamor_convert_gradient_picture(screen, mask, x_mask, y_mask, width, height);
+    if (!temp_mask) {
+      temp_mask = mask;
+      goto fail; 
+    }
+    x_temp_mask = y_temp_mask = 0;
+  }
   /* Do two-pass PictOpOver componentAlpha, until we enable
    * dual source color blending.
    */
+
   if (mask && mask->componentAlpha) {
     if (op == PictOpOver) {
       glamor_composite(PictOpOutReverse,
-		       source, mask, dest,
-		       x_source, y_source,
-		       x_mask, y_mask,
+		       temp_src, temp_mask, dest,
+		       x_temp_src, y_temp_src,
+		       x_temp_mask, y_temp_mask,
 		       x_dest, y_dest,
 		       width, height);
       glamor_composite(PictOpAdd,
-		       source, mask, dest,
-		       x_source, y_source,
-		       x_mask, y_mask,
+		       temp_src, temp_mask, dest,
+		       x_temp_src, y_temp_src,
+		       x_temp_mask, y_temp_mask,
 		       x_dest, y_dest,
 		       width, height);
-      return;
+      goto done;
+
     } else if (op != PictOpAdd && op != PictOpOutReverse) {
       glamor_fallback("glamor_composite(): component alpha\n");
       goto fail;
@@ -1117,25 +1221,25 @@ glamor_composite(CARD8 op,
   }
 
   if (!mask) {
-    if (glamor_composite_with_copy(op, source, dest,
-				   x_source, y_source,
+    if (glamor_composite_with_copy(op, temp_src, dest,
+				   x_temp_src, y_temp_src,
 				   x_dest, y_dest,
 				   width, height))
-      return;
+      goto done;
   }
 
-  rect.x_src = x_source;
-  rect.y_src = y_source;
-  rect.x_mask = x_mask;
-  rect.y_mask = y_mask;
+  rect.x_src = x_temp_src;
+  rect.y_src = y_temp_src;
+  rect.x_mask = x_temp_mask;
+  rect.y_mask = y_temp_mask;
   rect.x_dst = x_dest;
   rect.y_dst = y_dest;
   rect.width = width;
   rect.height = height;
-  if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect))
-    return;
+  if (glamor_composite_with_shader(op, temp_src, temp_mask, dest, 1, &rect))
+    goto done;
 
- fail:
+fail:
 
   glamor_fallback(
 		  "from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
@@ -1157,6 +1261,7 @@ glamor_composite(CARD8 op,
 
   glUseProgramObjectARB(0);
   glDisable(GL_BLEND);
+
   if (op == PictOpSrc || op == PictOpClear)
     dest_access = GLAMOR_ACCESS_WO;
   else
@@ -1180,6 +1285,11 @@ glamor_composite(CARD8 op,
       }
     glamor_finish_access_picture(dest);
   }
+done:
+    if (temp_src != source)
+      FreePicture(temp_src, 0);
+    if (temp_mask != mask)
+      FreePicture(temp_mask, 0);
 }
 
 
commit 14503fbb819d07fa2b58d9bb741b55f93aff2cf6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:38:43 2011 +0800

    glamor: Fix the coords calculation in glamor_fill.
    
    glamor_fill is only called from internal functions
    glamor_fillspancs and glamor_polyfillrect. And both functions
    already add the offset to the coords, so the coords are already
    relative value, we can't add the offset once again.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 48f85ce..a41837b 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -41,14 +41,12 @@ glamor_fill(DrawablePtr drawable,
 	    int height)
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
-    int x_off, y_off;
-    glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off);
 
     switch (gc->fillStyle) {
     case FillSolid:
 	if (!glamor_solid(dst_pixmap,
-                         x + x_off,
-                         y + y_off,
+                         x,
+                         y,
 		         width,
 		         height,
 		         gc->alu,
@@ -60,24 +58,24 @@ glamor_fill(DrawablePtr drawable,
     case FillOpaqueStippled:
 	if (!glamor_stipple(dst_pixmap,
 		       gc->stipple,
-		       x+ x_off,
-		       y + y_off,
+		       x,
+		       y,
 		       width,
 		       height,
 		       gc->alu,
 		       gc->planemask,
 		       gc->fgPixel,
 		       gc->bgPixel,
-		       gc->patOrg.x + x_off,
-		       gc->patOrg.y + y_off))
+		       gc->patOrg.x,
+		       gc->patOrg.y))
 	goto fail;
         return;
 	break;
     case FillTiled:
 	if (!glamor_tile(dst_pixmap,
 		    gc->tile.pixmap,
-		    x + x_off,
-		    y + y_off,
+		    x,
+		    y,
 		    width,
 		    height,
 		    gc->alu,
commit 1dca5d7b91ed6fced34f389453678407bc223e9c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:04:59 2011 +0800

    glamor: Reduce source pixmap's size.
    
    If the dest pixmap is in texture memory, but source pixmap is not.
    Then we need to upload the source pixmap to texture memory. Previous
    version will upload the whole source pixmap. This commit preprocess
    the source pixmap, and reduce it to a smaller tempory pixmap only
    contains the required region.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index cebce21..2408e3a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -308,6 +308,23 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 Pixel		bitplane,
 		 void		*closure)
 {
+    glamor_access_t dst_access;
+    PixmapPtr dst_pixmap, src_pixmap, temp_pixmap;
+    DrawablePtr temp_src = src;
+    glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
+    BoxRec bound;
+    ScreenPtr screen;
+    int temp_dx = dx;
+    int temp_dy = dy;
+    dst_pixmap = glamor_get_drawable_pixmap(dst);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+    screen = dst_pixmap->drawable.pScreen;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+      glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap);
+      goto fail;
+    }
+
     if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
         goto done;
 	return;
@@ -318,17 +335,50 @@ glamor_copy_n_to_n(DrawablePtr src,
 	return;
      }
 
-    if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) {
-        goto done;
-	return;
+    src_pixmap = glamor_get_drawable_pixmap(src);
+    src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
+
+    glamor_calculate_boxes_bound(&bound, box, nbox);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) 
+	&& ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
+	    * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height)) {
+
+      temp_pixmap = (*screen->CreatePixmap)(screen,
+					 bound.x2 - bound.x1,
+					 bound.y2 - bound.y1,
+					 src_pixmap->drawable.depth,
+					 GLAMOR_CREATE_PIXMAP_CPU);
+      if (!temp_src)
+	goto fail;
+      glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
+      fbCopyNtoN(src, temp_src, gc, box, nbox,
+		 temp_dx + bound.x1, temp_dy + bound.y1, 
+		 reverse, upsidedown, bitplane,
+		 closure);
+      glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
+      temp_dx = -bound.x1;
+      temp_dy = -bound.y1;
+      temp_src = &temp_pixmap->drawable;
     }
 
+    if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
+        goto done;
+    }
+    
+ fail:
     glamor_report_delayed_fallbacks(src->pScreen);
     glamor_report_delayed_fallbacks(dst->pScreen);
 
     glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
 		    glamor_get_drawable_location(dst));
+
+    if (gc && gc->alu != GXcopy)
+      dst_access = GLAMOR_ACCESS_RW;
+    else
+      dst_access = GLAMOR_ACCESS_WO;
+
     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
 	if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
 	    fbCopyNtoN(src, dst, gc, box, nbox,
@@ -339,11 +389,13 @@ glamor_copy_n_to_n(DrawablePtr src,
 	}
 	glamor_finish_access(dst);
     }
-    return;
 
 done:
     glamor_clear_delayed_fallbacks(src->pScreen);
     glamor_clear_delayed_fallbacks(dst->pScreen);
+    if (temp_src != src) {
+      (*screen->DestroyPixmap)(temp_pixmap);
+    }
 }
 
 RegionPtr
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b8b437e..2c65632 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -121,4 +121,42 @@
   } while(0)
 
 
+inline static void
+glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
+{
+  int x_min, y_min;
+  int x_max, y_max;
+  int i;
+  x_min = y_min = MAXSHORT;
+  x_max = y_max = MINSHORT;
+  for(i = 0; i < nbox; i++)
+    {
+      if (x_min > boxes[i].x1)
+        x_min = boxes[i].x1;
+      if (y_min > boxes[i].y1)
+        x_min = boxes[i].y1;
+
+      if (x_max < boxes[i].x2)
+        x_max = boxes[i].x2;
+      if (y_max > boxes[i].y2)
+        y_max = boxes[i].y2;
+    }
+  bound->x1 = x_min;
+  bound->y1 = y_min;
+  bound->x2 = x_max;
+  bound->y2 = y_max;
+}
+
+inline static void 
+glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
+{
+  int i;
+  for (i = 0; i < nbox; i++)
+    {
+      boxes[i].x1 += dx;
+      boxes[i].y1 += dy;
+      boxes[i].x2 += dx;
+      boxes[i].y2 += dy;
+    }
+}
 #endif
commit 33c6c78ae9c7e72a94cc27536f3b5f50cdcc9241
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu Jun 30 16:01:57 2011 +0800

    glamor: Add one option to force create a cpu memory pixmap.
    
    Some special case we want to get a cpu memory pixmap. For example
    to gather a large cpu memory pixmap's block to a small pixmap.
    
    Add pixmap's priviate data's deallocation when destroy a pixmap.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b78feb4..6bab8c1 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -116,11 +116,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     GLuint tex;
     int type = GLAMOR_PIXMAP_TEXTURE;
     glamor_pixmap_private *pixmap_priv;
-
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    if (!glamor_check_fbo_width_height(w,h) || !glamor_check_fbo_depth(depth)) {
+    if (!glamor_check_fbo_width_height(w,h) 
+	|| !glamor_check_fbo_depth(depth) 
+	|| usage == GLAMOR_CREATE_PIXMAP_CPU) {
 	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
  	   If we exceed such limitation, we have to use framebuffer.*/
       type = GLAMOR_PIXMAP_MEMORY;
@@ -129,9 +130,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
                               NULL);
-
-      glamor_fallback("choose cpu memory for pixmap %p ,"
-	              " %d x %d depth %d\n", pixmap, w, h, depth);
+      if (usage != GLAMOR_CREATE_PIXMAP_CPU)
+	glamor_fallback("choose cpu memory for pixmap %p ,"
+			" %d x %d depth %d\n", pixmap, w, h, depth);
    } else 
       pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
@@ -217,6 +218,7 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
 	  glDeleteTextures(1, &pixmap_priv->tex);
         if (pixmap_priv->pbo)
           glDeleteBuffersARB(1, &pixmap_priv->pbo);
+        dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
     }
 
     return fbDestroyPixmap(pixmap);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 5b457e7..4b00373 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -50,9 +50,9 @@
 
 #include "glamor_debug.h"
 
-#define glamor_check_fbo_width_height(_w_, _h_)    (_w_ > 0 && _h_ > 0	\
-                                                    && _w_ < MAX_WIDTH	\
-                                                    && _h_ < MAX_HEIGHT)
+#define glamor_check_fbo_width_height(_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
+                                                    && (_w_) < MAX_WIDTH   \
+                                                    && (_h_) < MAX_HEIGHT)
 
 #define glamor_check_fbo_depth(_depth_) (			\
                                          _depth_ == 8		\
@@ -149,6 +149,7 @@ enum shader_in {
   SHADER_IN_COUNT,
 };
 
+#define GLAMOR_CREATE_PIXMAP_CPU  0x100
 typedef struct glamor_screen_private {
   CloseScreenProcPtr saved_close_screen;
   CreateGCProcPtr saved_create_gc;
commit 8890b38857128181cf506356046bf4a5bce53ab0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 28 17:17:23 2011 +0800

    glamor: Don't map the vbo to system memory.
    
    Access mapped vbo address is too slow. And by use system memory
    directly, rgb10text/aa10text increases from 980K/1160K to 117K/140K.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 5430422..b78feb4 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -399,6 +399,8 @@ glamor_close_screen(int idx, ScreenPtr screen)
         ps->CreatePicture = glamor_priv->saved_create_picture;
     }
 #endif
+    if (glamor_priv->vb)
+      free(glamor_priv->vb);
     free(glamor_priv);
     return screen->CloseScreen(idx, screen);   
     
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 27fff23..e7a886c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -285,10 +285,25 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
 
   return shader;
 }
+#define GLAMOR_COMPOSITE_VBO_SIZE 8192
+
+static void
+glamor_reset_composite_vbo(ScreenPtr screen)
+{
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_priv->vbo_offset = 0;
+  glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_SIZE;
+  glamor_priv->render_nr_verts = 0;
+}
+
 
 void
 glamor_init_composite_shaders(ScreenPtr screen)
 {
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_priv->vb = malloc(GLAMOR_COMPOSITE_VBO_SIZE);
+  assert(glamor_priv->vb != NULL);
+  glamor_reset_composite_vbo(screen);
 }
 
 static Bool
@@ -599,13 +614,11 @@ glamor_flush_composite_rects(ScreenPtr screen)
 
   if (!glamor_priv->render_nr_verts)
     return;
-
-  glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
-  glamor_priv->vb = NULL;
+  glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_offset, glamor_priv->vb,
+	    GL_STREAM_DRAW_ARB);
 
   glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
-  glamor_priv->render_nr_verts = 0;
-  glamor_priv->vbo_size = 0;
+  glamor_reset_composite_vbo(screen);
 }
 
 static void
@@ -622,16 +635,10 @@ glamor_emit_composite_rect(ScreenPtr screen,
       glamor_flush_composite_rects(screen);
     }
 
-  if (glamor_priv->vbo_size == 0) {
+  if (glamor_priv->vbo_offset == 0) {
     if (glamor_priv->vbo == 0)
       glGenBuffersARB(1, &glamor_priv->vbo);
-    glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
 
-    glamor_priv->vbo_size = 4096;
-    glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL,
-		    GL_STREAM_DRAW_ARB);
-    glamor_priv->vbo_offset = 0;
-    glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
     glamor_setup_composite_vbo(screen);
   }
 
commit c303949aabacb6a105ca0e0c521ca293dbda7d43
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 28 14:49:38 2011 +0800

    glamor: Reduce one extra copy in glamor_trapezoids.
    
    This reduce the time when running cairo-performance-trace with
    the firefox-planet-gnome.trace from 23.5 seconds to 21.5 seconds.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 59a74df..27fff23 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -748,7 +748,6 @@ glamor_composite_with_shader(CARD8 op,
     if (source->pSourcePict->type == SourcePictTypeSolidFill) {
       key.source = SHADER_SOURCE_SOLID;
     } else {
-      //key.source = SHADER_SOURCE_SOLID;
       glamor_fallback("gradient source\n");
       goto fail;
     }
@@ -1201,7 +1200,7 @@ glamor_create_mask_picture(ScreenPtr screen,
       return 0;
   }
 
-  pixmap = screen->CreatePixmap(screen, width, height,
+  pixmap = screen->CreatePixmap(screen, 0, 0,
 				pict_format->depth,
 				0);
   if (!pixmap)
@@ -1229,7 +1228,6 @@ glamor_trapezoids(CARD8 op,
   INT16 x_rel, y_rel;
   int width, height, stride;
   PixmapPtr pixmap;
-  GCPtr gc;
   pixman_image_t *image;
 
   /* If a mask format wasn't provided, we get to choose, but behavior should
@@ -1256,8 +1254,7 @@ glamor_trapezoids(CARD8 op,
 
   width = bounds.x2 - bounds.x1;
   height = bounds.y2 - bounds.y1;
-  stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8;
-
+  stride = PixmapBytePad(width, mask_format->depth);
   picture = glamor_create_mask_picture(screen, dst, mask_format,
 				       width, height);
   if (!picture)
@@ -1275,32 +1272,13 @@ glamor_trapezoids(CARD8 op,
     pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps,
 			       -bounds.x1, -bounds.y1);
 
-  pixmap = GetScratchPixmapHeader(screen, width, height,
-				  mask_format->depth,
-				  BitsPerPixel(mask_format->depth),
-				  PixmapBytePad(width, mask_format->depth),
-				  pixman_image_get_data(image));
-  if (!pixmap) {
-    FreePicture(picture, 0);
-    pixman_image_unref(image);
-    return;
-  }
-
-  gc = GetScratchGC(picture->pDrawable->depth, screen);
-  if (!gc) {
-    FreeScratchPixmapHeader(pixmap);
-    pixman_image_unref (image);
-    FreePicture(picture, 0);
-    return;
-  }
-  ValidateGC(picture->pDrawable, gc);
-
-  gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable,
-		    gc, 0, 0, width, height, 0, 0);
-
-  FreeScratchGC(gc);
-  FreeScratchPixmapHeader(pixmap);
-  pixman_image_unref(image);
+  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+ 
+  screen->ModifyPixmapHeader(pixmap, width, height, 
+                             mask_format->depth, 
+	                     BitsPerPixel(mask_format->depth),
+			     PixmapBytePad(width, mask_format->depth),
+			     pixman_image_get_data(image));
 
   x_rel = bounds.x1 + x_src - x_dst;
   y_rel = bounds.y1 + y_src - y_dst;
@@ -1309,6 +1287,9 @@ glamor_trapezoids(CARD8 op,
 		   0, 0,
 		   bounds.x1, bounds.y1,
 		   bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+
+  pixman_image_unref(image);
+
   FreePicture(picture, 0);
 }
 
commit 9e4567afe6019ed7a330182d660880d8ea6c3685
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 28 14:37:29 2011 +0800

    glamor: Change to use system memory for write only access.
    
    If the pixmap is write-only, then use a pbo mapping will not
    get too much benefit. And even worse, when the software
    rendering is access this mapped data range, it's much slower
    than just using a system memory. From the glamor_prepare_access
    glamor_finish_access view, we have two options here:
    
    option 1:
    1.0 create a pbo
    1.1 copy texture to the pbo
    1.2 map the pbo to va
    1.3 access the va directly in software rendering.
    1.4 bind the pbo as unpack buffer & draw it back to texture.
    
    option 2:
    2.0 allocate a block memory in system memory space.
    2.1 read the texture memory to the system memory.
    2.2 access the system memory and do rendering.
    2.3 draw the system memory back to texture.
    
    In general, 1.1 plush 1.2 is much faster than 2.1.
    And 1.3 is slower than 2.2. 1.4 is faster than 2.3.
    
    If the access mode is read only or read write, option 1
    may be fater, but if the access mode is write only. Then
    most of the time option 1 is much faster.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index b532bb3..c76920a 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -387,15 +387,23 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   }
 
   pixmap_priv->access_mode = access;
-
+  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+		      "Downloading pixmap %p  %dx%d depth%d\n", 
+		      pixmap, 
+		      pixmap->drawable.width, 
+		      pixmap->drawable.height,
+		      pixmap->drawable.depth);
+ 
+  stride = pixmap->devKind;
+ 
   switch (access) {
   case GLAMOR_ACCESS_RO:
     gl_access = GL_READ_ONLY_ARB;
     gl_usage = GL_STREAM_READ_ARB;
     break;
   case GLAMOR_ACCESS_WO:
-    gl_access = GL_WRITE_ONLY_ARB;
-    gl_usage = GL_STREAM_DRAW_ARB;
+    data = malloc(stride * pixmap->drawable.height);
+    goto done;
     break;
   case GLAMOR_ACCESS_RW:
     gl_access = GL_READ_WRITE_ARB;
@@ -405,15 +413,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     ErrorF("Glamor: Invalid access code. %d\n", access);
     assert(0);
   }
-
-  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
-		      "Downloading pixmap %p  %dx%d depth%d\n", 
-		      pixmap, 
-		      pixmap->drawable.width, 
-		      pixmap->drawable.height,
-		      pixmap->drawable.depth);
  
-  stride = pixmap->devKind;
   row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -429,8 +429,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
     glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT,
 		     stride * pixmap->drawable.height,
 		     NULL, gl_usage);
-    if (access != GLAMOR_ACCESS_WO)
-      glReadPixels (0, 0,
+    glReadPixels (0, 0,
                     row_length, pixmap->drawable.height,
                     format, type, 0);
     data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access);
@@ -438,7 +437,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
     if (!glamor_priv->yInverted) 
       glPixelStorei(GL_PACK_INVERT_MESA, 0);
-
+    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
   } else {
     data = malloc(stride * pixmap->drawable.height);
     assert(data);
@@ -465,6 +464,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
   }
 
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+done:
   pixmap->devPrivate.ptr = data;
   return TRUE;
 }
commit 4afa9e4080eebbee0752e5f45b2ff16df75cb9b1
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 28 14:28:19 2011 +0800

    glamor: Prepare/finish access once if src equal to dst.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index b1d8cfc..cebce21 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -322,6 +322,7 @@ glamor_copy_n_to_n(DrawablePtr src,
         goto done;
 	return;
     }
+
     glamor_report_delayed_fallbacks(src->pScreen);
     glamor_report_delayed_fallbacks(dst->pScreen);
 
@@ -329,11 +330,12 @@ glamor_copy_n_to_n(DrawablePtr src,
 		    glamor_get_drawable_location(src),
 		    glamor_get_drawable_location(dst));
     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
-	if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+	if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
 	    fbCopyNtoN(src, dst, gc, box, nbox,
 		       dx, dy, reverse, upsidedown, bitplane,
 		       closure);
-	    glamor_finish_access(src);
+            if (dst != src)
+	      glamor_finish_access(src);
 	}
 	glamor_finish_access(dst);
     }
commit cbedfe75135e3253c32ac8b89380f47d1b8a37c4
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun Jun 26 20:00:26 2011 +0800

    glamor: Don't need to read dest if op is SRC or CLEAR.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2d89cd4..59a74df 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1084,6 +1084,7 @@ glamor_composite(CARD8 op,
 		 CARD16 height)
 {
   glamor_composite_rect_t rect;
+  glamor_access_t dest_access;
 
   /* Do two-pass PictOpOver componentAlpha, until we enable
    * dual source color blending.
@@ -1150,7 +1151,11 @@ glamor_composite(CARD8 op,
 
   glUseProgramObjectARB(0);
   glDisable(GL_BLEND);
-  if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
+  if (op == PictOpSrc || op == PictOpClear)
+    dest_access = GLAMOR_ACCESS_WO;
+  else
+    dest_access = GLAMOR_ACCESS_RW;
+  if (glamor_prepare_access_picture(dest, dest_access)) {
     if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
       {
 	if (!mask ||
commit b8e692d94eb7075409e0d072fdf3066ca1d5d5f3
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun Jun 26 15:54:24 2011 +0800

    glamor: Move the blend set up after the pixmap uploading.
    
    This is a bug, as if we do blend set up before do the pixmap
    dynamic uploading. We will have a incorrect blend env when
    doing the uploading.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 14c3fa8..2d89cd4 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -734,7 +734,7 @@ glamor_composite_with_shader(CARD8 op,
   int mask_x_off, mask_y_off;
   enum glamor_pixmap_status source_status = GLAMOR_NONE;
   enum glamor_pixmap_status mask_status = GLAMOR_NONE;
-  PictFormatShort saved_source_format = 0;
+  PictFormatShort saved_source_format = 0; 
   float src_matrix[9], mask_matrix[9];
 
   dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
@@ -838,10 +838,6 @@ glamor_composite_with_shader(CARD8 op,
   if (!good_dest_format(dest)) {
     goto fail;
   }
-  if (!glamor_set_composite_op(screen, op, dest, mask)) {
-    goto fail;
-  }
-
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
   if (source_status == GLAMOR_UPLOAD_PENDING 
       && mask_status == GLAMOR_UPLOAD_PENDING 
@@ -849,17 +845,13 @@ glamor_composite_with_shader(CARD8 op,
 
     if (source->format != mask->format) {
       saved_source_format = source->format;
-      /* XXX
-       * when need to flip the texture and mask and source share the same pixmap,
-       * there is a bug, need to be fixed. *
-       */
-      if (!glamor_priv->yInverted)
-	goto fail;
+
       if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) {
 	glamor_fallback("combine source %x mask %x failed.\n", 
 			source->format, mask->format);
 	goto fail;
       }
+
       if (source->format != saved_source_format) {
 	glamor_picture_format_fixup(source, source_pixmap_priv);
       }
@@ -913,7 +905,9 @@ glamor_composite_with_shader(CARD8 op,
     }
   }
 #endif
-
+  if (!glamor_set_composite_op(screen, op, dest, mask)) {
+    goto fail;
+  }
   glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 
   shader = glamor_lookup_composite_shader(screen, &key);
commit bf782283371bc13c7b969a373c2a2eaaa3c81ec6
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun Jun 26 15:51:47 2011 +0800

    glamor: Fixed one bug when enable dynamic pixmap uploading.
    
    When try to upload a pixmap without yInverted set, we must
    set up a fbo for it to do the y flip. Previous implementation
    only consider the ax bit. After fix this problem, we can
    enable the dynamic uploading feature in copyarea function when
    the yInverted is not set (from Xephyr).
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 5543771..b1d8cfc 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -224,8 +224,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
 	goto fail;
 #else
-        /* XXX in yInverted mode we have bug here.*/
-        if (!glamor_priv->yInverted) goto fail;
         src_status = glamor_upload_pixmap_to_texture(src_pixmap);
 	if (src_status != GLAMOR_UPLOAD_DONE) 
 	goto fail;
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 6e2d9d5..b532bb3 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -241,11 +241,19 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, i
 }
 
 
-/*   */
+/*  
+ * Prepare to upload a pixmap to texture memory.
+ * ax 1 means the format needs to wire alpha to 1.
+ * Two condtion need to setup a fbo for a pixmap
+ * 1. !yInverted, we need to do flip if we are not yInverted.
+ * 2. ax != 0, we need to wire the alpha.
+ * */
 static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, int ax)
 {
+  int need_fbo;
   glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
 
   if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) 
       || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
@@ -253,25 +261,28 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo)
 		    pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth);
     return -1;
   }
+
   if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 
     return 0; 
-  if (pixmap_priv->tex == 0) {
-    /* Create a framebuffer object wrapping the texture so that we can render
-     * to it.
-     */
-    glGenTextures(1, &pixmap_priv->tex);
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-  }
 
-  if (need_fbo && pixmap_priv->fb == 0) {
+  if (ax != 0 || !glamor_priv->yInverted)
+    need_fbo = 1;
+  else
+    need_fbo = 0;
+
+  if (pixmap_priv->tex == 0) 
+    glGenTextures(1, &pixmap_priv->tex);
 
+  if (need_fbo) {
+    if (pixmap_priv->fb == 0) 
+      glGenFramebuffersEXT(1, &pixmap_priv->fb);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
 		 pixmap->drawable.height, 0,
 		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 
-    glGenFramebuffersEXT(1, &pixmap_priv->fb);
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
 			      GL_COLOR_ATTACHMENT0_EXT,
@@ -304,7 +315,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
 		      pixmap->drawable.width, 
 		      pixmap->drawable.height,
 		      pixmap->drawable.depth);
-  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 0);
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1);
   return GLAMOR_UPLOAD_DONE;
 }
 
commit 489e6c4e6f734d961ae8bbec67d78fccbeb9781f
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun Jun 26 15:49:13 2011 +0800

    glamor: Initialize pixmap private's container to correct value.
    
    When calling from ephyr, we forgot to initialize it to the correct
    value. Will cause segfault when run Xephyr.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c10ff40..5430422 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -197,6 +197,7 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
     pixmap_priv->tex = 0; 
     pixmap_priv->gl_fbo = 1;
     pixmap_priv->gl_tex = 1;
+    pixmap_priv->container = pixmap;
     
     screen->CreatePixmap = glamor_create_pixmap;
     return pixmap;
commit ca36ada041558d1823b12b1a0141e43b9f9ad939
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 22 18:15:02 2011 +0800

    glamor: Don't always fallback everything when change window attr.
    
    Change the glamor_change_window_attributes's handling. We don't need
    to fallback every thing to cpu at the beginning. Only when there
    is a real need to change the pixmap's format, we need to do something.
    Otherwise, we need do nothing here.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 53877dc..e2678f0 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -33,6 +33,7 @@ libglamor_la_SOURCES = \
         glamor_triangles.c\
         glamor_pixmap.c\
         glamor_picture.c\
+	glamor_window.c\
 	glamor.h
 libglamor_la_LIBADD = \
 	glu3/libglu3.la
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index a61b8ae..31734be 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -241,10 +241,13 @@ glamor_finish_access(DrawablePtr drawable)
 Bool
 glamor_prepare_access_gc(GCPtr gc)
 {
-  if (gc->stipple)
+  if (gc->stipple) {
+    glamor_fallback("has stipple %p\n", gc->stipple);
     if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
       return FALSE;
+  }
   if (gc->fillStyle == FillTiled) {
+    glamor_fallback("has tile pixmap %p\n", gc->tile.pixmap);
     if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
 				GLAMOR_ACCESS_RO)) {
       if (gc->stipple)
@@ -332,6 +335,8 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 	  /* fb24_32ReformatTile will do direct access of a newly-
 	   * allocated pixmap.
 	   */
+	  glamor_fallback("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile);
+
 	  if (glamor_prepare_access(&old_tile->drawable,
 				    GLAMOR_ACCESS_RO)) {
 	    new_tile = fb24_32ReformatTile(old_tile,
@@ -351,6 +356,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
     if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width *
 				       drawable->bitsPerPixel))
       {
+	glamor_fallback("GC %p tile changed %p.\n", gc, gc->tile.pixmap);
 	if (glamor_prepare_access(&gc->tile.pixmap->drawable,
 				  GLAMOR_ACCESS_RW)) {
 	  fbPadPixmap(gc->tile.pixmap);
@@ -367,6 +373,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
     /* We can't inline stipple handling like we do for GCTile because
      * it sets fbgc privates.
      */
+    glamor_fallback("GC %p stipple changed %p.\n", gc, gc->stipple);
     if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
       fbValidateGC(gc, changes, drawable);
       glamor_finish_access(&gc->stipple->drawable);
@@ -403,52 +410,11 @@ glamor_create_gc(GCPtr gc)
   return TRUE;
 }
 
-Bool
-glamor_prepare_access_window(WindowPtr window)
-{
-  if (window->backgroundState == BackgroundPixmap) {
-    if (!glamor_prepare_access(&window->background.pixmap->drawable,
-			       GLAMOR_ACCESS_RO))
-      return FALSE;
-  }
-
-  if (window->borderIsPixel == FALSE) {
-    if (!glamor_prepare_access(&window->border.pixmap->drawable,
-			       GLAMOR_ACCESS_RO)) {
-      if (window->backgroundState == BackgroundPixmap)
-	glamor_finish_access(&window->background.pixmap->drawable);
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-void
-glamor_finish_access_window(WindowPtr window)
-{
-  if (window->backgroundState == BackgroundPixmap)
-    glamor_finish_access(&window->background.pixmap->drawable);
-
-  if (window->borderIsPixel == FALSE)
-    glamor_finish_access(&window->border.pixmap->drawable);
-}
-
-Bool
-glamor_change_window_attributes(WindowPtr window, unsigned long mask)
-{
-  Bool ret;
-
-  if (!glamor_prepare_access_window(window))
-    return FALSE;
-  ret = fbChangeWindowAttributes(window, mask);
-  glamor_finish_access_window(window);
-  return ret;
-}
-
 RegionPtr
 glamor_bitmap_to_region(PixmapPtr pixmap)
 {
   RegionPtr ret;
+  glamor_fallback("pixmap %p \n", pixmap);
   if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
     return NULL;
   ret = fbPixmapToRegion(pixmap);
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
index aad4b3c..48682e8 100644
--- a/glamor/glamor_debug.h
+++ b/glamor/glamor_debug.h
@@ -5,9 +5,24 @@
 #define GLAMOR_DELAYED_STRING_MAX 64
 
 #define GLAMOR_DEBUG_NONE                     0
+#define GLAMOR_DEBUG_UNIMPL                   0
 #define GLAMOR_DEBUG_FALLBACK                 1
-#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD   2
-#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD         3
+#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD         2
+#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD   3
+
+extern void
+AbortServer(void) _X_NORETURN;
+
+#define GLAMOR_PANIC(_format_, ...)			\
+  do {							\
+    LogMessageVerb(X_NONE, 0, "Glamor Fatal Error"	\
+		   " at %32s line %d: " _format_ "\n",	\
+		   __FUNCTION__, __LINE__,		\
+		   ##__VA_ARGS__ );			\
+    AbortServer();					\
+  } while(0)
+                        
+
 
 
 #define __debug_output_message(_format_, _prefix_, ...) \
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f991b0f..14c3fa8 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -748,6 +748,7 @@ glamor_composite_with_shader(CARD8 op,
     if (source->pSourcePict->type == SourcePictTypeSolidFill) {
       key.source = SHADER_SOURCE_SOLID;
     } else {
+      //key.source = SHADER_SOURCE_SOLID;
       glamor_fallback("gradient source\n");
       goto fail;
     }
@@ -1134,12 +1135,23 @@ glamor_composite(CARD8 op,
     return;
 
  fail:
-  glamor_fallback("glamor_composite(): "
-		  "from picts %p/%p(%c,%c) to pict %p (%c)\n",
-		  source, mask,
+
+  glamor_fallback(
+		  "from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c)  to pict %p:%p %dx%d (%c)\n",
+		  source, 
+                  source->pDrawable,
+		  source->pDrawable ? source->pDrawable->width : 0,
+		  source->pDrawable ? source->pDrawable->height : 0,
+		  mask, 
+                  (!mask) ? NULL : mask->pDrawable,
+		  (!mask || !mask->pDrawable)? 0 : mask->pDrawable->width,
+		  (!mask || !mask->pDrawable)? 0 : mask->pDrawable->height,
 		  glamor_get_picture_location(source),
 		  glamor_get_picture_location(mask),
 		  dest,
+		  dest->pDrawable,
+		  dest->pDrawable->width,
+		  dest->pDrawable->height,
 		  glamor_get_picture_location(dest));
 
   glUseProgramObjectARB(0);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 90bf734..c62392c 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -94,18 +94,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_pixmap_private *src_pixmap_priv;
     glamor_pixmap_private *dst_pixmap_priv;
 
+
     src_pixmap_priv = glamor_get_pixmap_private(tile);
     dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-
     if (glamor_priv->tile_prog == 0) {
 	glamor_fallback("Tiling unsupported\n");
 	goto fail;
     }
 
-
     if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {      
-      glamor_fallback("dest has no fbo.");
+      glamor_fallback("dest has no fbo.\n");
       goto fail;
     }
 
diff --git a/glamor/glamor_window.c b/glamor/glamor_window.c
new file mode 100644
index 0000000..05555b2
--- /dev/null
+++ b/glamor/glamor_window.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_window.c
+ *
+ * Screen Change Window Attribute implementation.
+ */
+
+
+static void
+glamor_fixup_window_pixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap)
+{
+    PixmapPtr pPixmap = *ppPixmap;
+    glamor_pixmap_private *pixmap_priv;
+
+    if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
+    {
+        pixmap_priv = glamor_get_pixmap_private(pPixmap);
+        if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+          glamor_fallback("pixmap %p has no fbo\n", pPixmap);
+          goto fail;
+        }
+        glamor_debug_output(GLAMOR_DEBUG_UNIMPL, "To be implemented.\n");
+    }
+    return;
+
+fail:
+     GLAMOR_PANIC(" We can't fall back to fbFixupWindowPixmap, as the fb24_32ReformatTile"
+		  " is broken for glamor. \n");
+}
+
+Bool
+glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
+{
+    if (mask & CWBackPixmap) {
+       if (pWin->backgroundState == BackgroundPixmap) 
+         glamor_fixup_window_pixmap(&pWin->drawable, &pWin->background.pixmap);
+    }
+
+    if (mask & CWBorderPixmap) {
+       if (pWin->borderIsPixel == FALSE)
+         glamor_fixup_window_pixmap(&pWin->drawable, &pWin->border.pixmap);
+    }
+    return TRUE;
+}
+
+
+
commit ca1908e11dcb56cb952f6bce55503e932aa9a27c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 22 14:33:38 2011 +0800

    glamor: Concentrate and reduce some coords processing code.
    
    Concentrate the verties and texture coords processing code to a new
    file glamor_utils.h. Change most of the code to macro. Will have some
    performance benefit on slow machine. And reduce most of the duplicate
    code when calculate the normalized coords.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 766c9e2..5543771 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -199,11 +199,13 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int i;
-    float vertices[4][2], texcoords[4][2];
+    float vertices[8], texcoords[8];
     glamor_pixmap_private *src_pixmap_priv;
     glamor_pixmap_private *dst_pixmap_priv;
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
     enum glamor_pixmap_status src_status = GLAMOR_NONE;
+    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
     dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
@@ -237,6 +239,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     }
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@@ -258,42 +263,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     assert(GLEW_ARB_fragment_shader);
     glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
+   
 
     for (i = 0; i < nbox; i++) {
 
-	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
-	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
-	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
-	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
-	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
-	texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
-	texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
-	texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
-
-      if(glamor_priv->yInverted) {
-
-	vertices[0][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
-	vertices[1][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
-	vertices[2][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
-	vertices[3][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
-
-	texcoords[0][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
-	texcoords[1][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
-	texcoords[2][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
-	texcoords[3][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
-	} else {
-
-	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
-	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
-	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
-	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
-
-	texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
-	texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
-	texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
-	texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
-	}
-	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+      glamor_set_normalize_vcoords(dst_xscale, dst_yscale, 
+				   box[i].x1 + dst_x_off,
+				   box[i].y1 + dst_y_off,
+				   box[i].x2 + dst_x_off,
+				   box[i].y2 + dst_y_off,
+				   glamor_priv->yInverted,
+				   vertices);
+
+      glamor_set_normalize_tcoords(src_xscale, src_yscale,
+				   box[i].x1 + dx, box[i].y1 + dy,
+				   box[i].x2 + dx, box[i].y2 + dy,
+				   glamor_priv->yInverted,
+				   texcoords);
+
+      glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
     glUseProgramObjectARB(0);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index fade2b3..48f85ce 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -146,14 +146,16 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     int x1 = x;
     int x2 = x + width;
     int y1 = y;
     int y2 = y + height;
     GLfloat color[4];
-    float vertices[4][2];
-
-    if (glamor_set_destination_pixmap(pixmap)) {
+    float vertices[8];
+    GLfloat xscale, yscale;
+    
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
         glamor_fallback("dest has no fbo.\n");
 	goto fail;
     }
@@ -162,6 +164,9 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
       glamor_fallback("Failedto set planemask  in glamor_solid.\n");
       goto fail;
     } 
+
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_rgba_from_pixel(fg_pixel, 
                               &color[0], 
@@ -174,22 +179,11 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
-    vertices[0][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[1][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[2][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[3][0] = v_from_x_coord_x(pixmap, x1);
- 
-    if (glamor_priv->yInverted) {
-      vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
-      vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
-      vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
-      vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
-    } else {
-      vertices[0][1] = v_from_x_coord_y(pixmap, y1);
-      vertices[1][1] = v_from_x_coord_y(pixmap, y1);
-      vertices[2][1] = v_from_x_coord_y(pixmap, y2);
-      vertices[3][1] = v_from_x_coord_y(pixmap, y2);
-    }
+    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
+    glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
+				 glamor_priv->yInverted,
+				 vertices);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     glDisableClientState(GL_VERTEX_ARRAY);
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 10fa2a2..7fe05f9 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -42,11 +42,17 @@ glamor_get_spans(DrawablePtr drawable,
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
     int ax;
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(drawable->pScreen);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     int i;
     uint8_t *readpixels_dst = (uint8_t *)dst;
     int x_off, y_off;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+        glamor_fallback("pixmap has no fbo.\n");
+	goto fail;
+    }
+
     if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                                &format, 
                                                &type, 
@@ -57,10 +63,8 @@ glamor_get_spans(DrawablePtr drawable,
       goto fail;
     }
 
-    if (glamor_set_destination_pixmap(pixmap)) { 
-        glamor_fallback("pixmap has no fbo.\n");
-	goto fail;
-    }
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ 
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
     for (i = 0; i < count; i++) {
       if (glamor_priv->yInverted) {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index cf293b5..5b457e7 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -505,44 +505,6 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
 
 extern int glamor_debug_level;
 
-static inline float
-v_from_x_coord_x(PixmapPtr pixmap, int x)
-{
-  return (float)x / pixmap->drawable.width * 2.0 - 1.0;
-}
-
-static inline float
-v_from_x_coord_y(PixmapPtr pixmap, int y)
-{
-  return (float)y / pixmap->drawable.height * -2.0 + 1.0;
-}
-
-static inline float
-v_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
-{
-  return (float)y / pixmap->drawable.height * 2.0 - 1.0;
-}
-
-
-static inline float
-t_from_x_coord_x(PixmapPtr pixmap, int x)
-{
-  return (float)x / pixmap->drawable.width;
-}
-
-static inline float
-t_from_x_coord_y(PixmapPtr pixmap, int y)
-{
-  return 1.0 - (float)y / pixmap->drawable.height;
-}
-
-static inline float
-t_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
-{
-  return (float)y / pixmap->drawable.height;
-}
-
-
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
@@ -791,4 +753,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
 
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
 
+
+#include"glamor_utils.h" 
+
 #endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index d056576..e61425d 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -87,17 +87,6 @@ glamor_init_putimage_shaders(ScreenPtr screen)
     glUseProgramObjectARB(0);
 }
 
-static int
-y_flip(PixmapPtr pixmap, int y)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-    if (pixmap == screen_pixmap)
-	return (pixmap->drawable.height - 1) - y;
-    else
-	return y;
-}
 
 /* Do an XYBitmap putimage.  The bits are byte-aligned rows of bitmap
  * data (where each row starts at a bit index of left_pad), and the
@@ -110,6 +99,21 @@ y_flip(PixmapPtr pixmap, int y)
  * case we might be better off just doing the fg/bg choosing in the CPU
  * and just draw the resulting texture to the destination.
  */
+#if 0
+
+static int
+y_flip(PixmapPtr pixmap, int y)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+    if (pixmap == screen_pixmap)
+	return (pixmap->drawable.height - 1) - y;
+    else
+	return y;
+}
+
+
 static void
 glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 			  int x, int y, int w, int h, int left_pad,
@@ -124,25 +128,27 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     RegionPtr clip;
     BoxPtr box;
     int nbox;
-    float dest_coords[4][2];
+    float dest_coords[8];
     const float bitmap_coords[8] = {
 	0.0, 0.0,
 	1.0, 0.0,
 	1.0, 1.0,
 	0.0, 1.0,
     };
+    GLfloat xscale, yscale;
+    glamor_pixmap_private *pixmap_priv;
+   
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
 
+    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
 
-    dest_coords[0][0] = v_from_x_coord_x(pixmap, x);
-    dest_coords[0][1] = v_from_x_coord_y(pixmap, y);
-    dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w);
-    dest_coords[1][1] = v_from_x_coord_y(pixmap, y);
-    dest_coords[2][0] = v_from_x_coord_x(pixmap, x + w);
-    dest_coords[2][1] = v_from_x_coord_y(pixmap, y + h);
-    dest_coords[3][0] = v_from_x_coord_x(pixmap, x);
-    dest_coords[3][1] = v_from_x_coord_y(pixmap, y + h);
+    glamor_set_normalize_vcoords(xscale, yscale,
+				 x, y,
+				 x + w, y + h,
+				 glamor_priv->yInverted,
+				 dest_coords);
 
-   glamor_fallback("glamor_put_image_xybitmap: disabled\n");
+    glamor_fallback("glamor_put_image_xybitmap: disabled\n");
     goto fail;
 
     if (glamor_priv->put_image_xybitmap_prog == 0) {
@@ -237,6 +243,8 @@ fail:
 	glamor_finish_access(drawable);
     }
 }
+#endif
+
 
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
@@ -252,13 +260,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int nbox;
     int src_stride = PixmapBytePad(w, drawable->depth);
     int x_off, y_off;
-    float vertices[4][2], texcoords[4][2];
+    float vertices[8], texcoords[8];
+    GLfloat xscale, yscale, txscale, tyscale;
     GLuint tex;
     int ax = 0;
     if (image_format == XYBitmap) {
 	assert(depth == 1);
-	glamor_put_image_xybitmap(drawable, gc, x, y, w, h,
-				  left_pad, image_format, bits);
+        goto fail;
 	return;
     }
 
@@ -319,8 +327,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     y += drawable->y;
 
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-
     clip = fbGetCompositeClip(gc);
+
+    txscale = 1.0/w;
+    tyscale = 1.0/h;
+    pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
+
     for (nbox = REGION_NUM_RECTS(clip),
 	 pbox = REGION_RECTS(clip);
 	 nbox--;
@@ -330,7 +342,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	int y1 = y;
 	int x2 = x + w;
 	int y2 = y + h;
-	float src_x1, src_x2, src_y1, src_y2;
 
 	if (x1 < pbox->x1)
 	    x1 = pbox->x1;
@@ -343,41 +354,18 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (x1 >= x2 || y1 >= y2)
 	    continue;
 
-	src_x1 = (float)(x1 - x) / w;
-	src_y1 = (float)(y1 - y) / h;
-	src_x2 = (float)(x2 - x) / w;
-	src_y2 = (float)(y2 - y) / h;
-
-	vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off);
-	vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off);
-	vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off);
-	vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off);
-
-	texcoords[0][0] = src_x1;
-	texcoords[0][1] = src_y1;
-	texcoords[1][0] = src_x2;
-	texcoords[1][1] = src_y1;
-	texcoords[2][0] = src_x2;
-	texcoords[2][1] = src_y2;
-	texcoords[3][0] = src_x1;
-	texcoords[3][1] = src_y2;
- 
-
-	if (glamor_priv->yInverted) {
-
-	vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
-	vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
-	vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
-	vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
-
-	} else {
-
-	vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
-	vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
-	vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
-	vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
-
-	}
+	glamor_set_normalize_tcoords( txscale, tyscale, 
+				      x1 - x, y1 - y,
+				      x2 - x, y2 - y,
+				      1,
+				      texcoords);
+
+	glamor_set_normalize_vcoords( xscale, yscale,
+				      x1 + x_off, y1 + y_off,
+				      x2 + x_off, y2 + y_off,
+				      glamor_priv->yInverted,
+				      vertices);
+
 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ca27b4d..f991b0f 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -533,41 +533,6 @@ good_dest_format(PicturePtr picture)
   }
 }
 
-static inline float
-xFixedToFloat(pixman_fixed_t val)
-{
-  return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0));
-}
-
-static void
-glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
-			     float *texcoord, int x, int y)
-{
-  float result[3];
-  int i;
-  float tx, ty;
-  ScreenPtr screen = picture->pDrawable->pScreen;
-  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-
-  if (picture->transform) {
-    for (i = 0; i < 3; i++) {
-      result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x +
-		   xFixedToFloat(picture->transform->matrix[i][1]) * y +
-		   xFixedToFloat(picture->transform->matrix[i][2]));
-    }
-    tx = result[0] / result[2];
-    ty = result[1] / result[2];
-  } else {
-    tx = x;
-    ty = y;
-  }
-  texcoord[0] = t_from_x_coord_x(pixmap, tx);
-  if (glamor_priv->yInverted)
-    texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty);
-  else
-    texcoord[1] = t_from_x_coord_y(pixmap, ty);
-}
-
 static void
 glamor_setup_composite_vbo(ScreenPtr screen)
 {
@@ -756,6 +721,8 @@ glamor_composite_with_shader(CARD8 op,
   glamor_pixmap_private *source_pixmap_priv = NULL;
   glamor_pixmap_private *mask_pixmap_priv = NULL;
   glamor_pixmap_private *dest_pixmap_priv = NULL;
+  GLfloat dst_xscale, dst_yscale;
+  GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
   struct shader_key key;
   glamor_composite_shader *shader;
   RegionRec region;
@@ -768,6 +735,8 @@ glamor_composite_with_shader(CARD8 op,
   enum glamor_pixmap_status source_status = GLAMOR_NONE;
   enum glamor_pixmap_status mask_status = GLAMOR_NONE;
   PictFormatShort saved_source_format = 0;
+  float src_matrix[9], mask_matrix[9];
+
   dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 
   if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@@ -972,14 +941,24 @@ glamor_composite_with_shader(CARD8 op,
 
   glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
 			     &dest_x_off, &dest_y_off);
+  pixmap_priv_get_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+
+
+
   if (source_pixmap) {
     glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
 			       &source_x_off, &source_y_off);
+    pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
+    glamor_picture_get_matrixf(source, src_matrix);
   }
+
   if (mask_pixmap) {
     glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
 			       &mask_x_off, &mask_y_off);
+    pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
+    glamor_picture_get_matrixf(mask, mask_matrix);
   }
+
   while (nrect--) {
     INT16 x_source;
     INT16 y_source;
@@ -1025,65 +1004,41 @@ glamor_composite_with_shader(CARD8 op,
 
     box = REGION_RECTS(&region);
     for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-      vertices[0] = v_from_x_coord_x(dest_pixmap,
-				     box[i].x1 + dest_x_off);
-      vertices[2] = v_from_x_coord_x(dest_pixmap,
-				     box[i].x2 + dest_x_off);
-      vertices[4] = v_from_x_coord_x(dest_pixmap,
-				     box[i].x2 + dest_x_off);
-      vertices[6] = v_from_x_coord_x(dest_pixmap,
-				     box[i].x1 + dest_x_off);
-
-      if (glamor_priv->yInverted) {
-	vertices[1] = v_from_x_coord_y_inverted(dest_pixmap,
-						box[i].y1 + dest_y_off);
-	vertices[3] = v_from_x_coord_y_inverted(dest_pixmap,
-						box[i].y1 + dest_y_off);
-	vertices[5] = v_from_x_coord_y_inverted(dest_pixmap,
-						box[i].y2 + dest_y_off);
-	vertices[7] = v_from_x_coord_y_inverted(dest_pixmap,
-						box[i].y2 + dest_y_off);
+      int vx1 = box[i].x1 + dest_x_off;
+      int vx2 = box[i].x2 + dest_x_off;
+      int vy1 = box[i].y1 + dest_y_off;
+      int vy2 = box[i].y2 + dest_y_off;
+      glamor_set_normalize_vcoords(dst_xscale, dst_yscale, vx1, vy1, vx2, vy2, 
+				   glamor_priv->yInverted, vertices);
 
-      } else {
-	vertices[1] = v_from_x_coord_y(dest_pixmap,
-				       box[i].y1 + dest_y_off);
-	vertices[3] = v_from_x_coord_y(dest_pixmap,
-				       box[i].y1 + dest_y_off);
-	vertices[5] = v_from_x_coord_y(dest_pixmap,
-				       box[i].y2 + dest_y_off);
-	vertices[7] = v_from_x_coord_y(dest_pixmap,
-				       box[i].y2 + dest_y_off);
-      }
       if (key.source != SHADER_SOURCE_SOLID) {
 	int tx1 = box[i].x1 + x_source - x_dest;
 	int ty1 = box[i].y1 + y_source - y_dest;
 	int tx2 = box[i].x2 + x_source - x_dest;
 	int ty2 = box[i].y2 + y_source - y_dest;
-
-	glamor_set_transformed_point(source, source_pixmap,
-				     source_texcoords + 0, tx1, ty1);
-	glamor_set_transformed_point(source, source_pixmap,
-				     source_texcoords + 2, tx2, ty1);
-	glamor_set_transformed_point(source, source_pixmap,
-				     source_texcoords + 4, tx2, ty2);
-	glamor_set_transformed_point(source, source_pixmap,
-				     source_texcoords + 6, tx1, ty2);
-      }
+	if (source->transform)
+	  glamor_set_transformed_normalize_tcoords(src_matrix, src_xscale, src_yscale, 
+						   tx1, ty1, tx2, ty2,
+						   glamor_priv->yInverted, 
+						   source_texcoords);
+	else
+	  glamor_set_normalize_tcoords(src_xscale, src_yscale, tx1, ty1, tx2, ty2,
+				       glamor_priv->yInverted, source_texcoords);
+      }   
 
       if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
 	float tx1 = box[i].x1 + x_mask - x_dest;
 	float ty1 = box[i].y1 + y_mask - y_dest;
 	float tx2 = box[i].x2 + x_mask - x_dest;
 	float ty2 = box[i].y2 + y_mask - y_dest;
-
-	glamor_set_transformed_point(mask, mask_pixmap,
-				     mask_texcoords + 0, tx1, ty1);
-	glamor_set_transformed_point(mask, mask_pixmap,
-				     mask_texcoords + 2, tx2, ty1);
-	glamor_set_transformed_point(mask, mask_pixmap,
-				     mask_texcoords + 4, tx2, ty2);
-	glamor_set_transformed_point(mask, mask_pixmap,
-				     mask_texcoords + 6, tx1, ty2);
+	if (mask->transform)
+	  glamor_set_transformed_normalize_tcoords(mask_matrix, mask_xscale, mask_yscale, 
+						   tx1, ty1, tx2, ty2,
+						   glamor_priv->yInverted, 
+						   mask_texcoords);
+	else
+	  glamor_set_normalize_tcoords(mask_xscale, mask_yscale, tx1, ty1, tx2, ty2,
+				       glamor_priv->yInverted, mask_texcoords);
       }
       glamor_emit_composite_rect(screen, source_texcoords,
 				 mask_texcoords, vertices);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 2991edd..90bf734 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -88,70 +88,64 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     int tile_x2 = tile_x + width;
     int tile_y1 = tile_y;
     int tile_y2 = tile_y + height;
-    glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
-    float vertices[4][2];
-    float source_texcoords[4][2];
+    float vertices[8];
+    float source_texcoords[8];
+    GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
+    glamor_pixmap_private *src_pixmap_priv;
+    glamor_pixmap_private *dst_pixmap_priv;
+
+    src_pixmap_priv = glamor_get_pixmap_private(tile);
+    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+
     if (glamor_priv->tile_prog == 0) {
 	glamor_fallback("Tiling unsupported\n");
 	goto fail;
     }
 
-    if (glamor_set_destination_pixmap(pixmap)) {
-        glamor_fallback("dest has no fbo.");
-	goto fail;
+
+    if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {      
+      glamor_fallback("dest has no fbo.");
+      goto fail;
     }
 
-    if (tile_priv->gl_tex == 0) {
-	glamor_fallback("Non-texture tile pixmap\n");
-	goto fail;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+      /* XXX dynamic uploading candidate. */
+      glamor_fallback("Non-texture tile pixmap\n");
+      goto fail;
     }
 
     if (!glamor_set_planemask(pixmap, planemask)) {
         glamor_fallback("unsupported planemask %lx\n", planemask);
 	goto fail;
     }
+
+    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+    pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
+    pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
+
     glamor_set_alu(alu);
     glUseProgramObjectARB(glamor_priv->tile_prog);
 
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, tile_priv->tex);
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     glEnable(GL_TEXTURE_2D);
 
-    vertices[0][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[1][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[2][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[3][0] = v_from_x_coord_x(pixmap, x1);
-    source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1);
-    source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2);
-    source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2);
-    source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1);
- 
-    if (glamor_priv->yInverted) {
-      vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
-      vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
-      vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
-      vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
-
-      source_texcoords[0][1] = t_from_x_coord_y_inverted(tile, tile_y1);
-      source_texcoords[1][1] = t_from_x_coord_y_inverted(tile, tile_y1);
-      source_texcoords[2][1] = t_from_x_coord_y_inverted(tile, tile_y2);
-      source_texcoords[3][1] = t_from_x_coord_y_inverted(tile, tile_y2);
-    } else {
-
-      vertices[0][1] = v_from_x_coord_y(pixmap, y1);
-      vertices[1][1] = v_from_x_coord_y(pixmap, y1);
-      vertices[2][1] = v_from_x_coord_y(pixmap, y2);
-      vertices[3][1] = v_from_x_coord_y(pixmap, y2);
-
-      source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
-      source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
-      source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
-      source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
-    }
+    glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
+				 x1, y1,x2, y2,
+				 glamor_priv->yInverted,
+				 vertices);
+
+    glamor_set_normalize_tcoords(src_xscale, src_yscale,
+				 tile_x1, tile_y1,
+				 tile_x2, tile_y2,
+				 glamor_priv->yInverted,
+				 source_texcoords);
+
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
new file mode 100644
index 0000000..b8b437e
--- /dev/null
+++ b/glamor/glamor_utils.h
@@ -0,0 +1,124 @@
+#ifndef GLAMOR_PRIV_H
+#error This file can only be included by glamor_priv.h
+#endif
+
+#ifndef __GLAMOR_UTILS_H__
+#define __GLAMOR_UTILS_H__
+
+#define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
+#define v_from_x_coord_y(_yscale_, _y_)          (-2 * (_y_) * (_yscale_) + 1.0)
+#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0) 
+#define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_)) 
+#define t_from_x_coord_y(_yscale_, _y_)          (1.0 - (_y_) * (_yscale_))
+#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
+
+#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
+  do {									\
+    *(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width;	\
+    *(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height;	\
+  } while(0)
+        
+
+#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
+			      + ((float)xFixedFrac(_val_) / 65536.0))
+
+#define glamor_picture_get_matrixf(_picture_, _matrix_)			\
+  do {									\
+    int _i_;								\
+    if ((_picture_)->transform)						\
+      {									\
+	for(_i_ = 0; _i_ < 3; _i_++)					\
+	  {								\
+	    (_matrix_)[_i_ * 3 + 0] =					\
+	      xFixedToFloat((_picture_)->transform->matrix[_i_][0]);	\
+	    (_matrix_)[_i_ * 3 + 1] =					\
+	      xFixedToFloat((_picture_)->transform->matrix[_i_][1]);	\
+	    (_matrix_)[_i_ * 3 + 2] = \
+	      xFixedToFloat((_picture_)->transform->matrix[_i_][2]);	\
+	  }								\
+      }									\
+  }  while(0)
+
+#define glamor_set_transformed_point(matrix, xscale, yscale, texcoord,	\
+                                     x, y, yInverted)			\
+  do {									\
+    float result[4];							\
+    int i;								\
+    float tx, ty;							\
+									\
+    for (i = 0; i < 3; i++) {						\
+      result[i] = (matrix)[i * 3] * (x) + (matrix)[i * 3 + 1] * (y)	\
+	+ (matrix)[i * 3 + 2];						\
+    }									\
+    tx = result[0] / result[2];						\
+    ty = result[1] / result[2];						\
+									\
+    (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
+    if (yInverted)							\
+      (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty);		\
+    else								\
+      (texcoord)[1] = t_from_x_coord_y(yscale, ty);			\
+  } while(0)
+
+
+#define glamor_set_transformed_normalize_tcoords( matrix,		\
+						  xscale,		\
+						  yscale,		\
+                                                  tx1, ty1, tx2, ty2,   \
+                                                  yInverted, texcoords)	\
+  do {									\
+    glamor_set_transformed_point(matrix, xscale, yscale,		\
+				 texcoords, tx1, ty1,			\
+				 yInverted);				\
+    glamor_set_transformed_point(matrix, xscale, yscale,		\
+				 texcoords + 2, tx2, ty1,		\
+				 yInverted);				\
+    glamor_set_transformed_point(matrix, xscale, yscale,		\
+				 texcoords + 4, tx2, ty2,		\
+				 yInverted);				\
+    glamor_set_transformed_point(matrix, xscale, yscale,		\
+				 texcoords + 6, tx1, ty2,		\
+				 yInverted);				\
+  } while (0)
+
+#define glamor_set_normalize_tcoords(xscale, yscale, x1, y1, x2, y2,	\
+                                     yInverted, vertices)		\
+  do {									\
+    (vertices)[0] = t_from_x_coord_x(xscale, x1);			\
+    (vertices)[2] = t_from_x_coord_x(xscale, x2);			\
+    (vertices)[4] = (vertices)[2];					\
+    (vertices)[6] = (vertices)[0];					\
+    if (yInverted) {							\
+      (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1);		\
+      (vertices)[5] = t_from_x_coord_y_inverted(yscale, y2);		\
+    }									\
+    else {								\
+      (vertices)[1] = t_from_x_coord_y(yscale, y1);			\
+      (vertices)[5] = t_from_x_coord_y(yscale, y2);			\
+    }									\
+    (vertices)[3] = (vertices)[1];					\
+    (vertices)[7] = (vertices)[5];					\
+  } while(0)
+
+
+#define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,	\
+                                     yInverted, vertices)		\
+  do {									\
+    (vertices)[0] = v_from_x_coord_x(xscale, x1);			\
+    (vertices)[2] = v_from_x_coord_x(xscale, x2);			\
+    (vertices)[4] = (vertices)[2];					\
+    (vertices)[6] = (vertices)[0];					\
+    if (yInverted) {							\
+      (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1);		\
+      (vertices)[5] = v_from_x_coord_y_inverted(yscale, y2);		\
+    }									\
+    else {								\
+      (vertices)[1] = v_from_x_coord_y(yscale, y1);			\
+      (vertices)[5] = v_from_x_coord_y(yscale, y2);			\
+    }									\
+    (vertices)[3] = (vertices)[1];					\
+    (vertices)[7] = (vertices)[5];					\
+  } while(0)
+
+
+#endif
commit 355334fcd99e4dce62e2be1e27290c9a74ea944f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Tue Jun 21 18:31:11 2011 +0800

    glamor : Add dynamic texture uploading feature.
    
    Major refactoring.
    1. Rewrite the pixmap texture uploading and downloading functions.
       Add some new functions for both the prepare/finish access and
       the new performance feature dynamic texture uploading, which
       could download and upload the current image to/from a private
       texture/fbo. In the uploading or downloading phase, we need to
       handle two things:
       The first is the yInverted option, If it set, then we don't need
       to flip y. If not set, if it is from a dynamic texture uploading
       then we don't need to flip either if the current drawing process
       will flip it latter. If it is from finish_access, then we must
       flip the y axis.
    
       The second thing is the alpha channel hanlding, if the pixmap's
       format is something like x8a8r8g8, x1r5g5b5 which means it doesn't
       has alpha channel, but it do has those extra bits. Then we need to
       wire those bits to 1.
    
    2. Add almost all the required picture format support.
       This is not as trivial as it looks like. The previous implementation
       only support GL_a8,GL_a8r8g8b8,GL_x8r8g8b8. All the other format,
       we have to fallback to cpu. The reason why we can't simply add those
       other color format is because the exists of picture. one drawable
       pixmap may has one or even more container pictures. The drawable pixmap's
       depth can't map to a specified color format, for example depth 16 can
       mapped to r5g6b5, x1r5g5b5, a1r5g5b5, or even b5g6r5. So we can't get
       get the color format just from the depth value. But the pixmap do not
       has a pict_format element. We have to make a new one in the pixmap
       private data structure. Reroute the CreatePicture to glamor_create_picture
       and then store the picture's format to the pixmap's private structure.
    
       This is not an ideal solution, as there may be more than one pictures
       refer to the same pixmap. Then we will have trouble. There is an example
       in glamor_composite_with_shader. The source and mask often share the
       same pixmap, but use different picture format. Our current solution is to
       combine those two different picture formats to one which will not lose any
       data. Then change the source's format to this new format and then upload
       the pixmap to texture once. It works. If we fail to find a matched new
       format then we fallback.
    
       There still is a potential problem, if two pictures refer to the same
       pixmap, and one of them destroy the picture, but the other still remained
       to be used latter. We don't handle that situation currently. To be fixed.
    
    3. Dynamic texture uploading.
       This is a performance feature. Although we don't like the client to hold
       a pixmap data to shared memory and we can't accelerate it. And even worse,
       we may need to fallback all the required pixmaps to cpu memory and then
       process them on CPU. This feature is to mitigate this penalty. When the
       target pixmap has a valid gl fbo attached to it. But the other pixmaps are
       not. Then it will be more efficient to upload the other pixmaps to GPU and
       then do the blitting or rendering on GPU than fallback all the pixmaps to CPU.
       To enable this feature, I experienced a significant performance improvement
       in the Game "Mines" :).
    
    4. Debug facility.
       Modify the debug output mechanism. Now add a new macro:
       glamor_debug_output(_level_, _format_,...) to conditional output some messages
       according to the environment variable GLAMOR_DEBUG. We have the following
       levels currently.
        exports GLAMOR_DEBUG to 3 will enable all the above messages.
    
    5. Changes in pixmap private data structure.
       Add some for the full color format supports and relate it to the pictures which
       already described. Also Add the following new elements:
       gl_fbo - to indicates whether this pixmap is on gpu only.
       gl_tex - to indicates whether the tex is valid and is containing the pixmap's
                image originally.
       As we bring the dynamic pixmap uploading feature, so a cpu memory pixmap may
       also has a valid fbo or tex attached to it. So we will have to use the above
       new element to check it true type.
    
    After this commit, we can pass the rendercheck testing for all the picture formats.
    And is much much fater than fallback to cpu when doing rendercheck testing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 8f62920..53877dc 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -31,6 +31,8 @@ libglamor_la_SOURCES = \
 	glamor_render.c \
 	glamor_tile.c \
         glamor_triangles.c\
+        glamor_pixmap.c\
+        glamor_picture.c\
 	glamor.h
 libglamor_la_LIBADD = \
 	glu3/libglu3.la
diff --git a/glamor/glamor.c b/glamor/glamor.c
index d6d6d95..c10ff40 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -59,8 +59,7 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 	return (PixmapPtr)drawable;
 }
 
-
-void
+static void
 glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
@@ -73,6 +72,8 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
     /* Create a framebuffer object wrapping the texture so that we can render
      * to it.
      */
+    pixmap_priv->gl_fbo = 1;
+    pixmap_priv->gl_tex = 1;
     glGenFramebuffersEXT(1, &pixmap_priv->fb);
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
@@ -87,13 +88,24 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
                               NULL);
 }
 
+/* Set screen pixmap. If tex equal to 0, means it is called from ephyr. */
+void
+glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex)
+{
+  PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+  glamor_set_pixmap_texture(pixmap, w, h, tex);
+  glamor_priv->screen_fbo = pixmap_priv->fb;
+}
+
+
+
+#define GLAMOR_PIXMAP_MEMORY 0 
+#define GLAMOR_PIXMAP_TEXTURE 1 
+
 
-/* XXX For the screen pixmap, the w and h maybe 0,0 too, but it should
- * be GLAMOR_GL pixmap. Now, all the pixmap will have a valid pixmap_priv. 
- * This is not good enough. After we can identify which is the screen
- * pixmap and which is not, then we can split the pixmap to exclusive
- * two types GLAMOR_GL and GLAMOR_FB, and for those GLAMOR_FB pixmaps, 
- * we don't need to allocate pixmap_priv. */
 
 static PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
@@ -102,22 +114,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     PixmapPtr pixmap;
     GLenum format;
     GLuint tex;
-    enum glamor_pixmap_type type = GLAMOR_GL;
+    int type = GLAMOR_PIXMAP_TEXTURE;
+    glamor_pixmap_private *pixmap_priv;
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    if (w > MAX_WIDTH || h > MAX_HEIGHT || ( depth == 1 && w != 0 && h != 0)) {
+    if (!glamor_check_fbo_width_height(w,h) || !glamor_check_fbo_depth(depth)) {
 	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
  	   If we exceed such limitation, we have to use framebuffer.*/
-      type = GLAMOR_FB;
+      type = GLAMOR_PIXMAP_MEMORY;
       pixmap = fbCreatePixmap (screen, w, h, depth, usage);
       screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
                               NULL);
 
-      glamor_fallback("fallback to software fb for pixmap %p , %d x %d depth %d\n", pixmap, w, h, depth);
+      glamor_fallback("choose cpu memory for pixmap %p ,"
+	              " %d x %d depth %d\n", pixmap, w, h, depth);
    } else 
       pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
@@ -127,7 +141,10 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return NullPixmap;
     }	 
 
-    if (w == 0 || h == 0 || type == GLAMOR_FB)
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    pixmap_priv->container = pixmap;
+
+    if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
 	return pixmap;
 
     /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
@@ -136,7 +153,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     switch (depth) {
     case 24:
         format = GL_RGB;
-        break;
+        break; 
     default:
         format = GL_RGBA;
         break;
@@ -154,13 +171,51 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     return pixmap;
 }
 
+
+/**
+ * For Xephyr use only. set up the screen pixmap to correct state. 
+ **/
+static PixmapPtr
+glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
+		     unsigned int usage)
+{
+    PixmapPtr pixmap;
+    glamor_pixmap_private *pixmap_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    assert(w ==0 && h == 0);
+
+    glamor_priv->screen_fbo = 0; 
+    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+
+    if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
+        fbDestroyPixmap(pixmap);
+	ErrorF("Fail to allocate privates for PIXMAP.\n");
+	return NullPixmap;
+    }	 
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    pixmap_priv->tex = 0; 
+    pixmap_priv->gl_fbo = 1;
+    pixmap_priv->gl_tex = 1;
+    
+    screen->CreatePixmap = glamor_create_pixmap;
+    return pixmap;
+}
+
+
+
+
 static Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-	glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
-	glDeleteTextures(1, &pixmap_priv->tex);
+        if (pixmap_priv->fb)
+	  glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
+        if (pixmap_priv->tex)
+	  glDeleteTextures(1, &pixmap_priv->tex);
+        if (pixmap_priv->pbo)
+          glDeleteBuffersARB(1, &pixmap_priv->pbo);
     }
 
     return fbDestroyPixmap(pixmap);
@@ -177,6 +232,18 @@ glamor_wakeup_handler(void *data, int result, void *last_select_mask)
 {
 }
 
+static void 
+glamor_set_debug_level(int *debug_level)
+{
+  char *debug_level_string;
+  debug_level_string = getenv("GLAMOR_DEBUG");
+  if (debug_level_string && sscanf(debug_level_string, "%d", debug_level) == 1)
+     return;
+  *debug_level = 0;
+}
+
+int glamor_debug_level;
+
 /** Set up glamor for an already-configured GL context. */
 Bool
 glamor_init(ScreenPtr screen, unsigned int flags)
@@ -186,7 +253,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
-
     if (flags & ~GLAMOR_VALID_FLAGS) {
       ErrorF("glamor_init: Invalid flags %x\n", flags);
       return FALSE;
@@ -205,7 +271,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	LogMessage(X_WARNING,
 		   "glamor%d: Failed to allocate screen private\n",
 		   screen->myNum);
+        return FALSE;
     }
+
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
 
     if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP,
@@ -213,6 +281,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         LogMessage(X_WARNING,
                    "glamor%d: Failed to allocate pixmap private\n",
                    screen->myNum);
+        return FALSE;
     }
 
     glewInit();
@@ -243,7 +312,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	goto fail;
     }
 
-    
+    glamor_set_debug_level(&glamor_debug_level); 
     glamor_priv->saved_close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_close_screen;
 
@@ -251,7 +320,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     screen->CreateGC = glamor_create_gc;
 
     glamor_priv->saved_create_pixmap = screen->CreatePixmap;
-    screen->CreatePixmap = glamor_create_pixmap;
+
+    if (flags & GLAMOR_HOSTX)
+      screen->CreatePixmap = glamor_create_screen_pixmap;
+    else
+      screen->CreatePixmap = glamor_create_pixmap;
 
     glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
     screen->DestroyPixmap = glamor_destroy_pixmap;
@@ -281,6 +354,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_priv->saved_triangles = ps->Triangles;
     ps->Triangles = glamor_triangles;
     glamor_init_composite_shaders(screen);
+    glamor_priv->saved_create_picture = ps->CreatePicture; 
+    ps->CreatePicture = glamor_create_picture;
+    glamor_priv->saved_destroy_picture = ps->DestroyPicture; 
+    ps->DestroyPicture = glamor_destroy_picture;
 #endif
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
@@ -288,7 +365,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     glamor_init_finish_access_shaders(screen);
     glamor_glyphs_init(screen);
 
-
     return TRUE;
 
 fail:
@@ -319,6 +395,7 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	ps->Trapezoids = glamor_priv->saved_trapezoids;
 	ps->Glyphs = glamor_priv->saved_glyphs;
         ps->Triangles = glamor_priv->saved_triangles;
+        ps->CreatePicture = glamor_priv->saved_create_picture;
     }
 #endif
     free(glamor_priv);
diff --git a/glamor/glamor.h b/glamor/glamor.h
index c49662e..2c1b241 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -39,9 +39,10 @@
 #endif /* GLAMOR_H */
 
 
-#define GLAMOR_INVERTED_Y_AXIS  0x1
-#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS)
+#define GLAMOR_INVERTED_Y_AXIS  1
+#define GLAMOR_HOSTX            2
+#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX)
 
 Bool glamor_init(ScreenPtr screen, unsigned int flags);
 void glamor_fini(ScreenPtr screen);
-void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
+void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 07d8b14..766c9e2 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -31,7 +31,6 @@
  *
  * GC CopyArea implementation
  */
-
 static Bool
 glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 			    DrawablePtr dst,
@@ -49,45 +48,36 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
     if (src == dst) {
-	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
-				"src == dest\n");
+	glamor_delayed_fallback(screen,"src == dest\n");
 	return FALSE;
     }
 
     if (!GLEW_EXT_framebuffer_blit) {
-	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
-				"no EXT_framebuffer_blit\n");
+	glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
 	return FALSE;
    }
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
-    if (src_pixmap_priv->fb == 0) {
-        PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-        if (src_pixmap != screen_pixmap) {
-            glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
-				    "no src fbo\n");
-            return FALSE;
-        }
-    }
-
     if (gc) {
 	if (gc->alu != GXcopy) {
-	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
-				    "non-copy ALU\n");
+	    glamor_delayed_fallback(screen, "non-copy ALU\n");
 	    return FALSE;
 	}
 	if (!glamor_pm_is_solid(dst, gc->planemask)) {
-	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
-				    "non-solid planemask\n");
+	    glamor_delayed_fallback(screen, "non-solid planemask\n");
 	    return FALSE;
 	}
     }
 
-    if (!glamor_set_destination_pixmap(dst_pixmap))
-	return FALSE;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
+        glamor_delayed_fallback(screen, "no src fbo\n");
+        return FALSE;
+    }
 
+    if (glamor_set_destination_pixmap(dst_pixmap)) {
+	return FALSE;
+    }
     glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
@@ -124,7 +114,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 			     GL_NEAREST);
 	}
     }
-
     return TRUE;
 }
 
@@ -142,29 +131,26 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(screen);
     int x_off, y_off, i;
-
     if (src != dst) {
-	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
-				"src != dest\n");
+	glamor_delayed_fallback(screen, "src != dest\n");
 	return FALSE;
     }
 
     if (gc) {
 	if (gc->alu != GXcopy) {
-	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
-				    "non-copy ALU\n");
+	    glamor_delayed_fallback(screen,"non-copy ALU\n");
 	    return FALSE;
 	}
 	if (!glamor_pm_is_solid(dst, gc->planemask)) {
-	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
-				    "non-solid planemask\n");
+	    glamor_delayed_fallback(screen,"non-solid planemask\n");
 	    return FALSE;
 	}
     }
 
-    if (!glamor_set_destination_pixmap(dst_pixmap))
+    if (glamor_set_destination_pixmap(dst_pixmap)) {
+        glamor_delayed_fallback(screen, "dst has no fbo.\n");
 	return FALSE;
-
+    }
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glOrtho(0, dst_pixmap->drawable.width,
@@ -196,7 +182,6 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 		     GL_COLOR);
 	}
     }
-
     return TRUE;
 }
 
@@ -216,29 +201,43 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     int i;
     float vertices[4][2], texcoords[4][2];
     glamor_pixmap_private *src_pixmap_priv;
+    glamor_pixmap_private *dst_pixmap_priv;
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
-
+    enum glamor_pixmap_status src_status = GLAMOR_NONE;
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+    dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
     if (src == dst) {
-	glamor_fallback("glamor_copy_n_to_n with same src/dst\n");
+	glamor_delayed_fallback(dst->pScreen, "same src/dst\n");
 	goto fail;
     }
 
-    if (!src_pixmap_priv || !src_pixmap_priv->tex) {
-	glamor_fallback("glamor_copy_n_to_n with non-texture src\n");
-	goto fail;
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
+        glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
+        goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(dst_pixmap))
+    if (!src_pixmap_priv->gl_tex) {
+#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+	glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
+	goto fail;
+#else
+        /* XXX in yInverted mode we have bug here.*/
+        if (!glamor_priv->yInverted) goto fail;
+        src_status = glamor_upload_pixmap_to_texture(src_pixmap);
+	if (src_status != GLAMOR_UPLOAD_DONE) 
 	goto fail;
+#endif
+    }
 
     if (gc) {
 	glamor_set_alu(gc->alu);
 	if (!glamor_set_planemask(dst_pixmap, gc->planemask))
-	    goto fail;
+	  goto fail;
     }
 
+    glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
+
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     dx += src_x_off;
@@ -258,7 +257,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
     assert(GLEW_ARB_fragment_shader);
-    glUseProgramObjectARB(glamor_priv->finish_access_prog);
+    glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
 
     for (i = 0; i < nbox; i++) {
 
@@ -324,23 +323,23 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 void		*closure)
 {
     if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
-	glamor_clear_delayed_fallbacks(dst->pScreen);
+        goto done;
 	return;
     }
 
-    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) {
-	glamor_clear_delayed_fallbacks(dst->pScreen);
+    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)){
+        goto done;
 	return;
-    }
+     }
 
     if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) {
-	glamor_clear_delayed_fallbacks(dst->pScreen);
+        goto done;
 	return;
     }
-
+    glamor_report_delayed_fallbacks(src->pScreen);
     glamor_report_delayed_fallbacks(dst->pScreen);
 
-    glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst,
+    glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
 		    glamor_get_drawable_location(dst));
     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
@@ -352,6 +351,11 @@ glamor_copy_n_to_n(DrawablePtr src,
 	}
 	glamor_finish_access(dst);
     }
+    return;
+
+done:
+    glamor_clear_delayed_fallbacks(src->pScreen);
+    glamor_clear_delayed_fallbacks(dst->pScreen);
 }
 
 RegionPtr
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index a517045..a61b8ae 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -42,144 +42,27 @@
 const Bool
 glamor_get_drawable_location(const DrawablePtr drawable)
 {
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    if (pixmap_priv == NULL)
-	return 'm';
-    if (pixmap_priv->fb == 0)
-	return 's';
-    else
-	return 'f';
+  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv =
+    glamor_get_screen_private(drawable->pScreen);
+  if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
+    return 'm';
+  if (pixmap_priv->fb == glamor_priv->screen_fbo)
+    return 's';
+  else
+    return 'f';
 }
 
-/**
- * Sets the offsets to add to coordinates to make them address the same bits in
- * the backing drawable. These coordinates are nonzero only for redirected
- * windows.
- */
-void
-glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
-			   int *x, int *y)
-{
-#ifdef COMPOSITE
-    if (drawable->type == DRAWABLE_WINDOW) {
-	*x = -pixmap->screen_x;
-	*y = -pixmap->screen_y;
-	return;
-    }
-#endif
-
-    *x = 0;
-    *y = 0;
-}
-
-Bool
-glamor_set_destination_pixmap(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (pixmap_priv == NULL) {
-	glamor_fallback("glamor_set_destination_pixmap(): no pixmap priv");
-	return FALSE;
-    }
-
-    if (pixmap_priv->fb == 0) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-	if (pixmap != screen_pixmap) {
-	    glamor_fallback("glamor_set_destination_pixmap(): no fbo");
-	    return FALSE;
-	}
-    }
-
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-
-    glViewport(0, 0,
-	       pixmap->drawable.width,
-	       pixmap->drawable.height);
-
-    return TRUE;
-}
-
-Bool
-glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
-{
-    if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
-	return GL_TRUE;
-    }
-
-    ErrorF("unsupported planemask\n");
-    return GL_FALSE;
-}
-
-void
-glamor_set_alu(unsigned char alu)
-{
-    if (alu == GXcopy) {
-	glDisable(GL_COLOR_LOGIC_OP);
-	return;
-    }
-    glEnable(GL_COLOR_LOGIC_OP);
-    switch (alu) {
-    case GXclear:
-	glLogicOp(GL_CLEAR);
-	break;
-    case GXand:
-	glLogicOp(GL_AND);
-	break;
-    case GXandReverse:
-	glLogicOp(GL_AND_REVERSE);
-	break;
-    case GXandInverted:
-	glLogicOp(GL_AND_INVERTED);
-	break;
-    case GXnoop:
-	glLogicOp(GL_NOOP);
-	break;
-    case GXxor:
-	glLogicOp(GL_XOR);
-	break;
-    case GXor:
-	glLogicOp(GL_OR);
-	break;
-    case GXnor:
-	glLogicOp(GL_NOR);
-	break;
-    case GXequiv:
-	glLogicOp(GL_EQUIV);
-	break;
-    case GXinvert:
-	glLogicOp(GL_INVERT);
-	break;
-    case GXorReverse:
-	glLogicOp(GL_OR_REVERSE);
-	break;
-    case GXcopyInverted:
-	glLogicOp(GL_COPY_INVERTED);
-	break;
-    case GXorInverted:
-	glLogicOp(GL_OR_INVERTED);
-	break;
-    case GXnand:
-	glLogicOp(GL_NAND);
-	break;
-    case GXset:
-	glLogicOp(GL_SET);
-	break;
-    default:
-	FatalError("unknown logic op\n");
-    }
-}
 
 void
 glamor_get_transform_uniform_locations(GLint prog,
 				       glamor_transform_uniforms *uniform_locations)
 {
-    uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
-    uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
-    uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
-    uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
+  uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
+  uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
+  uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
+  uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
 }
 
 /* We don't use a full matrix for our transformations because it's
@@ -190,400 +73,163 @@ void
 glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				glamor_transform_uniforms *uniform_locations)
 {
-    glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
-    glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
-    glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
-    glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
+  glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
+  glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
+  glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
+  glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
 }
 
 GLint
 glamor_compile_glsl_prog(GLenum type, const char *source)
 {
-    GLint ok;
-    GLint prog;
-
-    prog = glCreateShaderObjectARB(type);
-    glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
-    glCompileShaderARB(prog);
-    glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
-    if (!ok) {
-	GLchar *info;
-	GLint size;
-
-	glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
-	info = malloc(size);
-
-	glGetInfoLogARB(prog, size, NULL, info);
-	ErrorF("Failed to compile %s: %s\n",
-	       type == GL_FRAGMENT_SHADER ? "FS" : "VS",
-	       info);
-	ErrorF("Program source:\n%s", source);
-	FatalError("GLSL compile failure\n");
-    }
-
-    return prog;
+  GLint ok;
+  GLint prog;
+
+  prog = glCreateShaderObjectARB(type);
+  glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
+  glCompileShaderARB(prog);
+  glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
+  if (!ok) {
+    GLchar *info;
+    GLint size;
+
+    glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+    info = malloc(size);
+
+    glGetInfoLogARB(prog, size, NULL, info);
+    ErrorF("Failed to compile %s: %s\n",
+	   type == GL_FRAGMENT_SHADER ? "FS" : "VS",
+	   info);
+    ErrorF("Program source:\n%s", source);
+    FatalError("GLSL compile failure\n");
+  }
+
+  return prog;
 }
 
 void
 glamor_link_glsl_prog(GLint prog)
 {
-    GLint ok;
-
-    glLinkProgram(prog);
-    glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
-    if (!ok) {
-	GLchar *info;
-	GLint size;
-
-	glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
-	info = malloc(size);
-
-	glGetInfoLogARB(prog, size, NULL, info);
-	ErrorF("Failed to link: %s\n",
-	       info);
-	FatalError("GLSL link failure\n");
-    }
-}
-
-static float ubyte_to_float(uint8_t b)
-{
-    return b / 255.0f;
+  GLint ok;
+
+  glLinkProgram(prog);
+  glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
+  if (!ok) {
+    GLchar *info;
+    GLint size;
+
+    glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+    info = malloc(size);
+
+    glGetInfoLogARB(prog, size, NULL, info);
+    ErrorF("Failed to link: %s\n",
+	   info);
+    FatalError("GLSL link failure\n");
+  }
 }
 
-void
-glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
-			       GLfloat *color)
-{
-    switch (pixmap->drawable.depth) {
-    case 1:
-	color[0] = 0.0;
-	color[1] = 0.0;
-	color[2] = 0.0;
-	color[3] = fg_pixel & 0x01;
-	break;
-    case 8:
-	color[0] = 0.0;
-	color[1] = 0.0;
-	color[2] = 0.0;
-	color[3] = (fg_pixel & 0xff) / 255.0;
-	break;
-    case 24:
-    case 32:
-	color[0] = ubyte_to_float((fg_pixel >> 16) & 0xFF);
-	color[1] = ubyte_to_float((fg_pixel >> 8) & 0xFF);
-	color[2] = ubyte_to_float((fg_pixel >> 0) & 0xFF);
-	color[3] = ubyte_to_float((fg_pixel >> 24) & 0xFF);
-	break;
-    default:
-	ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth);
-	color[0] = 1.0;
-	color[1] = 0.0;
-	color[2] = 1.0;
-	color[3] = 1.0;
-	break;
-    }
-}
 
 Bool
 glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride, row_length, y;
-    GLenum format, type;
-    uint8_t *data, *read;
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(drawable->pScreen);
-
-    if (!pixmap_priv)
-	return TRUE;
-
-    if (pixmap_priv->fb == 0) {
-    	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-	if (pixmap != screen_pixmap)
-	    return TRUE;
-    }
-
-    stride = pixmap->devKind;
-    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-
-    assert(drawable->depth != 1);	
-    switch (drawable->depth) {
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-	assert(drawable->bitsPerPixel == 32);
-	/* FALLTHROUGH */
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth);
-	return FALSE;
-    }
-
-    pixmap_priv->access_mode = access;
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
-
-    if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
-
-      if (!glamor_priv->yInverted) 
-        glPixelStorei(GL_PACK_INVERT_MESA, 1);
-
-      glGenBuffersARB (1, &pixmap_priv->pbo);
-      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-      glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT,
-                       stride * pixmap->drawable.height,
-                       NULL, GL_DYNAMIC_DRAW_ARB);
-      glReadPixels (0, 0,
-                    row_length, pixmap->drawable.height,
-                    format, type, 0);
-
-      data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
-
-      if (!glamor_priv->yInverted) 
-	glPixelStorei(GL_PACK_INVERT_MESA, 0);
-
-    } else {
-        data = malloc(stride * pixmap->drawable.height);
-
-        glGenBuffersARB(1, &pixmap_priv->pbo);
-	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-	glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
-			stride * pixmap->drawable.height,
-	                NULL, GL_STREAM_READ_ARB);
-	glReadPixels (0, 0, row_length, pixmap->drawable.height,
-		      format, type, 0);
-	read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB);
-
-	for (y = 0; y < pixmap->drawable.height; y++)
-	  memcpy(data + y * stride,
-	         read + (pixmap->drawable.height - y - 1) * stride, stride);
-	glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
-	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
-	glDeleteBuffersARB(1, &pixmap_priv->pbo);
-	pixmap_priv->pbo = 0;
-    }
-
-    pixmap->devPrivate.ptr = data;
+  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 
-    return TRUE;
+  return glamor_download_pixmap_to_cpu(pixmap, access);
 }
 
 void
 glamor_init_finish_access_shaders(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    const char *vs_source =
-	"void main()\n"
-	"{\n"
-	"	gl_Position = gl_Vertex;\n"
-	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
-	"}\n";
-    const char *fs_source =
-	"varying vec2 texcoords;\n"
-	"uniform sampler2D sampler;\n"
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
-	"}\n";
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  const char *vs_source =
+    "void main()\n"
+    "{\n"
+    "	gl_Position = gl_Vertex;\n"
+    "	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+    "}\n";
+  const char *fs_source =
+    "varying vec2 texcoords;\n"
+    "uniform sampler2D sampler;\n"
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
+    "}\n";
     
-    const char *aswizzle_source =
-        "varying vec2 texcoords;\n"
-        "uniform sampler2D sampler;\n"
-        "void main()\n"
-        "{\n"
-        " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
-        "}\n";
-
-    GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
-
-    glamor_priv->finish_access_prog = glCreateProgramObjectARB();
-    glamor_priv->aswizzle_prog = glCreateProgramObjectARB();
-
-    if (GLEW_ARB_fragment_shader) {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
-	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
-	glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog);
-
-        avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-        aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source);
-        glAttachObjectARB(glamor_priv->aswizzle_prog, avs_prog);
-        glAttachObjectARB(glamor_priv->aswizzle_prog, aswizzle_prog);
-    } else {
-	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
-	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
-        ErrorF("Lack of framgment shader support.\n");
-    }
-
-    glamor_link_glsl_prog(glamor_priv->finish_access_prog);
-    glamor_link_glsl_prog(glamor_priv->aswizzle_prog);
-
-    if (GLEW_ARB_fragment_shader) {
-	GLint sampler_uniform_location;
-
-	sampler_uniform_location =
-	    glGetUniformLocationARB(glamor_priv->finish_access_prog, "sampler");
-	glUseProgramObjectARB(glamor_priv->finish_access_prog);
-	glUniform1iARB(sampler_uniform_location, 0);
-	glUseProgramObjectARB(0);
-
-        sampler_uniform_location =
-            glGetUniformLocationARB(glamor_priv->aswizzle_prog, "sampler");
-        glUseProgramObjectARB(glamor_priv->aswizzle_prog);
-        glUniform1iARB(sampler_uniform_location, 0);
-        glUseProgramObjectARB(0);
-    }
-}
-
-/* 
- * Load texture from the pixmap's data pointer and then
- * draw the texture to the fbo, and flip the y axis.
- * */
-static void
-glamor_load_texture_pixmap(PixmapPtr pixmap)
-{
-
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(pixmap->drawable.pScreen);
-    unsigned int stride, row_length;
-    GLenum format, type;
-    static float vertices[8] = {-1, -1,
-				 1, -1,
-				 1,  1,
-				 -1, 1};
-    static float texcoords[8] = {0, 1,
-				 1, 1,
-				 1, 0,
-				 0, 0};
-    static float texcoords_inverted[8] = {0, 0,
-                                1, 0,
-                                1, 1,
-                                0, 1};
-    float *ptexcoords;
-
-    void * texel;
-    GLuint tex;
-    int alfa_mode = 0;
-
-    if (glamor_priv->yInverted)
-       ptexcoords = texcoords_inverted;
-    else
-       ptexcoords = texcoords;
-
-    assert(pixmap->drawable.depth != 1);	
-    stride = pixmap->devKind;
-    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-    switch (pixmap->drawable.depth) {
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-	assert(pixmap->drawable.bitsPerPixel == 32);
-	/* FALLTHROUGH */
-        alfa_mode = 1;
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth);
-	return;
-    }
-
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-
-    glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
-
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-
-    glGenTextures(1, &tex);
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, tex);
-
-    if (glamor_priv->yInverted || GLEW_MESA_pack_invert) {
-      texel = NULL;
-      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
-    }
-    else
-      texel = pixmap->devPrivate.ptr;
-
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-		 pixmap->drawable.width, pixmap->drawable.height, 0,
-		 format, type, texel);
-
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glEnable(GL_TEXTURE_2D);
-
-    assert(GLEW_ARB_fragment_shader);
-    if (alfa_mode == 0)
-      glUseProgramObjectARB(glamor_priv->finish_access_prog);
-    else
-      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
+  const char *aswizzle_source =
+    "varying vec2 texcoords;\n"
+    "uniform sampler2D sampler;\n"
+    "void main()\n"
+    "{\n"
+    " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
+    "}\n";
+
+  GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
+
+  glamor_priv->finish_access_prog[0] = glCreateProgramObjectARB();
+  glamor_priv->finish_access_prog[1] = glCreateProgramObjectARB();
+
+  if (GLEW_ARB_fragment_shader) {
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
+    glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog);
+    glAttachObjectARB(glamor_priv->finish_access_prog[0], fs_prog);
+
+    avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+    aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source);
+    glAttachObjectARB(glamor_priv->finish_access_prog[1], avs_prog);
+    glAttachObjectARB(glamor_priv->finish_access_prog[1], aswizzle_prog);
+  } else {
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+    glAttachObjectARB(glamor_priv->finish_access_prog[0], vs_prog);
+    ErrorF("Lack of framgment shader support.\n");
+  }
+
+  glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
+  glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
+
+  if (GLEW_ARB_fragment_shader) {
+    GLint sampler_uniform_location;
+
+    sampler_uniform_location =
+      glGetUniformLocationARB(glamor_priv->finish_access_prog[0], "sampler");
+    glUseProgramObjectARB(glamor_priv->finish_access_prog[0]);
+    glUniform1iARB(sampler_uniform_location, 0);
+    glUseProgramObjectARB(0);
 
-    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    glDisable(GL_TEXTURE_2D);
+    sampler_uniform_location =
+      glGetUniformLocationARB(glamor_priv->finish_access_prog[1], "sampler");
+    glUseProgramObjectARB(glamor_priv->finish_access_prog[1]);
+    glUniform1iARB(sampler_uniform_location, 0);
     glUseProgramObjectARB(0);
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glDeleteTextures(1, &tex);
+  }
 }
 
 void
 glamor_finish_access(DrawablePtr drawable)
 {
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(drawable->pScreen);
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    /* Check if finish_access was already called once on this */
-    if (pixmap->devPrivate.ptr == NULL)
-	return;
-
-    if (!pixmap_priv)
-	return;
-
-    if (pixmap_priv->fb == 0) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-	if (pixmap != screen_pixmap)
-	    return;
-    }
-
-    if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
-      glamor_load_texture_pixmap(pixmap);
-    }
+  PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    
+  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+    return;
+
+  if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
+    glamor_restore_pixmap_to_texture(pixmap);
+  }
+
+  if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
+    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+    pixmap_priv->pbo_valid = FALSE;
+    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+    pixmap_priv->pbo = 0;
+  } else
+    free(pixmap->devPrivate.ptr);
+
+  pixmap->devPrivate.ptr = NULL;
+}
 
-   if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
-     glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-     glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
-     glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
-     glDeleteBuffersARB (1, &pixmap_priv->pbo);
-     pixmap_priv->pbo = 0;
-   } else
-     free(pixmap->devPrivate.ptr);
 
-    pixmap->devPrivate.ptr = NULL;
-}
 /**
  * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
  * current fill style.
@@ -595,18 +241,18 @@ glamor_finish_access(DrawablePtr drawable)
 Bool
 glamor_prepare_access_gc(GCPtr gc)
 {
-    if (gc->stipple)
-	if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
-	    return FALSE;
-    if (gc->fillStyle == FillTiled) {
-	if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
-				    GLAMOR_ACCESS_RO)) {
-	    if (gc->stipple)
-		glamor_finish_access(&gc->stipple->drawable);
-	    return FALSE;
-	}
+  if (gc->stipple)
+    if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
+      return FALSE;
+  if (gc->fillStyle == FillTiled) {
+    if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
+				GLAMOR_ACCESS_RO)) {
+      if (gc->stipple)
+	glamor_finish_access(&gc->stipple->drawable);
+      return FALSE;
     }
-    return TRUE;
+  }
+  return TRUE;
 }
 
 /**
@@ -615,10 +261,10 @@ glamor_prepare_access_gc(GCPtr gc)
 void
 glamor_finish_access_gc(GCPtr gc)
 {
-	if (gc->fillStyle == FillTiled)
-		glamor_finish_access(&gc->tile.pixmap->drawable);
-	if (gc->stipple)
-		glamor_finish_access(&gc->stipple->drawable);
+  if (gc->fillStyle == FillTiled)
+    glamor_finish_access(&gc->tile.pixmap->drawable);
+  if (gc->stipple)
+    glamor_finish_access(&gc->stipple->drawable);
 }
 
 Bool
@@ -628,33 +274,31 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 	       unsigned long fg_pixel, unsigned long bg_pixel,
 	       int stipple_x, int stipple_y)
 {
-    glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
-    return FALSE;
-//    ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth);
-//    glamor_solid_fail_region(pixmap, x, y, width, height);
+  glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
+  return FALSE;
 }
 
 GCOps glamor_gc_ops = {
-    .FillSpans = glamor_fill_spans,
-    .SetSpans = glamor_set_spans,
-    .PutImage = glamor_put_image,
-    .CopyArea = glamor_copy_area,
-    .CopyPlane = miCopyPlane,
-    .PolyPoint = miPolyPoint,
-    .Polylines = glamor_poly_lines,
-    .PolySegment = miPolySegment,
-    .PolyRectangle = miPolyRectangle,
-    .PolyArc = miPolyArc,
-    .FillPolygon = miFillPolygon,
-    .PolyFillRect = glamor_poly_fill_rect,
-    .PolyFillArc = miPolyFillArc,
-    .PolyText8 = miPolyText8,
-    .PolyText16 = miPolyText16,
-    .ImageText8 = miImageText8,
-    .ImageText16 = miImageText16,
-    .ImageGlyphBlt = miImageGlyphBlt,
-    .PolyGlyphBlt = miPolyGlyphBlt,
-    .PushPixels = miPushPixels,
+  .FillSpans = glamor_fill_spans,
+  .SetSpans = glamor_set_spans,
+  .PutImage = glamor_put_image,
+  .CopyArea = glamor_copy_area,
+  .CopyPlane = miCopyPlane,
+  .PolyPoint = miPolyPoint,
+  .Polylines = glamor_poly_lines,
+  .PolySegment = miPolySegment,
+  .PolyRectangle = miPolyRectangle,
+  .PolyArc = miPolyArc,
+  .FillPolygon = miFillPolygon,
+  .PolyFillRect = glamor_poly_fill_rect,
+  .PolyFillArc = miPolyFillArc,
+  .PolyText8 = miPolyText8,
+  .PolyText16 = miPolyText16,
+  .ImageText8 = miImageText8,
+  .ImageText16 = miImageText16,
+  .ImageGlyphBlt = miImageGlyphBlt,
+  .PolyGlyphBlt = miPolyGlyphBlt,
+  .PushPixels = miPushPixels,
 };
 
 /**
@@ -664,84 +308,84 @@ GCOps glamor_gc_ops = {
 static void
 glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
-    /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
-     * Preempt fbValidateGC by doing its work and masking the change out, so
-     * that we can do the Prepare/finish_access.
-     */
+  /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
+   * Preempt fbValidateGC by doing its work and masking the change out, so
+   * that we can do the Prepare/finish_access.
+   */
 #ifdef FB_24_32BIT
-    if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
-	gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
-	fbGetRotatedPixmap(gc) = 0;
-    }
-
-    if (gc->fillStyle == FillTiled) {
-	PixmapPtr old_tile, new_tile;
-
-	old_tile = gc->tile.pixmap;
-	if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
-	    new_tile = fbGetRotatedPixmap(gc);
-	    if (!new_tile ||
-		new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel)
-	    {
-		if (new_tile)
-		    gc->pScreen->DestroyPixmap(new_tile);
-		/* fb24_32ReformatTile will do direct access of a newly-
-		 * allocated pixmap.
-		 */
-		if (glamor_prepare_access(&old_tile->drawable,
-					  GLAMOR_ACCESS_RO)) {
-		    new_tile = fb24_32ReformatTile(old_tile,
-						   drawable->bitsPerPixel);
-		    glamor_finish_access(&old_tile->drawable);
-		}
-	    }
-	    if (new_tile) {
-		fbGetRotatedPixmap(gc) = old_tile;
-		gc->tile.pixmap = new_tile;
-		changes |= GCTile;
-	    }
+  if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
+    gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
+    fbGetRotatedPixmap(gc) = 0;
+  }
+
+  if (gc->fillStyle == FillTiled) {
+    PixmapPtr old_tile, new_tile;
+
+    old_tile = gc->tile.pixmap;
+    if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
+      new_tile = fbGetRotatedPixmap(gc);
+      if (!new_tile ||
+	  new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel)
+	{
+	  if (new_tile)
+	    gc->pScreen->DestroyPixmap(new_tile);
+	  /* fb24_32ReformatTile will do direct access of a newly-
+	   * allocated pixmap.
+	   */
+	  if (glamor_prepare_access(&old_tile->drawable,
+				    GLAMOR_ACCESS_RO)) {
+	    new_tile = fb24_32ReformatTile(old_tile,
+					   drawable->bitsPerPixel);
+	    glamor_finish_access(&old_tile->drawable);
+	  }
 	}
+      if (new_tile) {
+	fbGetRotatedPixmap(gc) = old_tile;
+	gc->tile.pixmap = new_tile;
+	changes |= GCTile;
+      }
     }
+  }
 #endif
-    if (changes & GCTile) {
-	if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width *
-					   drawable->bitsPerPixel))
-	{
-	    if (glamor_prepare_access(&gc->tile.pixmap->drawable,
-				      GLAMOR_ACCESS_RW)) {
-		fbPadPixmap(gc->tile.pixmap);
-		glamor_finish_access(&gc->tile.pixmap->drawable);
-	    }
+  if (changes & GCTile) {
+    if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width *
+				       drawable->bitsPerPixel))
+      {
+	if (glamor_prepare_access(&gc->tile.pixmap->drawable,
+				  GLAMOR_ACCESS_RW)) {
+	  fbPadPixmap(gc->tile.pixmap);
+	  glamor_finish_access(&gc->tile.pixmap->drawable);
 	}
-	/* Mask out the GCTile change notification, now that we've done FB's
-	 * job for it.
-	 */
-	changes &= ~GCTile;
-    }
+      }
+    /* Mask out the GCTile change notification, now that we've done FB's
+     * job for it.
+     */
+    changes &= ~GCTile;
+  }
 
-    if (changes & GCStipple && gc->stipple) {
-	/* We can't inline stipple handling like we do for GCTile because
-	 * it sets fbgc privates.
-	 */
-	if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
-	    fbValidateGC(gc, changes, drawable);
-	    glamor_finish_access(&gc->stipple->drawable);
-	}
-    } else {
-	fbValidateGC(gc, changes, drawable);
+  if (changes & GCStipple && gc->stipple) {
+    /* We can't inline stipple handling like we do for GCTile because
+     * it sets fbgc privates.
+     */
+    if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
+      fbValidateGC(gc, changes, drawable);
+      glamor_finish_access(&gc->stipple->drawable);
     }
+  } else {
+    fbValidateGC(gc, changes, drawable);
+  }
 
-    gc->ops = &glamor_gc_ops;
+  gc->ops = &glamor_gc_ops;
 }
 
 static GCFuncs glamor_gc_funcs = {
-    glamor_validate_gc,
-    miChangeGC,
-    miCopyGC,
-    miDestroyGC,
-    miChangeClip,
-    miDestroyClip,
-    miCopyClip
+  glamor_validate_gc,
+  miChangeGC,
+  miCopyGC,
+  miDestroyGC,
+  miChangeClip,
+  miDestroyClip,
+  miCopyClip
 };
 
 /**
@@ -751,54 +395,54 @@ static GCFuncs glamor_gc_funcs = {
 int
 glamor_create_gc(GCPtr gc)
 {
-    if (!fbCreateGC(gc))
-	return FALSE;
+  if (!fbCreateGC(gc))
+    return FALSE;
 
-    gc->funcs = &glamor_gc_funcs;
+  gc->funcs = &glamor_gc_funcs;
 
-    return TRUE;
+  return TRUE;
 }
 
 Bool
 glamor_prepare_access_window(WindowPtr window)
 {
-    if (window->backgroundState == BackgroundPixmap) {
-        if (!glamor_prepare_access(&window->background.pixmap->drawable,
-				   GLAMOR_ACCESS_RO))
-	    return FALSE;
-    }
-
-    if (window->borderIsPixel == FALSE) {
-        if (!glamor_prepare_access(&window->border.pixmap->drawable,
-				   GLAMOR_ACCESS_RO)) {
-	    if (window->backgroundState == BackgroundPixmap)
-		glamor_finish_access(&window->background.pixmap->drawable);
-	    return FALSE;
-	}
+  if (window->backgroundState == BackgroundPixmap) {
+    if (!glamor_prepare_access(&window->background.pixmap->drawable,
+			       GLAMOR_ACCESS_RO))
+      return FALSE;
+  }
+
+  if (window->borderIsPixel == FALSE) {
+    if (!glamor_prepare_access(&window->border.pixmap->drawable,
+			       GLAMOR_ACCESS_RO)) {
+      if (window->backgroundState == BackgroundPixmap)
+	glamor_finish_access(&window->background.pixmap->drawable);
+      return FALSE;
     }
-    return TRUE;
+  }
+  return TRUE;
 }
 
 void
 glamor_finish_access_window(WindowPtr window)
 {
-    if (window->backgroundState == BackgroundPixmap)
-        glamor_finish_access(&window->background.pixmap->drawable);
+  if (window->backgroundState == BackgroundPixmap)
+    glamor_finish_access(&window->background.pixmap->drawable);
 
-    if (window->borderIsPixel == FALSE)
-        glamor_finish_access(&window->border.pixmap->drawable);
+  if (window->borderIsPixel == FALSE)
+    glamor_finish_access(&window->border.pixmap->drawable);
 }
 
 Bool
 glamor_change_window_attributes(WindowPtr window, unsigned long mask)
 {
-    Bool ret;
+  Bool ret;
 
-    if (!glamor_prepare_access_window(window))
-	return FALSE;
-    ret = fbChangeWindowAttributes(window, mask);
-    glamor_finish_access_window(window);
-    return ret;
+  if (!glamor_prepare_access_window(window))
+    return FALSE;
+  ret = fbChangeWindowAttributes(window, mask);
+  glamor_finish_access_window(window);
+  return ret;
 }
 
 RegionPtr
diff --git a/glamor/glamor_debug.h b/glamor/glamor_debug.h
new file mode 100644
index 0000000..aad4b3c
--- /dev/null
+++ b/glamor/glamor_debug.h
@@ -0,0 +1,67 @@
+#ifndef __GLAMOR_DEBUG_H__
+#define __GLAMOR_DEBUG_H__
+
+
+#define GLAMOR_DELAYED_STRING_MAX 64
+
+#define GLAMOR_DEBUG_NONE                     0
+#define GLAMOR_DEBUG_FALLBACK                 1
+#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD   2
+#define GLAMOR_DEBUG_TEXTURE_DOWNLOAD         3
+
+
+#define __debug_output_message(_format_, _prefix_, ...) \
+  LogMessageVerb(X_NONE, 0,				\
+		 "%32s:\t" _format_ ,		\
+		 /*_prefix_,*/				\
+		 __FUNCTION__,				\
+		 ##__VA_ARGS__)
+
+#define glamor_debug_output(_level_, _format_,...)	\
+  do {							\
+    if (glamor_debug_level >= _level_)			\
+      __debug_output_message(_format_,			\
+			     "Glamor debug",		\
+			     ##__VA_ARGS__);		\
+  } while(0)
+
+
+#define glamor_fallback(_format_,...)			\
+  do {							\
+    if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK)	\
+      __debug_output_message(_format_,			\
+			     "Glamor fallback",		\
+			     ##__VA_ARGS__);} while(0)
+
+
+
+#define glamor_delayed_fallback(_screen_, _format_,...)			\
+  do {									\
+    if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK)  {			\
+      glamor_screen_private *_glamor_priv_;				\
+      _glamor_priv_ = glamor_get_screen_private(_screen_);		\
+      _glamor_priv_->delayed_fallback_pending = 1;			\
+      snprintf(_glamor_priv_->delayed_fallback_string,			\
+	       GLAMOR_DELAYED_STRING_MAX,				\
+	       "glamor delayed fallback: \t%s " _format_ ,		\
+               __FUNCTION__, ##__VA_ARGS__); } } while(0)
+
+
+#define glamor_clear_delayed_fallbacks(_screen_)			\
+  do {									\
+    if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) {			\
+      glamor_screen_private *_glamor_priv_;				\
+	_glamor_priv_ = glamor_get_screen_private(_screen_);		\
+      _glamor_priv_->delayed_fallback_pending = 0;  } } while(0)
+
+#define glamor_report_delayed_fallbacks(_screen_)			\
+  do {									\
+    if (glamor_debug_level >= GLAMOR_DEBUG_FALLBACK) {			\
+      glamor_screen_private *_glamor_priv_;				\
+      _glamor_priv_ = glamor_get_screen_private(_screen_);		\
+      LogMessageVerb(X_INFO, 0, "%s",					\
+		     _glamor_priv_->delayed_fallback_string);		\
+      _glamor_priv_->delayed_fallback_pending = 0;  } } while(0)
+
+
+#endif
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 2b94934..fade2b3 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -89,7 +89,6 @@ glamor_fill(DrawablePtr drawable,
     }
     return;
 fail:
-    glamor_fallback("glamor_fill()");
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	if (glamor_prepare_access_gc(gc)) {
             fbFill(drawable, gc, x, y, width, height);
@@ -154,16 +153,22 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     GLfloat color[4];
     float vertices[4][2];
 
-    if (!glamor_set_destination_pixmap(pixmap))
+    if (glamor_set_destination_pixmap(pixmap)) {
+        glamor_fallback("dest has no fbo.\n");
 	goto fail;
+    }
     glamor_set_alu(alu);
     if (!glamor_set_planemask(pixmap, planemask)) {
-      ErrorF("Failedto set planemask  in glamor_solid.\n");
+      glamor_fallback("Failedto set planemask  in glamor_solid.\n");
       goto fail;
     } 
-
     glUseProgramObjectARB(glamor_priv->solid_prog);
-    glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
+    glamor_get_rgba_from_pixel(fg_pixel, 
+                              &color[0], 
+                              &color[1], 
+                              &color[2], 
+                              &color[3],
+                              format_for_pixmap(pixmap));
     glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
@@ -196,22 +201,4 @@ fail:
     return FALSE;
 }
 
-/* Highlight places where we're doing it wrong. */
-void
-glamor_solid_fail_region(PixmapPtr pixmap, int x, int y, int width, int height)
-{
-    unsigned long pixel;
 
-    switch (pixmap->drawable.depth) {
-    case 24:
-    case 32:
-	pixel = 0x00ff00ff; /* our favorite color */
-	break;
-    default:
-    case 8:
-	pixel = 0xd0d0d0d0;
-	break;
-    }
-
-    glamor_solid(pixmap, x, y, width, height, GXcopy, ~0, pixel);
-}
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index c6976c3..b1f79a9 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -47,10 +47,9 @@ glamor_fill_spans(DrawablePtr drawable,
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 
 
-    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
+    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) 
 	goto fail;
 
-
     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
 	ppt = points;
         while (n--) {
@@ -82,7 +81,7 @@ glamor_fill_spans(DrawablePtr drawable,
         }
     return;
 fail:
-    glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,
+    glamor_fallback("to %p (%c)\n", drawable,
 		    glamor_get_drawable_location(drawable));
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	if (glamor_prepare_access_gc(gc)) {
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index dba23a8..10fa2a2 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -31,18 +31,6 @@
 
 #include "glamor_priv.h"
 
-static void
-set_bit(uint8_t *bitfield, unsigned int index, unsigned int val)
-{
-    int i = index / 8;
-    int mask = 1 << (index % 8);
-
-    if (val)
-	bitfield[i] |= mask;
-    else
-	bitfield[i] &= ~mask;
-}
-
 void
 glamor_get_spans(DrawablePtr drawable,
 		 int wmax,
@@ -53,39 +41,27 @@ glamor_get_spans(DrawablePtr drawable,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
+    int ax;
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(drawable->pScreen);
-    int i, j;
-    uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
+    int i;
+    uint8_t *readpixels_dst = (uint8_t *)dst;
     int x_off, y_off;
-
-    switch (drawable->depth) {
-    case 1:
-	temp_dst = malloc(wmax);
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	readpixels_dst = temp_dst;
-	break;
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	glamor_fallback("glamor_get_spans(): "
-			"Unknown getspans depth %d\n", drawable->depth);
-	goto fail;
+    if (glamor_get_tex_format_type_from_pixmap(pixmap,
+                                               &format, 
+                                               &type, 
+                                               &ax
+                                               )) {
+      glamor_fallback("unknown depth. %d \n", 
+                     drawable->depth);
+      goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(pixmap))
+    if (glamor_set_destination_pixmap(pixmap)) { 
+        glamor_fallback("pixmap has no fbo.\n");
 	goto fail;
-
+    }
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-
     for (i = 0; i < count; i++) {
       if (glamor_priv->yInverted) {
 	glReadPixels(points[i].x + x_off,
@@ -102,21 +78,12 @@ glamor_get_spans(DrawablePtr drawable,
 		     format, type,
 		     readpixels_dst);
 	}
-	if (temp_dst) {
-	    for (j = 0; j < widths[i]; j++) {
-		set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1);
-	    }
-	    dst += PixmapBytePad(widths[i], drawable->depth);
-	} else {
-	    readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
-	}
+       readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
     }
-    free(temp_dst);
     return;
 
 fail:
-    free(temp_dst);
-    glamor_fallback("glamor_get_spans() from %p (%c)\n", drawable,
+    glamor_fallback("from %p (%c)\n", drawable,
 		    glamor_get_drawable_location(drawable));
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
 	fbGetSpans(drawable, wmax, points, widths, count, dst);
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index e24b222..26e0847 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -67,6 +67,7 @@
  */
 #define GLYPH_BUFFER_SIZE 256
 
+
 typedef struct {
     PicturePtr source;
     glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE];
@@ -573,6 +574,7 @@ static void glamor_glyphs_to_mask(PicturePtr mask,
 				  glamor_glyph_buffer_t *buffer)
 {
 #ifdef RENDER
+    
     glamor_composite_rects(PictOpAdd, buffer->source, mask,
 			   buffer->count, buffer->rects);
 #endif
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
new file mode 100644
index 0000000..c94c07c
--- /dev/null
+++ b/glamor/glamor_picture.c
@@ -0,0 +1,93 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+
+/* Upload picture to texture.  We may need to flip the y axis or
+ * wire alpha to 1. So we may conditional create fbo for the picture.
+ * */
+enum glamor_pixmap_status 
+glamor_upload_picture_to_texture(PicturePtr picture)
+{
+  PixmapPtr pixmap;
+  glamor_pixmap_private *pixmap_priv;
+  assert(picture->pDrawable);
+  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+  assert(GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) == 1);
+  return glamor_upload_pixmap_to_texture(pixmap);
+}
+
+
+Bool
+glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
+{
+  if (!picture || !picture->pDrawable)
+    return TRUE;
+    
+  return glamor_prepare_access(picture->pDrawable, access);
+}
+
+void
+glamor_finish_access_picture(PicturePtr picture)
+{
+  if (!picture || !picture->pDrawable)
+    return;
+    
+  glamor_finish_access(picture->pDrawable);
+}
+
+/* 
+ * We should already has drawable attached to it, if it has one.
+ * Then set the attached pixmap to is_picture format, and set
+ * the pict format.
+ * */
+int
+glamor_create_picture(PicturePtr picture)
+{
+  PixmapPtr pixmap;
+  glamor_pixmap_private *pixmap_priv;
+  glamor_screen_private *glamor_priv;
+
+  if (!picture || !picture->pDrawable)
+    return 0;
+
+  glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
+  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  assert(pixmap_priv);
+
+  pixmap_priv->is_picture = 1;
+  pixmap_priv->pict_format = picture->format;
+  return glamor_priv->saved_create_picture(picture);
+}
+
+void
+glamor_destroy_picture(PicturePtr picture)
+{
+  PixmapPtr pixmap;
+  glamor_pixmap_private *pixmap_priv;
+  glamor_screen_private *glamor_priv;
+
+  if (!picture || !picture->pDrawable)
+    return;
+
+  glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
+  pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  assert(pixmap_priv);
+
+  pixmap_priv->is_picture = 0;
+  pixmap_priv->pict_format = 0;
+  glamor_priv->saved_destroy_picture(picture);
+}
+
+void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv)
+{
+  pixmap_priv->pict_format = picture->format;
+}
+
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
new file mode 100644
index 0000000..6e2d9d5
--- /dev/null
+++ b/glamor/glamor_pixmap.c
@@ -0,0 +1,483 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+/**
+ * Sets the offsets to add to coordinates to make them address the same bits in
+ * the backing drawable. These coordinates are nonzero only for redirected
+ * windows.
+ */
+void
+glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
+			   int *x, int *y)
+{
+#ifdef COMPOSITE
+  if (drawable->type == DRAWABLE_WINDOW) {
+    *x = -pixmap->screen_x;
+    *y = -pixmap->screen_y;
+    return;
+  }
+#endif
+
+  *x = 0;
+  *y = 0;
+}
+
+void
+glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
+{
+  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+
+  glViewport(0, 0,
+	     pixmap_priv->container->drawable.width,
+	     pixmap_priv->container->drawable.height);
+}
+
+int
+glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
+{
+  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+    return -1;
+
+  glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+  return 0;
+}
+
+int
+glamor_set_destination_pixmap(PixmapPtr pixmap)
+{
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+  return glamor_set_destination_pixmap_priv(pixmap_priv);
+}
+
+Bool
+glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
+{
+  if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+    return GL_TRUE;
+  }
+
+  glamor_fallback("unsupported planemask %lx\n", planemask);
+  return GL_FALSE;
+}
+
+
+
+void
+glamor_set_alu(unsigned char alu)
+{
+  if (alu == GXcopy) {
+    glDisable(GL_COLOR_LOGIC_OP);
+    return;
+  }
+  glEnable(GL_COLOR_LOGIC_OP);
+  switch (alu) {
+  case GXclear:
+    glLogicOp(GL_CLEAR);
+    break;
+  case GXand:
+    glLogicOp(GL_AND);
+    break;
+  case GXandReverse:
+    glLogicOp(GL_AND_REVERSE);
+    break;
+  case GXandInverted:
+    glLogicOp(GL_AND_INVERTED);
+    break;
+  case GXnoop:
+    glLogicOp(GL_NOOP);
+    break;
+  case GXxor:
+    glLogicOp(GL_XOR);
+    break;
+  case GXor:
+    glLogicOp(GL_OR);
+    break;
+  case GXnor:
+    glLogicOp(GL_NOR);
+    break;
+  case GXequiv:
+    glLogicOp(GL_EQUIV);
+    break;
+  case GXinvert:
+    glLogicOp(GL_INVERT);
+    break;
+  case GXorReverse:
+    glLogicOp(GL_OR_REVERSE);
+    break;
+  case GXcopyInverted:
+    glLogicOp(GL_COPY_INVERTED);
+    break;
+  case GXorInverted:
+    glLogicOp(GL_OR_INVERTED);
+    break;
+  case GXnand:
+    glLogicOp(GL_NAND);
+    break;
+  case GXset:
+    glLogicOp(GL_SET);
+    break;
+  default:
+    FatalError("unknown logic op\n");
+  }
+}
+
+
+
+
+/**
+ * Upload pixmap to a specified texture.
+ * This texture may not be the one attached to it.
+ **/
+
+static void 
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, GLuint tex)
+{
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  unsigned int stride, row_length;
+  void *texels;
+  GLenum iformat = GL_RGBA;
+
+  stride = pixmap->devKind;
+  row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+
+  glBindTexture(GL_TEXTURE_2D, tex);
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+
+  if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
+    texels = NULL;
+    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+  }
+  else
+    texels = pixmap->devPrivate.ptr;
+
+  glTexImage2D(GL_TEXTURE_2D, 
+	       0, 
+	       iformat,
+	       pixmap->drawable.width, 
+	       pixmap->drawable.height, 0,
+	       format, type, texels);
+}
+
+
+/* 
+ * Load texture from the pixmap's data pointer and then
+ * draw the texture to the fbo, and flip the y axis.
+ * */
+
+static void
+_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type, int ax, int flip)
+{
+
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  glamor_screen_private *glamor_priv =
+    glamor_get_screen_private(pixmap->drawable.pScreen);
+  static float vertices[8] = {-1, -1,
+			      1, -1,
+			      1,  1,
+			      -1,  1};
+  static float texcoords[8] = {0, 1,
+			       1, 1,
+			       1, 0,
+			       0, 0};
+  static float texcoords_inv[8] = {0, 0,
+				   1, 0,
+				   1, 1,
+				   0, 1};
+  float *ptexcoords;
+
+  GLuint tex;
+  int need_flip;
+  need_flip = (flip && !glamor_priv->yInverted);
+
+  /* Try fast path firstly, upload the pixmap to the texture attached
+   * to the fbo directly. */
+
+  if (ax == 0 && !need_flip) {
+    __glamor_upload_pixmap_to_texture(pixmap, format, type, pixmap_priv->tex);
+    return;
+  }
+
+
+  if (need_flip)
+    ptexcoords = texcoords;
+  else
+    ptexcoords = texcoords_inv;
+
+  /* Slow path, we need to flip y or wire alpha to 1. */
+  glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+  glEnableClientState(GL_VERTEX_ARRAY);
+
+  glClientActiveTexture(GL_TEXTURE0);
+  glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+  glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
+
+  glGenTextures(1, &tex);
+
+  __glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
+  glActiveTexture(GL_TEXTURE0);
+  glBindTexture(GL_TEXTURE_2D, tex);
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glEnable(GL_TEXTURE_2D);
+  glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]);
+
+  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+  glDisable(GL_TEXTURE_2D);
+  glUseProgramObjectARB(0);
+  glDisableClientState(GL_VERTEX_ARRAY);
+  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+  glDeleteTextures(1, &tex);
+  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+}
+
+
+/*   */
+static int
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, int need_fbo)
+{
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+  if (!glamor_check_fbo_width_height(pixmap->drawable.width , pixmap->drawable.height) 
+      || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
+    glamor_fallback("upload failed reason: bad size or depth %d x %d @depth %d \n",
+		    pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth);
+    return -1;
+  }
+  if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 
+    return 0; 
+  if (pixmap_priv->tex == 0) {
+    /* Create a framebuffer object wrapping the texture so that we can render
+     * to it.
+     */
+    glGenTextures(1, &pixmap_priv->tex);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+  }
+
+  if (need_fbo && pixmap_priv->fb == 0) {
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, 
+		 pixmap->drawable.height, 0,
+		 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+    glGenFramebuffersEXT(1, &pixmap_priv->fb);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+			      GL_COLOR_ATTACHMENT0_EXT,
+			      GL_TEXTURE_2D,
+			      pixmap_priv->tex,
+			      0);
+  }
+ 
+  return 0;
+}
+ 
+enum glamor_pixmap_status 
+glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
+{
+  GLenum format, type;
+  int ax;
+
+  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
+					     &format, 
+					     &type, 
+					     &ax)) {
+    glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+    return GLAMOR_UPLOAD_FAILED;
+  }
+  if (glamor_pixmap_upload_prepare(pixmap, ax))
+    return GLAMOR_UPLOAD_FAILED;
+  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
+		      "Uploading pixmap %p  %dx%d depth%d.\n", 
+		      pixmap, 
+		      pixmap->drawable.width, 
+		      pixmap->drawable.height,
+		      pixmap->drawable.depth);
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 0);
+  return GLAMOR_UPLOAD_DONE;
+}
+
+#if 0
+enum glamor_pixmap_status 
+glamor_upload_pixmap_to_texure_from_data(PixmapPtr pixmap, void *data)
+{
+  enum glamor_pixmap_status upload_status;
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+  assert(pixmap_priv->pbo_valid == 0);
+  assert(pixmap->devPrivate.ptr == NULL);
+  pixmap->devPrivate.ptr = data;
+  upload_status = glamor_upload_pixmap_to_texture(pixmap);
+  pixmap->devPrivate.ptr = NULL;
+  return upload_status;
+}
+#endif
+
+void
+glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
+{
+  GLenum format, type;
+  int ax;
+
+  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
+					     &format, 
+					     &type, 
+					     &ax)) {
+    ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+    assert(0);
+  }
+  _glamor_upload_pixmap_to_texture(pixmap, format, type, ax, 1);
+}
+
+
+/**
+ * Move a pixmap to CPU memory.
+ * The input data is the pixmap's fbo.
+ * The output data is at pixmap->devPrivate.ptr. We always use pbo 
+ * to read the fbo and then map it to va. If possible, we will use
+ * it directly as devPrivate.ptr.
+ * If successfully download a fbo to cpu then return TRUE.
+ * Otherwise return FALSE.
+ **/
+
+Bool 
+glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
+{
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+  unsigned int stride, row_length, y;
+  GLenum format, type, gl_access, gl_usage;
+  int ax;
+  uint8_t *data, *read;
+  glamor_screen_private *glamor_priv =
+    glamor_get_screen_private(pixmap->drawable.pScreen);
+
+
+  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+    return TRUE;
+
+  if (glamor_get_tex_format_type_from_pixmap(pixmap, 
+					     &format,
+					     &type, 
+					     &ax)) {
+    ErrorF("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+    assert(0);  // Should never happen.
+    return FALSE;
+  }
+
+  pixmap_priv->access_mode = access;
+
+  switch (access) {
+  case GLAMOR_ACCESS_RO:
+    gl_access = GL_READ_ONLY_ARB;
+    gl_usage = GL_STREAM_READ_ARB;
+    break;
+  case GLAMOR_ACCESS_WO:
+    gl_access = GL_WRITE_ONLY_ARB;
+    gl_usage = GL_STREAM_DRAW_ARB;
+    break;
+  case GLAMOR_ACCESS_RW:
+    gl_access = GL_READ_WRITE_ARB;
+    gl_usage = GL_DYNAMIC_DRAW_ARB;
+    break;
+  default:
+    ErrorF("Glamor: Invalid access code. %d\n", access);
+    assert(0);
+  }
+
+  glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+		      "Downloading pixmap %p  %dx%d depth%d\n", 
+		      pixmap, 
+		      pixmap->drawable.width, 
+		      pixmap->drawable.height,
+		      pixmap->drawable.depth);
+ 
+  stride = pixmap->devKind;
+  row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+  glPixelStorei(GL_PACK_ALIGNMENT, 1);
+  glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+
+  if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
+
+    if (!glamor_priv->yInverted) 
+      glPixelStorei(GL_PACK_INVERT_MESA, 1);
+    if (pixmap_priv->pbo == 0)
+      glGenBuffersARB (1, &pixmap_priv->pbo);
+    glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+    glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT,
+		     stride * pixmap->drawable.height,
+		     NULL, gl_usage);
+    if (access != GLAMOR_ACCESS_WO)
+      glReadPixels (0, 0,
+                    row_length, pixmap->drawable.height,
+                    format, type, 0);
+    data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, gl_access);
+    pixmap_priv->pbo_valid = TRUE;
+
+    if (!glamor_priv->yInverted) 
+      glPixelStorei(GL_PACK_INVERT_MESA, 0);
+
+  } else {
+    data = malloc(stride * pixmap->drawable.height);
+    assert(data);
+    if (access != GLAMOR_ACCESS_WO) {
+      if (pixmap_priv->pbo == 0)
+	glGenBuffersARB(1, &pixmap_priv->pbo);
+      glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+      glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
+		      stride * pixmap->drawable.height,
+		      NULL, GL_STREAM_READ_ARB);
+      glReadPixels (0, 0, row_length, pixmap->drawable.height,
+		    format, type, 0);
+      read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB);
+	  
+      for (y = 0; y < pixmap->drawable.height; y++)
+	memcpy(data + y * stride,
+	       read + (pixmap->drawable.height - y - 1) * stride, stride);
+      glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
+      glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
+      pixmap_priv->pbo_valid = FALSE;
+      glDeleteBuffersARB(1, &pixmap_priv->pbo);
+      pixmap_priv->pbo = 0;
+    }
+  }
+
+  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+  pixmap->devPrivate.ptr = data;
+  return TRUE;
+}
+
+
+
+static void 
+_glamor_destroy_upload_pixmap(PixmapPtr pixmap)
+{
+  glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+  assert(pixmap_priv->gl_fbo == 0);
+  if (pixmap_priv->fb)
+    glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
+  if (pixmap_priv->tex)
+    glDeleteTextures(1, &pixmap_priv->tex);
+  if (pixmap_priv->pbo)
+    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+  pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
+
+}
+
+void glamor_destroy_upload_pixmap(PixmapPtr pixmap)
+{
+  _glamor_destroy_upload_pixmap(pixmap);
+}
+
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 660dc4a..218c308 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -50,9 +50,9 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     int off_x, off_y;
     RegionPtr pClip = fbGetCompositeClip(gc);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
-    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
+    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) {
 	goto fail;
+    }
 
     xorg = drawable->x;
     yorg = drawable->y;
@@ -101,9 +101,8 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     return;
 
 fail:
-    glamor_fallback("glamor_poly_fill_rect() to %p (%c)\n",
+    glamor_fallback(" to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
-
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	if (glamor_prepare_access_gc(gc)) {
 	    fbPolyFillRect(drawable, gc, nrect, prect );
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 75bc9bf..9149611 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -49,18 +49,17 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     xRectangle *rects;
     int x1, x2, y1, y2;
     int i;
-
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0) {
 	/* This ends up in miSetSpans, which is accelerated as well as we
 	 * can hope X wide lines will be.
 	 */
-	/*glamor_fallback("glamor_poly_lines(): wide lines\n");*/
 	goto fail;
     }
     if (gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	glamor_fallback("glamor_poly_lines(): non-solid fill\n");
+	glamor_fallback("non-solid fill line style %d, fill style %d\n",
+                         gc->lineStyle, gc->fillStyle);
 	goto fail;
     }
 
@@ -77,11 +76,9 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	    y2 = points[i + 1].y;
 	}
 	if (x1 != x2 && y1 != y2) {
-	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 	    free(rects);
 	    glamor_fallback("stub diagonal poly_line\n");
 	    goto fail;
-	    return;
 	}
 	if (x1 < x2) {
 	    rects[i].x = x1;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1dc2c42..cf293b5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -39,6 +39,7 @@
 #include "glyphstr.h"
 #endif
 
+
 #ifndef MAX_WIDTH
 #define MAX_WIDTH 4096
 #endif
@@ -47,169 +48,222 @@
 #define MAX_HEIGHT 4096
 #endif
 
-typedef enum glamor_access {
-    GLAMOR_ACCESS_RO,
-    GLAMOR_ACCESS_RW,
-} glamor_access_t;
+#include "glamor_debug.h"
+
+#define glamor_check_fbo_width_height(_w_, _h_)    (_w_ > 0 && _h_ > 0	\
+                                                    && _w_ < MAX_WIDTH	\
+                                                    && _h_ < MAX_HEIGHT)
+
+#define glamor_check_fbo_depth(_depth_) (			\
+                                         _depth_ == 8		\
+	                                 || _depth_ == 15	\
+                                         || _depth_ == 16	\
+                                         || _depth_ == 24	\
+                                         || _depth_ == 30	\
+                                         || _depth_ == 32)
+
+
+#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv->is_picture == 1)
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == 1)
 
 typedef struct glamor_transform_uniforms {
-    GLint x_bias;
-    GLint x_scale;
-    GLint y_bias;
-    GLint y_scale;
+  GLint x_bias;
+  GLint x_scale;
+  GLint y_bias;
+  GLint y_scale;
 } glamor_transform_uniforms;
 
 typedef struct glamor_composite_shader {
-    GLuint prog;
-    GLint dest_to_dest_uniform_location;
-    GLint dest_to_source_uniform_location;
-    GLint dest_to_mask_uniform_location;
-    GLint source_uniform_location;
-    GLint mask_uniform_location;
+  GLuint prog;
+  GLint dest_to_dest_uniform_location;
+  GLint dest_to_source_uniform_location;
+  GLint dest_to_mask_uniform_location;
+  GLint source_uniform_location;
+  GLint mask_uniform_location;
 } glamor_composite_shader;
 
 typedef struct {
-    INT16 x_src;
-    INT16 y_src;
-    INT16 x_mask;
-    INT16 y_mask;
-    INT16 x_dst;
-    INT16 y_dst;
-    INT16 width;
-    INT16 height;
+  INT16 x_src;
+  INT16 y_src;
+  INT16 x_mask;
+  INT16 y_mask;
+  INT16 x_dst;
+  INT16 y_dst;
+  INT16 width;
+  INT16 height;
 } glamor_composite_rect_t;
 
 typedef struct {
-    unsigned char sha1[20];
+  unsigned char sha1[20];
 } glamor_cached_glyph_t;
 
 typedef struct {
-    /* The identity of the cache, statically configured at initialization */
-    unsigned int format;
-    int glyph_width;
-    int glyph_height;
-
-    /* Size of cache; eventually this should be dynamically determined */
-    int size;
-
-    /* Hash table mapping from glyph sha1 to position in the glyph; we use
-     * open addressing with a hash table size determined based on size and large
-     * enough so that we always have a good amount of free space, so we can
-     * use linear probing. (Linear probing is preferrable to double hashing
-     * here because it allows us to easily remove entries.)
-     */
-    int *hash_entries;
-    int hash_size;
-
-    glamor_cached_glyph_t *glyphs;
-    int glyph_count;		/* Current number of glyphs */
-
-    PicturePtr picture;	/* Where the glyphs of the cache are stored */
-    int y_offset;		/* y location within the picture where the cache starts */
-    int columns;		/* Number of columns the glyphs are layed out in */
-    int eviction_position;	/* Next random position to evict a glyph */
+  /* The identity of the cache, statically configured at initialization */
+  unsigned int format;
+  int glyph_width;
+  int glyph_height;
+
+  /* Size of cache; eventually this should be dynamically determined */
+  int size;
+
+  /* Hash table mapping from glyph sha1 to position in the glyph; we use
+   * open addressing with a hash table size determined based on size and large
+   * enough so that we always have a good amount of free space, so we can
+   * use linear probing. (Linear probing is preferrable to double hashing
+   * here because it allows us to easily remove entries.)
+   */
+  int *hash_entries;
+  int hash_size;
+
+  glamor_cached_glyph_t *glyphs;
+  int glyph_count;		/* Current number of glyphs */
+
+  PicturePtr picture;	/* Where the glyphs of the cache are stored */
+  int y_offset;		/* y location within the picture where the cache starts */
+  int columns;		/* Number of columns the glyphs are layed out in */
+  int eviction_position;	/* Next random position to evict a glyph */
 } glamor_glyph_cache_t;
 
 #define GLAMOR_NUM_GLYPH_CACHES 4
 
 enum shader_source {
-    SHADER_SOURCE_SOLID,
-    SHADER_SOURCE_TEXTURE,
-    SHADER_SOURCE_TEXTURE_ALPHA,
-    SHADER_SOURCE_COUNT,
+  SHADER_SOURCE_SOLID,
+  SHADER_SOURCE_TEXTURE,
+  SHADER_SOURCE_TEXTURE_ALPHA,
+  SHADER_SOURCE_COUNT,
 };
 
 enum shader_mask {
-    SHADER_MASK_NONE,
-    SHADER_MASK_SOLID,
-    SHADER_MASK_TEXTURE,
-    SHADER_MASK_TEXTURE_ALPHA,
-    SHADER_MASK_COUNT,
+  SHADER_MASK_NONE,
+  SHADER_MASK_SOLID,
+  SHADER_MASK_TEXTURE,
+  SHADER_MASK_TEXTURE_ALPHA,
+  SHADER_MASK_COUNT,
 };
 
 enum shader_in {
-    SHADER_IN_SOURCE_ONLY,
-    SHADER_IN_NORMAL,
-    SHADER_IN_CA_SOURCE,
-    SHADER_IN_CA_ALPHA,
-    SHADER_IN_COUNT,
+  SHADER_IN_SOURCE_ONLY,
+  SHADER_IN_NORMAL,
+  SHADER_IN_CA_SOURCE,
+  SHADER_IN_CA_ALPHA,
+  SHADER_IN_COUNT,
 };
 
 typedef struct glamor_screen_private {
-    CloseScreenProcPtr saved_close_screen;
-    CreateGCProcPtr saved_create_gc;
-    CreatePixmapProcPtr saved_create_pixmap;
-    DestroyPixmapProcPtr saved_destroy_pixmap;
-    GetSpansProcPtr saved_get_spans;
-    GetImageProcPtr saved_get_image;
-    CompositeProcPtr saved_composite;
-    TrapezoidsProcPtr saved_trapezoids;
-    GlyphsProcPtr saved_glyphs;
-    ChangeWindowAttributesProcPtr saved_change_window_attributes;
-    CopyWindowProcPtr saved_copy_window;
-    BitmapToRegionProcPtr saved_bitmap_to_region;
-    TrianglesProcPtr saved_triangles;
-
-    char *delayed_fallback_string;
-    int yInverted;
-    GLuint vbo;
-    int vbo_offset;
-    int vbo_size;
-    char *vb;
-    int vb_stride;
-
-    /* glamor_finishaccess */
-    GLint finish_access_prog;
-    GLint aswizzle_prog;
-
-    /* glamor_solid */
-    GLint solid_prog;
-    GLint solid_color_uniform_location;
-
-    /* glamor_tile */
-    GLint tile_prog;
-
-    /* glamor_putimage */
-    GLint put_image_xybitmap_prog;
-    glamor_transform_uniforms put_image_xybitmap_transform;
-    GLint put_image_xybitmap_fg_uniform_location;
-    GLint put_image_xybitmap_bg_uniform_location;
-
-    /* glamor_composite */
-    glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
-					    [SHADER_MASK_COUNT]
-					    [SHADER_IN_COUNT];
-    Bool has_source_coords, has_mask_coords;
-    int render_nr_verts;
-
-    glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
+  CloseScreenProcPtr saved_close_screen;
+  CreateGCProcPtr saved_create_gc;
+  CreatePixmapProcPtr saved_create_pixmap;
+  DestroyPixmapProcPtr saved_destroy_pixmap;
+  GetSpansProcPtr saved_get_spans;
+  GetImageProcPtr saved_get_image;
+  CompositeProcPtr saved_composite;
+  TrapezoidsProcPtr saved_trapezoids;
+  GlyphsProcPtr saved_glyphs;
+  ChangeWindowAttributesProcPtr saved_change_window_attributes;
+  CopyWindowProcPtr saved_copy_window;
+  BitmapToRegionProcPtr saved_bitmap_to_region;
+  TrianglesProcPtr saved_triangles;
+  CreatePictureProcPtr saved_create_picture;
+  DestroyPictureProcPtr saved_destroy_picture;
+
+  int yInverted;
+  int screen_fbo;
+  GLuint vbo;
+  int vbo_offset;
+  int vbo_size;
+  char *vb;
+  int vb_stride;
+
+  /* glamor_finishaccess */
+  GLint finish_access_prog[2];
+
+  /* glamor_solid */
+  GLint solid_prog;
+  GLint solid_color_uniform_location;
+
+  /* glamor_tile */
+  GLint tile_prog;
+
+  /* glamor_putimage */
+  GLint put_image_xybitmap_prog;
+  glamor_transform_uniforms put_image_xybitmap_transform;
+  GLint put_image_xybitmap_fg_uniform_location;
+  GLint put_image_xybitmap_bg_uniform_location;
+
+  /* glamor_composite */
+  glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+  [SHADER_MASK_COUNT]
+  [SHADER_IN_COUNT];
+  Bool has_source_coords, has_mask_coords;
+  int render_nr_verts;
+
+  glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
+  char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
+  int  delayed_fallback_pending;
 } glamor_screen_private;
 
-enum glamor_pixmap_type {
-  GLAMOR_GL,
-  GLAMOR_FB
-};
+typedef enum glamor_access {
+  GLAMOR_ACCESS_RO,
+  GLAMOR_ACCESS_RW,
+  GLAMOR_ACCESS_WO,
+} glamor_access_t;
+
+/*
+ * glamor_pixmap_private - glamor pixmap's private structure.
+ * @gl_fbo:  The pixmap is attached to a fbo originally.
+ * @gl_tex:  The pixmap is in a gl texture originally.
+ * @pbo_valid: The pbo has a valid copy of the pixmap's data.
+ * @is_picture: The drawable is attached to a picture.
+ * @tex:     attached texture.
+ * @fb:      attached fbo.
+ * @pbo:     attached pbo.
+ * @access_mode: access mode during the prepare/finish pair.
+ * @pict_format: the corresponding picture's format.
+ * @container: The corresponding pixmap's pointer.
+ **/
 
 typedef struct glamor_pixmap_private {
-    GLuint tex;
-    GLuint fb;
-    GLuint pbo;
-    enum   glamor_pixmap_type type;
-    glamor_access_t access_mode;
+  unsigned char gl_fbo:1;
+  unsigned char gl_tex:1;
+  unsigned char pbo_valid:1;
+  unsigned char is_picture:1;
+  GLuint tex;			
+  GLuint fb;
+  GLuint pbo;                
+  glamor_access_t access_mode;
+  PictFormatShort pict_format;
+  PixmapPtr container;
 } glamor_pixmap_private;
 
+/* 
+ * Pixmap dynamic status, used by dynamic upload feature.
+ *
+ * GLAMOR_NONE:  initial status, don't need to do anything.
+ * GLAMOR_UPLOAD_PENDING: marked as need to be uploaded to gl texture.
+ * GLAMOR_UPLOAD_DONE: the pixmap has been uploaded successfully.
+ * GLAMOR_UPLOAD_FAILED: fail to upload the pixmap.
+ *
+ * */
+typedef enum glamor_pixmap_status {
+  GLAMOR_NONE,
+  GLAMOR_UPLOAD_PENDING,
+  GLAMOR_UPLOAD_DONE,
+  GLAMOR_UPLOAD_FAILED
+} glamor_pixmap_status_t; 
+
+
 extern DevPrivateKey glamor_screen_private_key;
 extern DevPrivateKey glamor_pixmap_private_key;
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
 {
-    return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
-						     glamor_screen_private_key);
+  return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
+						   glamor_screen_private_key);
 }
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
-    return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+  return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
 }
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -217,97 +271,275 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 
 /**
- * Returns TRUE if the given planemask covers all the significant bits in the
- * pixel values for pDrawable.
+ * Borrow from uxa.
  */
-static inline Bool
-glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
+static inline CARD32
+format_for_depth(int depth)
 {
-    return (planemask & FbFullMask(drawable->depth)) ==
-	FbFullMask(drawable->depth);
+  switch (depth) {
+  case 1: return PICT_a1;
+  case 4: return PICT_a4;
+  case 8: return PICT_a8;
+  case 15: return PICT_x1r5g5b5;
+  case 16: return PICT_r5g6b5;
+  default:
+  case 24: return PICT_x8r8g8b8;
+#if XORG_VERSION_CURRENT >= 10699900
+  case 30: return PICT_x2r10g10b10;
+#endif
+  case 32: return PICT_a8r8g8b8;
+  }
 }
 
-static inline void
-glamor_fallback(char *format, ...)
+static inline CARD32
+format_for_pixmap(PixmapPtr pixmap)
 {
-    va_list ap;
+  glamor_pixmap_private *pixmap_priv;
+  PictFormatShort pict_format;
 
-    va_start(ap, format);
-    //LogMessageVerb(X_INFO, 3, "fallback: ");
-    //LogMessageVerb(X_NONE, 3, format, ap);
-    va_end(ap);
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+    pict_format = pixmap_priv->pict_format;
+  else
+    pict_format = format_for_depth(pixmap->drawable.depth);
+
+  return pict_format;
 }
 
-static inline void
-glamor_delayed_fallback(ScreenPtr screen, char *format, ...)
+/*
+ * Map picture's format to the correct gl texture format and type.
+ * xa is used to indicate whehter we need to wire alpha to 1. 
+ *
+ * Return 0 if find a matched texture type. Otherwise return -1.
+ **/
+static inline int 
+glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
+					   GLenum *tex_format, 
+					   GLenum *tex_type,
+					   int *xa)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    va_list ap;
-
-    if (glamor_priv->delayed_fallback_string != NULL)
-	return;
-
-    va_start(ap, format);
-    XNFvasprintf(&glamor_priv->delayed_fallback_string, format, ap);
-    va_end(ap);
+  *xa = 0;
+  switch (format) {
+  case PICT_a1:
+    *tex_format = GL_COLOR_INDEX;
+    *tex_type = GL_BITMAP;
+    break;
+  case PICT_b8g8r8x8:
+    *xa = 1;
+  case PICT_b8g8r8a8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+    break;
+
+  case PICT_x8r8g8b8:
+    *xa = 1;
+  case PICT_a8r8g8b8:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    break;
+  case PICT_x8b8g8r8:
+    *xa = 1;
+  case PICT_a8b8g8r8:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+    break;
+  case PICT_x2r10g10b10:
+    *xa = 1;
+  case PICT_a2r10g10b10:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+    break;
+  case PICT_x2b10g10r10:
+    *xa = 1;
+  case PICT_a2b10g10r10:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+    break;
+ 
+  case PICT_r5g6b5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+    break;
+  case PICT_b5g6r5:
+    *tex_format = GL_RGB;
+    *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+    break;
+  case PICT_x1b5g5r5:
+    *xa = 1;
+  case PICT_a1b5g5r5:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    break;
+               
+  case PICT_x1r5g5b5:
+    *xa = 1;
+  case PICT_a1r5g5b5:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+    break;
+  case PICT_a8:
+    *tex_format = GL_ALPHA;
+    *tex_type = GL_UNSIGNED_BYTE;
+    break;
+  case PICT_x4r4g4b4:
+    *xa = 1;
+  case PICT_a4r4g4b4:
+    *tex_format = GL_BGRA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    break;
+
+  case PICT_x4b4g4r4:
+    *xa = 1;
+  case PICT_a4b4g4r4:
+    *tex_format = GL_RGBA;
+    *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+    break;
+ 
+  default:
+    LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
+    return -1;
+  }
+  return 0;
 }
 
-static inline void
-glamor_clear_delayed_fallbacks(ScreenPtr screen)
+
+static inline int 
+glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
+                                       GLenum *format, 
+                                       GLenum *type, 
+                                       int *ax)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_pixmap_private *pixmap_priv;
+  PictFormatShort pict_format;
 
-    free(glamor_priv->delayed_fallback_string);
-    glamor_priv->delayed_fallback_string = NULL;
+  pixmap_priv = glamor_get_pixmap_private(pixmap);
+  if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
+    pict_format = pixmap_priv->pict_format;
+  else
+    pict_format = format_for_depth(pixmap->drawable.depth);
+
+  return glamor_get_tex_format_type_from_pictformat(pict_format, 
+						    format, type, ax);  
 }
 
-static inline void
-glamor_report_delayed_fallbacks(ScreenPtr screen)
+
+/* borrowed from uxa */
+static inline Bool
+glamor_get_rgba_from_pixel(CARD32 pixel,
+			   float * red,
+			   float * green,
+			   float * blue,
+			   float * alpha,
+			   CARD32 format)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  int rbits, bbits, gbits, abits;
+  int rshift, bshift, gshift, ashift;
+
+  rbits = PICT_FORMAT_R(format);
+  gbits = PICT_FORMAT_G(format);
+  bbits = PICT_FORMAT_B(format);
+  abits = PICT_FORMAT_A(format);
+
+  if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
+    rshift = gshift = bshift = ashift = 0;
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+    bshift = 0;
+    gshift = bbits;
+    rshift = gshift + gbits;
+    ashift = rshift + rbits;
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+    rshift = 0;
+    gshift = rbits;
+    bshift = gshift + gbits;
+    ashift = bshift + bbits;
+#if XORG_VERSION_CURRENT >= 10699900
+  } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+    ashift = 0;
+    rshift = abits;
+    if (abits == 0)
+      rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
+    gshift = rshift + rbits;
+    bshift = gshift + gbits;
+#endif
+  } else {
+    return FALSE;
+  }
+#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
+  *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
+    / (float)((1<<(_bits_)) - 1) 
+
+  if (rbits) 
+    COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
+  else
+    *red = 0;
+
+  if (gbits) 
+    COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
+  else
+    *green = 0;
+
+  if (bbits) 
+    COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
+  else
+    *blue = 0;
+
+  if (abits) 
+    COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
+  else
+    *alpha = 1;
+
+  return TRUE;
+}
+
 
-    if (glamor_priv->delayed_fallback_string) {
-      	//LogMessageVerb(X_INFO, 3, "fallback: %s",
-      	//       glamor_priv->delayed_fallback_string);
-	glamor_clear_delayed_fallbacks(screen);
-    }
+/**
+ * Returns TRUE if the given planemask covers all the significant bits in the
+ * pixel values for pDrawable.
+ */
+static inline Bool
+glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
+{
+  return (planemask & FbFullMask(drawable->depth)) ==
+    FbFullMask(drawable->depth);
 }
 
+extern int glamor_debug_level;
+
 static inline float
 v_from_x_coord_x(PixmapPtr pixmap, int x)
 {
-    return (float)x / pixmap->drawable.width * 2.0 - 1.0;
+  return (float)x / pixmap->drawable.width * 2.0 - 1.0;
 }
 
 static inline float
 v_from_x_coord_y(PixmapPtr pixmap, int y)
 {
-    return (float)y / pixmap->drawable.height * -2.0 + 1.0;
+  return (float)y / pixmap->drawable.height * -2.0 + 1.0;
 }
 
 static inline float
 v_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
 {
-    return (float)y / pixmap->drawable.height * 2.0 - 1.0;
+  return (float)y / pixmap->drawable.height * 2.0 - 1.0;
 }
 
 
 static inline float
 t_from_x_coord_x(PixmapPtr pixmap, int x)
 {
-    return (float)x / pixmap->drawable.width;
+  return (float)x / pixmap->drawable.width;
 }
 
 static inline float
 t_from_x_coord_y(PixmapPtr pixmap, int y)
 {
-    return 1.0 - (float)y / pixmap->drawable.height;
+  return 1.0 - (float)y / pixmap->drawable.height;
 }
 
 static inline float
 t_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
 {
-    return (float)y / pixmap->drawable.height;
+  return (float)y / pixmap->drawable.height;
 }
 
 
@@ -359,7 +591,15 @@ GLint glamor_compile_glsl_prog(GLenum type, const char *source);
 void glamor_link_glsl_prog(GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 				    GLfloat *color);
-Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
+
+int glamor_set_destination_pixmap(PixmapPtr pixmap);
+int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
+
+/* nc means no check. caller must ensure this pixmap has valid fbo.
+ * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly. 
+ * */
+void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
+
 void glamor_set_alu(unsigned char alu);
 Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 void glamor_get_transform_uniform_locations(GLint prog,
@@ -462,15 +702,93 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 int tile_x, int tile_y);
 void glamor_init_tile_shader(ScreenPtr screen);
 
-/* glamor_triangles */
+/* glamor_triangles.c */
 void
 glamor_triangles (CARD8	    op,
-	     PicturePtr    pSrc,
-	     PicturePtr    pDst,
-	     PictFormatPtr maskFormat,
-	     INT16	    xSrc,
-	     INT16	    ySrc,
-	     int	    ntris,
-	     xTriangle    *tris);
+		  PicturePtr    pSrc,
+		  PicturePtr    pDst,
+		  PictFormatPtr maskFormat,
+		  INT16	    xSrc,
+		  INT16	    ySrc,
+		  int	    ntris,
+		  xTriangle    *tris);
+
+/* glamor_pixmap.c */
+
+/** 
+ * Download a pixmap's texture to cpu memory. If success,
+ * One copy of current pixmap's texture will be put into
+ * the pixmap->devPrivate.ptr. Will use pbo to map to 
+ * the pointer if possible.
+ * The pixmap must be a gl texture pixmap. gl_fbo and
+ * gl_tex must be 1. Used by glamor_prepare_access.
+ *
+ */
+Bool 
+glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
+
+/**
+ * Restore a pixmap's data which is downloaded by 
+ * glamor_download_pixmap_to_cpu to its original 
+ * gl texture. Used by glamor_finish_access. 
+ *
+ * The pixmap must be
+ * in texture originally. In other word, the gl_fbo
+ * must be 1.
+ **/
+void
+glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
+
+/**
+ * Upload a pixmap to gl texture. Used by dynamic pixmap
+ * uploading feature. The pixmap must be a software pixmap.
+ * This function will change current FBO and current shaders.
+ */
+enum glamor_pixmap_status 
+glamor_upload_pixmap_to_texture(PixmapPtr pixmap);
+
+/** 
+ * Upload a picture to gl texture. Similar to the
+ * glamor_upload_pixmap_to_texture. Used in rendering.
+ **/
+enum glamor_pixmap_status 
+glamor_upload_picture_to_texture(PicturePtr picture);
+
+/**
+ * Destroy all the resources allocated on the uploading
+ * phase, includs the tex and fbo.
+ **/
+void
+glamor_destroy_upload_pixmap(PixmapPtr pixmap);
+
+
+
+int
+glamor_create_picture(PicturePtr picture);
+
+Bool
+glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
+
+void
+glamor_finish_access_picture(PicturePtr picture);
+
+void
+glamor_destroy_picture(PicturePtr picture);
+
+enum glamor_pixmap_status 
+glamor_upload_picture_to_texture(PicturePtr picture);
+
+void 
+glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv);
+
+/* Dynamic pixmap upload to texture if needed. 
+ * Sometimes, the target is a gl texture pixmap/picture,
+ * but the source or mask is in cpu memory. In that case,
+ * upload the source/mask to gl texture and then avoid 
+ * fallback the whole process to cpu. Most of the time,
+ * this will increase performance obviously. */
+
+
+#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD 
 
 #endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index f1081b0..d056576 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -132,6 +132,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	0.0, 1.0,
     };
 
+
     dest_coords[0][0] = v_from_x_coord_x(pixmap, x);
     dest_coords[0][1] = v_from_x_coord_y(pixmap, y);
     dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w);
@@ -226,13 +227,11 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     return;
-
-fail:
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
-
-    glamor_fallback("glamor_put_image(): to %p (%c)\n",
+    glamor_fallback(": to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
+fail:
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits);
 	glamor_finish_access(drawable);
@@ -251,12 +250,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     RegionPtr clip;
     BoxPtr pbox;
     int nbox;
-    int bpp = drawable->bitsPerPixel;
     int src_stride = PixmapBytePad(w, drawable->depth);
     int x_off, y_off;
     float vertices[4][2], texcoords[4][2];
     GLuint tex;
-    int alfa_mode = 0;
+    int ax = 0;
     if (image_format == XYBitmap) {
 	assert(depth == 1);
 	glamor_put_image_xybitmap(drawable, gc, x, y, w, h,
@@ -264,56 +262,32 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	return;
     }
 
-    if (pixmap_priv == NULL) {
-	glamor_fallback("glamor_put_image: system memory pixmap\n");
-	goto fail;
-    }
-
-    if (pixmap_priv->fb == 0) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
-	if (pixmap != screen_pixmap) {
-	    glamor_fallback("glamor_put_image: no fbo\n");
-	    goto fail;
-	}
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
+	glamor_fallback("has no fbo.\n");
+        goto fail;
     }
 
-    if (bpp == 1 && image_format == XYPixmap)
-	image_format = ZPixmap;
-
     if (image_format != ZPixmap) {
-	glamor_fallback("glamor_put_image: non-ZPixmap\n");
+	glamor_fallback("non-ZPixmap\n");
 	goto fail;
     }
 
-    switch (drawable->depth) {
-    case 1:
-	format = GL_COLOR_INDEX;
-	type = GL_BITMAP;
-	break;
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-	assert(drawable->bitsPerPixel == 32);
-	/* FALLTHROUGH */
-        alfa_mode = 1;
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	glamor_fallback("glamor_putimage: bad depth %d\n", drawable->depth);
+    if (!glamor_set_planemask(pixmap, gc->planemask)) {
 	goto fail;
     }
-
-    if (!glamor_set_planemask(pixmap, gc->planemask))
-	goto fail;
-
     glamor_set_alu(gc->alu);
 
+    if (glamor_get_tex_format_type_from_pixmap(pixmap,
+                                               &format, 
+                                               &type, 
+                                               &ax
+                                               )) {
+      glamor_fallback("unknown depth. %d \n", 
+                     drawable->depth);
+      goto fail;
+    }
+
+    /* XXX consider to reuse a function to do the following work. */
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
@@ -321,15 +295,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
+    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
-    if (bpp == 1)
-	glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
 
+    
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
@@ -341,10 +313,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glEnable(GL_TEXTURE_2D);
 
     assert(GLEW_ARB_fragment_shader);
-    if (alfa_mode == 0)
-      glUseProgramObjectARB(glamor_priv->finish_access_prog);
-    else
-      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
+    glUseProgramObjectARB(glamor_priv->finish_access_prog[ax]);
 
     x += drawable->x;
     y += drawable->y;
@@ -425,7 +394,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 fail:
     glamor_set_planemask(pixmap, ~0);
-    glamor_fallback("glamor_put_image(): to %p (%c)\n",
+    glamor_fallback("to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e69d370..ca27b4d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -39,251 +39,251 @@
 #include "glu3/glu3.h"
 
 struct shader_key {
-    enum shader_source source;
-    enum shader_mask mask;
-    enum shader_in in;
+  enum shader_source source;
+  enum shader_mask mask;
+  enum shader_in in;
 };
 
 struct blendinfo {
-    Bool dest_alpha;
-    Bool source_alpha;
-    GLenum source_blend;
-    GLenum dest_blend;
+  Bool dest_alpha;
+  Bool source_alpha;
+  GLenum source_blend;
+  GLenum dest_blend;
 };
 
 static struct blendinfo composite_op_info[] = {
-    [PictOpClear] =       {0, 0, GL_ZERO,                GL_ZERO},
-    [PictOpSrc] =         {0, 0, GL_ONE,                 GL_ZERO},
-    [PictOpDst] =         {0, 0, GL_ZERO,                GL_ONE},
-    [PictOpOver] =        {0, 1, GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA},
-    [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
-    [PictOpIn] =          {1, 0, GL_DST_ALPHA,           GL_ZERO},
-    [PictOpInReverse] =   {0, 1, GL_ZERO,                GL_SRC_ALPHA},
-    [PictOpOut] =         {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
-    [PictOpOutReverse] =  {0, 1, GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA},
-    [PictOpAtop] =        {1, 1, GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA},
-    [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
-    [PictOpXor] =         {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
-    [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
+  [PictOpClear] =       {0, 0, GL_ZERO,                GL_ZERO},
+  [PictOpSrc] =         {0, 0, GL_ONE,                 GL_ZERO},
+  [PictOpDst] =         {0, 0, GL_ZERO,                GL_ONE},
+  [PictOpOver] =        {0, 1, GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA},
+  [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+  [PictOpIn] =          {1, 0, GL_DST_ALPHA,           GL_ZERO},
+  [PictOpInReverse] =   {0, 1, GL_ZERO,                GL_SRC_ALPHA},
+  [PictOpOut] =         {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+  [PictOpOutReverse] =  {0, 1, GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA},
+  [PictOpAtop] =        {1, 1, GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA},
+  [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+  [PictOpXor] =         {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+  [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
 };
 
 static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
-    const char *source_solid_fetch =
-	"uniform vec4 source;\n"
-	"vec4 get_source()\n"
-	"{\n"
-	"	return source;\n"
-	"}\n";
-    const char *source_alpha_pixmap_fetch =
-	"uniform sampler2D source_sampler;\n"
-	"vec4 get_source()\n"
-	"{\n"
-	"	return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
-	"}\n";
-    const char *source_pixmap_fetch =
-	"uniform sampler2D source_sampler;\n"
-	"vec4 get_source()\n"
-	"{\n"
-        "       return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
-	"}\n";
-    const char *mask_solid_fetch =
-	"uniform vec4 mask;\n"
-	"vec4 get_mask()\n"
-	"{\n"
-	"	return mask;\n"
-	"}\n";
-    const char *mask_alpha_pixmap_fetch =
-	"uniform sampler2D mask_sampler;\n"
-	"vec4 get_mask()\n"
-	"{\n"
-	"	return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
-	"}\n";
-    const char *mask_pixmap_fetch =
-	"uniform sampler2D mask_sampler;\n"
-	"vec4 get_mask()\n"
-	"{\n"
-        "       return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
-	"}\n";
-    const char *in_source_only =
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = get_source();\n"
-	"}\n";
-    const char *in_normal =
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = get_source() * get_mask().a;\n"
-	"}\n";
-    const char *in_ca_source =
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = get_source() * get_mask();\n"
-	"}\n";
-    const char *in_ca_alpha =
-	"void main()\n"
-	"{\n"
-	"	gl_FragColor = get_source().a * get_mask();\n"
-	"}\n";
-    char *source;
-    const char *source_fetch;
-    const char *mask_fetch = "";
-    const char *in;
-    GLuint prog;
-
-    switch (key->source) {
-    case SHADER_SOURCE_SOLID:
-	source_fetch = source_solid_fetch;
-	break;
-    case SHADER_SOURCE_TEXTURE_ALPHA:
-	source_fetch = source_alpha_pixmap_fetch;
-	break;
-    case SHADER_SOURCE_TEXTURE:
-	source_fetch = source_pixmap_fetch;
-	break;
-    default:
-	FatalError("Bad composite shader source");
-    }
-
-    switch (key->mask) {
-    case SHADER_MASK_NONE:
-	break;
-    case SHADER_MASK_SOLID:
-	mask_fetch = mask_solid_fetch;
-	break;
-    case SHADER_MASK_TEXTURE_ALPHA:
-	mask_fetch = mask_alpha_pixmap_fetch;
-	break;
-    case SHADER_MASK_TEXTURE:
-	mask_fetch = mask_pixmap_fetch;
-	break;
-    default:
-	FatalError("Bad composite shader mask");
-    }
-
-    switch (key->in) {
-    case SHADER_IN_SOURCE_ONLY:
-	in = in_source_only;
-	break;
-    case SHADER_IN_NORMAL:
-	in = in_normal;
-	break;
-    case SHADER_IN_CA_SOURCE:
-	in = in_ca_source;
-	break;
-    case SHADER_IN_CA_ALPHA:
-	in = in_ca_alpha;
-	break;
-    default:
-	FatalError("Bad composite IN type");
-    }
-
-    XNFasprintf(&source,
-		"%s%s%s",
-		source_fetch,
-		mask_fetch,
-		in);
+  const char *source_solid_fetch =
+    "uniform vec4 source;\n"
+    "vec4 get_source()\n"
+    "{\n"
+    "	return source;\n"
+    "}\n";
+  const char *source_alpha_pixmap_fetch =
+    "uniform sampler2D source_sampler;\n"
+    "vec4 get_source()\n"
+    "{\n"
+    "	return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
+    "}\n";
+  const char *source_pixmap_fetch =
+    "uniform sampler2D source_sampler;\n"
+    "vec4 get_source()\n"
+    "{\n"
+    "       return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb, 1);\n"
+    "}\n";
+  const char *mask_solid_fetch =
+    "uniform vec4 mask;\n"
+    "vec4 get_mask()\n"
+    "{\n"
+    "	return mask;\n"
+    "}\n";
+  const char *mask_alpha_pixmap_fetch =
+    "uniform sampler2D mask_sampler;\n"
+    "vec4 get_mask()\n"
+    "{\n"
+    "	return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
+    "}\n";
+  const char *mask_pixmap_fetch =
+    "uniform sampler2D mask_sampler;\n"
+    "vec4 get_mask()\n"
+    "{\n"
+    "       return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, 1);\n"
+    "}\n";
+  const char *in_source_only =
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = get_source();\n"
+    "}\n";
+  const char *in_normal =
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = get_source() * get_mask().a;\n"
+    "}\n";
+  const char *in_ca_source =
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = get_source() * get_mask();\n"
+    "}\n";
+  const char *in_ca_alpha =
+    "void main()\n"
+    "{\n"
+    "	gl_FragColor = get_source().a * get_mask();\n"
+    "}\n";
+  char *source;
+  const char *source_fetch;
+  const char *mask_fetch = "";
+  const char *in;
+  GLuint prog;
+
+  switch (key->source) {
+  case SHADER_SOURCE_SOLID:
+    source_fetch = source_solid_fetch;
+    break;
+  case SHADER_SOURCE_TEXTURE_ALPHA:
+    source_fetch = source_alpha_pixmap_fetch;
+    break;
+  case SHADER_SOURCE_TEXTURE:
+    source_fetch = source_pixmap_fetch;
+    break;
+  default:
+    FatalError("Bad composite shader source");
+  }
+
+  switch (key->mask) {
+  case SHADER_MASK_NONE:
+    break;
+  case SHADER_MASK_SOLID:
+    mask_fetch = mask_solid_fetch;
+    break;
+  case SHADER_MASK_TEXTURE_ALPHA:
+    mask_fetch = mask_alpha_pixmap_fetch;
+    break;
+  case SHADER_MASK_TEXTURE:
+    mask_fetch = mask_pixmap_fetch;
+    break;
+  default:
+    FatalError("Bad composite shader mask");
+  }
+
+  switch (key->in) {
+  case SHADER_IN_SOURCE_ONLY:
+    in = in_source_only;
+    break;
+  case SHADER_IN_NORMAL:
+    in = in_normal;
+    break;
+  case SHADER_IN_CA_SOURCE:
+    in = in_ca_source;
+    break;
+  case SHADER_IN_CA_ALPHA:
+    in = in_ca_alpha;
+    break;
+  default:
+    FatalError("Bad composite IN type");
+  }
+
+  XNFasprintf(&source,
+	      "%s%s%s",
+	      source_fetch,
+	      mask_fetch,
+	      in);
  
 
-    prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
-    free(source);
+  prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
+  free(source);
 
-    return prog;
+  return prog;
 }
 
 static GLuint
 glamor_create_composite_vs(struct shader_key *key)
 {
-    const char *main_opening =
-	"void main()\n"
-	"{\n"
-	"	gl_Position = gl_Vertex;\n";
-    const char *source_coords =
-	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n";
-    const char *mask_coords =
-	"	gl_TexCoord[1] = gl_MultiTexCoord1;\n";
-    const char *main_closing =
-	"}\n";
-    const char *source_coords_setup = "";
-    const char *mask_coords_setup = "";
-    char *source;
-    GLuint prog;
-
-    if (key->source != SHADER_SOURCE_SOLID)
-	source_coords_setup = source_coords;
-
-    if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
-	mask_coords_setup = mask_coords;
-
-    XNFasprintf(&source,
-		"%s%s%s%s",
-		 main_opening,
-		 source_coords_setup,
-		 mask_coords_setup,
-		 main_closing);
-
-    prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
-    free(source);
-
-    return prog;
+  const char *main_opening =
+    "void main()\n"
+    "{\n"
+    "	gl_Position = gl_Vertex;\n";
+  const char *source_coords =
+    "	gl_TexCoord[0] = gl_MultiTexCoord0;\n";
+  const char *mask_coords =
+    "	gl_TexCoord[1] = gl_MultiTexCoord1;\n";
+  const char *main_closing =
+    "}\n";
+  const char *source_coords_setup = "";
+  const char *mask_coords_setup = "";
+  char *source;
+  GLuint prog;
+
+  if (key->source != SHADER_SOURCE_SOLID)
+    source_coords_setup = source_coords;
+
+  if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
+    mask_coords_setup = mask_coords;
+
+  XNFasprintf(&source,
+	      "%s%s%s%s",
+	      main_opening,
+	      source_coords_setup,
+	      mask_coords_setup,
+	      main_closing);
+
+  prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
+  free(source);
+
+  return prog;
 }
 
 static void
 glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 			       glamor_composite_shader *shader)
 {
-    GLuint vs, fs, prog;
-    GLint source_sampler_uniform_location, mask_sampler_uniform_location;
-
-    vs = glamor_create_composite_vs(key);
-    if (vs == 0)
-	return;
-    fs = glamor_create_composite_fs(key);
-    if (fs == 0)
-	return;
-
-    prog = glCreateProgramObjectARB();
-    glAttachObjectARB(prog, vs);
-    glAttachObjectARB(prog, fs);
-    glamor_link_glsl_prog(prog);
-
-    shader->prog = prog;
-
-    glUseProgramObjectARB(prog);
-
-    if (key->source == SHADER_SOURCE_SOLID) {
-	shader->source_uniform_location = glGetUniformLocationARB(prog,
-								  "source");
+  GLuint vs, fs, prog;
+  GLint source_sampler_uniform_location, mask_sampler_uniform_location;
+
+  vs = glamor_create_composite_vs(key);
+  if (vs == 0)
+    return;
+  fs = glamor_create_composite_fs(key);
+  if (fs == 0)
+    return;
+
+  prog = glCreateProgramObjectARB();
+  glAttachObjectARB(prog, vs);
+  glAttachObjectARB(prog, fs);
+  glamor_link_glsl_prog(prog);
+
+  shader->prog = prog;
+
+  glUseProgramObjectARB(prog);
+
+  if (key->source == SHADER_SOURCE_SOLID) {
+    shader->source_uniform_location = glGetUniformLocationARB(prog,
+							      "source");
+  } else {
+    source_sampler_uniform_location = glGetUniformLocationARB(prog,
+							      "source_sampler");
+    glUniform1i(source_sampler_uniform_location, 0);
+  }
+
+  if (key->mask != SHADER_MASK_NONE) {
+    if (key->mask == SHADER_MASK_SOLID) {
+      shader->mask_uniform_location = glGetUniformLocationARB(prog,
+							      "mask");
     } else {
-	source_sampler_uniform_location = glGetUniformLocationARB(prog,
-								  "source_sampler");
-	glUniform1i(source_sampler_uniform_location, 0);
-    }
-
-    if (key->mask != SHADER_MASK_NONE) {
-	if (key->mask == SHADER_MASK_SOLID) {
-	    shader->mask_uniform_location = glGetUniformLocationARB(prog,
-								    "mask");
-	} else {
-	    mask_sampler_uniform_location = glGetUniformLocationARB(prog,
-								    "mask_sampler");
-	    glUniform1i(mask_sampler_uniform_location, 1);
-	}
+      mask_sampler_uniform_location = glGetUniformLocationARB(prog,
+							      "mask_sampler");
+      glUniform1i(mask_sampler_uniform_location, 1);
     }
+  }
 }
 
 static glamor_composite_shader *
 glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_composite_shader *shader;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_composite_shader *shader;
 
-    shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
-    if (shader->prog == 0)
-	glamor_create_composite_shader(screen, key, shader);
+  shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
+  if (shader->prog == 0)
+    glamor_create_composite_shader(screen, key, shader);
 
-    return shader;
+  return shader;
 }
 
 void
@@ -295,149 +295,149 @@ static Bool
 glamor_set_composite_op(ScreenPtr screen,
 			CARD8 op, PicturePtr dest, PicturePtr mask)
 {
-    GLenum source_blend, dest_blend;
-    struct blendinfo *op_info;
-
-    if (op >= ARRAY_SIZE(composite_op_info)) {
-	ErrorF("unsupported render op\n");
-	return GL_FALSE;
-    }
-    op_info = &composite_op_info[op];
-
-    source_blend = op_info->source_blend;
-    dest_blend = op_info->dest_blend;
-
-    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
-     * it as always 1.
-     */
-    if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
-        if (source_blend == GL_DST_ALPHA)
-            source_blend = GL_ONE;
-        else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
-            source_blend = GL_ZERO;
-    }
-
-    /* Set up the source alpha value for blending in component alpha mode. */
-    if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
-	op_info->source_alpha) {
-	if (source_blend != GL_ZERO) {
-	    ErrorF("Dual-source composite blending not supported\n");
-	    return GL_FALSE;
-	}
-	if (dest_blend == GL_SRC_ALPHA)
-	    dest_blend = GL_SRC_COLOR;
-	else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
-	    dest_blend = GL_ONE_MINUS_SRC_COLOR;
+  GLenum source_blend, dest_blend;
+  struct blendinfo *op_info;
+
+  if (op >= ARRAY_SIZE(composite_op_info)) {
+    glamor_fallback("unsupported render op %d \n", op);
+    return GL_FALSE;
+  }
+  op_info = &composite_op_info[op];
+
+  source_blend = op_info->source_blend;
+  dest_blend = op_info->dest_blend;
+
+  /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+   * it as always 1.
+   */
+  if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
+    if (source_blend == GL_DST_ALPHA)
+      source_blend = GL_ONE;
+    else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
+      source_blend = GL_ZERO;
+  }
+
+  /* Set up the source alpha value for blending in component alpha mode. */
+  if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
+      op_info->source_alpha) {
+    if (source_blend != GL_ZERO) {
+      glamor_fallback("Dual-source composite blending not supported\n");
+      return GL_FALSE;
     }
+    if (dest_blend == GL_SRC_ALPHA)
+      dest_blend = GL_SRC_COLOR;
+    else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+      dest_blend = GL_ONE_MINUS_SRC_COLOR;
+  }
 
-    if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
-	glDisable(GL_BLEND);
-    } else {
-	glEnable(GL_BLEND);
-	glBlendFunc(source_blend, dest_blend);
-    }
-    return TRUE;
+  if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
+    glDisable(GL_BLEND);
+  } else {
+    glEnable(GL_BLEND);
+    glBlendFunc(source_blend, dest_blend);
+  }
+  return TRUE;
 }
 
 static void
 glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
 			     glamor_pixmap_private *pixmap_priv)
 {
-    glActiveTexture(GL_TEXTURE0 + unit);
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-    switch (picture->repeatType) {
-    case RepeatNone:
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
-	break;
-    case RepeatNormal:
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-	break;
-    case RepeatPad:
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-	break;
-    case RepeatReflect:
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
-	break;
-    }
-
-    switch (picture->filter) {
-    case PictFilterNearest:
-	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        break;
-    case PictFilterBilinear:
-    default:
-	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        break;
-    }
-
-    glEnable(GL_TEXTURE_2D);
+  glActiveTexture(GL_TEXTURE0 + unit);
+  glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+  switch (picture->repeatType) {
+  case RepeatNone:
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+    break;
+  case RepeatNormal:
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    break;
+  case RepeatPad:
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    break;
+  case RepeatReflect:
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+    break;
+  }
+
+  switch (picture->filter) {
+  case PictFilterNearest:
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    break;
+  case PictFilterBilinear:
+  default:
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    break;
+  }
+
+  glEnable(GL_TEXTURE_2D);
 }
 
 static void
 glamor_set_composite_solid(PicturePtr picture, GLint uniform_location)
 {
-    CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */
-    float color[4]; /* rgba */
+  CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */
+  float color[4]; /* rgba */
 
-    color[0] = ((c >> 16) & 0xff) / 255.0;
-    color[1] = ((c >> 8) & 0xff) / 255.0;
-    color[2] = ((c >> 0) & 0xff) / 255.0;
-    color[3] = ((c >> 24) & 0xff) / 255.0;
+  color[0] = ((c >> 16) & 0xff) / 255.0;
+  color[1] = ((c >> 8) & 0xff) / 255.0;
+  color[2] = ((c >> 0) & 0xff) / 255.0;
+  color[3] = ((c >> 24) & 0xff) / 255.0;
 
-    glUniform4fvARB(uniform_location, 1, color);
+  glUniform4fvARB(uniform_location, 1, color);
 }
 
 static int
 compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
 {
-    if (op == PictOpSrc) {
-	if (src->format == dst->format)
-	    return 1;
+  if (op == PictOpSrc) {
+    if (src->format == dst->format)
+      return 1;
 
-	if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
-	    return 1;
+    if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
+      return 1;
 
-	if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
-	    return 1;
-    } else if (op == PictOpOver) {
-	if (src->alphaMap || dst->alphaMap)
-	    return 0;
+    if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
+      return 1;
+  } else if (op == PictOpOver) {
+    if (src->alphaMap || dst->alphaMap)
+      return 0;
 
-	if (src->format != dst->format)
-	    return 0;
+    if (src->format != dst->format)
+      return 0;
 
-	if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
-	    return 1;
-    }
+    if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
+      return 1;
+  }
 
-    return 0;
+  return 0;
 }
 
 static char
 glamor_get_picture_location(PicturePtr picture)
 {
-    if (picture == NULL)
-	return ' ';
-
-    if (picture->pDrawable == NULL) {
-	switch (picture->pSourcePict->type) {
-	case SourcePictTypeSolidFill:
-	    return 'c';
-	case SourcePictTypeLinear:
-	    return 'l';
-	case SourcePictTypeRadial:
-	    return 'r';
-	default:
-	    return '?';
-	}
+  if (picture == NULL)
+    return ' ';
+
+  if (picture->pDrawable == NULL) {
+    switch (picture->pSourcePict->type) {
+    case SourcePictTypeSolidFill:
+      return 'c';
+    case SourcePictTypeLinear:
+      return 'l';
+    case SourcePictTypeRadial:
+      return 'r';
+    default:
+      return '?';
     }
-    return glamor_get_drawable_location(picture->pDrawable);
+  }
+  return glamor_get_drawable_location(picture->pDrawable);
 }
 
 static Bool
@@ -451,151 +451,154 @@ glamor_composite_with_copy(CARD8 op,
 			   CARD16 width,
 			   CARD16 height)
 {
-    RegionRec region;
+  RegionRec region;
 
-    if (!source->pDrawable)
-	return FALSE;
-
-    if (!compatible_formats(op, dest, source))
-	return FALSE;
+  if (!source->pDrawable)
+    return FALSE;
 
-    if (source->repeat || source->transform)
-	return FALSE;
+  if (!compatible_formats(op, dest, source))
+    return FALSE;
 
-    x_dest += dest->pDrawable->x;
-    y_dest += dest->pDrawable->y;
-    x_source += source->pDrawable->x;
-    y_source += source->pDrawable->y;
+  if (source->repeat || source->transform)
+    return FALSE;
 
-    if (!miComputeCompositeRegion(&region,
-				  source, NULL, dest,
-				  x_source, y_source,
-				  0, 0,
-				  x_dest, y_dest,
-				  width, height))
-	return TRUE;
-
-    glamor_copy_n_to_n(source->pDrawable,
-		       dest->pDrawable, NULL,
-		       REGION_RECTS(&region),
-		       REGION_NUM_RECTS(&region),
-		       x_source - x_dest, y_source - y_dest,
-		       FALSE, FALSE, 0, NULL);
-    REGION_UNINIT(dest->pDrawable->pScreen,
-		  &region);
+  x_dest += dest->pDrawable->x;
+  y_dest += dest->pDrawable->y;
+  x_source += source->pDrawable->x;
+  y_source += source->pDrawable->y;
+
+  if (!miComputeCompositeRegion(&region,
+				source, NULL, dest,
+				x_source, y_source,
+				0, 0,
+				x_dest, y_dest,
+				width, height))
     return TRUE;
+
+  glamor_copy_n_to_n(source->pDrawable,
+		     dest->pDrawable, NULL,
+		     REGION_RECTS(&region),
+		     REGION_NUM_RECTS(&region),
+		     x_source - x_dest, y_source - y_dest,
+		     FALSE, FALSE, 0, NULL);
+  REGION_UNINIT(dest->pDrawable->pScreen,
+		&region);
+  return TRUE;
 }
 
 static Bool
 good_source_format(PicturePtr picture)
 {
-    switch (picture->format) {
-    case PICT_a1:
-    case PICT_a8:
-    case PICT_a8r8g8b8:
-    case PICT_x8r8g8b8:
-	return TRUE;
-    default:
-	glamor_fallback("Bad source format 0x%08x\n", picture->format);
-	return FALSE;
-    }
+  switch (picture->format) {
+  case PICT_a1:
+  case PICT_a8:
+  case PICT_a8r8g8b8:
+  case PICT_x8r8g8b8:
+    return TRUE;
+  default:
+    return TRUE;
+    glamor_fallback("Bad source format 0x%08x\n", picture->format);
+    return FALSE;
+  }
 }
 
 static Bool
 good_mask_format(PicturePtr picture)
 {
-    switch (picture->format) {
-    case PICT_a1:
-    case PICT_a8:
-    case PICT_a8r8g8b8:
-    case PICT_x8r8g8b8:
-	return TRUE;
-    default:
-	glamor_fallback("Bad mask format 0x%08x\n", picture->format);
-	return FALSE;
-    }
+  switch (picture->format) {
+  case PICT_a1:
+  case PICT_a8:
+  case PICT_a8r8g8b8:
+  case PICT_x8r8g8b8:
+    return TRUE;
+  default:
+    return TRUE;
+    glamor_fallback("Bad mask format 0x%08x\n", picture->format);
+    return FALSE;
+  }
 }
 
 static Bool
 good_dest_format(PicturePtr picture)
 {
-    switch (picture->format) {
-    case PICT_a8:
-    case PICT_a8r8g8b8:
-    case PICT_x8r8g8b8:
-	return TRUE;
-    default:
-	glamor_fallback("Bad dest format 0x%08x\n", picture->format);
-	return FALSE;
-    }
+  switch (picture->format) {
+  case PICT_a8:
+  case PICT_a8r8g8b8:
+  case PICT_x8r8g8b8:
+    return TRUE;
+  default:
+    return TRUE;
+    glamor_fallback("Bad dest format 0x%08x\n", picture->format);
+    return FALSE;
+  }
 }
 
 static inline float
 xFixedToFloat(pixman_fixed_t val)
 {
-    return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0));
+  return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0));
 }
 
 static void
 glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
 			     float *texcoord, int x, int y)
 {
-    float result[3];
-    int i;
-    float tx, ty;
-    ScreenPtr screen = picture->pDrawable->pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-
-    if (picture->transform) {
-	for (i = 0; i < 3; i++) {
-	    result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x +
-			 xFixedToFloat(picture->transform->matrix[i][1]) * y +
-			 xFixedToFloat(picture->transform->matrix[i][2]));
-	}
-	tx = result[0] / result[2];
-	ty = result[1] / result[2];
-    } else {
-	tx = x;
-	ty = y;
+  float result[3];
+  int i;
+  float tx, ty;
+  ScreenPtr screen = picture->pDrawable->pScreen;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+  if (picture->transform) {
+    for (i = 0; i < 3; i++) {
+      result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x +
+		   xFixedToFloat(picture->transform->matrix[i][1]) * y +
+		   xFixedToFloat(picture->transform->matrix[i][2]));
     }
-    texcoord[0] = t_from_x_coord_x(pixmap, tx);
-    if (glamor_priv->yInverted)
-      texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty);
-    else
-      texcoord[1] = t_from_x_coord_y(pixmap, ty);
+    tx = result[0] / result[2];
+    ty = result[1] / result[2];
+  } else {
+    tx = x;
+    ty = y;
+  }
+  texcoord[0] = t_from_x_coord_x(pixmap, tx);
+  if (glamor_priv->yInverted)
+    texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty);
+  else
+    texcoord[1] = t_from_x_coord_y(pixmap, ty);
 }
 
 static void
 glamor_setup_composite_vbo(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_priv->vb_stride = 2 * sizeof(float);
-    if (glamor_priv->has_source_coords)
-	glamor_priv->vb_stride += 2 * sizeof(float);
-    if (glamor_priv->has_mask_coords)
-	glamor_priv->vb_stride += 2 * sizeof(float);
+  glamor_priv->vb_stride = 2 * sizeof(float);
+  if (glamor_priv->has_source_coords)
+    glamor_priv->vb_stride += 2 * sizeof(float);
+  if (glamor_priv->has_mask_coords)
+    glamor_priv->vb_stride += 2 * sizeof(float);
 
-    glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
-    glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-		    (void *)((long)glamor_priv->vbo_offset));
-    glEnableClientState(GL_VERTEX_ARRAY);
-
-    if (glamor_priv->has_source_coords) {
-	glClientActiveTexture(GL_TEXTURE0);
-	glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-			  (void *)(glamor_priv->vbo_offset + 2 * sizeof(float)));
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
+  glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
+  glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+		  (void *)((long)glamor_priv->vbo_offset));
+  glEnableClientState(GL_VERTEX_ARRAY);
 
-    if (glamor_priv->has_mask_coords) {
-	glClientActiveTexture(GL_TEXTURE1);
-	glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-			  (void *)(glamor_priv->vbo_offset +
-				   (glamor_priv->has_source_coords ? 4 : 2) *
-				   sizeof(float)));
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
+  if (glamor_priv->has_source_coords) {
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+		      (void *)(glamor_priv->vbo_offset + 2 * sizeof(float)));
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+  }
+
+  if (glamor_priv->has_mask_coords) {
+    glClientActiveTexture(GL_TEXTURE1);
+    glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+		      (void *)(glamor_priv->vbo_offset +
+			       (glamor_priv->has_source_coords ? 4 : 2) *
+			       sizeof(float)));
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+  }
 }
 
 static void
@@ -605,39 +608,39 @@ glamor_emit_composite_vert(ScreenPtr screen,
 			   const float *dst_coords,
 			   int i)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset);
-    int j = 0;
-
-    vb[j++] = dst_coords[i * 2 + 0];
-    vb[j++] = dst_coords[i * 2 + 1];
-    if (glamor_priv->has_source_coords) {
-	vb[j++] = src_coords[i * 2 + 0];
-	vb[j++] = src_coords[i * 2 + 1];
-    }
-    if (glamor_priv->has_mask_coords) {
-	vb[j++] = mask_coords[i * 2 + 0];
-	vb[j++] = mask_coords[i * 2 + 1];
-    }
-
-    glamor_priv->render_nr_verts++;
-    glamor_priv->vbo_offset += glamor_priv->vb_stride;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset);
+  int j = 0;
+
+  vb[j++] = dst_coords[i * 2 + 0];
+  vb[j++] = dst_coords[i * 2 + 1];
+  if (glamor_priv->has_source_coords) {
+    vb[j++] = src_coords[i * 2 + 0];
+    vb[j++] = src_coords[i * 2 + 1];
+  }
+  if (glamor_priv->has_mask_coords) {
+    vb[j++] = mask_coords[i * 2 + 0];
+    vb[j++] = mask_coords[i * 2 + 1];
+  }
+
+  glamor_priv->render_nr_verts++;
+  glamor_priv->vbo_offset += glamor_priv->vb_stride;
 }
 
 static void
 glamor_flush_composite_rects(ScreenPtr screen)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    if (!glamor_priv->render_nr_verts)
-	return;
+  if (!glamor_priv->render_nr_verts)
+    return;
 
-    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
-    glamor_priv->vb = NULL;
+  glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+  glamor_priv->vb = NULL;
 
-    glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
-    glamor_priv->render_nr_verts = 0;
-    glamor_priv->vbo_size = 0;
+  glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
+  glamor_priv->render_nr_verts = 0;
+  glamor_priv->vbo_size = 0;
 }
 
 static void
@@ -646,31 +649,96 @@ glamor_emit_composite_rect(ScreenPtr screen,
 			   const float *mask_coords,
 			   const float *dst_coords)
 {
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
-	glamor_priv->vbo_size)
+  if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
+      glamor_priv->vbo_size)
     {
-	glamor_flush_composite_rects(screen);
+      glamor_flush_composite_rects(screen);
     }
 
-    if (glamor_priv->vbo_size == 0) {
-	if (glamor_priv->vbo == 0)
-	    glGenBuffersARB(1, &glamor_priv->vbo);
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
-
-	glamor_priv->vbo_size = 4096;
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL,
-			GL_STREAM_DRAW_ARB);
-	glamor_priv->vbo_offset = 0;
-	glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-	glamor_setup_composite_vbo(screen);
-    }
+  if (glamor_priv->vbo_size == 0) {
+    if (glamor_priv->vbo == 0)
+      glGenBuffersARB(1, &glamor_priv->vbo);
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
 
-    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
-    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
-    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
-    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3);
+    glamor_priv->vbo_size = 4096;
+    glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL,
+		    GL_STREAM_DRAW_ARB);
+    glamor_priv->vbo_offset = 0;
+    glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+    glamor_setup_composite_vbo(screen);
+  }
+
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
+  glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3);
+}
+
+
+int pict_format_combine_tab[][3] = 
+  {
+    {PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
+    {PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
+  };
+
+static Bool 
+combine_pict_format(PictFormatShort *des, const PictFormatShort src, 
+                    const PictFormatShort mask, enum shader_in in_ca)
+{
+  PictFormatShort new_vis;
+  int src_type, mask_type, src_bpp, mask_bpp;
+  int i;
+  if (src == mask) {
+    *des = src;
+    return TRUE;
+  }
+  src_bpp = PICT_FORMAT_BPP(src);
+  mask_bpp = PICT_FORMAT_BPP(mask);
+
+  assert(src_bpp == mask_bpp);
+ 
+  new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
+
+  switch(in_ca) {
+  case SHADER_IN_SOURCE_ONLY:
+    return TRUE;
+  case SHADER_IN_NORMAL:
+    src_type = PICT_FORMAT_TYPE(src);
+    mask_type = PICT_TYPE_A;
+    break;
+  case SHADER_IN_CA_SOURCE:
+    src_type = PICT_FORMAT_TYPE(src);
+    mask_type = PICT_FORMAT_TYPE(mask);
+    break;
+  case SHADER_IN_CA_ALPHA:
+    src_type = PICT_TYPE_A;
+    mask_type = PICT_FORMAT_TYPE(mask);
+    break;
+  default:
+    return FALSE;
+  }
+
+
+  if (src_type == mask_type) {
+    *des = PICT_VISFORMAT(src_bpp, src_type, new_vis);
+    return TRUE;
+  }
+
+  for(i = 0; 
+      i < sizeof(pict_format_combine_tab)/sizeof(pict_format_combine_tab[0]);
+      i++) 
+    {
+      if ((src_type == pict_format_combine_tab[i][0] 
+	   && mask_type == pict_format_combine_tab[i][1])
+	  ||(src_type == pict_format_combine_tab[i][1]
+	     && mask_type == pict_format_combine_tab[i][0])) {
+        *des = PICT_VISFORMAT(src_bpp, pict_format_combine_tab[i][2], new_vis);
+        return TRUE;
+      } 
+    } 
+  return FALSE;
 }
 
 static Bool
@@ -681,302 +749,374 @@ glamor_composite_with_shader(CARD8 op,
 			     int nrect,
 			     glamor_composite_rect_t *rects)
 {
-    ScreenPtr screen = dest->pDrawable->pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-    PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
-    glamor_pixmap_private *source_pixmap_priv = NULL;
-    glamor_pixmap_private *mask_pixmap_priv = NULL;
-    struct shader_key key;
-    glamor_composite_shader *shader;
-    RegionRec region;
-    float vertices[8], source_texcoords[8], mask_texcoords[8];
-    int i;
-    BoxPtr box;
-    int dest_x_off, dest_y_off;
-    int source_x_off, source_y_off;
-    int mask_x_off, mask_y_off;
-
-    memset(&key, 0, sizeof(key));
-    if (!source->pDrawable) {
-	if (source->pSourcePict->type == SourcePictTypeSolidFill) {
-	    key.source = SHADER_SOURCE_SOLID;
-	} else {
-	    glamor_fallback("gradient source\n");
-	    goto fail;
-	}
+  ScreenPtr screen = dest->pDrawable->pScreen;
+  glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+  PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+  PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+  glamor_pixmap_private *source_pixmap_priv = NULL;
+  glamor_pixmap_private *mask_pixmap_priv = NULL;
+  glamor_pixmap_private *dest_pixmap_priv = NULL;
+  struct shader_key key;
+  glamor_composite_shader *shader;
+  RegionRec region;
+  float vertices[8], source_texcoords[8], mask_texcoords[8];
+  int i;
+  BoxPtr box;
+  int dest_x_off, dest_y_off;
+  int source_x_off, source_y_off;
+  int mask_x_off, mask_y_off;
+  enum glamor_pixmap_status source_status = GLAMOR_NONE;
+  enum glamor_pixmap_status mask_status = GLAMOR_NONE;
+  PictFormatShort saved_source_format = 0;
+  dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
+  if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+    glamor_fallback("dest has no fbo.\n");
+    goto fail;
+  }
+  memset(&key, 0, sizeof(key));
+  if (!source->pDrawable) {
+    if (source->pSourcePict->type == SourcePictTypeSolidFill) {
+      key.source = SHADER_SOURCE_SOLID;
     } else {
-	if (PICT_FORMAT_A(source->format) != 0) {
-	    key.source = SHADER_SOURCE_TEXTURE_ALPHA;
-	} else {
-	    key.source = SHADER_SOURCE_TEXTURE;
-	}
+      glamor_fallback("gradient source\n");
+      goto fail;
     }
-    if (mask) {
-	if (!mask->pDrawable) {
-	    if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
-		key.mask = SHADER_MASK_SOLID;
-	    } else {
-		glamor_fallback("gradient mask\n");
-		goto fail;
-	    }
-	} else {
-	    if (PICT_FORMAT_A(mask->format) != 0) {
-		key.mask = SHADER_MASK_TEXTURE_ALPHA;
-	    } else {
-		key.mask = SHADER_MASK_TEXTURE;
-	    }
-	}
-
-	if (!mask->componentAlpha) {
-	    key.in = SHADER_IN_NORMAL;
-	} else {
-	    /* We only handle two CA modes. */
-	    if (op == PictOpAdd)
-		key.in = SHADER_IN_CA_SOURCE;
-	    else if (op == PictOpOutReverse) {
-		key.in = SHADER_IN_CA_ALPHA;
-	    } else {
-		glamor_fallback("Unsupported component alpha op: %d\n", op);
-		goto fail;
-	    }
-	}
+  } else {
+    key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+  }
+  if (mask) {
+    if (!mask->pDrawable) {
+      if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
+	key.mask = SHADER_MASK_SOLID;
+      } else {
+	glamor_fallback("gradient mask\n");
+	goto fail;
+      }
     } else {
-	key.mask = SHADER_MASK_NONE;
-	key.in = SHADER_IN_SOURCE_ONLY;
+      key.mask = SHADER_MASK_TEXTURE_ALPHA;
     }
 
-    if (source->alphaMap) {
-	glamor_fallback("source alphaMap\n");
+    if (!mask->componentAlpha) {
+      key.in = SHADER_IN_NORMAL;
+    } else {
+      /* We only handle two CA modes. */
+      if (op == PictOpAdd)
+	key.in = SHADER_IN_CA_SOURCE;
+      else if (op == PictOpOutReverse) {
+	key.in = SHADER_IN_CA_ALPHA;
+      } else {
+	glamor_fallback("Unsupported component alpha op: %d\n", op);
 	goto fail;
+      }
     }
-    if (mask && mask->alphaMap) {
-	glamor_fallback("mask alphaMap\n");
-	goto fail;
+  } else {
+    key.mask = SHADER_MASK_NONE;
+    key.in = SHADER_IN_SOURCE_ONLY;
+  }
+
+  if (source->alphaMap) {
+    glamor_fallback("source alphaMap\n");
+    goto fail;
+  }
+  if (mask && mask->alphaMap) {
+    glamor_fallback("mask alphaMap\n");
+    goto fail;
+  }
+  if (key.source == SHADER_SOURCE_TEXTURE ||
+      key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
+    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+    if (source_pixmap == dest_pixmap) {
+      glamor_fallback("source == dest\n");
+      goto fail;
     }
-
-    if (key.source == SHADER_SOURCE_TEXTURE ||
-	key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
-	source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-	source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-	if (source_pixmap == dest_pixmap) {
-	    glamor_fallback("glamor_composite(): source == dest\n");
-	    goto fail;
-	}
-	if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
-	    glamor_fallback("glamor_composite(): no texture in source\n");
-	    goto fail;
-	}
-	if (!good_source_format(source))
-	    goto fail;
+    if (!source_pixmap_priv || source_pixmap_priv->gl_tex == 0) {
+#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+      source_status = GLAMOR_UPLOAD_PENDING;
+#else
+      glamor_fallback("no texture in source\n");
+      goto fail;
+#endif
+    }
+    if ((source_status != GLAMOR_UPLOAD_PENDING) 
+	&& !good_source_format(source)) {
+      goto fail;
+    }
+  }
+  if (key.mask == SHADER_MASK_TEXTURE ||
+      key.mask == SHADER_MASK_TEXTURE_ALPHA) {
+    mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+    mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+    if (mask_pixmap == dest_pixmap) {
+      glamor_fallback("mask == dest\n");
+      goto fail;
+    }
+    if (!mask_pixmap_priv || mask_pixmap_priv->gl_tex == 0) {
+#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+      mask_status = GLAMOR_UPLOAD_PENDING;
+#else
+      glamor_fallback("no texture in mask\n");
+      goto fail;
+#endif
     }
-    if (key.mask == SHADER_MASK_TEXTURE ||
-	key.mask == SHADER_MASK_TEXTURE_ALPHA) {
-	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
-	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
-	if (mask_pixmap == dest_pixmap) {
-	    glamor_fallback("glamor_composite(): mask == dest\n");
-	    goto fail;
-	}
-	if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) {
-	    glamor_fallback("glamor_composite(): no texture in mask\n");
-	    goto fail;
-	}
-	if (!good_mask_format(mask))
-	    goto fail;
+    if ((mask_status != GLAMOR_UPLOAD_PENDING) 
+	&& !good_mask_format(mask)) {
+      goto fail;
     }
-    if (!good_dest_format(dest))
+  }
+  if (!good_dest_format(dest)) {
+    goto fail;
+  }
+  if (!glamor_set_composite_op(screen, op, dest, mask)) {
+    goto fail;
+  }
+
+#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
+  if (source_status == GLAMOR_UPLOAD_PENDING 
+      && mask_status == GLAMOR_UPLOAD_PENDING 
+      && source_pixmap == mask_pixmap) {
+
+    if (source->format != mask->format) {
+      saved_source_format = source->format;
+      /* XXX
+       * when need to flip the texture and mask and source share the same pixmap,
+       * there is a bug, need to be fixed. *
+       */
+      if (!glamor_priv->yInverted)
 	goto fail;
-
-    shader = glamor_lookup_composite_shader(screen, &key);
-    if (shader->prog == 0) {
-	glamor_fallback("glamor_composite(): "
-			"no shader program for this render acccel mode\n");
+      if (!combine_pict_format(&source->format, source->format, mask->format, key.in)) {
+	glamor_fallback("combine source %x mask %x failed.\n", 
+			source->format, mask->format);
 	goto fail;
+      }
+      if (source->format != saved_source_format) {
+	glamor_picture_format_fixup(source, source_pixmap_priv);
+      }
+      /* XXX  
+       * By default, glamor_upload_picture_to_texture will wire alpha to 1
+       * if one picture doesn't have alpha. So we don't do that again in 
+       * rendering function. But here is a special case, as source and
+       * mask share the same texture but may have different formats. For 
+       * example, source doesn't have alpha, but mask has alpha. Then the
+       * texture will have the alpha value for the mask. And will not wire
+       * to 1 for the source. In this case, we have to use different shader
+       * to wire the source's alpha to 1.
+       *
+       * But this may cause a potential problem if the source's repeat mode 
+       * is REPEAT_NONE, and if the source is smaller than the dest, then
+       * for the region not covered by the source may be painted incorrectly.
+       * because we wire the alpha to 1.
+       *
+       **/ 
+      if (!PICT_FORMAT_A(saved_source_format) && PICT_FORMAT_A(mask->format))
+	key.source = SHADER_SOURCE_TEXTURE;
+    
+      if (!PICT_FORMAT_A(mask->format) && PICT_FORMAT_A(saved_source_format))
+	key.mask = SHADER_MASK_TEXTURE;
+
+      mask_status = GLAMOR_NONE;
     }
+    source_status = glamor_upload_picture_to_texture(source);
+     
+    if (source_status != GLAMOR_UPLOAD_DONE) {
+      glamor_fallback("Failed to upload source texture.\n");
+      goto fail;
+    }
+  } 
+  else {
 
-    glUseProgramObjectARB(shader->prog);
-
-    if (!glamor_set_destination_pixmap(dest_pixmap))
+    if (source_status == GLAMOR_UPLOAD_PENDING) {
+      source_status = glamor_upload_picture_to_texture(source);
+      if (source_status != GLAMOR_UPLOAD_DONE) {
+	glamor_fallback("Failed to upload source texture.\n");
 	goto fail;
+      }
+    }
 
-    if (!glamor_set_composite_op(screen, op, dest, mask)) {
+    if (mask_status == GLAMOR_UPLOAD_PENDING) {
+      mask_status = glamor_upload_picture_to_texture(mask);
+      if (mask_status != GLAMOR_UPLOAD_DONE) {
+	glamor_fallback("Failed to upload mask texture.\n");
 	goto fail;
+      }
     }
+  }
+#endif
 
-    if (key.source == SHADER_SOURCE_SOLID) {
-	glamor_set_composite_solid(source, shader->source_uniform_location);
+  glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
+
+  shader = glamor_lookup_composite_shader(screen, &key);
+  if (shader->prog == 0) {
+    glamor_fallback("no shader program for this render acccel mode\n");
+    goto fail;
+  }
+
+  glUseProgramObjectARB(shader->prog);
+  if (key.source == SHADER_SOURCE_SOLID) {
+    glamor_set_composite_solid(source, shader->source_uniform_location);
+  } else {
+    glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
+  }
+  if (key.mask != SHADER_MASK_NONE) {
+    if (key.mask == SHADER_MASK_SOLID) {
+      glamor_set_composite_solid(mask, shader->mask_uniform_location);
     } else {
-	glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
-    }
-    if (key.mask != SHADER_MASK_NONE) {
-	if (key.mask == SHADER_MASK_SOLID) {
-	    glamor_set_composite_solid(mask, shader->mask_uniform_location);
-	} else {
-	    glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
-	}
+      glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
     }
+  }
+
+  glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+  glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+				  key.mask != SHADER_MASK_SOLID);
+
+  glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
+			     &dest_x_off, &dest_y_off);
+  if (source_pixmap) {
+    glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
+			       &source_x_off, &source_y_off);
+  }
+  if (mask_pixmap) {
+    glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
+			       &mask_x_off, &mask_y_off);
+  }
+  while (nrect--) {
+    INT16 x_source;
+    INT16 y_source;
+    INT16 x_mask;
+    INT16 y_mask;
+    INT16 x_dest;
+    INT16 y_dest;
+    CARD16 width;
+    CARD16 height;
+
+    x_dest = rects->x_dst;
+    y_dest = rects->y_dst;
+    x_source = rects->x_src;
+    y_source = rects->y_src;
+    x_mask = rects->x_mask;
+    y_mask = rects->y_mask;
+    width = rects->width;
+    height = rects->height;
 
-    glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
-    glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
-				    key.mask != SHADER_MASK_SOLID);
-
-    glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
-			       &dest_x_off, &dest_y_off);
-    if (source_pixmap) {
-	glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
-				   &source_x_off, &source_y_off);
+    x_dest += dest->pDrawable->x;
+    y_dest += dest->pDrawable->y;
+    if (source->pDrawable) {
+      x_source += source->pDrawable->x;
+      y_source += source->pDrawable->y;
     }
-    if (mask_pixmap) {
-	glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
-				   &mask_x_off, &mask_y_off);
+    if (mask && mask->pDrawable) {
+      x_mask += mask->pDrawable->x;
+      y_mask += mask->pDrawable->y;
     }
 
-    while (nrect--) {
-	INT16 x_source;
-	INT16 y_source;
-	INT16 x_mask;
-	INT16 y_mask;
-	INT16 x_dest;
-	INT16 y_dest;
-	CARD16 width;
-	CARD16 height;
-
-	x_dest = rects->x_dst;
-	y_dest = rects->y_dst;
-	x_source = rects->x_src;
-	y_source = rects->y_src;
-	x_mask = rects->x_mask;
-	y_mask = rects->y_mask;
-	width = rects->width;
-	height = rects->height;
-
-	x_dest += dest->pDrawable->x;
-	y_dest += dest->pDrawable->y;
-	if (source->pDrawable) {
-	    x_source += source->pDrawable->x;
-	    y_source += source->pDrawable->y;
-	}
-	if (mask && mask->pDrawable) {
-	    x_mask += mask->pDrawable->x;
-	    y_mask += mask->pDrawable->y;
-	}
-
-	if (!miComputeCompositeRegion(&region,
-				      source, mask, dest,
-				      x_source, y_source,
-				      x_mask, y_mask,
-				      x_dest, y_dest,
-				      width, height))
-	    continue;
-
-	x_source += source_x_off;
-	y_source += source_y_off;
-	x_mask += mask_x_off;
-	y_mask += mask_y_off;
-
-	box = REGION_RECTS(&region);
-	for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-	    vertices[0] = v_from_x_coord_x(dest_pixmap,
-					   box[i].x1 + dest_x_off);
-	    vertices[2] = v_from_x_coord_x(dest_pixmap,
-					   box[i].x2 + dest_x_off);
-	    vertices[4] = v_from_x_coord_x(dest_pixmap,
-					   box[i].x2 + dest_x_off);
-	    vertices[6] = v_from_x_coord_x(dest_pixmap,
-					   box[i].x1 + dest_x_off);
-
-	  if (glamor_priv->yInverted) {
-	    vertices[1] = v_from_x_coord_y_inverted(dest_pixmap,
-					   box[i].y1 + dest_y_off);
-	    vertices[3] = v_from_x_coord_y_inverted(dest_pixmap,
-					   box[i].y1 + dest_y_off);
-	    vertices[5] = v_from_x_coord_y_inverted(dest_pixmap,
-					   box[i].y2 + dest_y_off);
-	    vertices[7] = v_from_x_coord_y_inverted(dest_pixmap,
-					   box[i].y2 + dest_y_off);
-
-	    } else {
-	    vertices[1] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y1 + dest_y_off);
-	    vertices[3] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y1 + dest_y_off);
-	    vertices[5] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y2 + dest_y_off);
-	    vertices[7] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y2 + dest_y_off);
-	   }
-	    if (key.source != SHADER_SOURCE_SOLID) {
-		int tx1 = box[i].x1 + x_source - x_dest;
-		int ty1 = box[i].y1 + y_source - y_dest;
-		int tx2 = box[i].x2 + x_source - x_dest;
-		int ty2 = box[i].y2 + y_source - y_dest;
-
-		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords + 0, tx1, ty1);
-		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords + 2, tx2, ty1);
-		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords + 4, tx2, ty2);
-		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords + 6, tx1, ty2);
-	    }
-
-	    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-		float tx1 = box[i].x1 + x_mask - x_dest;
-		float ty1 = box[i].y1 + y_mask - y_dest;
-		float tx2 = box[i].x2 + x_mask - x_dest;
-		float ty2 = box[i].y2 + y_mask - y_dest;
-
-		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords + 0, tx1, ty1);
-		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords + 2, tx2, ty1);
-		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords + 4, tx2, ty2);
-		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords + 6, tx1, ty2);
-	    }
-#if 0
- else memset(mask_texcoords, 0, sizeof(mask_texcoords));
-	    for (i = 0; i < 4; i++) {
-		ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) "
-		       "(%04.4f, %04.4f)\n",
-		       i,
-		       source_texcoords[i][0], source_texcoords[i][1],
-		       mask_texcoords[i][0], mask_texcoords[i][1],
-		       vertices[i][0], vertices[i][1]);
-	    }
-#endif
-
-	    glamor_emit_composite_rect(screen, source_texcoords,
-				       mask_texcoords, vertices);
-	}
-	rects++;
+    if (!miComputeCompositeRegion(&region,
+				  source, mask, dest,
+				  x_source, y_source,
+				  x_mask, y_mask,
+				  x_dest, y_dest,
+				  width, height))
+      continue;
+
+    x_source += source_x_off;
+    y_source += source_y_off;
+    x_mask += mask_x_off;
+    y_mask += mask_y_off;
+
+    box = REGION_RECTS(&region);
+    for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
+      vertices[0] = v_from_x_coord_x(dest_pixmap,
+				     box[i].x1 + dest_x_off);
+      vertices[2] = v_from_x_coord_x(dest_pixmap,
+				     box[i].x2 + dest_x_off);
+      vertices[4] = v_from_x_coord_x(dest_pixmap,
+				     box[i].x2 + dest_x_off);
+      vertices[6] = v_from_x_coord_x(dest_pixmap,
+				     box[i].x1 + dest_x_off);
+
+      if (glamor_priv->yInverted) {
+	vertices[1] = v_from_x_coord_y_inverted(dest_pixmap,
+						box[i].y1 + dest_y_off);
+	vertices[3] = v_from_x_coord_y_inverted(dest_pixmap,
+						box[i].y1 + dest_y_off);
+	vertices[5] = v_from_x_coord_y_inverted(dest_pixmap,
+						box[i].y2 + dest_y_off);
+	vertices[7] = v_from_x_coord_y_inverted(dest_pixmap,
+						box[i].y2 + dest_y_off);
+
+      } else {
+	vertices[1] = v_from_x_coord_y(dest_pixmap,
+				       box[i].y1 + dest_y_off);
+	vertices[3] = v_from_x_coord_y(dest_pixmap,
+				       box[i].y1 + dest_y_off);
+	vertices[5] = v_from_x_coord_y(dest_pixmap,
+				       box[i].y2 + dest_y_off);
+	vertices[7] = v_from_x_coord_y(dest_pixmap,
+				       box[i].y2 + dest_y_off);
+      }
+      if (key.source != SHADER_SOURCE_SOLID) {
+	int tx1 = box[i].x1 + x_source - x_dest;
+	int ty1 = box[i].y1 + y_source - y_dest;
+	int tx2 = box[i].x2 + x_source - x_dest;
+	int ty2 = box[i].y2 + y_source - y_dest;
+
+	glamor_set_transformed_point(source, source_pixmap,
+				     source_texcoords + 0, tx1, ty1);
+	glamor_set_transformed_point(source, source_pixmap,
+				     source_texcoords + 2, tx2, ty1);
+	glamor_set_transformed_point(source, source_pixmap,
+				     source_texcoords + 4, tx2, ty2);
+	glamor_set_transformed_point(source, source_pixmap,
+				     source_texcoords + 6, tx1, ty2);
+      }
+
+      if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
+	float tx1 = box[i].x1 + x_mask - x_dest;
+	float ty1 = box[i].y1 + y_mask - y_dest;
+	float tx2 = box[i].x2 + x_mask - x_dest;
+	float ty2 = box[i].y2 + y_mask - y_dest;
+
+	glamor_set_transformed_point(mask, mask_pixmap,
+				     mask_texcoords + 0, tx1, ty1);
+	glamor_set_transformed_point(mask, mask_pixmap,
+				     mask_texcoords + 2, tx2, ty1);
+	glamor_set_transformed_point(mask, mask_pixmap,
+				     mask_texcoords + 4, tx2, ty2);
+	glamor_set_transformed_point(mask, mask_pixmap,
+				     mask_texcoords + 6, tx1, ty2);
+      }
+      glamor_emit_composite_rect(screen, source_texcoords,
+				 mask_texcoords, vertices);
     }
-
-    glamor_flush_composite_rects(screen);
-
-    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
-    glClientActiveTexture(GL_TEXTURE0);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glClientActiveTexture(GL_TEXTURE1);
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glDisableClientState(GL_VERTEX_ARRAY);
-
-    REGION_UNINIT(dst->pDrawable->pScreen, &region);
-    glDisable(GL_BLEND);
-    glActiveTexture(GL_TEXTURE0);
-    glDisable(GL_TEXTURE_2D);
-    glActiveTexture(GL_TEXTURE1);
-    glDisable(GL_TEXTURE_2D);
-    glUseProgramObjectARB(0);
-    return TRUE;
-
-fail:
-    glDisable(GL_BLEND);
-    glUseProgramObjectARB(0);
-    return FALSE;
+    rects++;
+  }
+  glamor_flush_composite_rects(screen);
+
+  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+  glClientActiveTexture(GL_TEXTURE0);
+  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+  glClientActiveTexture(GL_TEXTURE1);
+  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+  glDisableClientState(GL_VERTEX_ARRAY);
+
+  REGION_UNINIT(dst->pDrawable->pScreen, &region);
+  glDisable(GL_BLEND);
+  glActiveTexture(GL_TEXTURE0);
+  glDisable(GL_TEXTURE_2D);
+  glActiveTexture(GL_TEXTURE1);
+  glDisable(GL_TEXTURE_2D);
+  glUseProgramObjectARB(0);
+  if (saved_source_format) 
+    source->format = saved_source_format;
+  return TRUE;
+
+ fail:
+  if (saved_source_format) 
+    source->format = saved_source_format;
+
+  glDisable(GL_BLEND);
+  glUseProgramObjectARB(0);
+  return FALSE;
 }
 
 void
@@ -993,83 +1133,81 @@ glamor_composite(CARD8 op,
 		 CARD16 width,
 		 CARD16 height)
 {
-    glamor_composite_rect_t rect;
-
-    /* Do two-pass PictOpOver componentAlpha, until we enable
-     * dual source color blending.
-     */
-    if (mask && mask->componentAlpha) {
-	if (op == PictOpOver) {
-	    glamor_composite(PictOpOutReverse,
-			     source, mask, dest,
-			     x_source, y_source,
-			     x_mask, y_mask,
-			     x_dest, y_dest,
-			     width, height);
-	    glamor_composite(PictOpAdd,
-			     source, mask, dest,
-			     x_source, y_source,
-			     x_mask, y_mask,
-			     x_dest, y_dest,
-			     width, height);
-	    return;
-	} else if (op != PictOpAdd && op != PictOpOutReverse) {
-	    glamor_fallback("glamor_composite(): component alpha\n");
-	    goto fail;
-	}
-    }
-
-    if (!mask) {
-	if (glamor_composite_with_copy(op, source, dest,
-				       x_source, y_source,
-				       x_dest, y_dest,
-				       width, height))
-	    return;
-    }
-
-    rect.x_src = x_source;
-    rect.y_src = y_source;
-    rect.x_mask = x_mask;
-    rect.y_mask = y_mask;
-    rect.x_dst = x_dest;
-    rect.y_dst = y_dest;
-    rect.width = width;
-    rect.height = height;
-    if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect))
-	return;
-
-fail:
-    glamor_fallback("glamor_composite(): "
-		    "from picts %p/%p(%c,%c) to pict %p (%c)\n",
-		    source, mask,
-		    glamor_get_picture_location(source),
-		    glamor_get_picture_location(mask),
-		    dest,
-		    glamor_get_picture_location(dest));
-
-    glUseProgramObjectARB(0);
-    glDisable(GL_BLEND);
-    if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
-	if (source->pDrawable == NULL ||
-	    glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO))
-	{
-	    if (!mask || mask->pDrawable == NULL ||
-		glamor_prepare_access(mask->pDrawable, GLAMOR_ACCESS_RO))
-	    {
-		fbComposite(op,
-			    source, mask, dest,
-			    x_source, y_source,
-			    x_mask, y_mask,
-			    x_dest, y_dest,
-			    width, height);
-		if (mask && mask->pDrawable != NULL)
-		    glamor_finish_access(mask->pDrawable);
-	    }
-	    if (source->pDrawable != NULL)
-		glamor_finish_access(source->pDrawable);
-	}
-	glamor_finish_access(dest->pDrawable);
+  glamor_composite_rect_t rect;
+
+  /* Do two-pass PictOpOver componentAlpha, until we enable
+   * dual source color blending.
+   */
+  if (mask && mask->componentAlpha) {
+    if (op == PictOpOver) {
+      glamor_composite(PictOpOutReverse,
+		       source, mask, dest,
+		       x_source, y_source,
+		       x_mask, y_mask,
+		       x_dest, y_dest,
+		       width, height);
+      glamor_composite(PictOpAdd,
+		       source, mask, dest,
+		       x_source, y_source,
+		       x_mask, y_mask,
+		       x_dest, y_dest,
+		       width, height);
+      return;
+    } else if (op != PictOpAdd && op != PictOpOutReverse) {
+      glamor_fallback("glamor_composite(): component alpha\n");
+      goto fail;
     }
+  }
+
+  if (!mask) {
+    if (glamor_composite_with_copy(op, source, dest,
+				   x_source, y_source,
+				   x_dest, y_dest,
+				   width, height))
+      return;
+  }
+
+  rect.x_src = x_source;
+  rect.y_src = y_source;
+  rect.x_mask = x_mask;
+  rect.y_mask = y_mask;
+  rect.x_dst = x_dest;
+  rect.y_dst = y_dest;
+  rect.width = width;
+  rect.height = height;
+  if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect))
+    return;
+
+ fail:
+  glamor_fallback("glamor_composite(): "
+		  "from picts %p/%p(%c,%c) to pict %p (%c)\n",
+		  source, mask,
+		  glamor_get_picture_location(source),
+		  glamor_get_picture_location(mask),
+		  dest,
+		  glamor_get_picture_location(dest));
+
+  glUseProgramObjectARB(0);
+  glDisable(GL_BLEND);
+  if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
+    if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
+      {
+	if (!mask ||
+	    glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO))
+	  {
+	    fbComposite(op,
+			source, mask, dest,
+			x_source, y_source,
+			x_mask, y_mask,
+			x_dest, y_dest,
+			width, height);
+	    if (mask)
+	      glamor_finish_access_picture(mask);
+	  }
+	glamor_finish_access_picture(source);
+      }
+    glamor_finish_access_picture(dest);
+  }
 }
 
 
@@ -1084,28 +1222,28 @@ glamor_create_mask_picture(ScreenPtr screen,
 			   CARD16 width,
 			   CARD16 height)
 {
-    PixmapPtr pixmap;
-    PicturePtr picture;
-    int	error;
-
-    if (!pict_format) {
-	if (dst->polyEdge == PolyEdgeSharp)
-	    pict_format = PictureMatchFormat(screen, 1, PICT_a1);
-	else
-	    pict_format = PictureMatchFormat(screen, 8, PICT_a8);
-	if (!pict_format)
-	    return 0;
-    }
+  PixmapPtr pixmap;
+  PicturePtr picture;
+  int	error;
 
-    pixmap = screen->CreatePixmap(screen, width, height,
-				  pict_format->depth,
-				  0);
-    if (!pixmap)
-	return 0;
-    picture = CreatePicture(0, &pixmap->drawable, pict_format,
-			    0, 0, serverClient, &error);
-    screen->DestroyPixmap(pixmap);
-    return picture;
+  if (!pict_format) {
+    if (dst->polyEdge == PolyEdgeSharp)
+      pict_format = PictureMatchFormat(screen, 1, PICT_a1);
+    else
+      pict_format = PictureMatchFormat(screen, 8, PICT_a8);
+    if (!pict_format)
+      return 0;
+  }
+
+  pixmap = screen->CreatePixmap(screen, width, height,
+				pict_format->depth,
+				0);
+  if (!pixmap)
+    return 0;
+  picture = CreatePicture(0, &pixmap->drawable, pict_format,
+			  0, 0, serverClient, &error);
+  screen->DestroyPixmap(pixmap);
+  return picture;
 }
 
 /**
@@ -1118,94 +1256,94 @@ glamor_trapezoids(CARD8 op,
 		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		  int ntrap, xTrapezoid *traps)
 {
-    ScreenPtr screen = dst->pDrawable->pScreen;
-    BoxRec bounds;
-    PicturePtr picture;
-    INT16 x_dst, y_dst;
-    INT16 x_rel, y_rel;
-    int width, height, stride;
-    PixmapPtr pixmap;
-    GCPtr gc;
-    pixman_image_t *image;
-
-    /* If a mask format wasn't provided, we get to choose, but behavior should
-     * be as if there was no temporary mask the traps were accumulated into.
-     */
-    if (!mask_format) {
-	if (dst->polyEdge == PolyEdgeSharp)
-	    mask_format = PictureMatchFormat(screen, 1, PICT_a1);
-	else
-	    mask_format = PictureMatchFormat(screen, 8, PICT_a8);
-	for (; ntrap; ntrap--, traps++)
-	    glamor_trapezoids(op, src, dst, mask_format, x_src, y_src,
-			      1, traps);
-	return;
-    }
-
-    miTrapezoidBounds(ntrap, traps, &bounds);
-
-    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-	return;
-
-    x_dst = traps[0].left.p1.x >> 16;
-    y_dst = traps[0].left.p1.y >> 16;
+  ScreenPtr screen = dst->pDrawable->pScreen;
+  BoxRec bounds;
+  PicturePtr picture;
+  INT16 x_dst, y_dst;
+  INT16 x_rel, y_rel;
+  int width, height, stride;
+  PixmapPtr pixmap;
+  GCPtr gc;
+  pixman_image_t *image;
+
+  /* If a mask format wasn't provided, we get to choose, but behavior should
+   * be as if there was no temporary mask the traps were accumulated into.
+   */
+  if (!mask_format) {
+    if (dst->polyEdge == PolyEdgeSharp)
+      mask_format = PictureMatchFormat(screen, 1, PICT_a1);
+    else
+      mask_format = PictureMatchFormat(screen, 8, PICT_a8);
+    for (; ntrap; ntrap--, traps++)
+      glamor_trapezoids(op, src, dst, mask_format, x_src, y_src,
+			1, traps);
+    return;
+  }
 
-    width = bounds.x2 - bounds.x1;
-    height = bounds.y2 - bounds.y1;
-    stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8;
+  miTrapezoidBounds(ntrap, traps, &bounds);
 
-    picture = glamor_create_mask_picture(screen, dst, mask_format,
-					 width, height);
-    if (!picture)
-	return;
+  if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+    return;
 
-    image = pixman_image_create_bits(picture->format,
-				     width, height,
-				     NULL, stride);
-    if (!image) {
-	FreePicture(picture, 0);
-	return;
-    }
+  x_dst = traps[0].left.p1.x >> 16;
+  y_dst = traps[0].left.p1.y >> 16;
 
-    for (; ntrap; ntrap--, traps++)
-	pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps,
-				   -bounds.x1, -bounds.y1);
-
-    pixmap = GetScratchPixmapHeader(screen, width, height,
-				    mask_format->depth,
-				    BitsPerPixel(mask_format->depth),
-				    PixmapBytePad(width, mask_format->depth),
-				    pixman_image_get_data(image));
-    if (!pixmap) {
-	FreePicture(picture, 0);
-	pixman_image_unref(image);
-	return;
-    }
+  width = bounds.x2 - bounds.x1;
+  height = bounds.y2 - bounds.y1;
+  stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8;
 
-    gc = GetScratchGC(picture->pDrawable->depth, screen);
-    if (!gc) {
-	FreeScratchPixmapHeader(pixmap);
-	pixman_image_unref (image);
-	FreePicture(picture, 0);
-	return;
-    }
-    ValidateGC(picture->pDrawable, gc);
-
-    gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable,
-		      gc, 0, 0, width, height, 0, 0);
+  picture = glamor_create_mask_picture(screen, dst, mask_format,
+				       width, height);
+  if (!picture)
+    return;
 
-    FreeScratchGC(gc);
-    FreeScratchPixmapHeader(pixmap);
+  image = pixman_image_create_bits(picture->format,
+				   width, height,
+				   NULL, stride);
+  if (!image) {
+    FreePicture(picture, 0);
+    return;
+  }
+
+  for (; ntrap; ntrap--, traps++)
+    pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps,
+			       -bounds.x1, -bounds.y1);
+
+  pixmap = GetScratchPixmapHeader(screen, width, height,
+				  mask_format->depth,
+				  BitsPerPixel(mask_format->depth),
+				  PixmapBytePad(width, mask_format->depth),
+				  pixman_image_get_data(image));
+  if (!pixmap) {
+    FreePicture(picture, 0);
     pixman_image_unref(image);
+    return;
+  }
 
-    x_rel = bounds.x1 + x_src - x_dst;
-    y_rel = bounds.y1 + y_src - y_dst;
-    CompositePicture(op, src, picture, dst,
-		     x_rel, y_rel,
-		     0, 0,
-		     bounds.x1, bounds.y1,
-		     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+  gc = GetScratchGC(picture->pDrawable->depth, screen);
+  if (!gc) {
+    FreeScratchPixmapHeader(pixmap);
+    pixman_image_unref (image);
     FreePicture(picture, 0);
+    return;
+  }
+  ValidateGC(picture->pDrawable, gc);
+
+  gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable,
+		    gc, 0, 0, width, height, 0, 0);
+
+  FreeScratchGC(gc);
+  FreeScratchPixmapHeader(pixmap);
+  pixman_image_unref(image);
+
+  x_rel = bounds.x1 + x_src - x_dst;
+  y_rel = bounds.y1 + y_src - y_dst;
+  CompositePicture(op, src, picture, dst,
+		   x_rel, y_rel,
+		   0, 0,
+		   bounds.x1, bounds.y1,
+		   bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+  FreePicture(picture, 0);
 }
 
 void
@@ -1213,29 +1351,29 @@ glamor_composite_rects(CARD8 op,
 		       PicturePtr src, PicturePtr dst,
 		       int nrect, glamor_composite_rect_t *rects)
 {
-    int n;
-    glamor_composite_rect_t *r;
-
-    ValidatePicture(src);
-    ValidatePicture(dst);
-
-    if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects))
-	return;
-
-    n = nrect;
-    r = rects;
-
-    while (n--) {
-	CompositePicture(op,
-			 src,
-			 NULL,
-			 dst,
-			 r->x_src, r->y_src,
-			 0, 0,
-			 r->x_dst, r->y_dst,
-			 r->width, r->height);
-	r++;
-    }
+  int n;
+  glamor_composite_rect_t *r;
+
+  ValidatePicture(src);
+  ValidatePicture(dst);
+
+  if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects))
+    return;
+
+  n = nrect;
+  r = rects;
+
+  while (n--) {
+    CompositePicture(op,
+		     src,
+		     NULL,
+		     dst,
+		     r->x_src, r->y_src,
+		     0, 0,
+		     r->x_dst, r->y_dst,
+		     r->width, r->height);
+    r++;
+  }
 }
 
 #endif /* RENDER */
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 6c1c2ff..253f203 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -37,46 +37,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 {
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src;
-    int i, j;
-    int wmax = 0;
+    int ax, i;
+    uint8_t *drawpixels_src = (uint8_t *)src;
     RegionPtr clip = fbGetCompositeClip(gc);
     BoxRec *pbox;
     int x_off, y_off;
 
-    goto fail;
-
-    for (i = 0 ; i < n; i++) {
-	if (wmax < widths[i])
-	    wmax = widths[i];
-    }
-
-    switch (drawable->depth) {
-    case 1:
-	temp_src = malloc(wmax);
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	drawpixels_src = temp_src;
-	break;
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-	format = GL_RGB;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	glamor_fallback("glamor_set_spans()Unknown depth %d\n",
-			drawable->depth);
-	goto fail;
+    if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
+                                               &format, 
+                                               &type, 
+                                               &ax
+                                               )) {
+      glamor_fallback("unknown depth. %d \n", 
+                     drawable->depth);
+      goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(dest_pixmap))
+    if (glamor_set_destination_pixmap(dest_pixmap))
 	goto fail;
     if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 	goto fail;
@@ -87,14 +64,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
 
     for (i = 0; i < n; i++) {
-	if (temp_src) {
-	    for (j = 0; j < widths[i]; j++) {
-		if (src[j / 8] & (1 << (j % 8)))
-		    temp_src[j] = 0xff;
-		else
-		    temp_src[j] = 0;
-	    }
-	}
 
 	n = REGION_NUM_RECTS(clip);
 	pbox = REGION_RECTS(clip);
@@ -113,19 +82,14 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 			 format, type,
 			 drawpixels_src);
 	}
-	if (temp_src) {
-	    src += PixmapBytePad(widths[i], drawable->depth);
-	} else {
 	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
-	}
     }
 fail:
     glDisable(GL_SCISSOR_TEST);
     glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
-    free(temp_src);
 
-    glamor_fallback("glamor_set_spans(): to %p (%c)\n",
+    glamor_fallback("to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 5b1e73d..2991edd 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -91,24 +91,26 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
     float vertices[4][2];
     float source_texcoords[4][2];
-
     if (glamor_priv->tile_prog == 0) {
 	glamor_fallback("Tiling unsupported\n");
 	goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(pixmap))
+    if (glamor_set_destination_pixmap(pixmap)) {
+        glamor_fallback("dest has no fbo.");
 	goto fail;
+    }
 
-    if (tile_priv->tex == 0) {
+    if (tile_priv->gl_tex == 0) {
 	glamor_fallback("Non-texture tile pixmap\n");
 	goto fail;
     }
 
-    if (!glamor_set_planemask(pixmap, planemask))
+    if (!glamor_set_planemask(pixmap, planemask)) {
+        glamor_fallback("unsupported planemask %lx\n", planemask);
 	goto fail;
+    }
     glamor_set_alu(alu);
-
     glUseProgramObjectARB(glamor_priv->tile_prog);
 
     glActiveTexture(GL_TEXTURE0);
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
index 027cfc5..53bfbb9 100644
--- a/hw/kdrive/ephyr/ephyr_glamor.c
+++ b/hw/kdrive/ephyr/ephyr_glamor.c
@@ -45,7 +45,7 @@ ephyr_glamor_init(ScreenPtr screen)
 
     ephyr_glamor_host_create_context(kd_screen);
 
-    glamor_init(screen, 0);
+    glamor_init(screen, GLAMOR_HOSTX);
 
     return TRUE;
 }
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 665cd0a..d0432b3 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -113,8 +113,7 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); 
 
-	glamor_set_pixmap_texture(screen->GetScreenPixmap(screen),
-				  width, height, texture);
+	glamor_set_screen_pixmap_texture(screen, width, height, texture);
 	glamor->root = image;
 	scrn->virtualX = width;
 	scrn->virtualY = height;
commit ba6dd8aa492d9d555d8b175bcf350e5db1821597
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 18:32:15 2011 +0800

    glamor: Simplify fill acceleration for spans/polyfillrect by only clipping once.
    
        This commit was borrowed from uxa driver contributed by Eric.
        commit number is e0066e77e026b0dd0daa0c3765473c7d63aa6753. commit log paste as
        below:
        We were clipping each span against the bounds of the clip, throwing
        out the span early if it was all clipped, and then walked the clip box
        clipping against each of the cliprects.  We would expect spans to
        typically be clipped against one box, and not thrown out, so we were
        not saving any work there.  For multiple cliprects, we were adding
        work.  Only for many spans clipped entirely out of a complicated clip
        region would it have saved work, and it clearly didn't save bugs as
        evidenced by the many fix attempts here.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index a633b30..c6976c3 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -38,68 +38,48 @@ glamor_fill_spans(DrawablePtr drawable,
 		  int *widths,
 		  int sorted)
 {
-    RegionPtr clip = gc->pCompositeClip;
-    BoxPtr extents, boxes;
+    DDXPointPtr ppt;
     int nbox;
-    int extentX1, extentX2, extentY1, extentY2;
-    int fullX1, fullX2, fullY1;
-    int partX1, partX2;
+    BoxPtr pbox;
+    int x1, x2, y;
+    int off_x, off_y;
+    RegionPtr pClip = fbGetCompositeClip(gc);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
 
     if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 	goto fail;
 
-    extents = REGION_EXTENTS(gc->pScreen, clip);
-    extentX1 = extents->x1;
-    extentY1 = extents->y1;
-    extentX2 = extents->x2;
-    extentY2 = extents->y2;
-    while (n--) {
-	fullX1 = points->x;
-	fullY1 = points->y;
-	fullX2 = fullX1 + *widths;
-	points++;
-	widths++;
 
-	if (fullY1 < extentY1 || extentY2 <= fullY1)
-	    continue;
+    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+	ppt = points;
+        while (n--) {
+                x1 = ppt->x;
+                y = ppt->y;
+                x2 = x1 + (int)*widths;
+                ppt++;
+                widths++;
 
-	if (fullX1 < extentX1)
-	    fullX1 = extentX1;
+                nbox = REGION_NUM_RECTS(pClip);
+                pbox = REGION_RECTS(pClip);
+                while (nbox--) {
+                        if (pbox->y1 > y || pbox->y2 <= y)
+                                continue;
 
-	if (fullX2 > extentX2)
-	    fullX2 = extentX2;
+                        if (x1 < pbox->x1)
+                                x1 = pbox->x1;
 
-	if (fullX1 >= fullX2)
-	    continue;
+                        if (x2 > pbox->x2)
+                                x2 = pbox->x2;
 
-	nbox = REGION_NUM_RECTS (clip);
-	if (nbox == 1) {
-	    glamor_fill(drawable,
-			gc,
-			fullX1, fullY1, fullX2-fullX1, 1);
-	} else {
-	    boxes = REGION_RECTS(clip);
-	    while(nbox--)
-	    {
-		if (boxes->y1 <= fullY1 && fullY1 < boxes->y2)
-		{
-		    partX1 = boxes->x1;
-		    if (partX1 < fullX1)
-			partX1 = fullX1;
-		    partX2 = boxes->x2;
-		    if (partX2 > fullX2)
-			partX2 = fullX2;
-		    if (partX2 > partX1)
-		    {
-			glamor_fill(drawable, gc,
-				    partX1, fullY1,
-				    partX2 - partX1, 1);
-		    }
-		}
-		boxes++;
-	    }
-	}
-    }
+                        if (x2 <= x1)
+                                continue;
+                        glamor_fill (drawable,gc,
+                                     x1 + off_x, y + off_y,
+                                     x2 - x1 ,  1);
+                        pbox++;
+                }
+        }
     return;
 fail:
     glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 29e9db5..660dc4a 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -43,80 +43,60 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 		      int nrect,
 		      xRectangle *prect)
 {
-    RegionPtr	    clip = fbGetCompositeClip(gc);
-    register BoxPtr box;
-    BoxPtr	    pextent;
-    int		    extentX1, extentX2, extentY1, extentY2;
     int		    fullX1, fullX2, fullY1, fullY2;
-    int		    partX1, partX2, partY1, partY2;
     int		    xorg, yorg;
     int		    n;
+    register BoxPtr pbox;
+    int off_x, off_y;
+    RegionPtr pClip = fbGetCompositeClip(gc);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 
     if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 	goto fail;
 
     xorg = drawable->x;
     yorg = drawable->y;
-
-    pextent = REGION_EXTENTS(gc->pScreen, clip);
-    extentX1 = pextent->x1;
-    extentY1 = pextent->y1;
-    extentX2 = pextent->x2;
-    extentY2 = pextent->y2;
-    while (nrect--)
-    {
-	fullX1 = prect->x + xorg;
-	fullY1 = prect->y + yorg;
-	fullX2 = fullX1 + (int)prect->width;
-	fullY2 = fullY1 + (int)prect->height;
-	prect++;
-
-	if (fullX1 < extentX1)
-	    fullX1 = extentX1;
-
-	if (fullY1 < extentY1)
-	    fullY1 = extentY1;
-
-	if (fullX2 > extentX2)
-	    fullX2 = extentX2;
-
-	if (fullY2 > extentY2)
-	    fullY2 = extentY2;
-
-	if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
-	    continue;
-	n = REGION_NUM_RECTS(clip);
-	if (n == 1) {
-	    glamor_fill(drawable,
-			gc,
-			fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
-	} else {
-	    box = REGION_RECTS(clip);
-	    /* clip the rectangle to each box in the clip region
-	     * this is logically equivalent to calling Intersect()
-	     */
-	    while (n--) {
-		partX1 = box->x1;
-		if (partX1 < fullX1)
-		    partX1 = fullX1;
-		partY1 = box->y1;
-		if (partY1 < fullY1)
-		    partY1 = fullY1;
-		partX2 = box->x2;
-		if (partX2 > fullX2)
-		    partX2 = fullX2;
-		partY2 = box->y2;
-		if (partY2 > fullY2)
-		    partY2 = fullY2;
-
-		box++;
-
-		if (partX1 < partX2 && partY1 < partY2)
-		    glamor_fill(drawable, gc,
-				partX1, partY1,
-				partX2 - partX1, partY2 - partY1);
-	    }
-	}
+    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+        while (nrect--) {
+                fullX1 = prect->x + xorg;
+                fullY1 = prect->y + yorg;
+                fullX2 = fullX1 + (int)prect->width;
+                fullY2 = fullY1 + (int)prect->height;
+                prect++;
+
+                n = REGION_NUM_RECTS(pClip);
+                pbox = REGION_RECTS(pClip);
+                /*
+                 * clip the rectangle to each box in the clip region
+                 * this is logically equivalent to calling Intersect(),
+                 * but rectangles may overlap each other here.
+                 */
+                while (n--) {
+                        int x1 = fullX1;
+                        int x2 = fullX2;
+                        int y1 = fullY1;
+                        int y2 = fullY2;
+
+                        if (pbox->x1 > x1)
+                                x1 = pbox->x1;
+                        if (pbox->x2 < x2)
+                                x2 = pbox->x2;
+                        if (pbox->y1 > y1)
+                                y1 = pbox->y1;
+                        if (pbox->y2 < y2)
+                                y2 = pbox->y2;
+                        pbox++;
+
+                        if (x1 >= x2 || y1 >= y2)
+                                continue;
+	                glamor_fill(drawable,
+			            gc,
+				    x1 + off_x,
+				    y1 + off_y,
+				    x2 - x1,
+                                    y2 - y1);
+                }
     }
     return;
 
commit a0a52be73994c93521e94f1f10152ce851485ea3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 16:51:27 2011 +0800

    glamor: Fallback to fbPolylines for diagonal poly_line.
    
    It's better to give a correct output when we haven't
    implement all the code path.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index c975268..75bc9bf 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -76,17 +76,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	    x2 = points[i + 1].x;
 	    y2 = points[i + 1].y;
 	}
-
 	if (x1 != x2 && y1 != y2) {
 	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
 	    free(rects);
-
-	    ErrorF("stub diagonal poly_line\n");
-	    glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1);
+	    glamor_fallback("stub diagonal poly_line\n");
+	    goto fail;
 	    return;
 	}
-
 	if (x1 < x2) {
 	    rects[i].x = x1;
 	    rects[i].width = x2 - x1 + 1;
commit d7f8b888d0961af8d0ec6ad5c920ce758529b620
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 16:01:40 2011 +0800

    glamor: For non-supported fill style fallback to fbFill.
    
    The previous implementation will just skip the rendering
    which is not good.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 14031d2..a517045 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -621,15 +621,17 @@ glamor_finish_access_gc(GCPtr gc)
 		glamor_finish_access(&gc->stipple->drawable);
 }
 
-void
+Bool
 glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 	       int x, int y, int width, int height,
 	       unsigned char alu, unsigned long planemask,
 	       unsigned long fg_pixel, unsigned long bg_pixel,
 	       int stipple_x, int stipple_y)
 {
-    ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth);
-    glamor_solid_fail_region(pixmap, x, y, width, height);
+    glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
+    return FALSE;
+//    ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth);
+//    glamor_solid_fail_region(pixmap, x, y, width, height);
 }
 
 GCOps glamor_gc_ops = {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 8ea70d0..2b94934 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -42,23 +42,23 @@ glamor_fill(DrawablePtr drawable,
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
     int x_off, y_off;
-
     glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off);
 
     switch (gc->fillStyle) {
     case FillSolid:
-	glamor_solid(dst_pixmap,
-		     x + x_off,
-		     y + y_off,
-		     width,
-		     height,
-		     gc->alu,
-		     gc->planemask,
-		     gc->fgPixel);
+	if (!glamor_solid(dst_pixmap,
+                         x + x_off,
+                         y + y_off,
+		         width,
+		         height,
+		         gc->alu,
+		         gc->planemask,
+		         gc->fgPixel))
+	goto fail;
 	break;
     case FillStippled:
     case FillOpaqueStippled:
-	glamor_stipple(dst_pixmap,
+	if (!glamor_stipple(dst_pixmap,
 		       gc->stipple,
 		       x+ x_off,
 		       y + y_off,
@@ -69,10 +69,12 @@ glamor_fill(DrawablePtr drawable,
 		       gc->fgPixel,
 		       gc->bgPixel,
 		       gc->patOrg.x + x_off,
-		       gc->patOrg.y + y_off);
+		       gc->patOrg.y + y_off))
+	goto fail;
+        return;
 	break;
     case FillTiled:
-	glamor_tile(dst_pixmap,
+	if (!glamor_tile(dst_pixmap,
 		    gc->tile.pixmap,
 		    x + x_off,
 		    y + y_off,
@@ -81,12 +83,12 @@ glamor_fill(DrawablePtr drawable,
 		    gc->alu,
 		    gc->planemask,
 		    drawable->x + x - gc->patOrg.x,
-		    drawable->y + y - gc->patOrg.y);
+		    drawable->y + y - gc->patOrg.y))
+	goto fail;
 	break;
     }
     return;
-#if 0
- fail:
+fail:
     glamor_fallback("glamor_fill()");
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	if (glamor_prepare_access_gc(gc)) {
@@ -95,7 +97,6 @@ glamor_fill(DrawablePtr drawable,
 	}
 	glamor_finish_access(drawable);
     }
-#endif
 return;
 
 }
@@ -140,7 +141,7 @@ glamor_init_solid_shader(ScreenPtr screen)
 	glGetUniformLocationARB(glamor_priv->solid_prog, "color");
 }
 
-void
+Bool
 glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 	     unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
 {
@@ -154,12 +155,12 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     float vertices[4][2];
 
     if (!glamor_set_destination_pixmap(pixmap))
-	return;
+	goto fail;
     glamor_set_alu(alu);
     if (!glamor_set_planemask(pixmap, planemask)) {
-	ErrorF("Failedto set planemask  in glamor_solid.\n");
-	goto fail;
-	}
+      ErrorF("Failedto set planemask  in glamor_solid.\n");
+      goto fail;
+    } 
 
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
@@ -188,9 +189,11 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 
     glDisableClientState(GL_VERTEX_ARRAY);
     glUseProgramObjectARB(0);
+    return TRUE;
 fail:
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
+    return FALSE;
 }
 
 /* Highlight places where we're doing it wrong. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9f16792..1dc2c42 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -350,7 +350,7 @@ const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
 				int *x, int *y);
 Bool glamor_create_gc(GCPtr gc);
-void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
+Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
 		    unsigned char alu, unsigned long planemask,
 		    unsigned long fg_pixel, unsigned long bg_pixel,
@@ -376,7 +376,7 @@ void glamor_fill(DrawablePtr drawable,
 		 int y,
 		 int width,
 		 int height);
-void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		  unsigned char alu, unsigned long planemask,
 		  unsigned long fg_pixel);
 void glamor_solid_fail_region(PixmapPtr pixmap,
@@ -456,7 +456,7 @@ void glamor_composite_rects(CARD8 op,
 			    int nrect, glamor_composite_rect_t *rects);
 
 /* glamor_tile.c */
-void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 int x, int y, int width, int height,
 		 unsigned char alu, unsigned long planemask,
 		 int tile_x, int tile_y);
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 5892370..5b1e73d 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -72,7 +72,7 @@ glamor_init_tile_shader(ScreenPtr screen)
     glUseProgramObjectARB(0);
 }
 
-void
+Bool
 glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	    int x, int y, int width, int height,
 	    unsigned char alu, unsigned long planemask,
@@ -93,7 +93,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     float source_texcoords[4][2];
 
     if (glamor_priv->tile_prog == 0) {
-	ErrorF("Tiling unsupported\n");
+	glamor_fallback("Tiling unsupported\n");
 	goto fail;
     }
 
@@ -101,7 +101,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	goto fail;
 
     if (tile_priv->tex == 0) {
-	ErrorF("Non-texture tile pixmap\n");
+	glamor_fallback("Non-texture tile pixmap\n");
 	goto fail;
     }
 
@@ -167,9 +167,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glDisable(GL_TEXTURE_2D);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
-    return;
+    return TRUE;
 
 fail:
-    glamor_solid_fail_region(pixmap, x, y, width, height);
-    return;
+    return FALSE;
 }
commit b60e6cb66d3fba43d5403b2b5027537d09ee7c98
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 15:46:23 2011 +0800

    glamor: Silence compilation warnings.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7eebba3..d6d6d95 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -102,7 +102,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     PixmapPtr pixmap;
     GLenum format;
     GLuint tex;
-    glamor_pixmap_private *pixmap_priv;
     enum glamor_pixmap_type type = GLAMOR_GL;
 
     if (w > 32767 || h > 32767)
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 33610a6..c49662e 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -34,6 +34,7 @@
 #include "gcstruct.h"
 #include "picturestr.h"
 #include "fb.h"
+#include "fbpict.h"
 
 #endif /* GLAMOR_H */
 
commit 229240e565f976de8e7b82dd606c2e862152b2b5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 14:07:54 2011 +0800

    glamor: Add render triangles support.
    
    By default, fallback to frame buffer currently. This commit
    makes us pass the rendercheck's triangles testing.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index e823234..8f62920 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -30,6 +30,7 @@ libglamor_la_SOURCES = \
 	glamor_setspans.c \
 	glamor_render.c \
 	glamor_tile.c \
+        glamor_triangles.c\
 	glamor.h
 libglamor_la_LIBADD = \
 	glu3/libglu3.la
diff --git a/glamor/glamor.c b/glamor/glamor.c
index be5999a..7eebba3 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -279,6 +279,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     ps->Trapezoids = glamor_trapezoids;
     glamor_priv->saved_glyphs = ps->Glyphs;
     ps->Glyphs = glamor_glyphs;
+    glamor_priv->saved_triangles = ps->Triangles;
+    ps->Triangles = glamor_triangles;
     glamor_init_composite_shaders(screen);
 #endif
     glamor_init_solid_shader(screen);
@@ -317,6 +319,7 @@ glamor_close_screen(int idx, ScreenPtr screen)
 	ps->Composite = glamor_priv->saved_composite;
 	ps->Trapezoids = glamor_priv->saved_trapezoids;
 	ps->Glyphs = glamor_priv->saved_glyphs;
+        ps->Triangles = glamor_priv->saved_triangles;
     }
 #endif
     free(glamor_priv);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8c9ff85..9f16792 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -148,6 +148,7 @@ typedef struct glamor_screen_private {
     ChangeWindowAttributesProcPtr saved_change_window_attributes;
     CopyWindowProcPtr saved_copy_window;
     BitmapToRegionProcPtr saved_bitmap_to_region;
+    TrianglesProcPtr saved_triangles;
 
     char *delayed_fallback_string;
     int yInverted;
@@ -232,8 +233,8 @@ glamor_fallback(char *format, ...)
     va_list ap;
 
     va_start(ap, format);
-    LogMessageVerb(X_INFO, 3, "fallback: ");
-    LogMessageVerb(X_NONE, 3, format, ap);
+    //LogMessageVerb(X_INFO, 3, "fallback: ");
+    //LogMessageVerb(X_NONE, 3, format, ap);
     va_end(ap);
 }
 
@@ -266,8 +267,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
     if (glamor_priv->delayed_fallback_string) {
-      	LogMessageVerb(X_INFO, 3, "fallback: %s",
-      	       glamor_priv->delayed_fallback_string);
+      	//LogMessageVerb(X_INFO, 3, "fallback: %s",
+      	//       glamor_priv->delayed_fallback_string);
 	glamor_clear_delayed_fallbacks(screen);
     }
 }
@@ -461,4 +462,15 @@ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 int tile_x, int tile_y);
 void glamor_init_tile_shader(ScreenPtr screen);
 
+/* glamor_triangles */
+void
+glamor_triangles (CARD8	    op,
+	     PicturePtr    pSrc,
+	     PicturePtr    pDst,
+	     PictFormatPtr maskFormat,
+	     INT16	    xSrc,
+	     INT16	    ySrc,
+	     int	    ntris,
+	     xTriangle    *tris);
+
 #endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c
new file mode 100644
index 0000000..168d485
--- /dev/null
+++ b/glamor/glamor_triangles.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Zhigang Gong <zhigang.gong at gmail.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+void
+glamor_triangles (CARD8	    op,
+	     PicturePtr    pSrc,
+	     PicturePtr    pDst,
+	     PictFormatPtr maskFormat,
+	     INT16	    xSrc,
+	     INT16	    ySrc,
+	     int	    ntris,
+	     xTriangle    *tris)
+{ 
+
+    if (glamor_prepare_access(pDst->pDrawable, GLAMOR_ACCESS_RW)) {
+	if (pSrc->pDrawable == NULL ||
+	    glamor_prepare_access(pSrc->pDrawable, GLAMOR_ACCESS_RO))
+	{
+
+                fbTriangles(op, 
+                            pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
+	}
+	    if (pSrc->pDrawable != NULL)
+		glamor_finish_access(pSrc->pDrawable);
+
+	glamor_finish_access(pDst->pDrawable);
+	}
+}
+
+
commit ac0589c91699433bc9dbc25b7edff456dff742a4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Jun 10 14:02:19 2011 +0800

    glamor: Use software fb for 1bpp pixmap.
    
    For 1bpp pixmap, software fb get better performance than
    GL surface. The main reason is that fbo doesn't support
    1bpp texture as internal format, so we have to translate
    a 1bpp bitmap to a 8bit alpha format each time which is
    very inefficient. And the previous implementation is
    not supported by the latest OpenGL 4.0, the GL_BITMAP
    was deprecated.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 42e3986..be5999a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -108,7 +108,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    if (w > MAX_WIDTH || h > MAX_HEIGHT) {
+    if (w > MAX_WIDTH || h > MAX_HEIGHT || ( depth == 1 && w != 0 && h != 0)) {
 	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
  	   If we exceed such limitation, we have to use framebuffer.*/
       type = GLAMOR_FB;
@@ -117,7 +117,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                               (((w * pixmap->drawable.bitsPerPixel +
                                  7) / 8) + 3) & ~3,
                               NULL);
-      ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h);
+
+      glamor_fallback("fallback to software fb for pixmap %p , %d x %d depth %d\n", pixmap, w, h, depth);
    } else 
       pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 0bfa760..14031d2 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -309,13 +309,8 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
-	
+    assert(drawable->depth != 1);	
     switch (drawable->depth) {
-    case 1:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	row_length = stride;
-	break;
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
@@ -485,14 +480,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
     else
        ptexcoords = texcoords;
 
+    assert(pixmap->drawable.depth != 1);	
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
     switch (pixmap->drawable.depth) {
-    case 1:
-	format = GL_COLOR_INDEX;
-	type = GL_BITMAP;
-	row_length = stride;
-	break;
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
commit 3c44e3e0ce1e286e0540298d5db547c43903629f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 1 19:35:15 2011 +0800

    glamor: Optimize composite when soure/mask is xrgb.
    
    Added a new shader aswizlle_prog to wired the alpha to 1 when
    the image color depth is 24 (xrgb). Then we don't need to fallback
    the xrgb source/mask to software composite in render phase. Also
    don't wire the alpha bit to 1 in the render phase. This can get
    about 2x performance gain with the cairo performance trace's
    firefox-planet case.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f9e43c5..0bfa760 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride, row_length, x, y;
+    unsigned int stride, row_length, y;
     GLenum format, type;
     uint8_t *data, *read;
     glamor_screen_private *glamor_priv =
@@ -399,20 +399,38 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	"{\n"
 	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
 	"}\n";
-    GLint fs_prog, vs_prog;
+    
+    const char *aswizzle_source =
+        "varying vec2 texcoords;\n"
+        "uniform sampler2D sampler;\n"
+        "void main()\n"
+        "{\n"
+        " gl_FragColor = vec4(texture2D(sampler, gl_TexCoord[0].xy).rgb, 1);\n"
+        "}\n";
+
+    GLint fs_prog, vs_prog, avs_prog, aswizzle_prog;
 
     glamor_priv->finish_access_prog = glCreateProgramObjectARB();
+    glamor_priv->aswizzle_prog = glCreateProgramObjectARB();
+
     if (GLEW_ARB_fragment_shader) {
 	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
 	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
 	glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog);
+
+        avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+        aswizzle_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, aswizzle_source);
+        glAttachObjectARB(glamor_priv->aswizzle_prog, avs_prog);
+        glAttachObjectARB(glamor_priv->aswizzle_prog, aswizzle_prog);
     } else {
 	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
 	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
+        ErrorF("Lack of framgment shader support.\n");
     }
 
     glamor_link_glsl_prog(glamor_priv->finish_access_prog);
+    glamor_link_glsl_prog(glamor_priv->aswizzle_prog);
 
     if (GLEW_ARB_fragment_shader) {
 	GLint sampler_uniform_location;
@@ -422,6 +440,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
 	glUseProgramObjectARB(glamor_priv->finish_access_prog);
 	glUniform1iARB(sampler_uniform_location, 0);
 	glUseProgramObjectARB(0);
+
+        sampler_uniform_location =
+            glGetUniformLocationARB(glamor_priv->aswizzle_prog, "sampler");
+        glUseProgramObjectARB(glamor_priv->aswizzle_prog);
+        glUniform1iARB(sampler_uniform_location, 0);
+        glUseProgramObjectARB(0);
     }
 }
 
@@ -429,7 +453,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
  * Load texture from the pixmap's data pointer and then
  * draw the texture to the fbo, and flip the y axis.
  * */
-void
+static void
 glamor_load_texture_pixmap(PixmapPtr pixmap)
 {
 
@@ -454,9 +478,12 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
 
     void * texel;
     GLuint tex;
+    int alfa_mode = 0;
 
     if (glamor_priv->yInverted)
        ptexcoords = texcoords_inverted;
+    else
+       ptexcoords = texcoords;
 
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
@@ -473,6 +500,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
     case 24:
 	assert(pixmap->drawable.bitsPerPixel == 32);
 	/* FALLTHROUGH */
+        alfa_mode = 1;
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -515,7 +543,10 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
     glEnable(GL_TEXTURE_2D);
 
     assert(GLEW_ARB_fragment_shader);
-    glUseProgramObjectARB(glamor_priv->finish_access_prog);
+    if (alfa_mode == 0)
+      glUseProgramObjectARB(glamor_priv->finish_access_prog);
+    else
+      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     glDisable(GL_TEXTURE_2D);
@@ -547,14 +578,12 @@ glamor_finish_access(DrawablePtr drawable)
 	    return;
     }
 
-
     if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
       glamor_load_texture_pixmap(pixmap);
     }
 
    if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-     glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
      glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
      glDeleteBuffersARB (1, &pixmap_priv->pbo);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d88626f..8c9ff85 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -159,6 +159,7 @@ typedef struct glamor_screen_private {
 
     /* glamor_finishaccess */
     GLint finish_access_prog;
+    GLint aswizzle_prog;
 
     /* glamor_solid */
     GLint solid_prog;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 6a9c1aa..f1081b0 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -256,7 +256,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int x_off, y_off;
     float vertices[4][2], texcoords[4][2];
     GLuint tex;
-
+    int alfa_mode = 0;
     if (image_format == XYBitmap) {
 	assert(depth == 1);
 	glamor_put_image_xybitmap(drawable, gc, x, y, w, h,
@@ -299,6 +299,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     case 24:
 	assert(drawable->bitsPerPixel == 32);
 	/* FALLTHROUGH */
+        alfa_mode = 1;
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -340,8 +341,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glEnable(GL_TEXTURE_2D);
 
     assert(GLEW_ARB_fragment_shader);
-    glUseProgramObjectARB(glamor_priv->finish_access_prog);
-
+    if (alfa_mode == 0)
+      glUseProgramObjectARB(glamor_priv->finish_access_prog);
+    else
+      glUseProgramObjectARB(glamor_priv->aswizzle_prog);
 
     x += drawable->x;
     y += drawable->y;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6139b0d..e69d370 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -86,8 +86,7 @@ glamor_create_composite_fs(struct shader_key *key)
 	"uniform sampler2D source_sampler;\n"
 	"vec4 get_source()\n"
 	"{\n"
-	"	return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n"
-	"		    1.0);\n"
+        "       return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
 	"}\n";
     const char *mask_solid_fetch =
 	"uniform vec4 mask;\n"
@@ -105,8 +104,7 @@ glamor_create_composite_fs(struct shader_key *key)
 	"uniform sampler2D mask_sampler;\n"
 	"vec4 get_mask()\n"
 	"{\n"
-	"	return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n"
-	"		    1.0);\n"
+        "       return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
 	"}\n";
     const char *in_source_only =
 	"void main()\n"
@@ -495,15 +493,8 @@ good_source_format(PicturePtr picture)
     case PICT_a1:
     case PICT_a8:
     case PICT_a8r8g8b8:
-	return TRUE;
     case PICT_x8r8g8b8:
-	/* In order to support formats with no alpha, we have to wire the
-	 * alpha to 1 in the shader, which conflicts with
-	 * GL_CLAMP_TO_BORDERing to transparent.  We could possibly compute
-	 * coverage of the texels in the sampling area if we need to, but
-	 * that isn't implemented today.
-	 */
-	return (picture->repeatType != RepeatNone);
+	return TRUE;
     default:
 	glamor_fallback("Bad source format 0x%08x\n", picture->format);
 	return FALSE;
@@ -517,15 +508,8 @@ good_mask_format(PicturePtr picture)
     case PICT_a1:
     case PICT_a8:
     case PICT_a8r8g8b8:
-	return TRUE;
     case PICT_x8r8g8b8:
-	/* In order to support formats with no alpha, we have to wire the
-	 * alpha to 1 in the shader, which conflicts with
-	 * GL_CLAMP_TO_BORDERing to transparent.  We could possibly compute
-	 * coverage of the texels in the sampling area if we need to, but
-	 * that isn't implemented today.
-	 */
-	return (picture->repeatType != RepeatNone);
+	return TRUE;
     default:
 	glamor_fallback("Bad mask format 0x%08x\n", picture->format);
 	return FALSE;
commit 0e2af4d0c942405dd0869f1e6a1effee943de139
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 1 18:14:01 2011 +0800

    glamor: Don't print those fallback messages by default.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 8ded91a..d88626f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -231,8 +231,8 @@ glamor_fallback(char *format, ...)
     va_list ap;
 
     va_start(ap, format);
-    LogMessageVerb(X_INFO, 0, "fallback: ");
-    LogVMessageVerb(X_NONE, 0, format, ap);
+    LogMessageVerb(X_INFO, 3, "fallback: ");
+    LogMessageVerb(X_NONE, 3, format, ap);
     va_end(ap);
 }
 
@@ -265,8 +265,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
     if (glamor_priv->delayed_fallback_string) {
-      //	LogMessageVerb(X_INFO, 0, "fallback: %s",
-      //	       glamor_priv->delayed_fallback_string);
+      	LogMessageVerb(X_INFO, 3, "fallback: %s",
+      	       glamor_priv->delayed_fallback_string);
 	glamor_clear_delayed_fallbacks(screen);
     }
 }
commit 925fc9724ff72d9e2a4940d7a1e39c23fb3ec9f0
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 1 18:02:03 2011 +0800

    glamor: Optimize glamor_finish_access.
    
    use pbo if possible when we load texture to a temporary tex.
    And for the previous direct texture load function, it's not
    correct and get removed in this commit.
    
    Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index d41b26d..f9e43c5 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -295,7 +295,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(drawable->pScreen);
 
-    if (pixmap_priv == NULL)
+    if (!pixmap_priv)
 	return TRUE;
 
     if (pixmap_priv->fb == 0) {
@@ -425,53 +425,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     }
 }
 
-/* Load the pixmap's data to the fbo's texutre directly. 
- * Only useful when the platform enable yInverted, for
- * example MESA/EGL. 
- * */
-void glamor_load_texture_pixmap_direct(PixmapPtr pixmap)
-{
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(pixmap->drawable.pScreen);
-    unsigned int stride, row_length;
-    GLenum format, type;
-
-    stride = pixmap->devKind;
-    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-    switch (pixmap->drawable.depth) {
-    case 1:
-	format = GL_COLOR_INDEX;
-	type = GL_BITMAP;
-	row_length = stride;
-	break;
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-	break;
-    case 24:
-	assert(pixmap->drawable.bitsPerPixel == 32);
-	/* FALLTHROUGH */
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth);
-	return;
-    }
-
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-		 pixmap->drawable.width, pixmap->drawable.height, 0,
-		 format, type, pixmap->devPrivate.ptr);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-}
-
-
 /* 
  * Load texture from the pixmap's data pointer and then
  * draw the texture to the fbo, and flip the y axis.
@@ -493,8 +446,18 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
 				 1, 1,
 				 1, 0,
 				 0, 0};
+    static float texcoords_inverted[8] = {0, 0,
+                                1, 0,
+                                1, 1,
+                                0, 1};
+    float *ptexcoords;
+
+    void * texel;
     GLuint tex;
 
+    if (glamor_priv->yInverted)
+       ptexcoords = texcoords_inverted;
+
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
     switch (pixmap->drawable.depth) {
@@ -523,7 +486,7 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
     glEnableClientState(GL_VERTEX_ARRAY);
 
     glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
@@ -535,9 +498,18 @@ glamor_load_texture_pixmap(PixmapPtr pixmap)
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
+
+    if (glamor_priv->yInverted || GLEW_MESA_pack_invert) {
+      texel = NULL;
+      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+    }
+    else
+      texel = pixmap->devPrivate.ptr;
+
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
 		 pixmap->drawable.width, pixmap->drawable.height, 0,
-		 format, type, pixmap->devPrivate.ptr);
+		 format, type, texel);
+
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glEnable(GL_TEXTURE_2D);
@@ -560,13 +532,11 @@ glamor_finish_access(DrawablePtr drawable)
 	glamor_get_screen_private(drawable->pScreen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride, row_length;
-    GLenum format, type;
     /* Check if finish_access was already called once on this */
     if (pixmap->devPrivate.ptr == NULL)
 	return;
 
-    if (pixmap_priv == NULL)
+    if (!pixmap_priv)
 	return;
 
     if (pixmap_priv->fb == 0) {
@@ -577,21 +547,20 @@ glamor_finish_access(DrawablePtr drawable)
 	    return;
     }
 
-    if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
-      if (glamor_priv->yInverted) 
-        glamor_load_texture_pixmap_direct(pixmap);
-      else 
-        glamor_load_texture_pixmap(pixmap);
-    } 
 
-    if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
-      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-      glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
-      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
-      glDeleteBuffersARB (1, &pixmap_priv->pbo);
-      pixmap_priv->pbo = 0;
-    } else
-      free(pixmap->devPrivate.ptr);
+    if ( pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
+      glamor_load_texture_pixmap(pixmap);
+    }
+
+   if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
+     glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+     glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
+     glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
+     glBindBufferARB (GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+     glDeleteBuffersARB (1, &pixmap_priv->pbo);
+     pixmap_priv->pbo = 0;
+   } else
+     free(pixmap->devPrivate.ptr);
 
     pixmap->devPrivate.ptr = NULL;
 }
commit b8ce483f58112f200dec9853fcd7ff455479990f
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Jun 1 17:54:01 2011 +0800

    glamor: Don't use glamor_pixmap_type currently.
    
    Added comments to glamor_pixmap_create. To be refined in the future.
    We need to identify whether a pixmap is a CPU memory pixmap or a
    GPU pixmap. Current implementation is not correct. There are three
    cases:
    
    1. Too large pixmap, we direct it to CPU memory pixmap.
    2. w ==0 ||  h == 0 pixmap, this case has two possibilities:
       2.1 It will become a screen pixmap latter, then it should be
           GPU type.
       2.2 It's a scratch pixmap or created from a share memory, then
           it should belong to CPU memory.
    
    XXX, need to be refined latter.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 4594f14..42e3986 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -67,6 +67,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
     glamor_pixmap_private *pixmap_priv;
 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
+    assert(pixmap_priv);
     pixmap_priv->tex = tex;
 
     /* Create a framebuffer object wrapping the texture so that we can render
@@ -87,6 +88,12 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
 }
 
 
+/* XXX For the screen pixmap, the w and h maybe 0,0 too, but it should
+ * be GLAMOR_GL pixmap. Now, all the pixmap will have a valid pixmap_priv. 
+ * This is not good enough. After we can identify which is the screen
+ * pixmap and which is not, then we can split the pixmap to exclusive
+ * two types GLAMOR_GL and GLAMOR_FB, and for those GLAMOR_FB pixmaps, 
+ * we don't need to allocate pixmap_priv. */
 
 static PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
@@ -96,7 +103,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     GLenum format;
     GLuint tex;
     glamor_pixmap_private *pixmap_priv;
-    int type = GLAMOR_GL;
+    enum glamor_pixmap_type type = GLAMOR_GL;
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
@@ -111,7 +118,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                                  7) / 8) + 3) & ~3,
                               NULL);
       ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h);
-   } else
+   } else 
       pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
     if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
@@ -120,12 +127,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return NullPixmap;
     }	 
 
-    if (w == 0 || h == 0 || type != GLAMOR_GL)
+    if (w == 0 || h == 0 || type == GLAMOR_FB)
 	return pixmap;
 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    pixmap_priv->type = type;
-
     /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
      * FBOs, which EXT_fbo forgot to do.
      */
commit 28835be1b8a05e510aa7fcc2f331771e3cf7dfec
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Tue May 24 22:01:49 2011 +0800

    glamor: improve glamor_finish_access.
    
    When the platform's coordinate system is the same as X11's . We
    can load the texture to the fbo directly without one extra texture
    transformation.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f5fc1a3..d41b26d 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -425,56 +425,79 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     }
 }
 
-void
-glamor_finish_access(DrawablePtr drawable)
+/* Load the pixmap's data to the fbo's texutre directly. 
+ * Only useful when the platform enable yInverted, for
+ * example MESA/EGL. 
+ * */
+void glamor_load_texture_pixmap_direct(PixmapPtr pixmap)
 {
-    glamor_screen_private *glamor_priv =
-	glamor_get_screen_private(drawable->pScreen);
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(pixmap->drawable.pScreen);
     unsigned int stride, row_length;
     GLenum format, type;
-    static float vertices[4][2] = {{-1, -1},
-				   { 1, -1},
-				   { 1,  1},
-				   {-1,  1}};
-    static float texcoords[4][2] = {{0, 1},
-				    {1, 1},
-				    {1, 0},
-				    {0, 0}};
 
-    GLuint tex;
-    static float texcoords_inverted[4][2] =    {{0, 0},
-				    		{1, 0},
-				    		{1, 1},
-				    		{0, 1}};
-   static float *ptexcoords;
-
-    if (pixmap_priv == NULL)
+    stride = pixmap->devKind;
+    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
+    switch (pixmap->drawable.depth) {
+    case 1:
+	format = GL_COLOR_INDEX;
+	type = GL_BITMAP;
+	row_length = stride;
+	break;
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 24:
+	assert(pixmap->drawable.bitsPerPixel == 32);
+	/* FALLTHROUGH */
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth);
 	return;
-    if (glamor_priv->yInverted)
-	ptexcoords = &texcoords_inverted[0][0];
-    else
-	ptexcoords = &texcoords[0][0];
+    }
 
-    if (pixmap_priv->fb == 0) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+		 pixmap->drawable.width, pixmap->drawable.height, 0,
+		 format, type, pixmap->devPrivate.ptr);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+}
 
-	if (pixmap != screen_pixmap)
-	    return;
-    }
 
-    /* Check if finish_access was already called once on this */
-    if (pixmap->devPrivate.ptr == NULL)
-	return;
+/* 
+ * Load texture from the pixmap's data pointer and then
+ * draw the texture to the fbo, and flip the y axis.
+ * */
+void
+glamor_load_texture_pixmap(PixmapPtr pixmap)
+{
 
-    if (pixmap_priv->access_mode == GLAMOR_ACCESS_RO)
-      goto read_only;
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(pixmap->drawable.pScreen);
+    unsigned int stride, row_length;
+    GLenum format, type;
+    static float vertices[8] = {-1, -1,
+				 1, -1,
+				 1,  1,
+				 -1, 1};
+    static float texcoords[8] = {0, 1,
+				 1, 1,
+				 1, 0,
+				 0, 0};
+    GLuint tex;
 
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
-    switch (drawable->depth) {
+    switch (pixmap->drawable.depth) {
     case 1:
 	format = GL_COLOR_INDEX;
 	type = GL_BITMAP;
@@ -485,23 +508,22 @@ glamor_finish_access(DrawablePtr drawable)
 	type = GL_UNSIGNED_BYTE;
 	break;
     case 24:
-	assert(drawable->bitsPerPixel == 32);
+	assert(pixmap->drawable.bitsPerPixel == 32);
 	/* FALLTHROUGH */
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 	break;
     default:
-	ErrorF("Unknown finishaccess depth %d\n", drawable->depth);
+	ErrorF("Unknown finishaccess depth %d\n", pixmap->drawable.depth);
 	return;
     }
 
-
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
     glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
@@ -529,8 +551,39 @@ glamor_finish_access(DrawablePtr drawable)
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tex);
+}
+
+void
+glamor_finish_access(DrawablePtr drawable)
+{
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(drawable->pScreen);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    unsigned int stride, row_length;
+    GLenum format, type;
+    /* Check if finish_access was already called once on this */
+    if (pixmap->devPrivate.ptr == NULL)
+	return;
+
+    if (pixmap_priv == NULL)
+	return;
+
+    if (pixmap_priv->fb == 0) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (pixmap != screen_pixmap)
+	    return;
+    }
+
+    if (pixmap_priv->access_mode != GLAMOR_ACCESS_RO) {
+      if (glamor_priv->yInverted) 
+        glamor_load_texture_pixmap_direct(pixmap);
+      else 
+        glamor_load_texture_pixmap(pixmap);
+    } 
 
-read_only:
     if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
       glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
       glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
@@ -542,7 +595,6 @@ read_only:
 
     pixmap->devPrivate.ptr = NULL;
 }
-
 /**
  * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
  * current fill style.
commit 1edf0cc6ab340c98fde201328631ca61e9d871a1
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun May 22 23:45:51 2011 +0800

    glamor: Don't write back read only pixmap to fbo.
    
    For those pixmap which has valid fbo and opened as GLAMOR_ACCESS_RO
    mode, we don't need to upload the texture back when calling the
    glamor_finish_access(). This will get about 10% performance gain.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 635b726..f5fc1a3 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -332,6 +332,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	return FALSE;
     }
 
+    pixmap_priv->access_mode = access;
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
     glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
@@ -468,6 +469,9 @@ glamor_finish_access(DrawablePtr drawable)
     if (pixmap->devPrivate.ptr == NULL)
 	return;
 
+    if (pixmap_priv->access_mode == GLAMOR_ACCESS_RO)
+      goto read_only;
+
     stride = pixmap->devKind;
     row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
     switch (drawable->depth) {
@@ -526,6 +530,7 @@ glamor_finish_access(DrawablePtr drawable)
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tex);
 
+read_only:
     if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
       glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
       glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 93837e0..8ded91a 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -193,6 +193,7 @@ typedef struct glamor_pixmap_private {
     GLuint fb;
     GLuint pbo;
     enum   glamor_pixmap_type type;
+    glamor_access_t access_mode;
 } glamor_pixmap_private;
 
 extern DevPrivateKey glamor_screen_private_key;
commit 1495ba9e64633476508febb01ec2e9594a7b466b
Author: Zhigang Gong <zhigang.gong at gmail.com>
Date:   Sun May 22 17:51:27 2011 +0800

    glamor: Use buffer object as much as possible.
    
    Change the row length of 1bit color depth pixmap to the actual stride.
    The previous implementation use the width as its stride which is not
    good. As it will waste 8 times of space and also bring some non-unify
    code path. With this commit, we can merge those 1bit or other color
    depth to almost one code path. And we will use pixel buffer object
    as much as possible due to performance issue. By default, some mesa
    hardware driver will fallback to software rasterization when use
    glReadPixels on a non-buffer-object frame buffer. This change will
    get about 4x times performance improvemention when we use y-inverted
    glamor or the driver support hardware y-flipped blitting.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 5f13b56..635b726 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -289,7 +289,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride, read_stride, x, y;
+    unsigned int stride, row_length, x, y;
     GLenum format, type;
     uint8_t *data, *read;
     glamor_screen_private *glamor_priv =
@@ -307,15 +307,14 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     }
 
     stride = pixmap->devKind;
-    read_stride = stride;
-
-    data = malloc(stride * pixmap->drawable.height);
+    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
 
+	
     switch (drawable->depth) {
     case 1:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
-	read_stride = pixmap->drawable.width;
+	row_length = stride;
 	break;
     case 8:
 	format = GL_ALPHA;
@@ -330,67 +329,47 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	break;
     default:
 	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth);
-	free(data);
 	return FALSE;
     }
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    if (drawable->depth != 1) {
-	glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
-		      pixmap->drawable.bitsPerPixel);
-    } else {
-	glPixelStorei(GL_PACK_ROW_LENGTH, read_stride);
-    }
-    if (GLEW_MESA_pack_invert && drawable->depth != 1) {
-	if (!glamor_priv->yInverted)
-	  glPixelStorei(GL_PACK_INVERT_MESA, 1);
-	glReadPixels(0, 0,
-		     pixmap->drawable.width, pixmap->drawable.height,
-		     format, type, data);
-	if (!glamor_priv->yInverted)
-	  glPixelStorei(GL_PACK_INVERT_MESA, 0);
+    glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
+
+    if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
+
+      if (!glamor_priv->yInverted) 
+        glPixelStorei(GL_PACK_INVERT_MESA, 1);
+
+      glGenBuffersARB (1, &pixmap_priv->pbo);
+      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+      glBufferDataARB (GL_PIXEL_PACK_BUFFER_EXT,
+                       stride * pixmap->drawable.height,
+                       NULL, GL_DYNAMIC_DRAW_ARB);
+      glReadPixels (0, 0,
+                    row_length, pixmap->drawable.height,
+                    format, type, 0);
+
+      data = glMapBufferARB (GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
+
+      if (!glamor_priv->yInverted) 
+	glPixelStorei(GL_PACK_INVERT_MESA, 0);
+
     } else {
-	glGenBuffersARB(1, &pixmap_priv->pbo);
+        data = malloc(stride * pixmap->drawable.height);
+
+        glGenBuffersARB(1, &pixmap_priv->pbo);
 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
 	glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
-			read_stride * pixmap->drawable.height,
-			NULL, GL_STREAM_READ_ARB);
-	glReadPixels(0, 0,
-		     pixmap->drawable.width, pixmap->drawable.height,
-		     format, type, 0);
-
+			stride * pixmap->drawable.height,
+	                NULL, GL_STREAM_READ_ARB);
+	glReadPixels (0, 0, row_length, pixmap->drawable.height,
+		      format, type, 0);
 	read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB);
 
-	if (pixmap->drawable.depth == 1) {
-	    for (y = 0; y < pixmap->drawable.height; y++) {
-		uint8_t *read_row;
-		uint8_t *write_row = data + y * stride;
-
-		if (glamor_priv->yInverted) 
-		  read_row = read + read_stride * y;
-		else
-		  read_row = read + 
-			     read_stride * (pixmap->drawable.height - y - 1);
-
-		for (x = 0; x < pixmap->drawable.width; x++) {
-		    int index = x / 8;
-		    int bit = 1 << (x % 8);
-
-		    if (read_row[x])
-			write_row[index] |= bit;
-		    else
-			write_row[index] &= ~bit;
-		}
-	    }
-	} else {
-	    for (y = 0; y < pixmap->drawable.height; y++)
-	      if (glamor_priv->yInverted)
-		memcpy(data + y * stride, read + y * stride, stride);
-	      else
-		memcpy(data + y * stride,
-		       read + (pixmap->drawable.height - y - 1) * stride, stride);
-	}
+	for (y = 0; y < pixmap->drawable.height; y++)
+	  memcpy(data + y * stride,
+	         read + (pixmap->drawable.height - y - 1) * stride, stride);
 	glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
 	glDeleteBuffersARB(1, &pixmap_priv->pbo);
@@ -452,7 +431,7 @@ glamor_finish_access(DrawablePtr drawable)
 	glamor_get_screen_private(drawable->pScreen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride;
+    unsigned int stride, row_length;
     GLenum format, type;
     static float vertices[4][2] = {{-1, -1},
 				   { 1, -1},
@@ -489,10 +468,13 @@ glamor_finish_access(DrawablePtr drawable)
     if (pixmap->devPrivate.ptr == NULL)
 	return;
 
+    stride = pixmap->devKind;
+    row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
     switch (drawable->depth) {
     case 1:
 	format = GL_COLOR_INDEX;
 	type = GL_BITMAP;
+	row_length = stride;
 	break;
     case 8:
 	format = GL_ALPHA;
@@ -510,7 +492,6 @@ glamor_finish_access(DrawablePtr drawable)
 	return;
     }
 
-    stride = pixmap->devKind;
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
@@ -523,8 +504,7 @@ glamor_finish_access(DrawablePtr drawable)
     glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 /
-		  pixmap->drawable.bitsPerPixel);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
 
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
@@ -540,14 +520,21 @@ glamor_finish_access(DrawablePtr drawable)
     glUseProgramObjectARB(glamor_priv->finish_access_prog);
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
     glDisable(GL_TEXTURE_2D);
     glUseProgramObjectARB(0);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tex);
 
-    free(pixmap->devPrivate.ptr);
+    if (GLEW_MESA_pack_invert || glamor_priv->yInverted) {
+      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+      glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_EXT);
+      glBindBufferARB (GL_PIXEL_PACK_BUFFER_EXT, 0);
+      glDeleteBuffersARB (1, &pixmap_priv->pbo);
+      pixmap_priv->pbo = 0;
+    } else
+      free(pixmap->devPrivate.ptr);
+
     pixmap->devPrivate.ptr = NULL;
 }
 
commit 529c38a4601e8f0712773bf29a48cddfa7a5edc4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 19 18:03:12 2011 +0800

    glamor-ddx: Remove debug message when moving cursor.

diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index fd4ee86..aba9b2c 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -460,8 +460,6 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
-	ErrorF("move cursor\n");
-
 	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
 }
 
commit cd43b1ea831eac11bc6ad0c3b1e040bb968b9861
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 19 18:02:19 2011 +0800

    glamor: Add fallback code path for glamor_fill.

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 1a98205..8ea70d0 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -84,6 +84,20 @@ glamor_fill(DrawablePtr drawable,
 		    drawable->y + y - gc->patOrg.y);
 	break;
     }
+    return;
+#if 0
+ fail:
+    glamor_fallback("glamor_fill()");
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access_gc(gc)) {
+            fbFill(drawable, gc, x, y, width, height);
+	    glamor_finish_access_gc(gc);
+	}
+	glamor_finish_access(drawable);
+    }
+#endif
+return;
+
 }
 
 void
@@ -142,8 +156,10 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     if (!glamor_set_destination_pixmap(pixmap))
 	return;
     glamor_set_alu(alu);
-    if (!glamor_set_planemask(pixmap, planemask))
+    if (!glamor_set_planemask(pixmap, planemask)) {
+	ErrorF("Failedto set planemask  in glamor_solid.\n");
 	goto fail;
+	}
 
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
commit 8593f22fb8fc5e0d0f406d9c94cca22347505fd6
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 19 17:59:19 2011 +0800

    glamor: glamor_set_alu should enable GL_COLOR_LOGIC_OP.
    
    GL_COLOR_OP seems not supported in current MESA.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 09605e2..5f13b56 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -117,12 +117,10 @@ void
 glamor_set_alu(unsigned char alu)
 {
     if (alu == GXcopy) {
-	glDisable(GL_LOGIC_OP);
+	glDisable(GL_COLOR_LOGIC_OP);
 	return;
     }
-
-    glEnable(GL_LOGIC_OP);
-
+    glEnable(GL_COLOR_LOGIC_OP);
     switch (alu) {
     case GXclear:
 	glLogicOp(GL_CLEAR);
@@ -271,10 +269,10 @@ glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 	break;
     case 24:
     case 32:
-	color[0] = ubyte_to_float(fg_pixel >> 16);
-	color[1] = ubyte_to_float(fg_pixel >> 8);
-	color[2] = ubyte_to_float(fg_pixel >> 0);
-	color[3] = ubyte_to_float(fg_pixel >> 24);
+	color[0] = ubyte_to_float((fg_pixel >> 16) & 0xFF);
+	color[1] = ubyte_to_float((fg_pixel >> 8) & 0xFF);
+	color[2] = ubyte_to_float((fg_pixel >> 0) & 0xFF);
+	color[3] = ubyte_to_float((fg_pixel >> 24) & 0xFF);
 	break;
     default:
 	ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth);
commit f871d174a861e7c3d2b8f4d9a3f10c38a5120606
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 19 11:40:38 2011 +0800

    glamor: Switch to software fb for too large pixmap.
    
    If pixmap's size exceeds the limitation of the MESA library, the
    rendering will fail. So we switch to software fb if it is the case.
    Add one new element for pixmap private structure to indicate whehter
    we are a software fb type or a opengl type.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 66a694e..4594f14 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -95,12 +95,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     PixmapPtr pixmap;
     GLenum format;
     GLuint tex;
-
+    glamor_pixmap_private *pixmap_priv;
+    int type = GLAMOR_GL;
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
-    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+    if (w > MAX_WIDTH || h > MAX_HEIGHT) {
+	/* MESA can only support upto MAX_WIDTH*MAX_HEIGHT fbo.
+ 	   If we exceed such limitation, we have to use framebuffer.*/
+      type = GLAMOR_FB;
+      pixmap = fbCreatePixmap (screen, w, h, depth, usage);
+      screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+                              (((w * pixmap->drawable.bitsPerPixel +
+                                 7) / 8) + 3) & ~3,
+                              NULL);
+      ErrorF("fallback to software fb for pixmap %p , %d x %d \n", pixmap, w, h);
+   } else
+      pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
     if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
         fbDestroyPixmap(pixmap);
@@ -108,8 +120,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return NullPixmap;
     }	 
 
-    if (w == 0 || h == 0)
+    if (w == 0 || h == 0 || type != GLAMOR_GL)
 	return pixmap;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    pixmap_priv->type = type;
+
     /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
      * FBOs, which EXT_fbo forgot to do.
      */
@@ -122,7 +138,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
         break;
     }
 
-
     /* Create the texture used to store the pixmap's data. */
     glGenTextures(1, &tex);
     glBindTexture(GL_TEXTURE_2D, tex);
@@ -132,7 +147,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
                  format, GL_UNSIGNED_BYTE, NULL);
 
     glamor_set_pixmap_texture(pixmap, w, h, tex);
-
     return pixmap;
 }
 
@@ -141,7 +155,6 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
 {
     if (pixmap->refcnt == 1) {
 	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
 	glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
 	glDeleteTextures(1, &pixmap_priv->tex);
     }
@@ -285,7 +298,6 @@ glamor_close_screen(int idx, ScreenPtr screen)
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreenIfSet(screen);
 #endif
-
     glamor_glyphs_fini(screen);
     screen->CloseScreen = glamor_priv->saved_close_screen;
     screen->CreateGC = glamor_priv->saved_create_gc;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b989078..93837e0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -39,6 +39,14 @@
 #include "glyphstr.h"
 #endif
 
+#ifndef MAX_WIDTH
+#define MAX_WIDTH 4096
+#endif
+
+#ifndef MAX_HEIGHT
+#define MAX_HEIGHT 4096
+#endif
+
 typedef enum glamor_access {
     GLAMOR_ACCESS_RO,
     GLAMOR_ACCESS_RW,
@@ -175,10 +183,16 @@ typedef struct glamor_screen_private {
     glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
 } glamor_screen_private;
 
+enum glamor_pixmap_type {
+  GLAMOR_GL,
+  GLAMOR_FB
+};
+
 typedef struct glamor_pixmap_private {
     GLuint tex;
     GLuint fb;
     GLuint pbo;
+    enum   glamor_pixmap_type type;
 } glamor_pixmap_private;
 
 extern DevPrivateKey glamor_screen_private_key;
@@ -250,8 +264,8 @@ glamor_report_delayed_fallbacks(ScreenPtr screen)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
     if (glamor_priv->delayed_fallback_string) {
-	LogMessageVerb(X_INFO, 0, "fallback: %s",
-		       glamor_priv->delayed_fallback_string);
+      //	LogMessageVerb(X_INFO, 0, "fallback: %s",
+      //	       glamor_priv->delayed_fallback_string);
 	glamor_clear_delayed_fallbacks(screen);
     }
 }
commit 74ca45e7d0ed6654204189793261ef65f213bb2e
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed May 18 16:48:06 2011 +0800

    glamor-ddx: Fixed one bug when a client reset the connection.
    
    This commit fixed two bugs when one client reset the connection.
    The first is that we should reopen the graphic device when the previous
    node was closed during the screen closing. The second one is we should
    call glamor_close_screen (not the ddx version) prior to call
    eglTerminate(). As eglTerminate will release the share library. And
    the glamor_close_screen may still need to call openGL APIs and thus
    will hit segfault. And renamed the ddx functions to avoid naming
    conflications with the glamor functions.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 255661d..665cd0a 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -157,7 +157,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uin
 
 char * dri_device_name = "/dev/dri/card0";
 static Bool
-glamor_pre_init(ScrnInfoPtr scrn, int flags)
+glamor_pre_init_ddx(ScrnInfoPtr scrn, int flags)
 {
 	struct glamor_screen_private *glamor;
 	rgb defaultWeight = { 0, 0, 0 };
@@ -211,12 +211,12 @@ fail:
 }
 
 static void
-glamor_adjust_frame(int scrnIndex, int x, int y, int flags)
+glamor_adjust_frame_ddx(int scrnIndex, int x, int y, int flags)
 {
 }
 
 static Bool
-glamor_enter_vt(int scrnIndex, int flags)
+glamor_enter_vt_ddx(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
@@ -234,7 +234,7 @@ glamor_enter_vt(int scrnIndex, int flags)
 }
 
 static void
-glamor_leave_vt(int scrnIndex, int flags)
+glamor_leave_vt_ddx(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
@@ -243,7 +243,7 @@ glamor_leave_vt(int scrnIndex, int flags)
 }
 
 static Bool
-glamor_create_screen_resources(ScreenPtr screen)
+glamor_create_screen_resources_ddx(ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
@@ -260,13 +260,16 @@ glamor_create_screen_resources(ScreenPtr screen)
 }
 
 static Bool
-glamor_close_screen(int scrnIndex, ScreenPtr screen)
+glamor_close_screen_ddx(int scrnIndex, ScreenPtr screen)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 
+	screen->CloseScreen = glamor->CloseScreen;
+	(*screen->CloseScreen) (scrnIndex, screen);
+
 	if (scrn->vtSema == TRUE)
-		glamor_leave_vt(scrnIndex, 0);
+		glamor_leave_vt_ddx(scrnIndex, 0);
 
 	glamor_fini(screen);
 
@@ -275,21 +278,32 @@ glamor_close_screen(int scrnIndex, ScreenPtr screen)
 	eglTerminate(glamor->display);
 
 	drmmode_closefb(scrn);
-
-	screen->CloseScreen = glamor->CloseScreen;
-	(*screen->CloseScreen) (scrnIndex, screen);
+	
+	glamor->fd = -1;
+	glamor->root = EGL_NO_IMAGE_KHR;
 
 	return TRUE;
 }
 
 static Bool
-glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
+glamor_screen_init_ddx(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	const char *version;
 	VisualPtr visual;
 
+	/* If serverGeneration != 1 then fd was closed during the last
+	 time closing screen, actually in eglTerminate(). */
+
+	if (glamor->fd == -1 && serverGeneration != 1) {
+	  glamor->fd = open(dri_device_name, O_RDWR);
+	  if (glamor->fd == -1 ) {
+	    ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
+	    return FALSE;
+	  }
+	}
+
 	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
 	eglBindAPI(EGL_OPENGL_API);
         LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB));
@@ -378,15 +392,14 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	 * later memory should be bound when allocating, e.g rotate_mem */
 	scrn->vtSema = TRUE;
 
-	if (!glamor_enter_vt(scrnIndex, 0))
+	if (!glamor_enter_vt_ddx(scrnIndex, 0))
 		return FALSE;
 
 	screen->SaveScreen = xf86SaveScreen;
 	glamor->CreateScreenResources = screen->CreateScreenResources;
-	screen->CreateScreenResources = glamor_create_screen_resources;
+	screen->CreateScreenResources = glamor_create_screen_resources_ddx;
 	glamor->CloseScreen = screen->CloseScreen;
-	screen->CloseScreen = glamor_close_screen;
-
+	screen->CloseScreen = glamor_close_screen_ddx;
 	/* Fixme should we init crtc screen here? */
 	if (!xf86CrtcScreenInit(screen))
 	  return FALSE;
@@ -400,7 +413,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 }
 
 static void
-glamor_free_screen(int scrnIndex, int flags)
+glamor_free_screen_ddx(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
@@ -413,7 +426,7 @@ glamor_free_screen(int scrnIndex, int flags)
 }
 
 static ModeStatus
-glamor_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+glamor_valid_mode_ddx(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
 {
 	if (mode->Flags & V_INTERLACE) {
 		if (verbose) {
@@ -450,13 +463,13 @@ glamor_probe(struct _DriverRec *drv, int flags)
 	scrn->name = (char *) glamor_name;
 	scrn->Probe = NULL;
 
-	scrn->PreInit = glamor_pre_init;
-	scrn->ScreenInit = glamor_screen_init;
-	scrn->AdjustFrame = glamor_adjust_frame;
-	scrn->EnterVT = glamor_enter_vt;
-	scrn->LeaveVT = glamor_leave_vt;
-	scrn->FreeScreen = glamor_free_screen;
-	scrn->ValidMode = glamor_valid_mode;
+	scrn->PreInit = glamor_pre_init_ddx;
+	scrn->ScreenInit = glamor_screen_init_ddx;
+	scrn->AdjustFrame = glamor_adjust_frame_ddx;
+	scrn->EnterVT = glamor_enter_vt_ddx;
+	scrn->LeaveVT = glamor_leave_vt_ddx;
+	scrn->FreeScreen = glamor_free_screen_ddx;
+	scrn->ValidMode = glamor_valid_mode_ddx;
 
 	return TRUE;
 }
commit c97d4533f29e77d80c076deff9ad0f218eb2e8f4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 12 14:49:08 2011 +0800

    glamor: Silent compilation warnings due to some deprecated APIs.
    
    those xcalloc/xfree/xalloc/XNFprintf/... are deprecated. Replace
    then with the new one. And fix some other minor problems.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 026f1bf..66a694e 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -102,7 +102,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
     pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
 
-    if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
+    if (dixAllocatePrivates(&pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
         fbDestroyPixmap(pixmap);
 	ErrorF("Fail to allocate privates for PIXMAP.\n");
 	return NullPixmap;
@@ -166,16 +166,15 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 {
     glamor_screen_private *glamor_priv;
 
-    if (flags & ~GLAMOR_VALID_FLAGS) {
-      ErrorF("glamor_init: Invalid flags %x\n", flags);
-      return FALSE;
-    }
-
 #ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
 
-    glamor_priv = xcalloc(1, sizeof(*glamor_priv));
+    if (flags & ~GLAMOR_VALID_FLAGS) {
+      ErrorF("glamor_init: Invalid flags %x\n", flags);
+      return FALSE;
+    }
+    glamor_priv = calloc(1, sizeof(*glamor_priv));
     if (glamor_priv == NULL)
 	return FALSE;
 
@@ -274,7 +273,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
     return TRUE;
 
 fail:
-    xfree(glamor_priv);
+    free(glamor_priv);
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
     return FALSE;
 }
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 3d1d3f8..09605e2 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -311,7 +311,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     stride = pixmap->devKind;
     read_stride = stride;
 
-    data = xalloc(stride * pixmap->drawable.height);
+    data = malloc(stride * pixmap->drawable.height);
 
     switch (drawable->depth) {
     case 1:
@@ -332,7 +332,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	break;
     default:
 	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth);
-	xfree(data);
+	free(data);
 	return FALSE;
     }
 
@@ -475,9 +475,9 @@ glamor_finish_access(DrawablePtr drawable)
     if (pixmap_priv == NULL)
 	return;
     if (glamor_priv->yInverted)
-	ptexcoords = texcoords_inverted;
+	ptexcoords = &texcoords_inverted[0][0];
     else
-	ptexcoords = texcoords;
+	ptexcoords = &texcoords[0][0];
 
     if (pixmap_priv->fb == 0) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -549,7 +549,7 @@ glamor_finish_access(DrawablePtr drawable)
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tex);
 
-    xfree(pixmap->devPrivate.ptr);
+    free(pixmap->devPrivate.ptr);
     pixmap->devPrivate.ptr = NULL;
 }
 
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index e35c416..dba23a8 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -61,7 +61,7 @@ glamor_get_spans(DrawablePtr drawable,
 
     switch (drawable->depth) {
     case 1:
-	temp_dst = xalloc(wmax);
+	temp_dst = malloc(wmax);
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
 	readpixels_dst = temp_dst;
@@ -111,7 +111,7 @@ glamor_get_spans(DrawablePtr drawable,
 	    readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
 	}
     }
-    xfree(temp_dst);
+    free(temp_dst);
     return;
 
 fail:
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 6e5595e..e24b222 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -130,12 +130,12 @@ static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format)
 	}
 
 	if (cache->hash_entries) {
-	    xfree(cache->hash_entries);
+	    free(cache->hash_entries);
 	    cache->hash_entries = NULL;
 	}
 
 	if (cache->glyphs) {
-	    xfree(cache->glyphs);
+	    free(cache->glyphs);
 	    cache->glyphs = NULL;
 	}
 	cache->glyph_count = 0;
@@ -215,9 +215,9 @@ static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format)
 
 	cache->picture = picture;
 	cache->picture->refcnt++;
-	cache->hash_entries = xalloc(sizeof(int) * cache->hash_size);
+	cache->hash_entries = malloc(sizeof(int) * cache->hash_size);
 	cache->glyphs =
-	    xalloc(sizeof(glamor_cached_glyph_t) * cache->size);
+	    malloc(sizeof(glamor_cached_glyph_t) * cache->size);
 	cache->glyph_count = 0;
 
 	if (!cache->hash_entries || !cache->glyphs)
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index acf6bf6..c975268 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -64,7 +64,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	goto fail;
     }
 
-    rects = xalloc(sizeof(xRectangle) * (n - 1));
+    rects = malloc(sizeof(xRectangle) * (n - 1));
     x1 = points[0].x;
     y1 = points[0].y;
     /* If we have any non-horizontal/vertical, fall back. */
@@ -80,7 +80,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	if (x1 != x2 && y1 != y2) {
 	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 
-	    xfree(rects);
+	    free(rects);
 
 	    ErrorF("stub diagonal poly_line\n");
 	    glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1);
@@ -106,7 +106,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	y1 = y2;
     }
     gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
-    xfree(rects);
+    free(rects);
     return;
 
 fail:
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index f12016d..b989078 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -231,7 +231,7 @@ glamor_delayed_fallback(ScreenPtr screen, char *format, ...)
 	return;
 
     va_start(ap, format);
-    glamor_priv->delayed_fallback_string = XNFvprintf(format, ap);
+    XNFvasprintf(&glamor_priv->delayed_fallback_string, format, ap);
     va_end(ap);
 }
 
@@ -240,7 +240,7 @@ glamor_clear_delayed_fallbacks(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    xfree(glamor_priv->delayed_fallback_string);
+    free(glamor_priv->delayed_fallback_string);
     glamor_priv->delayed_fallback_string = NULL;
 }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2ec811f..6139b0d 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -181,13 +181,15 @@ glamor_create_composite_fs(struct shader_key *key)
 	FatalError("Bad composite IN type");
     }
 
-    source = XNFprintf("%s%s%s",
-		       source_fetch,
-		       mask_fetch,
-		       in);
+    XNFasprintf(&source,
+		"%s%s%s",
+		source_fetch,
+		mask_fetch,
+		in);
+ 
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
-    xfree(source);
+    free(source);
 
     return prog;
 }
@@ -216,14 +218,15 @@ glamor_create_composite_vs(struct shader_key *key)
     if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
 	mask_coords_setup = mask_coords;
 
-    source = XNFprintf("%s%s%s%s",
-		       main_opening,
-		       source_coords_setup,
-		       mask_coords_setup,
-		       main_closing);
+    XNFasprintf(&source,
+		"%s%s%s%s",
+		 main_opening,
+		 source_coords_setup,
+		 mask_coords_setup,
+		 main_closing);
 
     prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
-    xfree(source);
+    free(source);
 
     return prog;
 }
@@ -591,7 +594,7 @@ glamor_setup_composite_vbo(ScreenPtr screen)
 
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
     glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
-		    (void *)(glamor_priv->vbo_offset));
+		    (void *)((long)glamor_priv->vbo_offset));
     glEnableClientState(GL_VERTEX_ARRAY);
 
     if (glamor_priv->has_source_coords) {
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 54aa266..6c1c2ff 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -53,7 +53,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 
     switch (drawable->depth) {
     case 1:
-	temp_src = xalloc(wmax);
+	temp_src = malloc(wmax);
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
 	drawpixels_src = temp_src;
@@ -123,7 +123,7 @@ fail:
     glDisable(GL_SCISSOR_TEST);
     glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
-    xfree(temp_src);
+    free(temp_src);
 
     glamor_fallback("glamor_set_spans(): to %p (%c)\n",
 		    drawable, glamor_get_drawable_location(drawable));
diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h
index 27bcebc..0a698cc 100644
--- a/glamor/glu3/glu3.h
+++ b/glamor/glu3/glu3.h
@@ -123,44 +123,14 @@ typedef struct GLUmat4Stack GLUmat4Stack;
 #ifdef __cplusplus
 extern "C" {
 #endif
-#if 0
-GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *);
-GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *);
-GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *);
-
-void gluCross4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
-void gluNormalize4v(GLUvec4 *result, const GLUvec4 *);
-GLfloat gluLength4v(const GLUvec4 *);
-GLfloat gluLengthSqr4v(const GLUvec4 *);
-void gluOuter4v(GLUmat4 *result, const GLUvec4 *, const GLUvec4 *);
-
-
-void gluMult4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
-void gluDiv4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
-void gluAdd4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
-void gluSub4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
-
-void gluMult4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
-void gluDiv4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
-void gluAdd4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
-void gluSub4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
-
-void gluMult4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
-void gluAdd4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
-void gluSub4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
-void gluMult4m_4v(GLUvec4 *result, const GLUmat4 *m, const GLUvec4 *v);
-
-void gluMult4m_f(GLUmat4 *result, const GLUmat4 *, GLfloat);
 
 void gluScale4v(GLUmat4 *result, const GLUvec4 *);
-void gluTranslate3f(GLUmat4 *result, GLfloat x, GLfloat y, GLfloat z);
 void gluTranslate4v(GLUmat4 *result, const GLUvec4 *);
 void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle);
 void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center,
 		 const GLUvec4 *up);
 void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect,
 		      GLfloat near, GLfloat far);
-void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m);
 void gluFrustum6f(GLUmat4 *result,
 		  GLfloat left, GLfloat right,
 		  GLfloat bottom, GLfloat top,
@@ -169,7 +139,6 @@ void gluOrtho6f(GLUmat4 *result,
 		GLfloat left, GLfloat right,
 		GLfloat bottom, GLfloat top,
 		GLfloat near, GLfloat far);
-#endif
 extern const GLUmat4 gluIdentityMatrix;
 
 #ifdef __cplusplus
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index bf05a0b..255661d 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -103,7 +103,6 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 
 	attribs[1] = width;
 	attribs[3] = height;
-	EGLint name, handle, stride, i; 
 	image =	 eglCreateDRMImageMESA(glamor->display, attribs);  
 	if (image == EGL_NO_IMAGE_KHR)
 		return FALSE;
@@ -206,8 +205,9 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags)
 	return TRUE;
 
 fail:
-	  scrn->driverPrivate = NULL;
-	  xfree(glamor);
+	scrn->driverPrivate = NULL;
+	free(glamor);
+	return FALSE;
 }
 
 static void
@@ -407,7 +407,7 @@ glamor_free_screen(int scrnIndex, int flags)
 	if (glamor != NULL)
 	{
 	  close(glamor->fd);
-	  xfree(glamor);
+	  free(glamor);
 	  scrn->driverPrivate = NULL;
 	}
 }
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 9425b69..fd4ee86 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -377,7 +377,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	crtc->y = y;
 	crtc->rotation = rotation;
 
-	output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+	output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
 	if (!output_ids) {
 		ret = FALSE;
 		goto done;
@@ -469,10 +469,8 @@ static void
 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	ScrnInfoPtr scrn = crtc->scrn;
 
-
 	if (drmmode_crtc->cursor == NULL)
 	{
 	     drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64);
@@ -489,7 +487,6 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 
 	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
 	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
-	//	memset(image, 0xff, 64*64*4);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
 	  GL_BGRA,  GL_UNSIGNED_INT_8_8_8_8_REV, image);
 
@@ -775,7 +772,7 @@ static int drmmode_output_lvds_edid(xf86OutputPtr output,
 	 * device. This is similar to what we have done in i830_lvds.c
 	 */
 	edid_mon = NULL;
-	edid_mon = xcalloc(1, sizeof(xf86Monitor));
+	edid_mon = calloc(1, sizeof(xf86Monitor));
 	if (!edid_mon) {
 		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
 			"Can't allocate memory for edid_mon.\n");
@@ -915,17 +912,17 @@ drmmode_output_destroy(xf86OutputPtr output)
 		drmModeFreePropertyBlob(drmmode_output->edid_blob);
 	for (i = 0; i < drmmode_output->num_props; i++) {
 	    drmModeFreeProperty(drmmode_output->props[i].mode_prop);
-	    xfree(drmmode_output->props[i].atoms);
+	    free(drmmode_output->props[i].atoms);
 	}
-	xfree(drmmode_output->props);
+	free(drmmode_output->props);
 	drmModeFreeConnector(drmmode_output->mode_output);
 	if (drmmode_output->private_data) {
-		xfree(drmmode_output->private_data);
+		free(drmmode_output->private_data);
 		drmmode_output->private_data = NULL;
 	}
 	if (drmmode_output->backlight_iface)
 		drmmode_backlight_set(output, drmmode_output->backlight_active_level);
-	xfree(drmmode_output);
+	free(drmmode_output);
 	output->driver_private = NULL;
 }
 
@@ -1008,7 +1005,7 @@ drmmode_output_create_resources(xf86OutputPtr output)
     drmModePropertyPtr drmmode_prop;
     int i, j, err;
 
-    drmmode_output->props = xcalloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+    drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
     if (!drmmode_output->props)
 	return;
 
@@ -1033,7 +1030,7 @@ drmmode_output_create_resources(xf86OutputPtr output)
 	    INT32 range[2];
 
 	    p->num_atoms = 1;
-	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
 	    if (!p->atoms)
 		continue;
 	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
@@ -1055,7 +1052,7 @@ drmmode_output_create_resources(xf86OutputPtr output)
 	    }
 	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
 	    p->num_atoms = drmmode_prop->count_enums + 1;
-	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    p->atoms = calloc(p->num_atoms, sizeof(Atom));
 	    if (!p->atoms)
 		continue;
 	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
@@ -1291,7 +1288,7 @@ drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
 		return;
 	}
 
-	drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+	drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
 	if (!drmmode_output) {
 		xf86OutputDestroy(output);
 		drmModeFreeConnector(koutput);
@@ -1305,7 +1302,7 @@ drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
 	 */
 	drmmode_output->private_data = NULL;
 	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) {
-		drmmode_output->private_data = xcalloc(
+		drmmode_output->private_data = calloc(
 				sizeof(struct fixed_panel_lvds), 1);
 		if (!drmmode_output->private_data)
 			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 0f7cbe4..6f8de11 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -8,6 +8,7 @@ Bool glamor_load_cursor(ScrnInfoPtr scrn,
 			CARD32 *image, int width, int height);
 
 void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch);
+EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height);
 
 Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
 void drmmode_closefb(ScrnInfoPtr scrn);
commit e3295d4106ac5b62f63e32dcb24a6094194cb1a8
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 12 10:22:07 2011 +0800

    glamor-ddx: Move the cursor EGL image to crtc strcture.
    
    Cursor is a per crtc resource. And this commit also fix the cursor
    initialization regard to the latest mesa EGL code. Now hardware
    cursor works fine.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 5947528..bf05a0b 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -66,9 +66,8 @@ glamor_identify(int flags)
 struct glamor_screen_private {
 	EGLDisplay display;
 	EGLContext context;
-	EGLImageKHR root, cursor;
+	EGLImageKHR root;
 	EGLint major, minor;
-	GLuint cursor_tex;
 
 	CreateScreenResourcesProcPtr CreateScreenResources;
 	CloseScreenProcPtr CloseScreen;
@@ -149,14 +148,15 @@ EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 }
 
 void
-glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
+glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR cursor, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	EGLint name;
-	eglExportDRMImageMESA (glamor->display, glamor->cursor, &name, (EGLint*) handle, (EGLint*) pitch);
+	eglExportDRMImageMESA (glamor->display, cursor, &name, (EGLint*) handle, (EGLint*) pitch);
 	ErrorF("cursor stride: %d\n", *pitch);
 }
 
+char * dri_device_name = "/dev/dri/card0";
 static Bool
 glamor_pre_init(ScrnInfoPtr scrn, int flags)
 {
@@ -166,7 +166,12 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags)
 	glamor = xnfcalloc(sizeof *glamor, 1);
 
 	scrn->driverPrivate = glamor;
-	glamor->fd = open("/dev/dri/card1", O_RDWR);
+	glamor->fd = open(dri_device_name, O_RDWR);
+	if (glamor->fd == -1 ) {
+	  ErrorF("Failed to open %s: %s\n", dri_device_name, strerror(errno));
+	  goto fail;
+	}
+
 	glamor->cpp = 4;
 
 	scrn->monitor = scrn->confScreen->monitor;
@@ -174,22 +179,21 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags)
 	scrn->rgbBits = 8;
 
 	if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb))
-		return FALSE;
+	  goto fail;
 
 	xf86PrintDepthBpp(scrn);
 
 	if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
-		return FALSE;
+	  goto fail;
 	if (!xf86SetDefaultVisual(scrn, -1))
-		return FALSE;
+	  goto fail;
 
 	glamor->cpp = scrn->bitsPerPixel / 8;
 
 	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Kernel modesetting setup failed\n");
-		xfree(glamor);
-		return FALSE;
+	  goto fail;
 	}
 
 	scrn->currentMode = scrn->modes;
@@ -197,9 +201,13 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags)
 
 	/* Load the required sub modules */
 	if (!xf86LoadSubModule(scrn, "fb"))
-		return FALSE;
+	  goto fail;
 
 	return TRUE;
+
+fail:
+	  scrn->driverPrivate = NULL;
+	  xfree(glamor);
 }
 
 static void
@@ -396,10 +404,12 @@ glamor_free_screen(int scrnIndex, int flags)
 {
 	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
-
-	close(glamor->fd);
-	xfree(scrn->driverPrivate);
-	scrn->driverPrivate = NULL;
+	if (glamor != NULL)
+	{
+	  close(glamor->fd);
+	  xfree(glamor);
+	  scrn->driverPrivate = NULL;
+	}
 }
 
 static ModeStatus
@@ -422,8 +432,6 @@ glamor_probe(struct _DriverRec *drv, int flags)
 	ScrnInfoPtr scrn = NULL;
        	GDevPtr *sections;
 	int entity, n;
-	LogMessageVerb(X_INFO, 0 , "%s : %d \n", __FUNCTION__, __LINE__);
-
 
 	n = xf86MatchDevice(glamor_name, &sections);
 	if (n <= 0)
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 352f79f..9425b69 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -48,6 +48,14 @@
 #include <xf86Crtc.h>
 #include <xf86DDC.h>
 #include <xorgVersion.h>
+#include <libkms/libkms.h>
+
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+#define EGL_DISPLAY_NO_X_MESA
+#include <GL/gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 
 #include "glamor_ddx.h"
 
@@ -67,6 +75,7 @@ typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     uint32_t rotate_fb_id;
+    EGLImageKHR cursor;
     unsigned int cursor_tex;
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
@@ -328,7 +337,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height)
 		drmModeRmFB(drmmode->fd, drmmode->fb_id);
 	glamor_frontbuffer_handle(scrn, &handle, &pitch);
 	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
-			   scrn->bitsPerPixel, pitch,
+			   scrn->bitsPerPixel, pitch /** drmmode->cpp*/,
 			   handle, &drmmode->fb_id);
 	if (ret)
 		/* FIXME: Undo glamor_resize() */
@@ -459,9 +468,31 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 static void
 drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	ScrnInfoPtr scrn = crtc->scrn;
 
-	//glamor_load_cursor(scrn, image, 64, 64);
+
+	if (drmmode_crtc->cursor == NULL)
+	{
+	     drmmode_crtc->cursor = glamor_create_cursor_argb(scrn, 64, 64);
+	     if (drmmode_crtc->cursor == EGL_NO_IMAGE_KHR)
+		return;
+		glGenTextures(1, &drmmode_crtc->cursor_tex);
+		glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
+		glTexParameteri(GL_TEXTURE_2D,
+				GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D,
+				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, drmmode_crtc->cursor);
+	}
+
+	glPixelStorei(GL_UNPACK_ROW_LENGTH, 64);
+	glBindTexture(GL_TEXTURE_2D, drmmode_crtc->cursor_tex);
+	//	memset(image, 0xff, 64*64*4);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
+	  GL_BGRA,  GL_UNSIGNED_INT_8_8_8_8_REV, image);
+
 }
 
 
@@ -484,7 +515,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc)
 	uint32_t handle, stride;
 
 	ErrorF("show cursor\n");
-	glamor_cursor_handle(scrn, &handle, &stride);
+	glamor_cursor_handle(scrn, drmmode_crtc->cursor, &handle, &stride);
 
 	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 			 handle, 64, 64);
@@ -596,6 +627,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 	.show_cursor = drmmode_show_cursor,
 	.hide_cursor = drmmode_hide_cursor,
 	.load_cursor_argb = drmmode_load_cursor_argb,
+	.load_cursor_image = NULL,
 #if 0
 	.shadow_create = drmmode_crtc_shadow_create,
 	.shadow_allocate = drmmode_crtc_shadow_allocate,
@@ -1311,9 +1343,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 
 		if (!crtc->enabled)
 			continue;
-
+#if 0
 		drmmode_set_mode_major(crtc, &crtc->mode,
 				       crtc->rotation, crtc->x, crtc->y);
+#endif
 	}
 
 	return TRUE;
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
index 0968f01..0f7cbe4 100644
--- a/hw/xfree86/glamor/glamor_ddx.h
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -6,8 +6,8 @@ void glamor_frontbuffer_handle(ScrnInfoPtr scrn,
 			       uint32_t *handle, uint32_t *pitch);
 Bool glamor_load_cursor(ScrnInfoPtr scrn,
 			CARD32 *image, int width, int height);
-void glamor_cursor_handle(ScrnInfoPtr scrn,
-			  uint32_t *handle, uint32_t *pitch);
+
+void glamor_cursor_handle(ScrnInfoPtr scrn, EGLImageKHR image, uint32_t *handle, uint32_t *pitch);
 
 Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
 void drmmode_closefb(ScrnInfoPtr scrn);
commit 43280372686177603111b175e92e1c88ad4ccdee
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 12 01:42:05 2011 +0800

    glamor-ddx: Fix a compiling error. Need revisit.
    
    GC is redefined in the X11/Xlib.h and include/gcstruct.h which is
    a xorg header file. Just use a macro to simply avoid the conflict.
    Need revisit latter to find a correct way to fix this problem.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index 61db4ad..5947528 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -45,7 +45,9 @@
 #include "../../../mi/micmap.h"
 #include <xf86Crtc.h>
 #include <xf86.h>
+#define GC XORG_GC
 #include <glamor.h>
+#undef GC
 
 #include "glamor_ddx.h"
 
commit 18a52e23882e4664fdb2de4958c4f9c97e16068c
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 12 01:37:52 2011 +0800

    glamor-ddx: Migrate the code to latest mesa library.
    
    Use eglCreateDRMImageMESA to create surfaceless image. And then
    export the drm buffer back which can be used to create the frame
    buffer.

diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
index b80d587..61db4ad 100644
--- a/hw/xfree86/glamor/glamor.c
+++ b/hw/xfree86/glamor/glamor.c
@@ -27,6 +27,9 @@
  *
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -85,11 +88,11 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	EGLImageKHR image;
 	GLuint texture;
 	EGLint attribs[] = {
-		EGL_IMAGE_WIDTH_INTEL,	0,
-		EGL_IMAGE_HEIGHT_INTEL,	0,
-		EGL_IMAGE_FORMAT_INTEL,	EGL_FORMAT_RGBA_8888_KHR,
-		EGL_IMAGE_USE_INTEL,	EGL_IMAGE_USE_SHARE_INTEL |
-					EGL_IMAGE_USE_SCANOUT_INTEL,
+		EGL_WIDTH,	0,
+		EGL_HEIGHT,	0,
+		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
+					EGL_DRM_BUFFER_USE_SCANOUT_MESA,
 		EGL_NONE
 	};
 
@@ -99,9 +102,8 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 
 	attribs[1] = width;
 	attribs[3] = height;
-	image = eglCreateImageKHR(glamor->display, glamor->context,
-				  EGL_SYSTEM_IMAGE_INTEL,
-				  NULL, attribs);
+	EGLint name, handle, stride, i; 
+	image =	 eglCreateDRMImageMESA(glamor->display, attribs);  
 	if (image == EGL_NO_IMAGE_KHR)
 		return FALSE;
 
@@ -109,14 +111,13 @@ glamor_resize(ScrnInfoPtr scrn, int width, int height)
 	glBindTexture(GL_TEXTURE_2D, texture);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); 
 
 	glamor_set_pixmap_texture(screen->GetScreenPixmap(screen),
 				  width, height, texture);
 	glamor->root = image;
 	scrn->virtualX = width;
 	scrn->virtualY = height;
-
 	return TRUE;
 }
 
@@ -125,49 +126,24 @@ glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	EGLint name;
-
-	eglShareImageINTEL (glamor->display, glamor->context, glamor->root, 0,
-			    &name, (EGLint *) handle, (EGLint *) pitch);
+	eglExportDRMImageMESA (glamor->display, glamor->root, &name, (EGLint*) handle, (EGLint*) pitch);
 }
 
-Bool
-glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height)
+EGLImageKHR glamor_create_cursor_argb(ScrnInfoPtr scrn, int width, int height)
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	EGLint attribs[] = {
+		EGL_WIDTH,	0,
+		EGL_HEIGHT,	0,
+		EGL_DRM_BUFFER_FORMAT_MESA,	EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+		EGL_DRM_BUFFER_USE_MESA,	EGL_DRM_BUFFER_USE_SHARE_MESA |
+					EGL_DRM_BUFFER_USE_SCANOUT_MESA | EGL_DRM_BUFFER_USE_CURSOR_MESA,
+		EGL_NONE
+	};
 
-	if (glamor->cursor == NULL) {
-		EGLint attribs[] = {
-			EGL_IMAGE_WIDTH_INTEL,	0,
-			EGL_IMAGE_HEIGHT_INTEL,	0,
-			EGL_IMAGE_FORMAT_INTEL,	EGL_FORMAT_RGBA_8888_KHR,
-			EGL_IMAGE_USE_INTEL,	EGL_IMAGE_USE_SHARE_INTEL |
-						EGL_IMAGE_USE_SCANOUT_INTEL,
-			EGL_NONE
-		};
-
-		attribs[1] = width;
-		attribs[3] = height;
-		glamor->cursor =
-			eglCreateImageKHR(glamor->display, glamor->context,
-					  EGL_SYSTEM_IMAGE_INTEL,
-					  NULL, attribs);
-		if (image == EGL_NO_IMAGE_KHR)
-			return FALSE;
-
-		glGenTextures(1, &glamor->cursor_tex);
-		glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex);
-		glTexParameteri(GL_TEXTURE_2D,
-				GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		glTexParameteri(GL_TEXTURE_2D,
-				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, glamor->cursor);
-	}
-
-	glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
-		     GL_RGBA, GL_UNSIGNED_BYTE, image);
-
-	return TRUE;
+	attribs[1] = width;
+	attribs[3] = height;
+	return	eglCreateDRMImageMESA(glamor->display, attribs); 
 }
 
 void
@@ -175,9 +151,7 @@ glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
 {
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
 	EGLint name;
-
-	eglShareImageINTEL (glamor->display, glamor->context, glamor->cursor, 
-			    0, &name, (EGLint *) handle, (EGLint *) pitch);
+	eglExportDRMImageMESA (glamor->display, glamor->cursor, &name, (EGLint*) handle, (EGLint*) pitch);
 	ErrorF("cursor stride: %d\n", *pitch);
 }
 
@@ -190,8 +164,7 @@ glamor_pre_init(ScrnInfoPtr scrn, int flags)
 	glamor = xnfcalloc(sizeof *glamor, 1);
 
 	scrn->driverPrivate = glamor;
-
-	glamor->fd = open("/dev/dri/card0", O_RDWR);
+	glamor->fd = open("/dev/dri/card1", O_RDWR);
 	glamor->cpp = 4;
 
 	scrn->monitor = scrn->confScreen->monitor;
@@ -243,7 +216,10 @@ glamor_enter_vt(int scrnIndex, int flags)
 			   "drmSetMaster failed: %s\n", strerror(errno));
 		return FALSE;
 	}
-
+#if 0
+        if (!xf86SetDesiredModes(scrn))
+	  return FALSE;
+#endif               
 	return TRUE;
 }
 
@@ -266,6 +242,7 @@ glamor_create_screen_resources(ScreenPtr screen)
 	if (!(*screen->CreateScreenResources) (screen))
 		return FALSE;
 
+
 	if (!xf86SetDesiredModes(scrn))
 		return FALSE;
 
@@ -300,15 +277,12 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
-	EGLDisplayTypeDRMMESA display;
 	const char *version;
+	VisualPtr visual;
 
-	display.type = EGL_DISPLAY_TYPE_DRM_MESA;
-	display.device = NULL;
-	display.fd = glamor->fd;
-	
-	glamor->display = eglGetDisplay((EGLNativeDisplayType) &display);
-	
+	glamor->display = eglGetDRMDisplayMESA(glamor->fd);
+	eglBindAPI(EGL_OPENGL_API);
+        LogMessageVerb(X_INFO, 0, "%s glCreateProgramObjectARB=%p", __FUNCTION__, *(&glCreateProgramObjectARB));
 	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "eglInitialize() failed\n");
@@ -325,6 +299,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 			   "Failed to create EGL context\n");
 		return FALSE;
 	}
+
 	if (!eglMakeCurrent(glamor->display,
 			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -346,16 +321,29 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 			  1, scrn->bitsPerPixel))
 		return FALSE;
 
-	fbPictureInit(screen, NULL, 0);
+	if (scrn->bitsPerPixel > 8) {
+	  /* Fixup RGB ordering */
+	  visual = screen->visuals + screen->numVisuals;
+	  while(--visual >= screen->visuals) {
+	    if ((visual->class | DynamicClass) == DirectColor) {
+	      visual->offsetRed = scrn->offset.red;
+	      visual->offsetGreen = scrn->offset.green;
+	      visual->offsetBlue = scrn->offset.blue;
+	      visual->redMask = scrn->mask.red;
+	      visual->blueMask = scrn->mask.blue;
+	    }
+	  }
+	}
 
+	fbPictureInit(screen, NULL, 0);
 	xf86SetBlackWhitePixels(screen);
 
-	if (!glamor_init(screen)) {
+	if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "Failed to initialize glamor\n");
 		return FALSE;
 	}
-		
+	
 	miInitializeBackingStore(screen);
 	xf86SetBackingStore(screen);
 	xf86SetSilkenMouse(screen);
@@ -369,7 +357,7 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 				HARDWARE_CURSOR_INVERT_MASK |
 				HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
 				HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
-				HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+				HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
 				HARDWARE_CURSOR_UPDATE_UNHIDDEN |
 				HARDWARE_CURSOR_ARGB))) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -389,6 +377,15 @@ glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	glamor->CloseScreen = screen->CloseScreen;
 	screen->CloseScreen = glamor_close_screen;
 
+	/* Fixme should we init crtc screen here? */
+	if (!xf86CrtcScreenInit(screen))
+	  return FALSE;
+	if (!miCreateDefColormap(screen))
+	  return FALSE;
+	/* Fixme should we add handle colormap here? */
+
+	xf86DPMSInit(screen, xf86DPMSSet, 0);
+
 	return TRUE;
 }
 
@@ -423,6 +420,8 @@ glamor_probe(struct _DriverRec *drv, int flags)
 	ScrnInfoPtr scrn = NULL;
        	GDevPtr *sections;
 	int entity, n;
+	LogMessageVerb(X_INFO, 0 , "%s : %d \n", __FUNCTION__, __LINE__);
+
 
 	n = xf86MatchDevice(glamor_name, &sections);
 	if (n <= 0)
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
index 4c91819..352f79f 100644
--- a/hw/xfree86/glamor/glamor_crtc.c
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -328,7 +328,7 @@ drmmode_update_fb (ScrnInfoPtr scrn, int width, int height)
 		drmModeRmFB(drmmode->fd, drmmode->fb_id);
 	glamor_frontbuffer_handle(scrn, &handle, &pitch);
 	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
-			   scrn->bitsPerPixel, pitch * drmmode->cpp,
+			   scrn->bitsPerPixel, pitch,
 			   handle, &drmmode->fb_id);
 	if (ret)
 		/* FIXME: Undo glamor_resize() */
@@ -461,7 +461,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
 	ScrnInfoPtr scrn = crtc->scrn;
 
-	glamor_load_cursor(scrn, image, 64, 64);
+	//glamor_load_cursor(scrn, image, 64, 64);
 }
 
 
commit eb3487a448ff0efa46079323821d65d7c3e4d872
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Thu May 12 01:08:38 2011 +0800

    glamor: Add new feature which is to flip output on y axis.
    
    Due to the coordinate system on EGL is different from FBO
    object. To support EGL surface well, we add this new feature.
    When calling glamor_init from EGL ddx driver, it should use
    the new flag GLAMOR_INVERTED_Y_AXIS.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b5252aa..026f1bf 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -162,10 +162,15 @@ glamor_wakeup_handler(void *data, int result, void *last_select_mask)
 
 /** Set up glamor for an already-configured GL context. */
 Bool
-glamor_init(ScreenPtr screen)
+glamor_init(ScreenPtr screen, unsigned int flags)
 {
     glamor_screen_private *glamor_priv;
 
+    if (flags & ~GLAMOR_VALID_FLAGS) {
+      ErrorF("glamor_init: Invalid flags %x\n", flags);
+      return FALSE;
+    }
+
 #ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
@@ -174,6 +179,10 @@ glamor_init(ScreenPtr screen)
     if (glamor_priv == NULL)
 	return FALSE;
 
+    if (flags & GLAMOR_INVERTED_Y_AXIS) {
+	glamor_priv->yInverted = 1;
+    } else
+	glamor_priv->yInverted = 0;
 
     if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN,
 			   0)) {
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 546a50c..33610a6 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -38,6 +38,9 @@
 #endif /* GLAMOR_H */
 
 
-Bool glamor_init(ScreenPtr screen);
+#define GLAMOR_INVERTED_Y_AXIS  0x1
+#define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS)
+
+Bool glamor_init(ScreenPtr screen, unsigned int flags);
 void glamor_fini(ScreenPtr screen);
 void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 297a1fb..07d8b14 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -45,6 +45,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     glamor_pixmap_private *src_pixmap_priv;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
 
     if (src == dst) {
@@ -94,6 +95,18 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     src_y_off += dy;
 
     for (i = 0; i < nbox; i++) {
+      if(glamor_priv->yInverted) {
+	glBlitFramebufferEXT((box[i].x1 + dx + src_x_off),
+                             (box[i].y1 + src_y_off),
+			     (box[i].x2 + dx + src_x_off),
+			     (box[i].y2 + src_y_off),
+                             (box[i].x1 + dst_x_off),
+                             (box[i].y1 + dst_y_off),
+			     (box[i].x2 + dst_x_off),
+			     (box[i].y2 + dst_y_off),
+			     GL_COLOR_BUFFER_BIT,
+			     GL_NEAREST);
+       } else {
 	int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
 	int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
 	int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
@@ -109,6 +122,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
 			     flip_dst_y2,
 			     GL_COLOR_BUFFER_BIT,
 			     GL_NEAREST);
+	}
     }
 
     return TRUE;
@@ -125,6 +139,8 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 {
     ScreenPtr screen = dst->pScreen;
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(screen);
     int x_off, y_off, i;
 
     if (src != dst) {
@@ -161,6 +177,15 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
     glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
 
     for (i = 0; i < nbox; i++) {
+      if(glamor_priv->yInverted) {
+	glRasterPos2i(box[i].x1 + x_off,
+		      box[i].y1 + y_off);
+	glCopyPixels(box[i].x1 + dx + x_off,
+		     box[i].y1 + dy + y_off,
+		     box[i].x2 - box[i].x1,
+		     box[i].y2 - box[i].y1,
+		     GL_COLOR);
+	} else {
 	int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off;
 	glRasterPos2i(box[i].x1 + x_off,
 		      flip_y1);
@@ -169,6 +194,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 		     box[i].x2 - box[i].x1,
 		     box[i].y2 - box[i].y1,
 		     GL_COLOR);
+	}
     }
 
     return TRUE;
@@ -235,23 +261,39 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glUseProgramObjectARB(glamor_priv->finish_access_prog);
 
     for (i = 0; i < nbox; i++) {
+
 	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
-	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
 	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
-	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
 	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
-	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
 	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
+	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
+	texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
+	texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
+	texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
+
+      if(glamor_priv->yInverted) {
+
+	vertices[0][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[1][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[2][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
+	vertices[3][1] = v_from_x_coord_y_inverted(dst_pixmap, box[i].y2 + dst_y_off);
+
+	texcoords[0][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
+	texcoords[1][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y1 + dy);
+	texcoords[2][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
+	texcoords[3][1] = t_from_x_coord_y_inverted(src_pixmap, box[i].y2 + dy);
+	} else {
+
+	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
 	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
 
-	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
 	texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
-	texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
 	texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
-	texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
 	texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
-	texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
 	texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
+	}
 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index a4036c8..3d1d3f8 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -294,12 +294,14 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     unsigned int stride, read_stride, x, y;
     GLenum format, type;
     uint8_t *data, *read;
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(drawable->pScreen);
 
     if (pixmap_priv == NULL)
 	return TRUE;
 
     if (pixmap_priv->fb == 0) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
+    	ScreenPtr screen = pixmap->drawable.pScreen;
 	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 
 	if (pixmap != screen_pixmap)
@@ -343,11 +345,13 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	glPixelStorei(GL_PACK_ROW_LENGTH, read_stride);
     }
     if (GLEW_MESA_pack_invert && drawable->depth != 1) {
-	glPixelStorei(GL_PACK_INVERT_MESA, 1);
+	if (!glamor_priv->yInverted)
+	  glPixelStorei(GL_PACK_INVERT_MESA, 1);
 	glReadPixels(0, 0,
 		     pixmap->drawable.width, pixmap->drawable.height,
 		     format, type, data);
-	glPixelStorei(GL_PACK_INVERT_MESA, 0);
+	if (!glamor_priv->yInverted)
+	  glPixelStorei(GL_PACK_INVERT_MESA, 0);
     } else {
 	glGenBuffersARB(1, &pixmap_priv->pbo);
 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
@@ -362,10 +366,15 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 
 	if (pixmap->drawable.depth == 1) {
 	    for (y = 0; y < pixmap->drawable.height; y++) {
-		uint8_t *read_row = read +
-		    read_stride * (pixmap->drawable.height - y - 1);
+		uint8_t *read_row;
 		uint8_t *write_row = data + y * stride;
 
+		if (glamor_priv->yInverted) 
+		  read_row = read + read_stride * y;
+		else
+		  read_row = read + 
+			     read_stride * (pixmap->drawable.height - y - 1);
+
 		for (x = 0; x < pixmap->drawable.width; x++) {
 		    int index = x / 8;
 		    int bit = 1 << (x % 8);
@@ -378,6 +387,9 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	    }
 	} else {
 	    for (y = 0; y < pixmap->drawable.height; y++)
+	      if (glamor_priv->yInverted)
+		memcpy(data + y * stride, read + y * stride, stride);
+	      else
 		memcpy(data + y * stride,
 		       read + (pixmap->drawable.height - y - 1) * stride, stride);
 	}
@@ -452,10 +464,20 @@ glamor_finish_access(DrawablePtr drawable)
 				    {1, 1},
 				    {1, 0},
 				    {0, 0}};
+
     GLuint tex;
+    static float texcoords_inverted[4][2] =    {{0, 0},
+				    		{1, 0},
+				    		{1, 1},
+				    		{0, 1}};
+   static float *ptexcoords;
 
     if (pixmap_priv == NULL)
 	return;
+    if (glamor_priv->yInverted)
+	ptexcoords = texcoords_inverted;
+    else
+	ptexcoords = texcoords;
 
     if (pixmap_priv->fb == 0) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -496,7 +518,7 @@ glamor_finish_access(DrawablePtr drawable)
     glEnableClientState(GL_VERTEX_ARRAY);
 
     glClientActiveTexture(GL_TEXTURE0);
-    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, ptexcoords);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index c3e0528..1a98205 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -153,14 +153,21 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glEnableClientState(GL_VERTEX_ARRAY);
 
     vertices[0][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[0][1] = v_from_x_coord_y(pixmap, y1);
     vertices[1][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[1][1] = v_from_x_coord_y(pixmap, y1);
     vertices[2][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[2][1] = v_from_x_coord_y(pixmap, y2);
     vertices[3][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[3][1] = v_from_x_coord_y(pixmap, y2);
-
+ 
+    if (glamor_priv->yInverted) {
+      vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
+      vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
+      vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
+      vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
+    } else {
+      vertices[0][1] = v_from_x_coord_y(pixmap, y1);
+      vertices[1][1] = v_from_x_coord_y(pixmap, y1);
+      vertices[2][1] = v_from_x_coord_y(pixmap, y2);
+      vertices[3][1] = v_from_x_coord_y(pixmap, y2);
+    }
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     glDisableClientState(GL_VERTEX_ARRAY);
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 9b77f28..e35c416 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -53,6 +53,8 @@ glamor_get_spans(DrawablePtr drawable,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(drawable->pScreen);
     int i, j;
     uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
     int x_off, y_off;
@@ -85,12 +87,21 @@ glamor_get_spans(DrawablePtr drawable,
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
     for (i = 0; i < count; i++) {
+      if (glamor_priv->yInverted) {
+	glReadPixels(points[i].x + x_off,
+		     (points[i].y + y_off),
+		     widths[i],
+		     1,
+		     format, type,
+		     readpixels_dst);
+ 	} else {
 	glReadPixels(points[i].x + x_off,
 		     pixmap->drawable.height - 1 - (points[i].y + y_off),
 		     widths[i],
 		     1,
 		     format, type,
 		     readpixels_dst);
+	}
 	if (temp_dst) {
 	    for (j = 0; j < widths[i]; j++) {
 		set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c2f516d..f12016d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -142,7 +142,7 @@ typedef struct glamor_screen_private {
     BitmapToRegionProcPtr saved_bitmap_to_region;
 
     char *delayed_fallback_string;
-
+    int yInverted;
     GLuint vbo;
     int vbo_offset;
     int vbo_size;
@@ -269,6 +269,13 @@ v_from_x_coord_y(PixmapPtr pixmap, int y)
 }
 
 static inline float
+v_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
+{
+    return (float)y / pixmap->drawable.height * 2.0 - 1.0;
+}
+
+
+static inline float
 t_from_x_coord_x(PixmapPtr pixmap, int x)
 {
     return (float)x / pixmap->drawable.width;
@@ -280,6 +287,13 @@ t_from_x_coord_y(PixmapPtr pixmap, int y)
     return 1.0 - (float)y / pixmap->drawable.height;
 }
 
+static inline float
+t_from_x_coord_y_inverted(PixmapPtr pixmap, int y)
+{
+    return (float)y / pixmap->drawable.height;
+}
+
+
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index ead5b69..6a9c1aa 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -377,13 +377,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	src_y2 = (float)(y2 - y) / h;
 
 	vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off);
-	vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
 	vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off);
-	vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
 	vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off);
-	vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
 	vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off);
-	vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
 
 	texcoords[0][0] = src_x1;
 	texcoords[0][1] = src_y1;
@@ -393,7 +389,23 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	texcoords[2][1] = src_y2;
 	texcoords[3][0] = src_x1;
 	texcoords[3][1] = src_y2;
+ 
+
+	if (glamor_priv->yInverted) {
+
+	vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
+	vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1 + y_off);
+	vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
+	vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2 + y_off);
+
+	} else {
 
+	vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
+	vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
+	vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
+	vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
+
+	}
 	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index de57f52..2ec811f 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -556,6 +556,8 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
     float result[3];
     int i;
     float tx, ty;
+    ScreenPtr screen = picture->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
     if (picture->transform) {
 	for (i = 0; i < 3; i++) {
@@ -570,7 +572,10 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
 	ty = y;
     }
     texcoord[0] = t_from_x_coord_x(pixmap, tx);
-    texcoord[1] = t_from_x_coord_y(pixmap, ty);
+    if (glamor_priv->yInverted)
+      texcoord[1] = t_from_x_coord_y_inverted(pixmap, ty);
+    else
+      texcoord[1] = t_from_x_coord_y(pixmap, ty);
 }
 
 static void
@@ -887,21 +892,33 @@ glamor_composite_with_shader(CARD8 op,
 	for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
 	    vertices[0] = v_from_x_coord_x(dest_pixmap,
 					   box[i].x1 + dest_x_off);
-	    vertices[1] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y1 + dest_y_off);
 	    vertices[2] = v_from_x_coord_x(dest_pixmap,
 					   box[i].x2 + dest_x_off);
-	    vertices[3] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y1 + dest_y_off);
 	    vertices[4] = v_from_x_coord_x(dest_pixmap,
 					   box[i].x2 + dest_x_off);
-	    vertices[5] = v_from_x_coord_y(dest_pixmap,
-					   box[i].y2 + dest_y_off);
 	    vertices[6] = v_from_x_coord_x(dest_pixmap,
 					   box[i].x1 + dest_x_off);
-	    vertices[7] = v_from_x_coord_y(dest_pixmap,
+
+	  if (glamor_priv->yInverted) {
+	    vertices[1] = v_from_x_coord_y_inverted(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[3] = v_from_x_coord_y_inverted(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[5] = v_from_x_coord_y_inverted(dest_pixmap,
+					   box[i].y2 + dest_y_off);
+	    vertices[7] = v_from_x_coord_y_inverted(dest_pixmap,
 					   box[i].y2 + dest_y_off);
 
+	    } else {
+	    vertices[1] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[3] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[5] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y2 + dest_y_off);
+	    vertices[7] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y2 + dest_y_off);
+	   }
 	    if (key.source != SHADER_SOURCE_SOLID) {
 		int tx1 = box[i].x1 + x_source - x_dest;
 		int ty1 = box[i].y1 + y_source - y_dest;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 60a1a1e..5892370 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -120,23 +120,36 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glEnable(GL_TEXTURE_2D);
 
     vertices[0][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[0][1] = v_from_x_coord_y(pixmap, y1);
     vertices[1][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[1][1] = v_from_x_coord_y(pixmap, y1);
     vertices[2][0] = v_from_x_coord_x(pixmap, x2);
-    vertices[2][1] = v_from_x_coord_y(pixmap, y2);
     vertices[3][0] = v_from_x_coord_x(pixmap, x1);
-    vertices[3][1] = v_from_x_coord_y(pixmap, y2);
-
     source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1);
-    source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
     source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2);
-    source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
     source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2);
-    source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
     source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1);
-    source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
-
+ 
+    if (glamor_priv->yInverted) {
+      vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
+      vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
+      vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
+      vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
+
+      source_texcoords[0][1] = t_from_x_coord_y_inverted(tile, tile_y1);
+      source_texcoords[1][1] = t_from_x_coord_y_inverted(tile, tile_y1);
+      source_texcoords[2][1] = t_from_x_coord_y_inverted(tile, tile_y2);
+      source_texcoords[3][1] = t_from_x_coord_y_inverted(tile, tile_y2);
+    } else {
+
+      vertices[0][1] = v_from_x_coord_y(pixmap, y1);
+      vertices[1][1] = v_from_x_coord_y(pixmap, y1);
+      vertices[2][1] = v_from_x_coord_y(pixmap, y2);
+      vertices[3][1] = v_from_x_coord_y(pixmap, y2);
+
+      source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
+      source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
+      source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
+      source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
+    }
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
index 70b4663..027cfc5 100644
--- a/hw/kdrive/ephyr/ephyr_glamor.c
+++ b/hw/kdrive/ephyr/ephyr_glamor.c
@@ -45,7 +45,7 @@ ephyr_glamor_init(ScreenPtr screen)
 
     ephyr_glamor_host_create_context(kd_screen);
 
-    glamor_init(screen);
+    glamor_init(screen, 0);
 
     return TRUE;
 }
commit 6dae8dc7ea6e7add3c6fda30773f264904ef8df5
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed May 11 15:57:05 2011 +0800

    glamor: Add glamor-ddx driver to the build tree.
    
    Correct the linking parameters and add dependency to the libglamor.a.

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index e3ef14f..830f17a 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -27,12 +27,12 @@ if INT10MODULE
 INT10_SUBDIR = int10
 endif
 
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
+SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw glamor os-support parser \
 	  ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
 	  loader dixmods exa modes \
 	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
 
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
+DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw glamor os-support \
                parser ramdac shadowfb vbe vgahw xaa \
                loader dixmods dri dri2 exa modes \
 	       utils doc man
diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
index 4c82b42..d691009 100644
--- a/hw/xfree86/glamor/Makefile.am
+++ b/hw/xfree86/glamor/Makefile.am
@@ -13,9 +13,12 @@ glamor_la_CFLAGS =					\
 	-I/usr/include/drm
 
 glamor_la_LDFLAGS =							\
-	-module -avoid-version -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW
+	-module -avoid-version -L$(libdir) -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW
 glamor_ladir = $(moduledir)/drivers
 glamor_la_SOURCES =				\
 	glamor.c				\
 	glamor_crtc.c				\
 	glamor_ddx.h
+
+glamor_la_DEPENDENCIES = 			\
+ $(top_builddir)/glamor/libglamor.la
commit 26ff612171d53baef08078a852875d5ddf1804ed
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed May 11 15:54:50 2011 +0800

    glamor:  Resolved merge conflictions with Kristian's glamor-ddx patch.

diff --git a/configure.ac b/configure.ac
index 7a8e507..caefc46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2185,6 +2185,7 @@ hw/xfree86/utils/Makefile
 hw/xfree86/utils/man/Makefile
 hw/xfree86/utils/cvt/Makefile
 hw/xfree86/utils/gtf/Makefile
+hw/xfree86/glamor/Makefile
 hw/dmx/config/Makefile
 hw/dmx/config/man/Makefile
 hw/dmx/doc/Makefile
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 537fb68..b5252aa 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -59,25 +59,54 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 	return (PixmapPtr)drawable;
 }
 
+
+void
+glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_pixmap_private *pixmap_priv;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    pixmap_priv->tex = tex;
+
+    /* Create a framebuffer object wrapping the texture so that we can render
+     * to it.
+     */
+    glGenFramebuffersEXT(1, &pixmap_priv->fb);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+                             GL_COLOR_ATTACHMENT0_EXT,
+                             GL_TEXTURE_2D,
+                             pixmap_priv->tex,
+                             0);
+
+    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+                              (((w * pixmap->drawable.bitsPerPixel +
+                                 7) / 8) + 3) & ~3,
+                              NULL);
+}
+
+
+
 static PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
 {
     PixmapPtr pixmap;
-    glamor_pixmap_private *pixmap_priv, *newpixmap_priv;
     GLenum format;
+    GLuint tex;
+
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
     pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+
     if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
         fbDestroyPixmap(pixmap);
 	ErrorF("Fail to allocate privates for PIXMAP.\n");
 	return NullPixmap;
     }	 
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-    assert(pixmap_priv != NULL);
 
     if (w == 0 || h == 0)
 	return pixmap;
@@ -95,28 +124,15 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 
     /* Create the texture used to store the pixmap's data. */
-    glGenTextures(1, &pixmap_priv->tex);
-    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                  format, GL_UNSIGNED_BYTE, NULL);
 
-    /*  Create a framebuffer object wrapping the texture so that we can render
-     ** to it.
-     **/
-    glGenFramebuffersEXT(1, &pixmap_priv->fb);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-                              GL_COLOR_ATTACHMENT0_EXT,
-                              GL_TEXTURE_2D,
-                              pixmap_priv->tex,
-                              0);
-
-    screen->ModifyPixmapHeader(pixmap, w, h, depth, 0,
-			       (((w * pixmap->drawable.bitsPerPixel +
-				  7) / 8) + 3) & ~3,
-			       NULL);
+    glamor_set_pixmap_texture(pixmap, w, h, tex);
+
     return pixmap;
 }
 
@@ -149,6 +165,7 @@ Bool
 glamor_init(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
+
 #ifdef RENDER
     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
 #endif
@@ -173,7 +190,6 @@ glamor_init(ScreenPtr screen)
                    screen->myNum);
     }
 
-
     glewInit();
 
     if (!GLEW_EXT_framebuffer_object) {
@@ -196,13 +212,13 @@ glamor_init(ScreenPtr screen)
 	ErrorF("GL_EXT_bgra required\n");
 	goto fail;
     }
-
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
 					NULL)) {
 	goto fail;
     }
 
+    
     glamor_priv->saved_close_screen = screen->CloseScreen;
     screen->CloseScreen = glamor_close_screen;
 
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 50617b8..546a50c 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -37,5 +37,7 @@
 
 #endif /* GLAMOR_H */
 
+
 Bool glamor_init(ScreenPtr screen);
 void glamor_fini(ScreenPtr screen);
+void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 447b192..56fb62f 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1118,7 +1118,7 @@ videoPtrToDriverList(struct pci_device *dev,
             } else if (dev->device_id == 0x8108) {
                 break; /* "hooray" for poulsbo */
 	    } else {
-		driverList[0] = "intel";
+	      driverList[0] = "glamor";
 	    }
 	    break;
 	case 0x102b:		    driverList[0] = "mga";	break;
commit 49bf0e301e7317a02e8b34ec2e290fcfda520e7e
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Mar 5 14:53:35 2010 -0500

    glamor ddx driver using EGL on KMS

diff --git a/hw/xfree86/glamor/Makefile.am b/hw/xfree86/glamor/Makefile.am
new file mode 100644
index 0000000..4c82b42
--- /dev/null
+++ b/hw/xfree86/glamor/Makefile.am
@@ -0,0 +1,21 @@
+glamor_la_LTLIBRARIES = glamor.la
+glamor_la_CFLAGS =					\
+	-DHAVE_XORG_CONFIG_H				\
+	@DIX_CFLAGS@ @XORG_CFLAGS@			\
+	-I$(top_srcdir)/hw/xfree86/common		\
+	-I$(top_srcdir)/hw/xfree86/os-support/bus	\
+	-I$(top_srcdir)/hw/xfree86/parser		\
+	-I$(top_srcdir)/hw/xfree86/modes		\
+	-I$(top_srcdir)/hw/xfree86/ddc			\
+	-I$(top_srcdir)/hw/xfree86/ramdac		\
+	-I$(top_srcdir)/hw/xfree86/i2c			\
+	-I$(top_srcdir)/glamor				\
+	-I/usr/include/drm
+
+glamor_la_LDFLAGS =							\
+	-module -avoid-version -lEGL $(top_builddir)/glamor/libglamor.la -lGLEW
+glamor_ladir = $(moduledir)/drivers
+glamor_la_SOURCES =				\
+	glamor.c				\
+	glamor_crtc.c				\
+	glamor_ddx.h
diff --git a/hw/xfree86/glamor/glamor.c b/hw/xfree86/glamor/glamor.c
new file mode 100644
index 0000000..b80d587
--- /dev/null
+++ b/hw/xfree86/glamor/glamor.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright © 2010 Intel Corporation.
+ *
+ * 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 (including
+ * the next paragraph) 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.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh at bitplanet.net>
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <xf86drm.h>
+
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+#define EGL_DISPLAY_NO_X_MESA
+#include <GL/gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "../../../mi/micmap.h"
+#include <xf86Crtc.h>
+#include <xf86.h>
+#include <glamor.h>
+
+#include "glamor_ddx.h"
+
+#define GLAMOR_VERSION_MAJOR 0
+#define GLAMOR_VERSION_MINOR 1
+#define GLAMOR_VERSION_PATCH 0
+
+static const char glamor_name[] = "glamor";
+
+static void
+glamor_identify(int flags)
+{
+	xf86Msg(X_INFO, "%s: OpenGL accelerated X.org driver\n", glamor_name);
+}
+
+struct glamor_screen_private {
+	EGLDisplay display;
+	EGLContext context;
+	EGLImageKHR root, cursor;
+	EGLint major, minor;
+	GLuint cursor_tex;
+
+	CreateScreenResourcesProcPtr CreateScreenResources;
+	CloseScreenProcPtr CloseScreen;
+	int fd;
+	int cpp;
+};
+
+static inline struct glamor_screen_private *
+glamor_get_screen_private(ScrnInfoPtr scrn)
+{
+	return (struct glamor_screen_private *) (scrn->driverPrivate);
+}
+
+Bool
+glamor_resize(ScrnInfoPtr scrn, int width, int height)
+{
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+	EGLImageKHR image;
+	GLuint texture;
+	EGLint attribs[] = {
+		EGL_IMAGE_WIDTH_INTEL,	0,
+		EGL_IMAGE_HEIGHT_INTEL,	0,
+		EGL_IMAGE_FORMAT_INTEL,	EGL_FORMAT_RGBA_8888_KHR,
+		EGL_IMAGE_USE_INTEL,	EGL_IMAGE_USE_SHARE_INTEL |
+					EGL_IMAGE_USE_SCANOUT_INTEL,
+		EGL_NONE
+	};
+
+	if (glamor->root != EGL_NO_IMAGE_KHR &&
+	    scrn->virtualX == width && scrn->virtualY == height)
+		return TRUE;
+
+	attribs[1] = width;
+	attribs[3] = height;
+	image = eglCreateImageKHR(glamor->display, glamor->context,
+				  EGL_SYSTEM_IMAGE_INTEL,
+				  NULL, attribs);
+	if (image == EGL_NO_IMAGE_KHR)
+		return FALSE;
+
+	glGenTextures(1, &texture);
+	glBindTexture(GL_TEXTURE_2D, texture);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+	glamor_set_pixmap_texture(screen->GetScreenPixmap(screen),
+				  width, height, texture);
+	glamor->root = image;
+	scrn->virtualX = width;
+	scrn->virtualY = height;
+
+	return TRUE;
+}
+
+void
+glamor_frontbuffer_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
+{
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	EGLint name;
+
+	eglShareImageINTEL (glamor->display, glamor->context, glamor->root, 0,
+			    &name, (EGLint *) handle, (EGLint *) pitch);
+}
+
+Bool
+glamor_load_cursor(ScrnInfoPtr scrn, CARD32 *image, int width, int height)
+{
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	if (glamor->cursor == NULL) {
+		EGLint attribs[] = {
+			EGL_IMAGE_WIDTH_INTEL,	0,
+			EGL_IMAGE_HEIGHT_INTEL,	0,
+			EGL_IMAGE_FORMAT_INTEL,	EGL_FORMAT_RGBA_8888_KHR,
+			EGL_IMAGE_USE_INTEL,	EGL_IMAGE_USE_SHARE_INTEL |
+						EGL_IMAGE_USE_SCANOUT_INTEL,
+			EGL_NONE
+		};
+
+		attribs[1] = width;
+		attribs[3] = height;
+		glamor->cursor =
+			eglCreateImageKHR(glamor->display, glamor->context,
+					  EGL_SYSTEM_IMAGE_INTEL,
+					  NULL, attribs);
+		if (image == EGL_NO_IMAGE_KHR)
+			return FALSE;
+
+		glGenTextures(1, &glamor->cursor_tex);
+		glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex);
+		glTexParameteri(GL_TEXTURE_2D,
+				GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D,
+				GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, glamor->cursor);
+	}
+
+	glBindTexture(GL_TEXTURE_2D, glamor->cursor_tex);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, image);
+
+	return TRUE;
+}
+
+void
+glamor_cursor_handle(ScrnInfoPtr scrn, uint32_t *handle, uint32_t *pitch)
+{
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	EGLint name;
+
+	eglShareImageINTEL (glamor->display, glamor->context, glamor->cursor, 
+			    0, &name, (EGLint *) handle, (EGLint *) pitch);
+	ErrorF("cursor stride: %d\n", *pitch);
+}
+
+static Bool
+glamor_pre_init(ScrnInfoPtr scrn, int flags)
+{
+	struct glamor_screen_private *glamor;
+	rgb defaultWeight = { 0, 0, 0 };
+
+	glamor = xnfcalloc(sizeof *glamor, 1);
+
+	scrn->driverPrivate = glamor;
+
+	glamor->fd = open("/dev/dri/card0", O_RDWR);
+	glamor->cpp = 4;
+
+	scrn->monitor = scrn->confScreen->monitor;
+	scrn->progClock = TRUE;
+	scrn->rgbBits = 8;
+
+	if (!xf86SetDepthBpp(scrn, 0, 0, 0, Support32bppFb))
+		return FALSE;
+
+	xf86PrintDepthBpp(scrn);
+
+	if (!xf86SetWeight(scrn, defaultWeight, defaultWeight))
+		return FALSE;
+	if (!xf86SetDefaultVisual(scrn, -1))
+		return FALSE;
+
+	glamor->cpp = scrn->bitsPerPixel / 8;
+
+	if (drmmode_pre_init(scrn, glamor->fd, glamor->cpp) == FALSE) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Kernel modesetting setup failed\n");
+		xfree(glamor);
+		return FALSE;
+	}
+
+	scrn->currentMode = scrn->modes;
+	xf86SetDpi(scrn, 0, 0);
+
+	/* Load the required sub modules */
+	if (!xf86LoadSubModule(scrn, "fb"))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+glamor_adjust_frame(int scrnIndex, int x, int y, int flags)
+{
+}
+
+static Bool
+glamor_enter_vt(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	if (drmSetMaster(glamor->fd)) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "drmSetMaster failed: %s\n", strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+glamor_leave_vt(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	drmDropMaster(glamor->fd);
+}
+
+static Bool
+glamor_create_screen_resources(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	screen->CreateScreenResources = glamor->CreateScreenResources;
+	if (!(*screen->CreateScreenResources) (screen))
+		return FALSE;
+
+	if (!xf86SetDesiredModes(scrn))
+		return FALSE;
+
+	return TRUE;
+}
+
+static Bool
+glamor_close_screen(int scrnIndex, ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	if (scrn->vtSema == TRUE)
+		glamor_leave_vt(scrnIndex, 0);
+
+	glamor_fini(screen);
+
+	eglMakeCurrent(glamor->display,
+		       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+	eglTerminate(glamor->display);
+
+	drmmode_closefb(scrn);
+
+	screen->CloseScreen = glamor->CloseScreen;
+	(*screen->CloseScreen) (scrnIndex, screen);
+
+	return TRUE;
+}
+
+static Bool
+glamor_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+	EGLDisplayTypeDRMMESA display;
+	const char *version;
+
+	display.type = EGL_DISPLAY_TYPE_DRM_MESA;
+	display.device = NULL;
+	display.fd = glamor->fd;
+	
+	glamor->display = eglGetDisplay((EGLNativeDisplayType) &display);
+	
+	if (!eglInitialize(glamor->display, &glamor->major, &glamor->minor)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "eglInitialize() failed\n");
+		return FALSE;
+	}
+
+	version = eglQueryString(glamor->display, EGL_VERSION);
+	xf86Msg(X_INFO, "%s: EGL version %s:", glamor_name, version);
+
+	glamor->context = eglCreateContext(glamor->display,
+					   NULL, EGL_NO_CONTEXT, NULL);
+	if (glamor->context == EGL_NO_CONTEXT) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to create EGL context\n");
+		return FALSE;
+	}
+	if (!eglMakeCurrent(glamor->display,
+			    EGL_NO_SURFACE, EGL_NO_SURFACE, glamor->context)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to make EGL context current\n");
+		return FALSE;
+	}
+
+	miClearVisualTypes();
+	if (!miSetVisualTypes(scrn->depth,
+			      miGetDefaultVisualMask(scrn->depth),
+			      scrn->rgbBits, scrn->defaultVisual))
+		return FALSE;
+	if (!miSetPixmapDepths())
+		return FALSE;
+
+	if (!fbScreenInit(screen, NULL,
+			  scrn->virtualX, scrn->virtualY,
+			  scrn->xDpi, scrn->yDpi,
+			  1, scrn->bitsPerPixel))
+		return FALSE;
+
+	fbPictureInit(screen, NULL, 0);
+
+	xf86SetBlackWhitePixels(screen);
+
+	if (!glamor_init(screen)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to initialize glamor\n");
+		return FALSE;
+	}
+		
+	miInitializeBackingStore(screen);
+	xf86SetBackingStore(screen);
+	xf86SetSilkenMouse(screen);
+	miDCInitialize(screen, xf86GetPointerScreenFuncs());
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
+
+	if (!xf86_cursors_init(screen, 64, 64,
+			       (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+				HARDWARE_CURSOR_INVERT_MASK |
+				HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+				HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+				HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+				HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+				HARDWARE_CURSOR_ARGB))) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Hardware cursor initialization failed\n");
+	}
+
+	/* Must force it before EnterVT, so we are in control of VT and
+	 * later memory should be bound when allocating, e.g rotate_mem */
+	scrn->vtSema = TRUE;
+
+	if (!glamor_enter_vt(scrnIndex, 0))
+		return FALSE;
+
+	screen->SaveScreen = xf86SaveScreen;
+	glamor->CreateScreenResources = screen->CreateScreenResources;
+	screen->CreateScreenResources = glamor_create_screen_resources;
+	glamor->CloseScreen = screen->CloseScreen;
+	screen->CloseScreen = glamor_close_screen;
+
+	return TRUE;
+}
+
+static void
+glamor_free_screen(int scrnIndex, int flags)
+{
+	ScrnInfoPtr scrn = xf86Screens[scrnIndex];
+	struct glamor_screen_private *glamor = glamor_get_screen_private(scrn);
+
+	close(glamor->fd);
+	xfree(scrn->driverPrivate);
+	scrn->driverPrivate = NULL;
+}
+
+static ModeStatus
+glamor_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+	if (mode->Flags & V_INTERLACE) {
+		if (verbose) {
+			xf86DrvMsg(scrnIndex, X_PROBED,
+				   "Removing interlaced mode \"%s\"\n",
+				   mode->name);
+		}
+		return MODE_BAD;
+	}
+	return MODE_OK;
+}
+
+static Bool
+glamor_probe(struct _DriverRec *drv, int flags)
+{
+	ScrnInfoPtr scrn = NULL;
+       	GDevPtr *sections;
+	int entity, n;
+
+	n = xf86MatchDevice(glamor_name, &sections);
+	if (n <= 0)
+	    return FALSE;
+
+	entity = xf86ClaimFbSlot(drv, 0, sections[0], TRUE);
+
+	scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
+	if (scrn == NULL) {
+		xf86Msg(X_ERROR, "Failed to add fb entity\n");
+		return FALSE;
+	}
+
+	scrn->driverVersion = 1;
+	scrn->driverName = (char *) glamor_name;
+	scrn->name = (char *) glamor_name;
+	scrn->Probe = NULL;
+
+	scrn->PreInit = glamor_pre_init;
+	scrn->ScreenInit = glamor_screen_init;
+	scrn->AdjustFrame = glamor_adjust_frame;
+	scrn->EnterVT = glamor_enter_vt;
+	scrn->LeaveVT = glamor_leave_vt;
+	scrn->FreeScreen = glamor_free_screen;
+	scrn->ValidMode = glamor_valid_mode;
+
+	return TRUE;
+}
+
+static const OptionInfoRec *
+glamor_available_options(int chipid, int busid)
+{
+	return NULL;
+}
+
+static Bool
+glamor_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
+{
+	xorgHWFlags *flag;
+
+	switch (op) {
+        case GET_REQUIRED_HW_INTERFACES:
+		flag = (CARD32*)ptr;
+		(*flag) = 0;
+		return TRUE;
+        default:
+		/* Unknown or deprecated function */
+		return FALSE;
+	}
+}
+
+_X_EXPORT DriverRec glamor = {
+	1,
+	"glamor",
+	glamor_identify,
+	glamor_probe,
+	glamor_available_options,
+	NULL,
+	0,
+	glamor_driver_func,
+};
+
+static pointer
+glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+   static Bool setupDone = 0;
+
+   /* This module should be loaded only once, but check to be sure.
+    */
+   if (!setupDone) {
+      setupDone = 1;
+      xf86AddDriver(&glamor, module, HaveDriverFuncs);
+
+      /*
+       * The return value must be non-NULL on success even though there
+       * is no TearDownProc.
+       */
+      return (pointer) 1;
+   } else {
+      if (errmaj)
+	 *errmaj = LDR_ONCEONLY;
+      return NULL;
+   }
+}
+
+static XF86ModuleVersionInfo glamor_version_info = {
+	glamor_name,
+	MODULEVENDORSTRING,
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XORG_VERSION_CURRENT,
+	GLAMOR_VERSION_MAJOR,
+	GLAMOR_VERSION_MINOR,
+	GLAMOR_VERSION_PATCH,
+	ABI_CLASS_VIDEODRV,
+	ABI_VIDEODRV_VERSION,
+	MOD_CLASS_VIDEODRV,
+	{0, 0, 0, 0}
+};
+
+_X_EXPORT XF86ModuleData glamorModuleData = {
+	&glamor_version_info,
+	glamor_setup,
+	NULL
+};
diff --git a/hw/xfree86/glamor/glamor_crtc.c b/hw/xfree86/glamor/glamor_crtc.c
new file mode 100644
index 0000000..4c91819
--- /dev/null
+++ b/hw/xfree86/glamor/glamor_crtc.c
@@ -0,0 +1,1493 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2010 Intel Corporation.
+ *
+ * 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 (including
+ * the next paragraph) 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.
+ *
+ * Authors:
+ *    Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdint.h>
+#include <X11/Xdefs.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/dpmsconst.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <xf86Crtc.h>
+#include <xf86DDC.h>
+#include <xorgVersion.h>
+
+#include "glamor_ddx.h"
+
+typedef struct {
+    int fd;
+    uint32_t fb_id;
+    drmModeResPtr mode_res;
+    int cpp;
+    
+    drmEventContext event_context;
+    void *event_data;
+    int old_fb_id;
+    int flip_count;
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+    drmmode_ptr drmmode;
+    drmModeCrtcPtr mode_crtc;
+    uint32_t rotate_fb_id;
+    unsigned int cursor_tex;
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+    drmModePropertyPtr mode_prop;
+    uint64_t value;
+    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
+    Atom *atoms;
+} drmmode_prop_rec, *drmmode_prop_ptr;
+
+struct fixed_panel_lvds {
+	int hdisplay;
+	int vdisplay;
+};
+typedef struct {
+    drmmode_ptr drmmode;
+    int output_id;
+    drmModeConnectorPtr mode_output;
+    drmModeEncoderPtr mode_encoder;
+    drmModePropertyBlobPtr edid_blob;
+    int num_props;
+    drmmode_prop_ptr props;
+    void *private_data;
+    int dpms_mode;
+    char *backlight_iface;
+    int backlight_active_level;
+    int backlight_max;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode);
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height);
+
+#define BACKLIGHT_CLASS "/sys/class/backlight"
+
+/*
+ * List of available kernel interfaces in priority order
+ */
+static char *backlight_interfaces[] = {
+    "asus-laptop",
+    "eeepc",
+    "thinkpad_screen",
+    "acpi_video1",
+    "acpi_video0",
+    "fujitsu-laptop",
+    "sony",
+    "samsung",
+    NULL,
+};
+/*
+ * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table +
+ * '/' + "max_backlight"
+ */
+#define BACKLIGHT_PATH_LEN 80
+/* Enough for 10 digits of backlight + '\n' + '\0' */
+#define BACKLIGHT_VALUE_LEN 12
+
+static void
+drmmode_backlight_set(xf86OutputPtr output, int level)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd, len, ret;
+
+    if (level > drmmode_output->backlight_max)
+	level = drmmode_output->backlight_max;
+    if (! drmmode_output->backlight_iface || level < 0)
+	return;
+
+    len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level);
+    sprintf(path, "%s/%s/brightness",
+	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
+    fd = open(path, O_RDWR);
+    if (fd == -1) {
+	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
+		   "control: %s\n", path, strerror(errno));
+	return;
+    }
+
+    ret = write(fd, val, len);
+    if (ret == -1) {
+	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "write to %s for backlight "
+		   "control failed: %s\n", path, strerror(errno));
+    }
+
+    close(fd);
+}
+
+static int
+drmmode_backlight_get(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd, level;
+
+    if (! drmmode_output->backlight_iface)
+	return -1;
+
+    sprintf(path, "%s/%s/actual_brightness",
+	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s "
+		   "for backlight control: %s\n", path, strerror(errno));
+	return -1;
+    }
+
+    memset(val, 0, sizeof(val));
+    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) {
+	close(fd);
+	return -1;
+    }
+
+    close(fd);
+
+    level = atoi(val);
+    if (level > drmmode_output->backlight_max)
+	level = drmmode_output->backlight_max;
+    if (level < 0)
+	level = -1;
+    return level;
+}
+
+static int
+drmmode_backlight_get_max(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd, max = 0;
+
+    sprintf(path, "%s/%s/max_brightness",
+	    BACKLIGHT_CLASS, drmmode_output->backlight_iface);
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+	xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s "
+		   "for backlight control: %s\n", path, strerror(errno));
+	return 0;
+    }
+
+    memset(val, 0, sizeof(val));
+    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) {
+	close(fd);
+	return -1;
+    }
+
+    close(fd);
+
+    max = atoi(val);
+    if (max <= 0)
+	max  = -1;
+    return max;
+}
+
+static void
+drmmode_backlight_init(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    char path[BACKLIGHT_PATH_LEN];
+    struct stat buf;
+    int i;
+
+    for (i = 0; backlight_interfaces[i] != NULL; i++) {
+	sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
+	if (!stat(path, &buf)) {
+	    drmmode_output->backlight_iface = backlight_interfaces[i];
+	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
+		       "found backlight control interface %s\n", path);
+	    drmmode_output->backlight_max = drmmode_backlight_get_max(output);
+	    drmmode_output->backlight_active_level = drmmode_backlight_get(output);
+	    return;
+	}
+    }
+    drmmode_output->backlight_iface = NULL;
+}
+
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
+			 drmModeModeInfoPtr kmode,
+			 DisplayModePtr	mode)
+{
+	memset(mode, 0, sizeof(DisplayModeRec));
+	mode->status = MODE_OK;
+
+	mode->Clock = kmode->clock;
+
+	mode->HDisplay = kmode->hdisplay;
+	mode->HSyncStart = kmode->hsync_start;
+	mode->HSyncEnd = kmode->hsync_end;
+	mode->HTotal = kmode->htotal;
+	mode->HSkew = kmode->hskew;
+
+	mode->VDisplay = kmode->vdisplay;
+	mode->VSyncStart = kmode->vsync_start;
+	mode->VSyncEnd = kmode->vsync_end;
+	mode->VTotal = kmode->vtotal;
+	mode->VScan = kmode->vscan;
+
+	mode->Flags = kmode->flags; //& FLAG_BITS;
+	mode->name = strdup(kmode->name);
+
+	if (kmode->type & DRM_MODE_TYPE_DRIVER)
+		mode->type = M_T_DRIVER;
+	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
+		mode->type |= M_T_PREFERRED;
+	xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr scrn,
+		       drmModeModeInfoPtr kmode,
+		       DisplayModePtr mode)
+{
+	memset(kmode, 0, sizeof(*kmode));
+
+	kmode->clock = mode->Clock;
+	kmode->hdisplay = mode->HDisplay;
+	kmode->hsync_start = mode->HSyncStart;
+	kmode->hsync_end = mode->HSyncEnd;
+	kmode->htotal = mode->HTotal;
+	kmode->hskew = mode->HSkew;
+
+	kmode->vdisplay = mode->VDisplay;
+	kmode->vsync_start = mode->VSyncStart;
+	kmode->vsync_end = mode->VSyncEnd;
+	kmode->vtotal = mode->VTotal;
+	kmode->vscan = mode->VScan;
+
+	kmode->flags = mode->Flags; //& FLAG_BITS;
+	if (mode->name)
+		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+}
+
+static void
+drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+
+}
+
+static Bool
+drmmode_update_fb (ScrnInfoPtr scrn, int width, int height)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmmode_crtc_private_ptr
+		drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	uint32_t handle, pitch;
+	int ret;
+
+	if (drmmode->fb_id != 0 &&
+	    scrn->virtualX == width && scrn->virtualY == height) 
+		return TRUE;
+	if (!glamor_resize(scrn, width, height))
+		return FALSE;
+	if (drmmode->fb_id != 0)
+		drmModeRmFB(drmmode->fd, drmmode->fb_id);
+	glamor_frontbuffer_handle(scrn, &handle, &pitch);
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch * drmmode->cpp,
+			   handle, &drmmode->fb_id);
+	if (ret)
+		/* FIXME: Undo glamor_resize() */
+		return FALSE;
+
+	return TRUE;
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		       Rotation rotation, int x, int y)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int saved_x, saved_y;
+	Rotation saved_rotation;
+	DisplayModeRec saved_mode;
+	uint32_t *output_ids;
+	int output_count = 0;
+	int ret = TRUE;
+	int i;
+	int fb_id;
+	drmModeModeInfo kmode;
+
+	if (!drmmode_update_fb(scrn, scrn->virtualX, scrn->virtualY))
+		return FALSE;
+
+	saved_mode = crtc->mode;
+	saved_x = crtc->x;
+	saved_y = crtc->y;
+	saved_rotation = crtc->rotation;
+
+	crtc->mode = *mode;
+	crtc->x = x;
+	crtc->y = y;
+	crtc->rotation = rotation;
+
+	output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+	if (!output_ids) {
+		ret = FALSE;
+		goto done;
+	}
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		drmmode_output_private_ptr drmmode_output;
+
+		if (output->crtc != crtc)
+			continue;
+
+		drmmode_output = output->driver_private;
+		output_ids[output_count] =
+			drmmode_output->mode_output->connector_id;
+		output_count++;
+	}
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0)
+	if (!xf86CrtcRotate(crtc, mode, rotation))
+		goto done;
+#else
+	if (!xf86CrtcRotate(crtc))
+		goto done;
+#endif
+
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0)
+	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+			       crtc->gamma_blue, crtc->gamma_size);
+#endif
+
+	drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
+
+
+	fb_id = drmmode->fb_id;
+	if (drmmode_crtc->rotate_fb_id) {
+		fb_id = drmmode_crtc->rotate_fb_id;
+		x = 0;
+		y = 0;
+	}
+	ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			     fb_id, x, y, output_ids, output_count, &kmode);
+	if (ret)
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "failed to set mode: %s", strerror(-ret));
+	else
+		ret = TRUE;
+
+	/* Turn on any outputs on this crtc that may have been disabled */
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+
+		if (output->crtc != crtc)
+			continue;
+
+		drmmode_output_dpms(output, DPMSModeOn);
+	}
+
+	if (scrn->pScreen)
+		xf86_reload_cursors(scrn->pScreen);
+done:
+	if (!ret) {
+		crtc->x = saved_x;
+		crtc->y = saved_y;
+		crtc->rotation = saved_rotation;
+		crtc->mode = saved_mode;
+	}
+	return ret;
+}
+
+static void
+drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+
+}
+
+static void
+drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	ErrorF("move cursor\n");
+
+	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
+}
+
+static void
+drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+
+	glamor_load_cursor(scrn, image, 64, 64);
+}
+
+
+static void
+drmmode_hide_cursor (xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			 0, 64, 64);
+}
+
+static void
+drmmode_show_cursor (xf86CrtcPtr crtc)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	uint32_t handle, stride;
+
+	ErrorF("show cursor\n");
+	glamor_cursor_handle(scrn, &handle, &stride);
+
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			 handle, 64, 64);
+}
+
+#if 0
+static void *
+drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int size, ret;
+	unsigned long rotate_pitch;
+
+	width = i830_pad_drawable_width(width, drmmode->cpp);
+	rotate_pitch = width * drmmode->cpp;
+	size = rotate_pitch * height;
+
+	drmmode_crtc->rotate_bo =
+		drm_intel_bo_alloc(intel->bufmgr, "rotate", size, 4096);
+
+	if (!drmmode_crtc->rotate_bo) {
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate shadow memory for rotated CRTC\n");
+		return NULL;
+	}
+
+	drm_intel_bo_disable_reuse(drmmode_crtc->rotate_bo);
+
+	ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+			   crtc->scrn->bitsPerPixel, rotate_pitch,
+			   drmmode_crtc->rotate_bo->handle,
+			   &drmmode_crtc->rotate_fb_id);
+	if (ret) {
+		ErrorF("failed to add rotate fb\n");
+		drm_intel_bo_unreference(drmmode_crtc->rotate_bo);
+		return NULL;
+	}
+
+	return drmmode_crtc->rotate_bo;
+}
+
+static PixmapPtr
+drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	unsigned long rotate_pitch;
+	PixmapPtr rotate_pixmap;
+
+	if (!data) {
+		data = drmmode_crtc_shadow_allocate (crtc, width, height);
+		if (!data) {
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+			return NULL;
+		}
+	}
+
+	rotate_pitch =
+		i830_pad_drawable_width(width, drmmode->cpp) * drmmode->cpp;
+	rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen,
+					       width, height,
+					       scrn->depth,
+					       scrn->bitsPerPixel,
+					       rotate_pitch,
+					       NULL);
+
+	if (rotate_pixmap == NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+		return NULL;
+	}
+
+	if (drmmode_crtc->rotate_bo)
+		i830_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo);
+
+	intel->shadow_present = TRUE;
+
+	return rotate_pixmap;
+}
+
+static void
+drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+}
+#endif
+
+static void
+drmmode_crtc_gamma_set(xf86CrtcPtr crtc,
+		       CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			    size, red, green, blue);
+}
+
+static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
+	.dpms = drmmode_crtc_dpms,
+	.set_mode_major = drmmode_set_mode_major,
+	.set_cursor_colors = drmmode_set_cursor_colors,
+	.set_cursor_position = drmmode_set_cursor_position,
+	.show_cursor = drmmode_show_cursor,
+	.hide_cursor = drmmode_hide_cursor,
+	.load_cursor_argb = drmmode_load_cursor_argb,
+#if 0
+	.shadow_create = drmmode_crtc_shadow_create,
+	.shadow_allocate = drmmode_crtc_shadow_allocate,
+	.shadow_destroy = drmmode_crtc_shadow_destroy,
+#endif
+	.gamma_set = drmmode_crtc_gamma_set,
+	.destroy = NULL, /* XXX */
+};
+
+
+static void
+drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
+{
+	xf86CrtcPtr crtc;
+	drmmode_crtc_private_ptr drmmode_crtc;
+
+	crtc = xf86CrtcCreate(scrn, &drmmode_crtc_funcs);
+	if (crtc == NULL)
+		return;
+
+	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
+						 drmmode->mode_res->crtcs[num]);
+	drmmode_crtc->drmmode = drmmode;
+	crtc->driver_private = drmmode_crtc;
+
+	return;
+}
+
+static xf86OutputStatus
+drmmode_output_detect(xf86OutputPtr output)
+{
+	/* go to the hw and retrieve a new output struct */
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	xf86OutputStatus status;
+	drmModeFreeConnector(drmmode_output->mode_output);
+
+	drmmode_output->mode_output =
+		drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
+	switch (drmmode_output->mode_output->connection) {
+	case DRM_MODE_CONNECTED:
+		status = XF86OutputStatusConnected;
+		break;
+	case DRM_MODE_DISCONNECTED:
+		status = XF86OutputStatusDisconnected;
+		break;
+	default:
+	case DRM_MODE_UNKNOWNCONNECTION:
+		status = XF86OutputStatusUnknown;
+		break;
+	}
+	return status;
+}
+
+static Bool
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	struct fixed_panel_lvds *p_lvds = drmmode_output->private_data;
+
+	/*
+	 * If the connector type is LVDS, we will use the panel limit to
+	 * verfiy whether the mode is valid.
+	 */
+	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
+		if (pModes->HDisplay > p_lvds->hdisplay ||
+			pModes->VDisplay > p_lvds->vdisplay)
+			return MODE_PANEL;
+		else
+			return MODE_OK;
+	}
+	return MODE_OK;
+}
+
+static void fill_detailed_lvds_block(struct detailed_monitor_section *det_mon,
+					DisplayModePtr mode)
+{
+	struct detailed_timings *timing = &det_mon->section.d_timings;
+
+	det_mon->type = DT;
+	timing->clock = mode->Clock * 1000;
+	timing->h_active = mode->HDisplay;
+	timing->h_blanking = mode->HTotal - mode->HDisplay;
+	timing->v_active = mode->VDisplay;
+	timing->v_blanking = mode->VTotal - mode->VDisplay;
+	timing->h_sync_off = mode->HSyncStart - mode->HDisplay;
+	timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart;
+	timing->v_sync_off = mode->VSyncStart - mode->VDisplay;
+	timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart;
+
+	if (mode->Flags & V_PVSYNC)
+		timing->misc |= 0x02;
+
+	if (mode->Flags & V_PHSYNC)
+		timing->misc |= 0x01;
+}
+
+static int drmmode_output_lvds_edid(xf86OutputPtr output,
+				struct fixed_panel_lvds *p_lvds)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	int i, j;
+	DisplayModePtr pmode;
+	xf86MonPtr	edid_mon;
+	drmModeModeInfo *mode_ptr;
+	struct detailed_monitor_section *det_mon;
+
+	if (output->MonInfo) {
+		/*
+		 * If there exists the EDID, we will either find a DS_RANGES
+		 * or replace a DS_VENDOR block, smashing it into a DS_RANGES
+		 * block with opern refresh to match all the default modes.
+		 */
+		int edid_det_block_num;
+		edid_mon = output->MonInfo;
+		edid_mon->features.msc |= 0x01;
+		j = -1;
+		edid_det_block_num = sizeof(edid_mon->det_mon) /
+					sizeof(edid_mon->det_mon[0]);
+		for (i = 0; i < edid_det_block_num; i++) {
+			if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1)
+				j = i;
+			if (edid_mon->det_mon[i].type == DS_RANGES) {
+				j = i;
+				break;
+			}
+		}
+		if (j != -1) {
+			struct monitor_ranges	*ranges =
+				&edid_mon->det_mon[j].section.ranges;
+			edid_mon->det_mon[j].type = DS_RANGES;
+			ranges->min_v = 0;
+			ranges->max_v = 200;
+			ranges->min_h = 0;
+			ranges->max_h = 200;
+		}
+		return 0;
+	}
+	/*
+	 * If there is no EDID, we will construct a bogus EDID for LVDS output
+	 * device. This is similar to what we have done in i830_lvds.c
+	 */
+	edid_mon = NULL;
+	edid_mon = xcalloc(1, sizeof(xf86Monitor));
+	if (!edid_mon) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"Can't allocate memory for edid_mon.\n");
+		return 0;
+	}
+	/* Find the fixed panel mode.
+	 * In theory when there is no EDID, KMS kernel will return only one
+	 * mode. And this can be regarded as fixed lvds panel mode.
+	 * But it will be better to traverse the mode list to get the fixed
+	 * lvds panel mode again as we don't know whether some new modes
+	 * are added for the LVDS output device
+	 */
+	j = 0;
+	for (i = 0; i < koutput->count_modes; i++) {
+		mode_ptr = &koutput->modes[i];
+		if ((mode_ptr->hdisplay == p_lvds->hdisplay) &&
+			(mode_ptr->vdisplay == p_lvds->vdisplay)) {
+			/* find the fixed panel mode */
+			j = i;
+			break;
+		}
+	}
+	pmode = xnfalloc(sizeof(DisplayModeRec));
+	drmmode_ConvertFromKMode(output->scrn, &koutput->modes[j], pmode);
+	/*support DPM, instead of DPMS*/
+	edid_mon->features.dpms |= 0x1;
+	/*defaultly support RGB color display*/
+	edid_mon->features.display_type |= 0x1;
+	/*defaultly display support continuous-freqencey*/
+	edid_mon->features.msc |= 0x1;
+	/*defaultly  the EDID version is 1.4 */
+	edid_mon->ver.version = 1;
+	edid_mon->ver.revision = 4;
+	det_mon = edid_mon->det_mon;
+	if (pmode) {
+		/* now we construct new EDID monitor,
+		 * so filled one detailed timing block
+		 */
+		fill_detailed_lvds_block(det_mon, pmode);
+		/* the filed timing block should be set preferred*/
+		edid_mon->features.msc |= 0x2;
+		det_mon = det_mon + 1;
+	}
+	/* Set wide sync ranges so we get all modes
+	 * handed to valid_mode for checking
+	 */
+	det_mon->type = DS_RANGES;
+	det_mon->section.ranges.min_v = 0;
+	det_mon->section.ranges.max_v = 200;
+	det_mon->section.ranges.min_h = 0;
+	det_mon->section.ranges.max_h = 200;
+	output->MonInfo = edid_mon;
+	return 0;
+}
+
+static DisplayModePtr
+drmmode_output_get_modes(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	int i;
+	DisplayModePtr Modes = NULL, Mode;
+	drmModePropertyPtr props;
+	struct fixed_panel_lvds *p_lvds;
+	drmModeModeInfo *mode_ptr;
+
+	/* look for an EDID property */
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (!props)
+			continue;
+		if (!(props->flags & DRM_MODE_PROP_BLOB)) {
+			drmModeFreeProperty(props);
+			continue;
+		}
+
+		if (!strcmp(props->name, "EDID")) {
+			drmModeFreePropertyBlob(drmmode_output->edid_blob);
+			drmmode_output->edid_blob =
+				drmModeGetPropertyBlob(drmmode->fd,
+						       koutput->prop_values[i]);
+		}
+		drmModeFreeProperty(props);
+	}
+
+	if (drmmode_output->edid_blob)
+		xf86OutputSetEDID(output,
+				  xf86InterpretEDID(output->scrn->scrnIndex,
+						    drmmode_output->edid_blob->data));
+	else
+		xf86OutputSetEDID(output,
+				  xf86InterpretEDID(output->scrn->scrnIndex,
+						    NULL));
+
+	/* modes should already be available */
+	for (i = 0; i < koutput->count_modes; i++) {
+		Mode = xnfalloc(sizeof(DisplayModeRec));
+
+		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i],
+					 Mode);
+		Modes = xf86ModesAdd(Modes, Mode);
+
+	}
+	p_lvds = drmmode_output->private_data;
+	/*
+	 * If the connector type is LVDS, we will traverse the kernel mode to
+	 * get the panel limit.
+	 * If it is incorrect, please fix me.
+	 */
+	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
+		p_lvds->hdisplay = 0;
+		p_lvds->vdisplay = 0;
+		for (i = 0; i < koutput->count_modes; i++) {
+			mode_ptr = &koutput->modes[i];
+			if ((mode_ptr->hdisplay >= p_lvds->hdisplay) &&
+				(mode_ptr->vdisplay >= p_lvds->vdisplay)) {
+				p_lvds->hdisplay = mode_ptr->hdisplay;
+				p_lvds->vdisplay = mode_ptr->vdisplay;
+			}
+		}
+		if (!p_lvds->hdisplay || !p_lvds->vdisplay)
+			xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+				"Incorrect KMS mode.\n");
+		drmmode_output_lvds_edid(output, p_lvds);
+	}
+	return Modes;
+}
+
+static void
+drmmode_output_destroy(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	int i;
+
+	if (drmmode_output->edid_blob)
+		drmModeFreePropertyBlob(drmmode_output->edid_blob);
+	for (i = 0; i < drmmode_output->num_props; i++) {
+	    drmModeFreeProperty(drmmode_output->props[i].mode_prop);
+	    xfree(drmmode_output->props[i].atoms);
+	}
+	xfree(drmmode_output->props);
+	drmModeFreeConnector(drmmode_output->mode_output);
+	if (drmmode_output->private_data) {
+		xfree(drmmode_output->private_data);
+		drmmode_output->private_data = NULL;
+	}
+	if (drmmode_output->backlight_iface)
+		drmmode_backlight_set(output, drmmode_output->backlight_active_level);
+	xfree(drmmode_output);
+	output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+	if (!drmmode_output->backlight_iface)
+		return;
+
+	if (mode == DPMSModeOn) {
+		/* If we're going from off->on we may need to turn on the backlight. */
+		if (oldmode != DPMSModeOn)
+			drmmode_backlight_set(output, drmmode_output->backlight_active_level);
+	} else {
+		/* Only save the current backlight value if we're going from on to off. */
+		if (oldmode == DPMSModeOn)
+			drmmode_output->backlight_active_level = drmmode_backlight_get(output);
+		drmmode_backlight_set(output, 0);
+	}
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	int i;
+	drmModePropertyPtr props;
+
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (!props)
+			continue;
+
+		if (!strcmp(props->name, "DPMS")) {
+                        drmModeConnectorSetProperty(drmmode->fd,
+                                drmmode_output->output_id,
+                                props->prop_id,
+                                mode);
+			drmmode_output_dpms_backlight(output,
+				drmmode_output->dpms_mode,
+				mode);
+			drmmode_output->dpms_mode = mode;
+                        drmModeFreeProperty(props);
+                        return;
+		}
+		drmModeFreeProperty(props);
+	}
+}
+
+static Bool
+drmmode_property_ignore(drmModePropertyPtr prop)
+{
+    if (!prop)
+	return TRUE;
+    /* ignore blob prop */
+    if (prop->flags & DRM_MODE_PROP_BLOB)
+	return TRUE;
+    /* ignore standard property */
+    if (!strcmp(prop->name, "EDID") ||
+	    !strcmp(prop->name, "DPMS"))
+	return TRUE;
+
+    return FALSE;
+}
+
+#define BACKLIGHT_NAME             "Backlight"
+#define BACKLIGHT_DEPRECATED_NAME  "BACKLIGHT"
+static Atom backlight_atom, backlight_deprecated_atom;
+
+static void
+drmmode_output_create_resources(xf86OutputPtr output)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmModeConnectorPtr mode_output = drmmode_output->mode_output;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    drmModePropertyPtr drmmode_prop;
+    int i, j, err;
+
+    drmmode_output->props = xcalloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+    if (!drmmode_output->props)
+	return;
+
+    drmmode_output->num_props = 0;
+    for (i = 0, j = 0; i < mode_output->count_props; i++) {
+	drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
+	if (drmmode_property_ignore(drmmode_prop)) {
+	    drmModeFreeProperty(drmmode_prop);
+	    continue;
+	}
+	drmmode_output->props[j].mode_prop = drmmode_prop;
+	drmmode_output->props[j].value = mode_output->prop_values[i];
+	drmmode_output->num_props++;
+	j++;
+    }
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+	drmmode_prop = p->mode_prop;
+
+	if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    INT32 range[2];
+
+	    p->num_atoms = 1;
+	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    range[0] = drmmode_prop->values[0];
+	    range[1] = drmmode_prop->values[1];
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, TRUE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    2, range);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_INTEGER, 32, PropModeReplace, 1, &p->value, FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	} else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    p->num_atoms = drmmode_prop->count_enums + 1;
+	    p->atoms = xcalloc(p->num_atoms, sizeof(Atom));
+	    if (!p->atoms)
+		continue;
+	    p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
+	    for (j = 1; j <= drmmode_prop->count_enums; j++) {
+		struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1];
+		p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
+	    }
+	    err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
+		    FALSE, FALSE,
+		    drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
+		    p->num_atoms - 1, (INT32 *)&p->atoms[1]);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    for (j = 0; j < drmmode_prop->count_enums; j++)
+		if (drmmode_prop->enums[j].value == p->value)
+		    break;
+	    /* there's always a matching value */
+	    err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
+		    XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+			"RRChangeOutputProperty error, %d\n", err);
+	    }
+	}
+    }
+
+    if (drmmode_output->backlight_iface) {
+	INT32 data, backlight_range[2];
+	/* Set up the backlight property, which takes effect immediately
+	 * and accepts values only within the backlight_range. */
+	backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, TRUE);
+	backlight_deprecated_atom = MakeAtom(BACKLIGHT_DEPRECATED_NAME,
+		sizeof(BACKLIGHT_DEPRECATED_NAME) - 1, TRUE);
+
+	backlight_range[0] = 0;
+	backlight_range[1] = drmmode_output->backlight_max;
+	err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
+	                                FALSE, TRUE, FALSE, 2, backlight_range);
+	if (err != 0) {
+	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+	               "RRConfigureOutputProperty error, %d\n", err);
+	}
+	err = RRConfigureOutputProperty(output->randr_output, backlight_deprecated_atom,
+	                                FALSE, TRUE, FALSE, 2, backlight_range);
+	if (err != 0) {
+	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+	               "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the backlight property */
+	data = drmmode_output->backlight_active_level;
+	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
+	                             XA_INTEGER, 32, PropModeReplace, 1, &data,
+	                             FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+	               "RRChangeOutputProperty error, %d\n", err);
+	}
+	err = RRChangeOutputProperty(output->randr_output, backlight_deprecated_atom,
+	                             XA_INTEGER, 32, PropModeReplace, 1, &data,
+	                             FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+	               "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+}
+
+static Bool
+drmmode_output_set_property(xf86OutputPtr output, Atom property,
+		RRPropertyValuePtr value)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    drmmode_ptr drmmode = drmmode_output->drmmode;
+    int i;
+
+    if (property == backlight_atom || property == backlight_deprecated_atom) {
+	INT32 val;
+
+	if (value->type != XA_INTEGER || value->format != 32 ||
+	    value->size != 1)
+	{
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < 0 || val > drmmode_output->backlight_max)
+	    return FALSE;
+
+	if (drmmode_output->dpms_mode == DPMSModeOn)
+	    drmmode_backlight_set(output, val);
+	drmmode_output->backlight_active_level = val;
+	return TRUE;
+    }
+
+    for (i = 0; i < drmmode_output->num_props; i++) {
+	drmmode_prop_ptr p = &drmmode_output->props[i];
+
+	if (p->atoms[0] != property)
+	    continue;
+
+	if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
+	    uint32_t val;
+
+	    if (value->type != XA_INTEGER || value->format != 32 ||
+		    value->size != 1)
+		return FALSE;
+	    val = *(uint32_t *)value->data;
+
+	    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+		    p->mode_prop->prop_id, (uint64_t)val);
+	    return TRUE;
+	} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
+	    Atom	atom;
+	    const char	*name;
+	    int		j;
+
+	    if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
+		return FALSE;
+	    memcpy(&atom, value->data, 4);
+	    name = NameForAtom(atom);
+
+	    /* search for matching name string, then set its value down */
+	    for (j = 0; j < p->mode_prop->count_enums; j++) {
+		if (!strcmp(p->mode_prop->enums[j].name, name)) {
+		    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
+			    p->mode_prop->prop_id, p->mode_prop->enums[j].value);
+		    return TRUE;
+		}
+	    }
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
+static Bool
+drmmode_output_get_property(xf86OutputPtr output, Atom property)
+{
+    drmmode_output_private_ptr drmmode_output = output->driver_private;
+    int err;
+
+    if (property == backlight_atom || property == backlight_deprecated_atom) {
+	INT32 val;
+
+	if (! drmmode_output->backlight_iface)
+	    return FALSE;
+
+	val = drmmode_backlight_get(output);
+	if (val < 0)
+	    return FALSE;
+	err = RRChangeOutputProperty(output->randr_output, property,
+	                             XA_INTEGER, 32, PropModeReplace, 1, &val,
+	                             FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+	               "RRChangeOutputProperty error, %d\n", err);
+	    return FALSE;
+	}
+
+	return TRUE;
+    }
+
+    return TRUE;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+	.create_resources = drmmode_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+	.set_property = drmmode_output_set_property,
+	.get_property = drmmode_output_get_property,
+#endif
+	.dpms = drmmode_output_dpms,
+	.detect = drmmode_output_detect,
+	.mode_valid = drmmode_output_mode_valid,
+
+	.get_modes = drmmode_output_get_modes,
+	.destroy = drmmode_output_destroy
+};
+
+static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
+				      SubPixelHorizontalRGB,
+				      SubPixelHorizontalBGR,
+				      SubPixelVerticalRGB,
+				      SubPixelVerticalBGR,
+				      SubPixelNone };
+
+static const char *output_names[] = { "None",
+				      "VGA",
+				      "DVI",
+				      "DVI",
+				      "DVI",
+				      "Composite",
+				      "TV",
+				      "LVDS",
+				      "CTV",
+				      "DIN",
+				      "DP",
+				      "HDMI",
+				      "HDMI",
+};
+
+
+static void
+drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num)
+{
+	xf86OutputPtr output;
+	drmModeConnectorPtr koutput;
+	drmModeEncoderPtr kencoder;
+	drmmode_output_private_ptr drmmode_output;
+	char name[32];
+
+	koutput = drmModeGetConnector(drmmode->fd,
+				      drmmode->mode_res->connectors[num]);
+	if (!koutput)
+		return;
+
+	kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
+	if (!kencoder) {
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	snprintf(name, 32, "%s%d", output_names[koutput->connector_type],
+		 koutput->connector_type_id);
+
+	output = xf86OutputCreate (scrn, &drmmode_output_funcs, name);
+	if (!output) {
+		drmModeFreeEncoder(kencoder);
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+	if (!drmmode_output) {
+		xf86OutputDestroy(output);
+		drmModeFreeConnector(koutput);
+		drmModeFreeEncoder(kencoder);
+		return;
+	}
+	/*
+	 * If the connector type of the output device is LVDS, we will
+	 * allocate the private_data to store the panel limit.
+	 * For example: hdisplay, vdisplay
+	 */
+	drmmode_output->private_data = NULL;
+	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) {
+		drmmode_output->private_data = xcalloc(
+				sizeof(struct fixed_panel_lvds), 1);
+		if (!drmmode_output->private_data)
+			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+				"Can't allocate private memory for LVDS.\n");
+	}
+	drmmode_output->output_id = drmmode->mode_res->connectors[num];
+	drmmode_output->mode_output = koutput;
+	drmmode_output->mode_encoder = kencoder;
+	drmmode_output->drmmode = drmmode;
+	output->mm_width = koutput->mmWidth;
+	output->mm_height = koutput->mmHeight;
+
+	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+	output->driver_private = drmmode_output;
+
+	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS)
+		drmmode_backlight_init(output);
+
+	output->possible_crtcs = kencoder->possible_crtcs;
+	output->possible_clones = kencoder->possible_clones;
+	return;
+}
+
+
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	int i;
+
+	if (!drmmode_update_fb(scrn, width, height))
+		return FALSE;
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+		if (!crtc->enabled)
+			continue;
+
+		drmmode_set_mode_major(crtc, &crtc->mode,
+				       crtc->rotation, crtc->x, crtc->y);
+	}
+
+	return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+	drmmode_xf86crtc_resize
+};
+
+#if 0
+Bool
+drmmode_do_pageflip(ScreenPtr screen, dri_bo *new_front, dri_bo *old_front,
+		    void *data)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	unsigned int pitch = scrn->displayWidth * intel->cpp;
+	int i, old_fb_id;
+	unsigned int crtc_id;
+
+	/*
+	 * Create a new handle for the back buffer
+	 */
+	old_fb_id = drmmode->fb_id;
+	if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY,
+			 scrn->depth, scrn->bitsPerPixel, pitch,
+			 new_front->handle, &drmmode->fb_id))
+		goto error_out;
+
+	/*
+	 * Queue flips on all enabled CRTCs
+	 * Note that if/when we get per-CRTC buffers, we'll have to update this.
+	 * Right now it assumes a single shared fb across all CRTCs, with the
+	 * kernel fixing up the offset of each CRTC as necessary.
+	 *
+	 * Also, flips queued on disabled or incorrectly configured displays
+	 * may never complete; this is a configuration error.
+	 */
+	for (i = 0; i < config->num_crtc; i++) {
+		xf86CrtcPtr crtc = config->crtc[i];
+
+		if (!crtc->enabled)
+			continue;
+
+		drmmode_crtc = crtc->driver_private;
+		crtc_id = drmmode_crtc->mode_crtc->crtc_id;
+		drmmode->event_data = data;
+		drmmode->flip_count++;
+		if (drmModePageFlip(drmmode->fd, crtc_id, drmmode->fb_id,
+				    DRM_MODE_PAGE_FLIP_EVENT, drmmode)) {
+			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+				   "flip queue failed: %s\n", strerror(errno));
+			goto error_undo;
+		}
+	}
+
+	dri_bo_pin(new_front, 0);
+	dri_bo_unpin(new_front);
+
+	scrn->fbOffset = new_front->offset;
+	intel->front_buffer->bo = new_front;
+	intel->front_buffer->offset = new_front->offset;
+	drmmode->old_fb_id = old_fb_id;
+
+	return TRUE;
+
+error_undo:
+	drmModeRmFB(drmmode->fd, drmmode->fb_id);
+	drmmode->fb_id = old_fb_id;
+
+error_out:
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
+		   strerror(errno));
+	return FALSE;
+}
+
+static void
+drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec,
+		       unsigned int tv_usec, void *event_data)
+{
+	I830DRI2FrameEventHandler(frame, tv_sec, tv_usec, event_data);
+}
+
+static void
+drmmode_page_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
+			  unsigned int tv_usec, void *event_data)
+{
+	drmmode_ptr drmmode = event_data;
+
+	drmmode->flip_count--;
+	if (drmmode->flip_count > 0)
+		return;
+
+	drmModeRmFB(drmmode->fd, drmmode->old_fb_id);
+
+	I830DRI2FlipEventHandler(frame, tv_sec, tv_usec, drmmode->event_data);
+}
+
+static void
+drm_wakeup_handler(pointer data, int err, pointer p)
+{
+    drmmode_ptr drmmode = data;
+    fd_set *read_mask = p;
+
+    if (err >= 0 && FD_ISSET(drmmode->fd, read_mask))
+	drmHandleEvent(drmmode->fd, &drmmode->event_context);
+}
+#endif
+
+Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
+{
+	drmmode_ptr drmmode;
+	unsigned int i;
+
+	drmmode = xnfalloc(sizeof *drmmode);
+	drmmode->fd = fd;
+	drmmode->fb_id = 0;
+
+	xf86CrtcConfigInit(scrn, &drmmode_xf86crtc_config_funcs);
+
+	drmmode->cpp = cpp;
+	drmmode->mode_res = drmModeGetResources(drmmode->fd);
+	if (!drmmode->mode_res) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "failed to get resources: %s\n", strerror(errno));
+		return FALSE;
+	}
+
+	xf86CrtcSetSizeRange(scrn, 320, 200, drmmode->mode_res->max_width,
+			     drmmode->mode_res->max_height);
+	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+		drmmode_crtc_init(scrn, drmmode, i);
+
+	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+		drmmode_output_init(scrn, drmmode, i);
+
+	xf86InitialConfiguration(scrn, TRUE);
+
+#if 0
+	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
+	gp.value = &has_flipping;
+	(void)drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp,
+				  sizeof(gp));
+	if (has_flipping) {
+		xf86DrvMsg(scrn->scrnIndex, X_INFO,
+			   "Kernel page flipping support detected, enabling\n");
+		intel->use_pageflipping = TRUE;
+		drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
+		drmmode->event_context.vblank_handler = drmmode_vblank_handler;
+		drmmode->event_context.page_flip_handler =
+		    drmmode_page_flip_handler;
+		AddGeneralSocket(fd);
+		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+					       drm_wakeup_handler, drmmode);
+	}
+#endif
+
+	return TRUE;
+}
+
+void drmmode_closefb(ScrnInfoPtr scrn)
+{
+	xf86CrtcConfigPtr xf86_config;
+	drmmode_crtc_private_ptr drmmode_crtc;
+	drmmode_ptr drmmode;
+
+	xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+	drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode = drmmode_crtc->drmmode;
+
+	drmModeRmFB(drmmode->fd, drmmode->fb_id);
+	drmmode->fb_id = 0;
+}
diff --git a/hw/xfree86/glamor/glamor_ddx.h b/hw/xfree86/glamor/glamor_ddx.h
new file mode 100644
index 0000000..0968f01
--- /dev/null
+++ b/hw/xfree86/glamor/glamor_ddx.h
@@ -0,0 +1,15 @@
+#ifndef GLAMOR_DDX_H
+#define GLAMOR_DDX_H
+
+Bool glamor_resize(ScrnInfoPtr scrn, int width, int height);
+void glamor_frontbuffer_handle(ScrnInfoPtr scrn,
+			       uint32_t *handle, uint32_t *pitch);
+Bool glamor_load_cursor(ScrnInfoPtr scrn,
+			CARD32 *image, int width, int height);
+void glamor_cursor_handle(ScrnInfoPtr scrn,
+			  uint32_t *handle, uint32_t *pitch);
+
+Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp);
+void drmmode_closefb(ScrnInfoPtr scrn);
+
+#endif
commit 47b6531273e3052b653194099a49ca11d80b12df
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Wed Apr 13 15:50:26 2011 +0800

    glamor: Fixed one segfault bug when close screen.
    
    move the original glamor_fini to glamor_close_screen. And wrap the CloseScreen
    with glamor_close_screen, Then we can do some thing before call the underlying
    CloseScreen().
    The root cause is that glamor_fini will be called after the ->CloseScreen().
    This may trigger a segmentation fault at
    glamor_unrealize_glyph_caches() at calling into FreePicture().

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 29cefa8..537fb68 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -203,6 +203,9 @@ glamor_init(ScreenPtr screen)
 	goto fail;
     }
 
+    glamor_priv->saved_close_screen = screen->CloseScreen;
+    screen->CloseScreen = glamor_close_screen;
+
     glamor_priv->saved_create_gc = screen->CreateGC;
     screen->CreateGC = glamor_create_gc;
 
@@ -251,8 +254,8 @@ fail:
     return FALSE;
 }
 
-void
-glamor_fini(ScreenPtr screen)
+Bool 
+glamor_close_screen(int idx, ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 #ifdef RENDER
@@ -260,7 +263,7 @@ glamor_fini(ScreenPtr screen)
 #endif
 
     glamor_glyphs_fini(screen);
-
+    screen->CloseScreen = glamor_priv->saved_close_screen;
     screen->CreateGC = glamor_priv->saved_create_gc;
     screen->CreatePixmap = glamor_priv->saved_create_pixmap;
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
@@ -275,4 +278,13 @@ glamor_fini(ScreenPtr screen)
 	ps->Glyphs = glamor_priv->saved_glyphs;
     }
 #endif
+    free(glamor_priv);
+    return screen->CloseScreen(idx, screen);   
+    
+}
+
+void
+glamor_fini(ScreenPtr screen)
+{
+/* Do nothing currently. */
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 18bd76b..c2f516d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -128,6 +128,7 @@ enum shader_in {
 };
 
 typedef struct glamor_screen_private {
+    CloseScreenProcPtr saved_close_screen;
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
     DestroyPixmapProcPtr saved_destroy_pixmap;
@@ -282,6 +283,9 @@ t_from_x_coord_y(PixmapPtr pixmap, int y)
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
+Bool glamor_close_screen(int idx, ScreenPtr screen);
+
+
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
commit 0d9e8db8d031d22b02df2c9b226287b1ca489f5a
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 8 15:30:45 2011 +0800

    glamor: Fixed one linking error.
    
    As current glamor implementation depends on the glx library in the
    mesa package which is conflict with the version in xorg. We have to
    --disable-glx when build Xephyr. But this leads to the linking error
    here. We comment out the calling to ephyrHijackGLXExtension() now.
    Need revisit latter.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 1aacc5f..4bead1f 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -669,7 +669,9 @@ ephyrInitScreen (ScreenPtr pScreen)
   }
   if (!ephyrNoDRI) {
     ephyrDRIExtensionInit (pScreen) ;
+#if 0
     ephyrHijackGLXExtension () ;
+#endif
   }
 #endif
 
commit b3577a1c853d870f4d583a35d27012acb9099ef4
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 8 15:24:55 2011 +0800

    glamor: Merged with latest xserver.
    
    Merged with latest xserver, the major change is due to the API change of
    the management of devPrivates.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b7259af..29cefa8 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -30,17 +30,13 @@
  * functions not responsible for performing rendering.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
 #include <stdlib.h>
 
 #include "glamor_priv.h"
 
-static int glamor_screen_private_key_index;
+static DevPrivateKeyRec glamor_screen_private_key_index;
 DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
-static int glamor_pixmap_private_key_index;
+static DevPrivateKeyRec glamor_pixmap_private_key_index;
 DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 
 /**
@@ -68,54 +64,59 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 		     unsigned int usage)
 {
     PixmapPtr pixmap;
-    glamor_pixmap_private *pixmap_priv;
+    glamor_pixmap_private *pixmap_priv, *newpixmap_priv;
     GLenum format;
 
     if (w > 32767 || h > 32767)
 	return NullPixmap;
 
     pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+    if (dixAllocatePrivates(pixmap->devPrivates, PRIVATE_PIXMAP) != TRUE) {
+        fbDestroyPixmap(pixmap);
+	ErrorF("Fail to allocate privates for PIXMAP.\n");
+	return NullPixmap;
+    }	 
     pixmap_priv = glamor_get_pixmap_private(pixmap);
+    assert(pixmap_priv != NULL);
 
     if (w == 0 || h == 0)
 	return pixmap;
-
     /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
      * FBOs, which EXT_fbo forgot to do.
      */
     switch (depth) {
     case 24:
-	format = GL_RGB;
-	break;
+        format = GL_RGB;
+        break;
     default:
-	format = GL_RGBA;
-	break;
+        format = GL_RGBA;
+        break;
     }
 
+
     /* Create the texture used to store the pixmap's data. */
     glGenTextures(1, &pixmap_priv->tex);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
-		 format, GL_UNSIGNED_BYTE, NULL);
+                 format, GL_UNSIGNED_BYTE, NULL);
 
-    /* Create a framebuffer object wrapping the texture so that we can render
-     * to it.
-     */
+    /*  Create a framebuffer object wrapping the texture so that we can render
+     ** to it.
+     **/
     glGenFramebuffersEXT(1, &pixmap_priv->fb);
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-			      GL_COLOR_ATTACHMENT0_EXT,
-			      GL_TEXTURE_2D,
-			      pixmap_priv->tex,
-			      0);
+                              GL_COLOR_ATTACHMENT0_EXT,
+                              GL_TEXTURE_2D,
+                              pixmap_priv->tex,
+                              0);
 
-    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+    screen->ModifyPixmapHeader(pixmap, w, h, depth, 0,
 			       (((w * pixmap->drawable.bitsPerPixel +
 				  7) / 8) + 3) & ~3,
 			       NULL);
-
     return pixmap;
 }
 
@@ -156,13 +157,22 @@ glamor_init(ScreenPtr screen)
     if (glamor_priv == NULL)
 	return FALSE;
 
-    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
-    if (!dixRequestPrivate(glamor_pixmap_private_key,
-			   sizeof(glamor_pixmap_private))) {
+
+    if (!dixRegisterPrivateKey(glamor_screen_private_key,PRIVATE_SCREEN,
+			   0)) {
 	LogMessage(X_WARNING,
-		   "glamor%d: Failed to allocate pixmap private\n",
+		   "glamor%d: Failed to allocate screen private\n",
 		   screen->myNum);
     }
+    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
+
+    if (!dixRegisterPrivateKey(glamor_pixmap_private_key,PRIVATE_PIXMAP,
+                           sizeof(glamor_pixmap_private))) {
+        LogMessage(X_WARNING,
+                   "glamor%d: Failed to allocate pixmap private\n",
+                   screen->myNum);
+    }
+
 
     glewInit();
 
@@ -224,16 +234,15 @@ glamor_init(ScreenPtr screen)
     ps->Trapezoids = glamor_trapezoids;
     glamor_priv->saved_glyphs = ps->Glyphs;
     ps->Glyphs = glamor_glyphs;
+    glamor_init_composite_shaders(screen);
 #endif
-
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
     glamor_init_putimage_shaders(screen);
-    glamor_init_composite_shaders(screen);
     glamor_init_finish_access_shaders(screen);
-
     glamor_glyphs_init(screen);
 
+
     return TRUE;
 
 fail:
commit 3105fe9f6491f37a1f82a9e6f03f4efaed6c7e92
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 8 15:22:52 2011 +0800

    glamor: Call glamor_composite_rects only when enable RENDER.

diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 7b2d13d..6e5595e 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -572,8 +572,10 @@ glamor_buffer_glyph(ScreenPtr screen,
 static void glamor_glyphs_to_mask(PicturePtr mask,
 				  glamor_glyph_buffer_t *buffer)
 {
+#ifdef RENDER
     glamor_composite_rects(PictOpAdd, buffer->source, mask,
 			   buffer->count, buffer->rects);
+#endif
 
     buffer->count = 0;
     buffer->source = NULL;
commit f9843c7a35975b178eec9812d21e1f02a2120928
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 8 14:53:15 2011 +0800

    glamor: Fixed one conflict data type(XID) bug.
    
    We should include the dix-config.h for all the glamor files. Otherwise
    the XID type maybe inconsisitent in different files in 64bit machine.
    The root cause is this macro "#define _XSERVER64 1" should be included
    in all files refer to the data type "XID" which is originally defined
    in X.h. If _XSERVER64 is defined as 1, then XID is defined as CARD32
    which is a 32bit integer. If _XSERVER64 is not defined as 1 then XID
    is "unsigned long". In a 32bit machine, "unsigned long" should be
    identical to CARD32. But in a 64bit machine, they are different.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3dc3a53..18bd76b 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -24,10 +24,14 @@
  *    Eric Anholt <eric at anholt.net>
  *
  */
-
 #ifndef GLAMOR_PRIV_H
 #define GLAMOR_PRIV_H
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
 #include "glamor.h"
 #include <GL/glew.h>
 
commit e194740c9413bbfefee6506a734e0c82c091dfa3
Author: Zhigang Gong <zhigang.gong at linux.intel.com>
Date:   Fri Apr 8 14:49:57 2011 +0800

    glamor: Fixed some compiling and linking errors.
    
    Change the inline functions to static type, otherwise when linking it
    complains multiple definitions of those functions.

diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h
index 29dba38..27bcebc 100644
--- a/glamor/glu3/glu3.h
+++ b/glamor/glu3/glu3.h
@@ -123,7 +123,7 @@ typedef struct GLUmat4Stack GLUmat4Stack;
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+#if 0
 GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *);
 GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *);
 GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *);
@@ -169,7 +169,7 @@ void gluOrtho6f(GLUmat4 *result,
 		GLfloat left, GLfloat right,
 		GLfloat bottom, GLfloat top,
 		GLfloat near, GLfloat far);
-
+#endif
 extern const GLUmat4 gluIdentityMatrix;
 
 #ifdef __cplusplus
diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h
index 3e87b8c..00592f0 100644
--- a/glamor/glu3/glu3_scalar.h
+++ b/glamor/glu3/glu3_scalar.h
@@ -24,7 +24,7 @@
 #include <math.h>
 #include <string.h>
 
-extern inline void gluMult4v_4v(GLUvec4 *result,
+static inline void gluMult4v_4v(GLUvec4 *result,
 				const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	result->values[0] = v1->values[0] * v2->values[0];
@@ -34,7 +34,7 @@ extern inline void gluMult4v_4v(GLUvec4 *result,
 }
 
 
-extern inline void gluDiv4v_4v(GLUvec4 *result,
+static inline void gluDiv4v_4v(GLUvec4 *result,
 			       const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	result->values[0] = v1->values[0] / v2->values[0];
@@ -44,7 +44,7 @@ extern inline void gluDiv4v_4v(GLUvec4 *result,
 }
 
 
-extern inline void gluAdd4v_4v(GLUvec4 *result,
+static inline void gluAdd4v_4v(GLUvec4 *result,
 			       const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	result->values[0] = v1->values[0] + v2->values[0];
@@ -54,7 +54,7 @@ extern inline void gluAdd4v_4v(GLUvec4 *result,
 }
 
 
-extern inline void gluSub4v_4v(GLUvec4 *result,
+static inline void gluSub4v_4v(GLUvec4 *result,
 			       const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	result->values[0] = v1->values[0] - v2->values[0];
@@ -64,7 +64,7 @@ extern inline void gluSub4v_4v(GLUvec4 *result,
 }
 
 
-extern inline void gluMult4v_f(GLUvec4 *result,
+static inline void gluMult4v_f(GLUvec4 *result,
 			       const GLUvec4 *v1, GLfloat f)
 {
 	result->values[0] = v1->values[0] * f;
@@ -74,7 +74,7 @@ extern inline void gluMult4v_f(GLUvec4 *result,
 }
 
 
-extern inline void gluDiv4v_f(GLUvec4 *result,
+static inline void gluDiv4v_f(GLUvec4 *result,
 			      const GLUvec4 *v1, GLfloat f)
 {
 	result->values[0] = v1->values[0] / f;
@@ -84,7 +84,7 @@ extern inline void gluDiv4v_f(GLUvec4 *result,
 }
 
 
-extern inline void gluAdd4v_f(GLUvec4 *result,
+static inline void gluAdd4v_f(GLUvec4 *result,
 			      const GLUvec4 *v1, GLfloat f)
 {
 	result->values[0] = v1->values[0] + f;
@@ -94,7 +94,7 @@ extern inline void gluAdd4v_f(GLUvec4 *result,
 }
 
 
-extern inline void gluSub4v_f(GLUvec4 *result,
+static inline void gluSub4v_f(GLUvec4 *result,
 			      const GLUvec4 *v1, GLfloat f)
 {
 	result->values[0] = v1->values[0] - f;
@@ -104,7 +104,7 @@ extern inline void gluSub4v_f(GLUvec4 *result,
 }
 
 
-extern inline void gluMult4m_f(GLUmat4 *result,
+static inline void gluMult4m_f(GLUmat4 *result,
 			       const GLUmat4 *m, GLfloat f)
 {
 	GLUmat4 temp;
@@ -117,7 +117,7 @@ extern inline void gluMult4m_f(GLUmat4 *result,
 }
 
 
-extern inline void gluMult4m_4v(GLUvec4 *result,
+static inline void gluMult4m_4v(GLUvec4 *result,
 				const GLUmat4 *m, const GLUvec4 *v)
 {
 	GLUvec4 temp[6];
@@ -133,7 +133,7 @@ extern inline void gluMult4m_4v(GLUvec4 *result,
 }
 
 
-extern inline void gluAdd4m_4m(GLUmat4 *result,
+static inline void gluAdd4m_4m(GLUmat4 *result,
 			       const GLUmat4 *m1, const GLUmat4 *m2)
 {
 	GLUmat4 temp;
@@ -145,7 +145,7 @@ extern inline void gluAdd4m_4m(GLUmat4 *result,
 	*result = temp;
 }
 
-extern inline void gluSub4m_4m(GLUmat4 *result,
+static inline void gluSub4m_4m(GLUmat4 *result,
 			       const GLUmat4 *m1, const GLUmat4 *m2)
 {
 	GLUmat4 temp;
@@ -157,7 +157,7 @@ extern inline void gluSub4m_4m(GLUmat4 *result,
 	*result = temp;
 }
 
-extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+static inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	return v1->values[0] * v2->values[0]
 		+ v1->values[1] * v2->values[1]
@@ -166,7 +166,7 @@ extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2)
 }
 
 
-extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+static inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	return v1->values[0] * v2->values[0]
 		+ v1->values[1] * v2->values[1]
@@ -174,14 +174,14 @@ extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2)
 }
 
 
-extern inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+static inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	return v1->values[0] * v2->values[0]
 		+ v1->values[1] * v2->values[1];
 }
 
 
-extern inline void gluCross4v(GLUvec4 *result,
+static inline void gluCross4v(GLUvec4 *result,
 			      const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	GLUvec4 temp;
@@ -197,7 +197,7 @@ extern inline void gluCross4v(GLUvec4 *result,
 }
 
 
-extern inline void gluOuter4v(GLUmat4 *result,
+static inline void gluOuter4v(GLUmat4 *result,
 			      const GLUvec4 *v1, const GLUvec4 *v2)
 {
 	GLUmat4 temp;
@@ -210,26 +210,26 @@ extern inline void gluOuter4v(GLUmat4 *result,
 }
 
 
-extern inline GLfloat gluLengthSqr4v(const GLUvec4 *v)
+static inline GLfloat gluLengthSqr4v(const GLUvec4 *v)
 {
 	return gluDot4_4v(v, v);
 }
 
 
-extern inline GLfloat gluLength4v(const GLUvec4 *v)
+static inline GLfloat gluLength4v(const GLUvec4 *v)
 {
 	return sqrt(gluLengthSqr4v(v));
 }
 
 
-extern inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v)
+static inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v)
 {
 	gluDiv4v_f(result, v, gluLength4v(v));
 }
 
 
 
-extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m)
+static inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m)
 {
 	unsigned i;
 	unsigned j;
@@ -245,7 +245,7 @@ extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m)
 }
 
 
-extern inline void gluMult4m_4m(GLUmat4 *result,
+static inline void gluMult4m_4m(GLUmat4 *result,
 				const GLUmat4 *m1, const GLUmat4 *m2)
 {
 	GLUmat4 temp;
@@ -260,7 +260,7 @@ extern inline void gluMult4m_4m(GLUmat4 *result,
 
 
 
-extern inline void gluTranslate3f(GLUmat4 *result,
+static inline void gluTranslate3f(GLUmat4 *result,
 				  GLfloat x, GLfloat y, GLfloat z)
 {
 	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
@@ -271,7 +271,7 @@ extern inline void gluTranslate3f(GLUmat4 *result,
 
 
 #ifdef __cplusplus
-extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2)
+static inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2)
 {
 	return v1.values[0] * v2.values[0]
 		+ v1.values[1] * v2.values[1]
@@ -280,7 +280,7 @@ extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2)
 }
 
 
-extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2)
+static inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2)
 {
 	return v1.values[0] * v2.values[0]
 		+ v1.values[1] * v2.values[1]
@@ -288,7 +288,7 @@ extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2)
 }
 
 
-extern inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2)
+static inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2)
 {
 	return v1.values[0] * v2.values[0]
 		+ v1.values[1] * v2.values[1];
commit 8cfcc614032320bb6a2eca2c61baeebf388d22ea
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Feb 19 07:14:13 2010 -0800

    glamor: Add support for using EXT_framebuffer_blit to do CopyArea.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 172b959..297a1fb 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -33,6 +33,88 @@
  */
 
 static Bool
+glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
+			    DrawablePtr dst,
+			    GCPtr gc,
+			    BoxPtr box,
+			    int nbox,
+			    int dx,
+			    int dy)
+{
+    ScreenPtr screen = dst->pScreen;
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    glamor_pixmap_private *src_pixmap_priv;
+    int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
+
+    if (src == dst) {
+	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+				"src == dest\n");
+	return FALSE;
+    }
+
+    if (!GLEW_EXT_framebuffer_blit) {
+	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+				"no EXT_framebuffer_blit\n");
+	return FALSE;
+   }
+
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+
+    if (src_pixmap_priv->fb == 0) {
+        PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+        if (src_pixmap != screen_pixmap) {
+            glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+				    "no src fbo\n");
+            return FALSE;
+        }
+    }
+
+    if (gc) {
+	if (gc->alu != GXcopy) {
+	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+				    "non-copy ALU\n");
+	    return FALSE;
+	}
+	if (!glamor_pm_is_solid(dst, gc->planemask)) {
+	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+				    "non-solid planemask\n");
+	    return FALSE;
+	}
+    }
+
+    if (!glamor_set_destination_pixmap(dst_pixmap))
+	return FALSE;
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
+
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    src_y_off += dy;
+
+    for (i = 0; i < nbox; i++) {
+	int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
+	int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
+	int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
+	int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
+
+	glBlitFramebufferEXT(box[i].x1 + dx + src_x_off,
+			     flip_src_y1,
+			     box[i].x2 + dx + src_x_off,
+			     flip_src_y2,
+			     box[i].x1 + dst_x_off,
+			     flip_dst_y1,
+			     box[i].x2 + dst_x_off,
+			     flip_dst_y2,
+			     GL_COLOR_BUFFER_BIT,
+			     GL_NEAREST);
+    }
+
+    return TRUE;
+}
+
+static Bool
 glamor_copy_n_to_n_copypixels(DrawablePtr src,
 			      DrawablePtr dst,
 			      GCPtr gc,
@@ -199,6 +281,11 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 Pixel		bitplane,
 		 void		*closure)
 {
+    if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
+	glamor_clear_delayed_fallbacks(dst->pScreen);
+	return;
+    }
+
     if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) {
 	glamor_clear_delayed_fallbacks(dst->pScreen);
 	return;
commit d2da9d1c22d25d1f86ecd83c15ca9909fab8610a
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Feb 19 07:36:28 2010 -0800

    glamor: Reduce the noise from wide lines "fallback".

diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 5a7204b..acf6bf6 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -52,7 +52,10 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0) {
-	glamor_fallback("glamor_poly_lines(): wide lines\n");
+	/* This ends up in miSetSpans, which is accelerated as well as we
+	 * can hope X wide lines will be.
+	 */
+	/*glamor_fallback("glamor_poly_lines(): wide lines\n");*/
 	goto fail;
     }
     if (gc->lineStyle != LineSolid ||
commit 955ccfbc34f370c80f7189ac5b0240e859e00b5f
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Feb 19 07:52:50 2010 -0800

    glamor: Fix the segfault at screen fini.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 03db7ec..b7259af 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -260,8 +260,10 @@ glamor_fini(ScreenPtr screen)
     screen->CopyWindow = glamor_priv->saved_copy_window;
     screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
 #ifdef RENDER
-    ps->Composite = glamor_priv->saved_composite;
-    ps->Trapezoids = glamor_priv->saved_trapezoids;
-    ps->Glyphs = glamor_priv->saved_glyphs;
+    if (ps) {
+	ps->Composite = glamor_priv->saved_composite;
+	ps->Trapezoids = glamor_priv->saved_trapezoids;
+	ps->Glyphs = glamor_priv->saved_glyphs;
+    }
 #endif
 }
commit 003dee4c82f8af9e7749876c736018410f347440
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Feb 19 06:10:11 2010 -0800

    glamor: Replace the immediate mode in glamor_fill() with glDrawArrays().

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 8e269e2..c3e0528 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -92,29 +92,15 @@ glamor_init_solid_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *solid_vs_only =
 	"uniform vec4 color;\n"
-	"uniform float x_bias;\n"
-	"uniform float x_scale;\n"
-	"uniform float y_bias;\n"
-	"uniform float y_scale;\n"
 	"void main()\n"
 	"{\n"
-	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
-	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
-	"			   0,\n"
-	"			   1);\n"
+	"	gl_Position = gl_Vertex;\n"
 	"	gl_Color = color;\n"
 	"}\n";
     const char *solid_vs =
-	"uniform float x_bias;\n"
-	"uniform float x_scale;\n"
-	"uniform float y_bias;\n"
-	"uniform float y_scale;\n"
 	"void main()\n"
 	"{\n"
-	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
-	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
-	"			   0,\n"
-	"			   1);\n"
+	"	gl_Position = gl_Vertex;\n"
 	"}\n";
     const char *solid_fs =
 	"uniform vec4 color;\n"
@@ -138,8 +124,6 @@ glamor_init_solid_shader(ScreenPtr screen)
 
     glamor_priv->solid_color_uniform_location =
 	glGetUniformLocationARB(glamor_priv->solid_prog, "color");
-    glamor_get_transform_uniform_locations(glamor_priv->solid_prog,
-					   &glamor_priv->solid_transform);
 }
 
 void
@@ -153,6 +137,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     int y1 = y;
     int y2 = y + height;
     GLfloat color[4];
+    float vertices[4][2];
 
     if (!glamor_set_destination_pixmap(pixmap))
 	return;
@@ -163,15 +148,22 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
     glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
-    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
 
-    glBegin(GL_TRIANGLE_FAN);
-    glVertex2f(x1, y1);
-    glVertex2f(x1, y2);
-    glVertex2f(x2, y2);
-    glVertex2f(x2, y1);
-    glEnd();
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
 
+    vertices[0][0] = v_from_x_coord_x(pixmap, x1);
+    vertices[0][1] = v_from_x_coord_y(pixmap, y1);
+    vertices[1][0] = v_from_x_coord_x(pixmap, x2);
+    vertices[1][1] = v_from_x_coord_y(pixmap, y1);
+    vertices[2][0] = v_from_x_coord_x(pixmap, x2);
+    vertices[2][1] = v_from_x_coord_y(pixmap, y2);
+    vertices[3][0] = v_from_x_coord_x(pixmap, x1);
+    vertices[3][1] = v_from_x_coord_y(pixmap, y2);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glDisableClientState(GL_VERTEX_ARRAY);
     glUseProgramObjectARB(0);
 fail:
     glamor_set_alu(GXcopy);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0db9b28..3dc3a53 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -150,7 +150,6 @@ typedef struct glamor_screen_private {
     /* glamor_solid */
     GLint solid_prog;
     GLint solid_color_uniform_location;
-    glamor_transform_uniforms solid_transform;
 
     /* glamor_tile */
     GLint tile_prog;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 74910fa..ead5b69 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -124,12 +124,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     RegionPtr clip;
     BoxPtr box;
     int nbox;
-    float dest_coords[8] = {
-	x, y,
-	x + w, y,
-	x + w, y + h,
-	x, y + h,
-    };
+    float dest_coords[4][2];
     const float bitmap_coords[8] = {
 	0.0, 0.0,
 	1.0, 0.0,
@@ -137,7 +132,16 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	0.0, 1.0,
     };
 
-    glamor_fallback("glamor_put_image_xybitmap: disabled\n");
+    dest_coords[0][0] = v_from_x_coord_x(pixmap, x);
+    dest_coords[0][1] = v_from_x_coord_y(pixmap, y);
+    dest_coords[1][0] = v_from_x_coord_x(pixmap, x + w);
+    dest_coords[1][1] = v_from_x_coord_y(pixmap, y);
+    dest_coords[2][0] = v_from_x_coord_x(pixmap, x + w);
+    dest_coords[2][1] = v_from_x_coord_y(pixmap, y + h);
+    dest_coords[3][0] = v_from_x_coord_x(pixmap, x);
+    dest_coords[3][1] = v_from_x_coord_y(pixmap, y + h);
+
+   glamor_fallback("glamor_put_image_xybitmap: disabled\n");
     goto fail;
 
     if (glamor_priv->put_image_xybitmap_prog == 0) {
@@ -158,8 +162,6 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location,
 		    1, bg);
 
-    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
-
     glGenTextures(1, &tex);
     glActiveTexture(GL_TEXTURE0);
     glEnable(GL_TEXTURE_2D);
commit 60775e21e3532452891e1b52589f7d5d7ef04b40
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 18 18:11:54 2010 -0800

    glamor: Use a VBO to accumulate multiple glyph quads at once.
    
    This increases us from 23000 to 27000/sec on rgb24text.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9a16404..0db9b28 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -138,6 +138,12 @@ typedef struct glamor_screen_private {
 
     char *delayed_fallback_string;
 
+    GLuint vbo;
+    int vbo_offset;
+    int vbo_size;
+    char *vb;
+    int vb_stride;
+
     /* glamor_finishaccess */
     GLint finish_access_prog;
 
@@ -159,6 +165,8 @@ typedef struct glamor_screen_private {
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
 					    [SHADER_MASK_COUNT]
 					    [SHADER_IN_COUNT];
+    Bool has_source_coords, has_mask_coords;
+    int render_nr_verts;
 
     glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
 } glamor_screen_private;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e78886c..de57f52 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -573,6 +573,114 @@ glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
     texcoord[1] = t_from_x_coord_y(pixmap, ty);
 }
 
+static void
+glamor_setup_composite_vbo(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    glamor_priv->vb_stride = 2 * sizeof(float);
+    if (glamor_priv->has_source_coords)
+	glamor_priv->vb_stride += 2 * sizeof(float);
+    if (glamor_priv->has_mask_coords)
+	glamor_priv->vb_stride += 2 * sizeof(float);
+
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
+    glVertexPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+		    (void *)(glamor_priv->vbo_offset));
+    glEnableClientState(GL_VERTEX_ARRAY);
+
+    if (glamor_priv->has_source_coords) {
+	glClientActiveTexture(GL_TEXTURE0);
+	glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+			  (void *)(glamor_priv->vbo_offset + 2 * sizeof(float)));
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+
+    if (glamor_priv->has_mask_coords) {
+	glClientActiveTexture(GL_TEXTURE1);
+	glTexCoordPointer(2, GL_FLOAT, glamor_priv->vb_stride,
+			  (void *)(glamor_priv->vbo_offset +
+				   (glamor_priv->has_source_coords ? 4 : 2) *
+				   sizeof(float)));
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+}
+
+static void
+glamor_emit_composite_vert(ScreenPtr screen,
+			   const float *src_coords,
+			   const float *mask_coords,
+			   const float *dst_coords,
+			   int i)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    float *vb = (float *)(glamor_priv->vb + glamor_priv->vbo_offset);
+    int j = 0;
+
+    vb[j++] = dst_coords[i * 2 + 0];
+    vb[j++] = dst_coords[i * 2 + 1];
+    if (glamor_priv->has_source_coords) {
+	vb[j++] = src_coords[i * 2 + 0];
+	vb[j++] = src_coords[i * 2 + 1];
+    }
+    if (glamor_priv->has_mask_coords) {
+	vb[j++] = mask_coords[i * 2 + 0];
+	vb[j++] = mask_coords[i * 2 + 1];
+    }
+
+    glamor_priv->render_nr_verts++;
+    glamor_priv->vbo_offset += glamor_priv->vb_stride;
+}
+
+static void
+glamor_flush_composite_rects(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (!glamor_priv->render_nr_verts)
+	return;
+
+    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+    glamor_priv->vb = NULL;
+
+    glDrawArrays(GL_QUADS, 0, glamor_priv->render_nr_verts);
+    glamor_priv->render_nr_verts = 0;
+    glamor_priv->vbo_size = 0;
+}
+
+static void
+glamor_emit_composite_rect(ScreenPtr screen,
+			   const float *src_coords,
+			   const float *mask_coords,
+			   const float *dst_coords)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (glamor_priv->vbo_offset + 4 * glamor_priv->vb_stride >
+	glamor_priv->vbo_size)
+    {
+	glamor_flush_composite_rects(screen);
+    }
+
+    if (glamor_priv->vbo_size == 0) {
+	if (glamor_priv->vbo == 0)
+	    glGenBuffersARB(1, &glamor_priv->vbo);
+	glBindBufferARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo);
+
+	glamor_priv->vbo_size = 4096;
+	glBufferDataARB(GL_ARRAY_BUFFER_ARB, glamor_priv->vbo_size, NULL,
+			GL_STREAM_DRAW_ARB);
+	glamor_priv->vbo_offset = 0;
+	glamor_priv->vb = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+	glamor_setup_composite_vbo(screen);
+    }
+
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 0);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 1);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 2);
+    glamor_emit_composite_vert(screen, src_coords, mask_coords, dst_coords, 3);
+}
+
 static Bool
 glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
@@ -582,6 +690,7 @@ glamor_composite_with_shader(CARD8 op,
 			     glamor_composite_rect_t *rects)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
     PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
     glamor_pixmap_private *source_pixmap_priv = NULL;
@@ -589,7 +698,7 @@ glamor_composite_with_shader(CARD8 op,
     struct shader_key key;
     glamor_composite_shader *shader;
     RegionRec region;
-    float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2];
+    float vertices[8], source_texcoords[8], mask_texcoords[8];
     int i;
     BoxPtr box;
     int dest_x_off, dest_y_off;
@@ -716,20 +825,9 @@ glamor_composite_with_shader(CARD8 op,
 	}
     }
 
-    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
-    glEnableClientState(GL_VERTEX_ARRAY);
-
-    if (key.source != SHADER_SOURCE_SOLID) {
-	glClientActiveTexture(GL_TEXTURE0);
-	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
-
-    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-	glClientActiveTexture(GL_TEXTURE1);
-	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
+    glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
+    glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
+				    key.mask != SHADER_MASK_SOLID);
 
     glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
 			       &dest_x_off, &dest_y_off);
@@ -787,22 +885,22 @@ glamor_composite_with_shader(CARD8 op,
 
 	box = REGION_RECTS(&region);
 	for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-	    vertices[0][0] = v_from_x_coord_x(dest_pixmap,
-					      box[i].x1 + dest_x_off);
-	    vertices[0][1] = v_from_x_coord_y(dest_pixmap,
-					      box[i].y1 + dest_y_off);
-	    vertices[1][0] = v_from_x_coord_x(dest_pixmap,
-					      box[i].x2 + dest_x_off);
-	    vertices[1][1] = v_from_x_coord_y(dest_pixmap,
-					      box[i].y1 + dest_y_off);
-	    vertices[2][0] = v_from_x_coord_x(dest_pixmap,
-					      box[i].x2 + dest_x_off);
-	    vertices[2][1] = v_from_x_coord_y(dest_pixmap,
-					      box[i].y2 + dest_y_off);
-	    vertices[3][0] = v_from_x_coord_x(dest_pixmap,
-					      box[i].x1 + dest_x_off);
-	    vertices[3][1] = v_from_x_coord_y(dest_pixmap,
-					      box[i].y2 + dest_y_off);
+	    vertices[0] = v_from_x_coord_x(dest_pixmap,
+					   box[i].x1 + dest_x_off);
+	    vertices[1] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[2] = v_from_x_coord_x(dest_pixmap,
+					   box[i].x2 + dest_x_off);
+	    vertices[3] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y1 + dest_y_off);
+	    vertices[4] = v_from_x_coord_x(dest_pixmap,
+					   box[i].x2 + dest_x_off);
+	    vertices[5] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y2 + dest_y_off);
+	    vertices[6] = v_from_x_coord_x(dest_pixmap,
+					   box[i].x1 + dest_x_off);
+	    vertices[7] = v_from_x_coord_y(dest_pixmap,
+					   box[i].y2 + dest_y_off);
 
 	    if (key.source != SHADER_SOURCE_SOLID) {
 		int tx1 = box[i].x1 + x_source - x_dest;
@@ -811,13 +909,13 @@ glamor_composite_with_shader(CARD8 op,
 		int ty2 = box[i].y2 + y_source - y_dest;
 
 		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords[0], tx1, ty1);
+					     source_texcoords + 0, tx1, ty1);
 		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords[1], tx2, ty1);
+					     source_texcoords + 2, tx2, ty1);
 		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords[2], tx2, ty2);
+					     source_texcoords + 4, tx2, ty2);
 		glamor_set_transformed_point(source, source_pixmap,
-					     source_texcoords[3], tx1, ty2);
+					     source_texcoords + 6, tx1, ty2);
 	    }
 
 	    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
@@ -827,13 +925,13 @@ glamor_composite_with_shader(CARD8 op,
 		float ty2 = box[i].y2 + y_mask - y_dest;
 
 		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords[0], tx1, ty1);
+					     mask_texcoords + 0, tx1, ty1);
 		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords[1], tx2, ty1);
+					     mask_texcoords + 2, tx2, ty1);
 		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords[2], tx2, ty2);
+					     mask_texcoords + 4, tx2, ty2);
 		glamor_set_transformed_point(mask, mask_pixmap,
-					     mask_texcoords[3], tx1, ty2);
+					     mask_texcoords + 6, tx1, ty2);
 	    }
 #if 0
  else memset(mask_texcoords, 0, sizeof(mask_texcoords));
@@ -847,11 +945,15 @@ glamor_composite_with_shader(CARD8 op,
 	    }
 #endif
 
-	    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	    glamor_emit_composite_rect(screen, source_texcoords,
+				       mask_texcoords, vertices);
 	}
 	rects++;
     }
 
+    glamor_flush_composite_rects(screen);
+
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
     glClientActiveTexture(GL_TEXTURE0);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture(GL_TEXTURE1);
commit 8ce312e61952e9f2193c28ac6124eff30f3a122c
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 18 14:49:06 2010 -0800

    glamor: Use glamor_composite_with_shader once per group of glyphs.
    
    This shaves CPU time in GL setup.  Performance of rgb24text went from
    18400/sec to 23500/sec.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 45c7d9c..e78886c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1113,6 +1113,9 @@ glamor_composite_rects(CARD8 op,
     ValidatePicture(src);
     ValidatePicture(dst);
 
+    if (glamor_composite_with_shader(op, src, NULL, dst, nrect, rects))
+	return;
+
     n = nrect;
     r = rects;
 
commit 6ce05e0b28052e5206694228218322f0dd3a6b00
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 18 14:44:20 2010 -0800

    glamor: Convert the shaders path to handling glamor_composite_rect_t.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1b9740f..9a16404 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -59,6 +59,8 @@ typedef struct glamor_composite_shader {
 typedef struct {
     INT16 x_src;
     INT16 y_src;
+    INT16 x_mask;
+    INT16 y_mask;
     INT16 x_dst;
     INT16 y_dst;
     INT16 width;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 55d5338..45c7d9c 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -578,18 +578,12 @@ glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
 			     PicturePtr mask,
 			     PicturePtr dest,
-			     INT16 x_source,
-			     INT16 y_source,
-			     INT16 x_mask,
-			     INT16 y_mask,
-			     INT16 x_dest,
-			     INT16 y_dest,
-			     CARD16 width,
-			     CARD16 height)
+			     int nrect,
+			     glamor_composite_rect_t *rects)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
-    PixmapPtr source_pixmap, mask_pixmap = NULL;
+    PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
     glamor_pixmap_private *source_pixmap_priv = NULL;
     glamor_pixmap_private *mask_pixmap_priv = NULL;
     struct shader_key key;
@@ -598,7 +592,9 @@ glamor_composite_with_shader(CARD8 op,
     float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2];
     int i;
     BoxPtr box;
-    int dst_x_off, dst_y_off;
+    int dest_x_off, dest_y_off;
+    int source_x_off, source_y_off;
+    int mask_x_off, mask_y_off;
 
     memset(&key, 0, sizeof(key));
     if (!source->pDrawable) {
@@ -637,9 +633,11 @@ glamor_composite_with_shader(CARD8 op,
 	    /* We only handle two CA modes. */
 	    if (op == PictOpAdd)
 		key.in = SHADER_IN_CA_SOURCE;
-	    else {
-		assert(op == PictOpOutReverse);
+	    else if (op == PictOpOutReverse) {
 		key.in = SHADER_IN_CA_ALPHA;
+	    } else {
+		glamor_fallback("Unsupported component alpha op: %d\n", op);
+		goto fail;
 	    }
 	}
     } else {
@@ -705,17 +703,6 @@ glamor_composite_with_shader(CARD8 op,
 	goto fail;
     }
 
-    x_dest += dest->pDrawable->x;
-    y_dest += dest->pDrawable->y;
-    if (source->pDrawable) {
-	x_source += source->pDrawable->x;
-	y_source += source->pDrawable->y;
-    }
-    if (mask && mask->pDrawable) {
-	x_mask += mask->pDrawable->x;
-	y_mask += mask->pDrawable->y;
-    }
-
     if (key.source == SHADER_SOURCE_SOLID) {
 	glamor_set_composite_solid(source, shader->source_uniform_location);
     } else {
@@ -729,15 +716,6 @@ glamor_composite_with_shader(CARD8 op,
 	}
     }
 
-    if (!miComputeCompositeRegion(&region,
-				  source, mask, dest,
-				  x_source, y_source,
-				  x_mask, y_mask,
-				  x_dest, y_dest,
-				  width, height))
-	goto done;
-
-
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
@@ -754,76 +732,124 @@ glamor_composite_with_shader(CARD8 op,
     }
 
     glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
-			       &dst_x_off, &dst_y_off);
+			       &dest_x_off, &dest_y_off);
     if (source_pixmap) {
-	int dx, dy;
-
-	glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &dx, &dy);
-	x_source += dx;
-	y_source += dy;
+	glamor_get_drawable_deltas(source->pDrawable, source_pixmap,
+				   &source_x_off, &source_y_off);
     }
     if (mask_pixmap) {
-	int dx, dy;
-
-	glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &dx, &dy);
-	x_mask += dx;
-	y_mask += dy;
+	glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
+				   &mask_x_off, &mask_y_off);
     }
 
-    box = REGION_RECTS(&region);
-    for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-	vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off);
-	vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off);
-	vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off);
-	vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off);
-	vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off);
-	vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off);
-	vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off);
-	vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off);
-
-	if (key.source != SHADER_SOURCE_SOLID) {
-	    int tx1 = box[i].x1 + x_source - x_dest;
-	    int ty1 = box[i].y1 + y_source - y_dest;
-	    int tx2 = box[i].x2 + x_source - x_dest;
-	    int ty2 = box[i].y2 + y_source - y_dest;
-
-	    glamor_set_transformed_point(source, source_pixmap,
-					 source_texcoords[0], tx1, ty1);
-	    glamor_set_transformed_point(source, source_pixmap,
-					 source_texcoords[1], tx2, ty1);
-	    glamor_set_transformed_point(source, source_pixmap,
-					 source_texcoords[2], tx2, ty2);
-	    glamor_set_transformed_point(source, source_pixmap,
-					 source_texcoords[3], tx1, ty2);
+    while (nrect--) {
+	INT16 x_source;
+	INT16 y_source;
+	INT16 x_mask;
+	INT16 y_mask;
+	INT16 x_dest;
+	INT16 y_dest;
+	CARD16 width;
+	CARD16 height;
+
+	x_dest = rects->x_dst;
+	y_dest = rects->y_dst;
+	x_source = rects->x_src;
+	y_source = rects->y_src;
+	x_mask = rects->x_mask;
+	y_mask = rects->y_mask;
+	width = rects->width;
+	height = rects->height;
+
+	x_dest += dest->pDrawable->x;
+	y_dest += dest->pDrawable->y;
+	if (source->pDrawable) {
+	    x_source += source->pDrawable->x;
+	    y_source += source->pDrawable->y;
 	}
-
-	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-	    float tx1 = box[i].x1 + x_mask - x_dest;
-	    float ty1 = box[i].y1 + y_mask - y_dest;
-	    float tx2 = box[i].x2 + x_mask - x_dest;
-	    float ty2 = box[i].y2 + y_mask - y_dest;
-
-	    glamor_set_transformed_point(mask, mask_pixmap,
-					 mask_texcoords[0], tx1, ty1);
-	    glamor_set_transformed_point(mask, mask_pixmap,
-					 mask_texcoords[1], tx2, ty1);
-	    glamor_set_transformed_point(mask, mask_pixmap,
-					 mask_texcoords[2], tx2, ty2);
-	    glamor_set_transformed_point(mask, mask_pixmap,
-					 mask_texcoords[3], tx1, ty2);
+	if (mask && mask->pDrawable) {
+	    x_mask += mask->pDrawable->x;
+	    y_mask += mask->pDrawable->y;
 	}
+
+	if (!miComputeCompositeRegion(&region,
+				      source, mask, dest,
+				      x_source, y_source,
+				      x_mask, y_mask,
+				      x_dest, y_dest,
+				      width, height))
+	    continue;
+
+	x_source += source_x_off;
+	y_source += source_y_off;
+	x_mask += mask_x_off;
+	y_mask += mask_y_off;
+
+	box = REGION_RECTS(&region);
+	for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
+	    vertices[0][0] = v_from_x_coord_x(dest_pixmap,
+					      box[i].x1 + dest_x_off);
+	    vertices[0][1] = v_from_x_coord_y(dest_pixmap,
+					      box[i].y1 + dest_y_off);
+	    vertices[1][0] = v_from_x_coord_x(dest_pixmap,
+					      box[i].x2 + dest_x_off);
+	    vertices[1][1] = v_from_x_coord_y(dest_pixmap,
+					      box[i].y1 + dest_y_off);
+	    vertices[2][0] = v_from_x_coord_x(dest_pixmap,
+					      box[i].x2 + dest_x_off);
+	    vertices[2][1] = v_from_x_coord_y(dest_pixmap,
+					      box[i].y2 + dest_y_off);
+	    vertices[3][0] = v_from_x_coord_x(dest_pixmap,
+					      box[i].x1 + dest_x_off);
+	    vertices[3][1] = v_from_x_coord_y(dest_pixmap,
+					      box[i].y2 + dest_y_off);
+
+	    if (key.source != SHADER_SOURCE_SOLID) {
+		int tx1 = box[i].x1 + x_source - x_dest;
+		int ty1 = box[i].y1 + y_source - y_dest;
+		int tx2 = box[i].x2 + x_source - x_dest;
+		int ty2 = box[i].y2 + y_source - y_dest;
+
+		glamor_set_transformed_point(source, source_pixmap,
+					     source_texcoords[0], tx1, ty1);
+		glamor_set_transformed_point(source, source_pixmap,
+					     source_texcoords[1], tx2, ty1);
+		glamor_set_transformed_point(source, source_pixmap,
+					     source_texcoords[2], tx2, ty2);
+		glamor_set_transformed_point(source, source_pixmap,
+					     source_texcoords[3], tx1, ty2);
+	    }
+
+	    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
+		float tx1 = box[i].x1 + x_mask - x_dest;
+		float ty1 = box[i].y1 + y_mask - y_dest;
+		float tx2 = box[i].x2 + x_mask - x_dest;
+		float ty2 = box[i].y2 + y_mask - y_dest;
+
+		glamor_set_transformed_point(mask, mask_pixmap,
+					     mask_texcoords[0], tx1, ty1);
+		glamor_set_transformed_point(mask, mask_pixmap,
+					     mask_texcoords[1], tx2, ty1);
+		glamor_set_transformed_point(mask, mask_pixmap,
+					     mask_texcoords[2], tx2, ty2);
+		glamor_set_transformed_point(mask, mask_pixmap,
+					     mask_texcoords[3], tx1, ty2);
+	    }
 #if 0
  else memset(mask_texcoords, 0, sizeof(mask_texcoords));
-	for (i = 0; i < 4; i++) {
-	    ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) (%04.4f, %04.4f)\n",
-		   i,
-		   source_texcoords[i][0], source_texcoords[i][1],
-		   mask_texcoords[i][0], mask_texcoords[i][1],
-		   vertices[i][0], vertices[i][1]);
-	}
+	    for (i = 0; i < 4; i++) {
+		ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) "
+		       "(%04.4f, %04.4f)\n",
+		       i,
+		       source_texcoords[i][0], source_texcoords[i][1],
+		       mask_texcoords[i][0], mask_texcoords[i][1],
+		       vertices[i][0], vertices[i][1]);
+	    }
 #endif
 
-	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+	}
+	rects++;
     }
 
     glClientActiveTexture(GL_TEXTURE0);
@@ -832,7 +858,6 @@ glamor_composite_with_shader(CARD8 op,
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDisableClientState(GL_VERTEX_ARRAY);
 
-done:
     REGION_UNINIT(dst->pDrawable->pScreen, &region);
     glDisable(GL_BLEND);
     glActiveTexture(GL_TEXTURE0);
@@ -862,6 +887,8 @@ glamor_composite(CARD8 op,
 		 CARD16 width,
 		 CARD16 height)
 {
+    glamor_composite_rect_t rect;
+
     /* Do two-pass PictOpOver componentAlpha, until we enable
      * dual source color blending.
      */
@@ -894,11 +921,15 @@ glamor_composite(CARD8 op,
 	    return;
     }
 
-    if (glamor_composite_with_shader(op, source, mask, dest,
-				     x_source, y_source,
-				     x_mask, y_mask,
-				     x_dest, y_dest,
-				     width, height))
+    rect.x_src = x_source;
+    rect.y_src = y_source;
+    rect.x_mask = x_mask;
+    rect.y_mask = y_mask;
+    rect.x_dst = x_dest;
+    rect.y_dst = y_dest;
+    rect.width = width;
+    rect.height = height;
+    if (glamor_composite_with_shader(op, source, mask, dest, 1, &rect))
 	return;
 
 fail:
commit 858ce0c1928c199435c9c2627f84c37c7ca7a38a
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 18 14:02:48 2010 -0800

    glamor: Add support for component alpha rendering.
    
    Brings x11perf -rgb24text from 230/sec to 18400/sec

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 5ce7489..1b9740f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -116,6 +116,8 @@ enum shader_mask {
 enum shader_in {
     SHADER_IN_SOURCE_ONLY,
     SHADER_IN_NORMAL,
+    SHADER_IN_CA_SOURCE,
+    SHADER_IN_CA_ALPHA,
     SHADER_IN_COUNT,
 };
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f4840dc..55d5338 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -118,6 +118,16 @@ glamor_create_composite_fs(struct shader_key *key)
 	"{\n"
 	"	gl_FragColor = get_source() * get_mask().a;\n"
 	"}\n";
+    const char *in_ca_source =
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = get_source() * get_mask();\n"
+	"}\n";
+    const char *in_ca_alpha =
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = get_source().a * get_mask();\n"
+	"}\n";
     char *source;
     const char *source_fetch;
     const char *mask_fetch = "";
@@ -161,6 +171,12 @@ glamor_create_composite_fs(struct shader_key *key)
     case SHADER_IN_NORMAL:
 	in = in_normal;
 	break;
+    case SHADER_IN_CA_SOURCE:
+	in = in_ca_source;
+	break;
+    case SHADER_IN_CA_ALPHA:
+	in = in_ca_alpha;
+	break;
     default:
 	FatalError("Bad composite IN type");
     }
@@ -615,11 +631,22 @@ glamor_composite_with_shader(CARD8 op,
 	    }
 	}
 
-	key.in = SHADER_IN_NORMAL;
+	if (!mask->componentAlpha) {
+	    key.in = SHADER_IN_NORMAL;
+	} else {
+	    /* We only handle two CA modes. */
+	    if (op == PictOpAdd)
+		key.in = SHADER_IN_CA_SOURCE;
+	    else {
+		assert(op == PictOpOutReverse);
+		key.in = SHADER_IN_CA_ALPHA;
+	    }
+	}
     } else {
 	key.mask = SHADER_MASK_NONE;
 	key.in = SHADER_IN_SOURCE_ONLY;
     }
+
     if (source->alphaMap) {
 	glamor_fallback("source alphaMap\n");
 	goto fail;
@@ -838,22 +865,25 @@ glamor_composite(CARD8 op,
     /* Do two-pass PictOpOver componentAlpha, until we enable
      * dual source color blending.
      */
-    if (mask && mask->componentAlpha)
-	goto fail;
-    if (mask && mask->componentAlpha && op == PictOpOver) {
-	glamor_composite(PictOpOutReverse,
-			 source, mask, dest,
-			 x_source, y_source,
-			 x_mask, y_mask,
-			 x_dest, y_dest,
-			 width, height);
-	glamor_composite(PictOpAdd,
-			 source, mask, dest,
-			 x_source, y_source,
-			 x_mask, y_mask,
-			 x_dest, y_dest,
-			 width, height);
-	return;
+    if (mask && mask->componentAlpha) {
+	if (op == PictOpOver) {
+	    glamor_composite(PictOpOutReverse,
+			     source, mask, dest,
+			     x_source, y_source,
+			     x_mask, y_mask,
+			     x_dest, y_dest,
+			     width, height);
+	    glamor_composite(PictOpAdd,
+			     source, mask, dest,
+			     x_source, y_source,
+			     x_mask, y_mask,
+			     x_dest, y_dest,
+			     width, height);
+	    return;
+	} else if (op != PictOpAdd && op != PictOpOutReverse) {
+	    glamor_fallback("glamor_composite(): component alpha\n");
+	    goto fail;
+	}
     }
 
     if (!mask) {
commit d07fc66a056dd4eab2dac82b3784c482071d1915
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 18 09:23:22 2010 -0800

    glamor: Rework shader setup to make extending the IN types easier.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index cd7ca15..5ce7489 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -113,6 +113,12 @@ enum shader_mask {
     SHADER_MASK_COUNT,
 };
 
+enum shader_in {
+    SHADER_IN_SOURCE_ONLY,
+    SHADER_IN_NORMAL,
+    SHADER_IN_COUNT,
+};
+
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
@@ -147,7 +153,8 @@ typedef struct glamor_screen_private {
 
     /* glamor_composite */
     glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
-					    [SHADER_MASK_COUNT];
+					    [SHADER_MASK_COUNT]
+					    [SHADER_IN_COUNT];
 
     glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
 } glamor_screen_private;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 421aa35..f4840dc 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -41,6 +41,7 @@
 struct shader_key {
     enum shader_source source;
     enum shader_mask mask;
+    enum shader_in in;
 };
 
 struct blendinfo {
@@ -69,51 +70,68 @@ static struct blendinfo composite_op_info[] = {
 static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
-    const char *source_pixmap_header =
-	"uniform sampler2D source_sampler;\n";
-    const char *source_solid_header =
-	"uniform vec4 source;\n";
-    const char *mask_pixmap_header =
-	"uniform sampler2D mask_sampler;\n";
-    const char *mask_solid_header =
-	"uniform vec4 mask;\n";
-    const char *main_opening =
-	"void main()\n"
-	"{\n";
+    const char *source_solid_fetch =
+	"uniform vec4 source;\n"
+	"vec4 get_source()\n"
+	"{\n"
+	"	return source;\n"
+	"}\n";
     const char *source_alpha_pixmap_fetch =
-	"	vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
+	"uniform sampler2D source_sampler;\n"
+	"vec4 get_source()\n"
+	"{\n"
+	"	return texture2D(source_sampler, gl_TexCoord[0].xy);\n"
+	"}\n";
     const char *source_pixmap_fetch =
-	"	vec4 source = vec4(texture2D(source_sampler, "
-	"				     gl_TexCoord[0].xy).rgb, 1.0);\n";
+	"uniform sampler2D source_sampler;\n"
+	"vec4 get_source()\n"
+	"{\n"
+	"	return vec4(texture2D(source_sampler, gl_TexCoord[0].xy).rgb,\n"
+	"		    1.0);\n"
+	"}\n";
+    const char *mask_solid_fetch =
+	"uniform vec4 mask;\n"
+	"vec4 get_mask()\n"
+	"{\n"
+	"	return mask;\n"
+	"}\n";
     const char *mask_alpha_pixmap_fetch =
-	"	vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
+	"uniform sampler2D mask_sampler;\n"
+	"vec4 get_mask()\n"
+	"{\n"
+	"	return texture2D(mask_sampler, gl_TexCoord[1].xy);\n"
+	"}\n";
     const char *mask_pixmap_fetch =
-	"	vec4 mask = vec4(texture2D(mask_sampler, "
-	"				   gl_TexCoord[1].xy).rgb, 1.0);\n";
-    const char *source_in_mask =
-	"	gl_FragColor = source * mask.a;\n";
-    const char *source_only =
-	"	gl_FragColor = source;\n";
-    const char *main_closing =
+	"uniform sampler2D mask_sampler;\n"
+	"vec4 get_mask()\n"
+	"{\n"
+	"	return vec4(texture2D(mask_sampler, gl_TexCoord[1].xy).rgb, \n"
+	"		    1.0);\n"
+	"}\n";
+    const char *in_source_only =
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = get_source();\n"
+	"}\n";
+    const char *in_normal =
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = get_source() * get_mask().a;\n"
 	"}\n";
     char *source;
-    const char *source_setup = "";
-    const char *source_fetch = "";
-    const char *mask_setup = "";
+    const char *source_fetch;
     const char *mask_fetch = "";
     const char *in;
     GLuint prog;
 
     switch (key->source) {
     case SHADER_SOURCE_SOLID:
-	source_setup = source_solid_header;
+	source_fetch = source_solid_fetch;
 	break;
     case SHADER_SOURCE_TEXTURE_ALPHA:
-	source_setup = source_pixmap_header;
 	source_fetch = source_alpha_pixmap_fetch;
 	break;
     case SHADER_SOURCE_TEXTURE:
-	source_setup = source_pixmap_header;
 	source_fetch = source_pixmap_fetch;
 	break;
     default:
@@ -124,34 +142,33 @@ glamor_create_composite_fs(struct shader_key *key)
     case SHADER_MASK_NONE:
 	break;
     case SHADER_MASK_SOLID:
-	mask_setup = mask_solid_header;
+	mask_fetch = mask_solid_fetch;
 	break;
     case SHADER_MASK_TEXTURE_ALPHA:
-	mask_setup = mask_pixmap_header;
 	mask_fetch = mask_alpha_pixmap_fetch;
 	break;
     case SHADER_MASK_TEXTURE:
-	mask_setup = mask_pixmap_header;
 	mask_fetch = mask_pixmap_fetch;
 	break;
     default:
 	FatalError("Bad composite shader mask");
     }
 
-    if (key->mask == SHADER_MASK_NONE) {
-	in = source_only;
-    } else {
-	in = source_in_mask;
+    switch (key->in) {
+    case SHADER_IN_SOURCE_ONLY:
+	in = in_source_only;
+	break;
+    case SHADER_IN_NORMAL:
+	in = in_normal;
+	break;
+    default:
+	FatalError("Bad composite IN type");
     }
 
-    source = XNFprintf("%s%s%s%s%s%s%s",
-		       source_setup,
-		       mask_setup,
-		       main_opening,
+    source = XNFprintf("%s%s%s",
 		       source_fetch,
 		       mask_fetch,
-		       in,
-		       main_closing);
+		       in);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
     xfree(source);
@@ -245,7 +262,7 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     glamor_composite_shader *shader;
 
-    shader = &glamor_priv->composite_shader[key->source][key->mask];
+    shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
     if (shader->prog == 0)
 	glamor_create_composite_shader(screen, key, shader);
 
@@ -597,8 +614,11 @@ glamor_composite_with_shader(CARD8 op,
 		key.mask = SHADER_MASK_TEXTURE;
 	    }
 	}
+
+	key.in = SHADER_IN_NORMAL;
     } else {
 	key.mask = SHADER_MASK_NONE;
+	key.in = SHADER_IN_SOURCE_ONLY;
     }
     if (source->alphaMap) {
 	glamor_fallback("source alphaMap\n");
@@ -851,6 +871,7 @@ glamor_composite(CARD8 op,
 				     width, height))
 	return;
 
+fail:
     glamor_fallback("glamor_composite(): "
 		    "from picts %p/%p(%c,%c) to pict %p (%c)\n",
 		    source, mask,
@@ -858,7 +879,7 @@ glamor_composite(CARD8 op,
 		    glamor_get_picture_location(mask),
 		    dest,
 		    glamor_get_picture_location(dest));
-fail:
+
     glUseProgramObjectARB(0);
     glDisable(GL_BLEND);
     if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
commit 8cefa287ddb4ed4ad178e751b35bb93b4a44e0ab
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 17 16:00:22 2010 -0800

    glamor: Add a little mechanism for only printing fallbacks when they happen.
    
    Sometimes we want to try a couple of different methods for
    accelerating.  If one of them says "no" and the other says "yes",
    don't spam the log about the "no."

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index b7762cc..172b959 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -41,22 +41,25 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 			      int dx,
 			      int dy)
 {
+    ScreenPtr screen = dst->pScreen;
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int x_off, y_off, i;
 
     if (src != dst) {
-	glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n");
+	glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
+				"src != dest\n");
 	return FALSE;
     }
 
     if (gc) {
 	if (gc->alu != GXcopy) {
-	    glamor_fallback("glamor_copy_n_to_n_copypixels(): non-copy ALU\n");
+	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
+				    "non-copy ALU\n");
 	    return FALSE;
 	}
 	if (!glamor_pm_is_solid(dst, gc->planemask)) {
-	    glamor_fallback("glamor_copy_n_to_n_copypixels(): "
-			    "non-solid planemask\n");
+	    glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): "
+				    "non-solid planemask\n");
 	    return FALSE;
 	}
     }
@@ -196,11 +199,17 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 Pixel		bitplane,
 		 void		*closure)
 {
-    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy))
+    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) {
+	glamor_clear_delayed_fallbacks(dst->pScreen);
 	return;
+    }
 
-    if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy))
+    if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) {
+	glamor_clear_delayed_fallbacks(dst->pScreen);
 	return;
+    }
+
+    glamor_report_delayed_fallbacks(dst->pScreen);
 
     glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 91fa6e1..cd7ca15 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -126,6 +126,8 @@ typedef struct glamor_screen_private {
     CopyWindowProcPtr saved_copy_window;
     BitmapToRegionProcPtr saved_bitmap_to_region;
 
+    char *delayed_fallback_string;
+
     /* glamor_finishaccess */
     GLint finish_access_prog;
 
@@ -196,6 +198,41 @@ glamor_fallback(char *format, ...)
     va_end(ap);
 }
 
+static inline void
+glamor_delayed_fallback(ScreenPtr screen, char *format, ...)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    va_list ap;
+
+    if (glamor_priv->delayed_fallback_string != NULL)
+	return;
+
+    va_start(ap, format);
+    glamor_priv->delayed_fallback_string = XNFvprintf(format, ap);
+    va_end(ap);
+}
+
+static inline void
+glamor_clear_delayed_fallbacks(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    xfree(glamor_priv->delayed_fallback_string);
+    glamor_priv->delayed_fallback_string = NULL;
+}
+
+static inline void
+glamor_report_delayed_fallbacks(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    if (glamor_priv->delayed_fallback_string) {
+	LogMessageVerb(X_INFO, 0, "fallback: %s",
+		       glamor_priv->delayed_fallback_string);
+	glamor_clear_delayed_fallbacks(screen);
+    }
+}
+
 static inline float
 v_from_x_coord_x(PixmapPtr pixmap, int x)
 {
commit 5f5c35b56d3568f72e2305e74ed8457e0a787a3b
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 17 15:02:17 2010 -0800

    glamor: Fix up the fallback message for no texture present on compositing.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6d8dd97..421aa35 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -618,7 +618,7 @@ glamor_composite_with_shader(CARD8 op,
 	    goto fail;
 	}
 	if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
-	    glamor_fallback("glamor_composite(): no FBO in source\n");
+	    glamor_fallback("glamor_composite(): no texture in source\n");
 	    goto fail;
 	}
 	if (!good_source_format(source))
@@ -633,7 +633,7 @@ glamor_composite_with_shader(CARD8 op,
 	    goto fail;
 	}
 	if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) {
-	    glamor_fallback("glamor_composite(): no FBO in mask\n");
+	    glamor_fallback("glamor_composite(): no texture in mask\n");
 	    goto fail;
 	}
 	if (!good_mask_format(mask))
commit 2fa95725d845e5bf8a41ac776267be0d55d58004
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 17 13:33:48 2010 -0800

    glamor: Add support for a1 composite sources.
    
    They're stored just like a8, but the values are set to either 0.0 or
    1.0.  Because they're a8 with only two legal values, we can't use them
    as destinations, but nobody's rendering to a1 dests anyway (we hope).

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 6e281c9..6d8dd97 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -456,6 +456,7 @@ static Bool
 good_source_format(PicturePtr picture)
 {
     switch (picture->format) {
+    case PICT_a1:
     case PICT_a8:
     case PICT_a8r8g8b8:
 	return TRUE;
@@ -477,6 +478,7 @@ static Bool
 good_mask_format(PicturePtr picture)
 {
     switch (picture->format) {
+    case PICT_a1:
     case PICT_a8:
     case PICT_a8r8g8b8:
 	return TRUE;
commit 9bcbcbf8c28e945fa5c4f4ad1a772b787618455f
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 17 13:30:20 2010 -0800

    glamor: Fix and enable ZPixmap PutImage acceleration.

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index b71644f..74910fa 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -137,6 +137,9 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 	0.0, 1.0,
     };
 
+    glamor_fallback("glamor_put_image_xybitmap: disabled\n");
+    goto fail;
+
     if (glamor_priv->put_image_xybitmap_prog == 0) {
 	ErrorF("no program for xybitmap putimage\n");
 	goto fail;
@@ -158,6 +161,7 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
     glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
 
     glGenTextures(1, &tex);
+    glActiveTexture(GL_TEXTURE0);
     glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -237,7 +241,10 @@ void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int left_pad, int image_format, char *bits)
 {
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(drawable->pScreen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     GLenum type, format;
     RegionPtr clip;
     BoxPtr pbox;
@@ -245,14 +252,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int bpp = drawable->bitsPerPixel;
     int src_stride = PixmapBytePad(w, drawable->depth);
     int x_off, y_off;
-
-    goto fail;
-
-    if (!glamor_set_destination_pixmap(pixmap)) {
-	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
-		   image_format, bits);
-	return;
-    }
+    float vertices[4][2], texcoords[4][2];
+    GLuint tex;
 
     if (image_format == XYBitmap) {
 	assert(depth == 1);
@@ -261,13 +262,26 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	return;
     }
 
+    if (pixmap_priv == NULL) {
+	glamor_fallback("glamor_put_image: system memory pixmap\n");
+	goto fail;
+    }
+
+    if (pixmap_priv->fb == 0) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (pixmap != screen_pixmap) {
+	    glamor_fallback("glamor_put_image: no fbo\n");
+	    goto fail;
+	}
+    }
+
     if (bpp == 1 && image_format == XYPixmap)
 	image_format = ZPixmap;
 
-    if (!glamor_set_planemask(pixmap, gc->planemask))
-	goto fail;
     if (image_format != ZPixmap) {
-	ErrorF("putimage: non-ZPixmap\n");
+	glamor_fallback("glamor_put_image: non-ZPixmap\n");
 	goto fail;
     }
 
@@ -281,29 +295,57 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	type = GL_UNSIGNED_BYTE;
 	break;
     case 24:
-	format = GL_RGB;
-	type = GL_UNSIGNED_BYTE;
-	break;
+	assert(drawable->bitsPerPixel == 32);
+	/* FALLTHROUGH */
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 	break;
     default:
-	ErrorF("stub put_image depth %d\n", drawable->depth);
+	glamor_fallback("glamor_putimage: bad depth %d\n", drawable->depth);
 	goto fail;
     }
 
+    if (!glamor_set_planemask(pixmap, gc->planemask))
+	goto fail;
+
     glamor_set_alu(gc->alu);
 
-    x += drawable->x;
-    y += drawable->y;
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
 
-    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
+		  pixmap->drawable.bitsPerPixel);
     if (bpp == 1)
 	glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+
+    glGenTextures(1, &tex);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+		 w, h, 0,
+		 format, type, bits);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glEnable(GL_TEXTURE_2D);
+
+    assert(GLEW_ARB_fragment_shader);
+    glUseProgramObjectARB(glamor_priv->finish_access_prog);
+
+
+    x += drawable->x;
+    y += drawable->y;
+
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
     clip = fbGetCompositeClip(gc);
     for (nbox = REGION_NUM_RECTS(clip),
 	 pbox = REGION_RECTS(clip);
@@ -314,7 +356,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	int y1 = y;
 	int x2 = x + w;
 	int y2 = y + h;
-	char *src;
+	float src_x1, src_x2, src_y1, src_y2;
 
 	if (x1 < pbox->x1)
 	    x1 = pbox->x1;
@@ -327,13 +369,37 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	if (x1 >= x2 || y1 >= y2)
 	    continue;
 
-	src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
-	glRasterPos2i(x1 + x_off, y1 + y_off);
-	glDrawPixels(x2 - x1,
-		     y2 - y1,
-		     format, type,
-		     src);
+	src_x1 = (float)(x1 - x) / w;
+	src_y1 = (float)(y1 - y) / h;
+	src_x2 = (float)(x2 - x) / w;
+	src_y2 = (float)(y2 - y) / h;
+
+	vertices[0][0] = v_from_x_coord_x(pixmap, x1 + x_off);
+	vertices[0][1] = v_from_x_coord_y(pixmap, y1 + y_off);
+	vertices[1][0] = v_from_x_coord_x(pixmap, x2 + x_off);
+	vertices[1][1] = v_from_x_coord_y(pixmap, y1 + y_off);
+	vertices[2][0] = v_from_x_coord_x(pixmap, x2 + x_off);
+	vertices[2][1] = v_from_x_coord_y(pixmap, y2 + y_off);
+	vertices[3][0] = v_from_x_coord_x(pixmap, x1 + x_off);
+	vertices[3][1] = v_from_x_coord_y(pixmap, y2 + y_off);
+
+	texcoords[0][0] = src_x1;
+	texcoords[0][1] = src_y1;
+	texcoords[1][0] = src_x2;
+	texcoords[1][1] = src_y1;
+	texcoords[2][0] = src_x2;
+	texcoords[2][1] = src_y2;
+	texcoords[3][0] = src_x1;
+	texcoords[3][1] = src_y2;
+
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
+
+    glDisable(GL_TEXTURE_2D);
+    glUseProgramObjectARB(0);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDeleteTextures(1, &tex);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
     glamor_set_alu(GXcopy);
commit 2ba634fab9b03995629497efdbf5305394011e4a
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 17:32:27 2010 -0800

    glamor: Fix render source transforms.
    
    Fixes (except for small bit differences) cairo source-pattern.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 35e3e0a..6e281c9 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -508,6 +508,36 @@ good_dest_format(PicturePtr picture)
     }
 }
 
+static inline float
+xFixedToFloat(pixman_fixed_t val)
+{
+    return ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0));
+}
+
+static void
+glamor_set_transformed_point(PicturePtr picture, PixmapPtr pixmap,
+			     float *texcoord, int x, int y)
+{
+    float result[3];
+    int i;
+    float tx, ty;
+
+    if (picture->transform) {
+	for (i = 0; i < 3; i++) {
+	    result[i] = (xFixedToFloat(picture->transform->matrix[i][0]) * x +
+			 xFixedToFloat(picture->transform->matrix[i][1]) * y +
+			 xFixedToFloat(picture->transform->matrix[i][2]));
+	}
+	tx = result[0] / result[2];
+	ty = result[1] / result[2];
+    } else {
+	tx = x;
+	ty = y;
+    }
+    texcoord[0] = t_from_x_coord_x(pixmap, tx);
+    texcoord[1] = t_from_x_coord_y(pixmap, ty);
+}
+
 static Bool
 glamor_composite_with_shader(CARD8 op,
 			     PicturePtr source,
@@ -707,29 +737,31 @@ glamor_composite_with_shader(CARD8 op,
 	    int ty1 = box[i].y1 + y_source - y_dest;
 	    int tx2 = box[i].x2 + x_source - x_dest;
 	    int ty2 = box[i].y2 + y_source - y_dest;
-	    source_texcoords[0][0] = t_from_x_coord_x(source_pixmap, tx1);
-	    source_texcoords[0][1] = t_from_x_coord_y(source_pixmap, ty1);
-	    source_texcoords[1][0] = t_from_x_coord_x(source_pixmap, tx2);
-	    source_texcoords[1][1] = t_from_x_coord_y(source_pixmap, ty1);
-	    source_texcoords[2][0] = t_from_x_coord_x(source_pixmap, tx2);
-	    source_texcoords[2][1] = t_from_x_coord_y(source_pixmap, ty2);
-	    source_texcoords[3][0] = t_from_x_coord_x(source_pixmap, tx1);
-	    source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2);
+
+	    glamor_set_transformed_point(source, source_pixmap,
+					 source_texcoords[0], tx1, ty1);
+	    glamor_set_transformed_point(source, source_pixmap,
+					 source_texcoords[1], tx2, ty1);
+	    glamor_set_transformed_point(source, source_pixmap,
+					 source_texcoords[2], tx2, ty2);
+	    glamor_set_transformed_point(source, source_pixmap,
+					 source_texcoords[3], tx1, ty2);
 	}
 
 	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
-	    int tx1 = box[i].x1 + x_mask - x_dest;
-	    int ty1 = box[i].y1 + y_mask - y_dest;
-	    int tx2 = box[i].x2 + x_mask - x_dest;
-	    int ty2 = box[i].y2 + y_mask - y_dest;
-	    mask_texcoords[0][0] = t_from_x_coord_x(mask_pixmap, tx1);
-	    mask_texcoords[0][1] = t_from_x_coord_y(mask_pixmap, ty1);
-	    mask_texcoords[1][0] = t_from_x_coord_x(mask_pixmap, tx2);
-	    mask_texcoords[1][1] = t_from_x_coord_y(mask_pixmap, ty1);
-	    mask_texcoords[2][0] = t_from_x_coord_x(mask_pixmap, tx2);
-	    mask_texcoords[2][1] = t_from_x_coord_y(mask_pixmap, ty2);
-	    mask_texcoords[3][0] = t_from_x_coord_x(mask_pixmap, tx1);
-	    mask_texcoords[3][1] = t_from_x_coord_y(mask_pixmap, ty2);
+	    float tx1 = box[i].x1 + x_mask - x_dest;
+	    float ty1 = box[i].y1 + y_mask - y_dest;
+	    float tx2 = box[i].x2 + x_mask - x_dest;
+	    float ty2 = box[i].y2 + y_mask - y_dest;
+
+	    glamor_set_transformed_point(mask, mask_pixmap,
+					 mask_texcoords[0], tx1, ty1);
+	    glamor_set_transformed_point(mask, mask_pixmap,
+					 mask_texcoords[1], tx2, ty1);
+	    glamor_set_transformed_point(mask, mask_pixmap,
+					 mask_texcoords[2], tx2, ty2);
+	    glamor_set_transformed_point(mask, mask_pixmap,
+					 mask_texcoords[3], tx1, ty2);
 	}
 #if 0
  else memset(mask_texcoords, 0, sizeof(mask_texcoords));
commit b1f67a5082420bbff141733833905f8ac95fe983
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 17:15:05 2010 -0800

    glamor: Fix and enable glamor_get_spans().
    
    This makes running the cairo test suite almost tolerable.

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 92ffba5..9b77f28 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -57,8 +57,6 @@ glamor_get_spans(DrawablePtr drawable,
     uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
     int x_off, y_off;
 
-    goto fail;
-
     switch (drawable->depth) {
     case 1:
 	temp_dst = xalloc(wmax);
@@ -71,9 +69,6 @@ glamor_get_spans(DrawablePtr drawable,
 	type = GL_UNSIGNED_BYTE;
 	break;
     case 24:
-	format = GL_RGB;
-	type = GL_UNSIGNED_BYTE;
-	break;
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -91,7 +86,7 @@ glamor_get_spans(DrawablePtr drawable,
 
     for (i = 0; i < count; i++) {
 	glReadPixels(points[i].x + x_off,
-		     points[i].y + y_off,
+		     pixmap->drawable.height - 1 - (points[i].y + y_off),
 		     widths[i],
 		     1,
 		     format, type,
commit f88d76cf7e05cf885d80c0b91f37f1b30675e928
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 16:51:13 2010 -0800

    glamor: Enable glamor_fill_spans().
    
    x11perf -wline100 performance goes from 8.8/sec to 111/sec.

diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 9b070ec..a633b30 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -45,7 +45,8 @@ glamor_fill_spans(DrawablePtr drawable,
     int fullX1, fullX2, fullY1;
     int partX1, partX2;
 
-    goto fail;
+    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
+	goto fail;
 
     extents = REGION_EXTENTS(gc->pScreen, clip);
     extentX1 = extents->x1;
@@ -101,7 +102,7 @@ glamor_fill_spans(DrawablePtr drawable,
     }
     return;
 fail:
-    glamor_fallback("to %p (%c)\n", drawable,
+    glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,
 		    glamor_get_drawable_location(drawable));
     if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
 	if (glamor_prepare_access_gc(gc)) {
commit a63df0c504be3be0e969f5080a6593a55cb87246
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 15:00:32 2010 -0800

    glamor: Fix up the wide/non-solid lines fallback.

diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 48e62f4..5a7204b 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -52,13 +52,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0) {
-	ErrorF("stub wide polylines\n");
-	return;
+	glamor_fallback("glamor_poly_lines(): wide lines\n");
+	goto fail;
     }
     if (gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	ErrorF("stub poly_line non-solid fill\n");
-	return;
+	glamor_fallback("glamor_poly_lines(): non-solid fill\n");
+	goto fail;
     }
 
     rects = xalloc(sizeof(xRectangle) * (n - 1));
@@ -104,4 +104,19 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     }
     gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
     xfree(rects);
+    return;
+
+fail:
+    if (gc->lineWidth == 0) {
+	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	    if (glamor_prepare_access_gc(gc)) {
+		fbPolyLine(drawable, gc, mode, n, points);
+		glamor_finish_access_gc(gc);
+	    }
+	    glamor_finish_access(drawable);
+	}
+	return;
+    }
+    /* fb calls mi functions in the lineWidth != 0 case. */
+    fbPolyLine(drawable, gc, mode, n, points);
 }
commit d61a13cf3f0a3028fbcf41310a4f5ecaa8546961
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 14:52:04 2010 -0800

    glamor: Fix and enable tile fill acceleration (aka the root weave).

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index d2e8e88..8e269e2 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -80,8 +80,8 @@ glamor_fill(DrawablePtr drawable,
 		    height,
 		    gc->alu,
 		    gc->planemask,
-		    gc->patOrg.x,
-		    gc->patOrg.y);
+		    drawable->x + x - gc->patOrg.x,
+		    drawable->y + y - gc->patOrg.y);
 	break;
     }
 }
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index 62e0a0f..29e9db5 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -52,7 +52,7 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     int		    xorg, yorg;
     int		    n;
 
-    if (gc->fillStyle != FillSolid)
+    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 	goto fail;
 
     xorg = drawable->x;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c69ff98..91fa6e1 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -136,7 +136,6 @@ typedef struct glamor_screen_private {
 
     /* glamor_tile */
     GLint tile_prog;
-    glamor_transform_uniforms tile_transform;
 
     /* glamor_putimage */
     GLint put_image_xybitmap_prog;
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 01c4b7a..60a1a1e 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -41,17 +41,10 @@ glamor_init_tile_shader(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     const char *tile_vs =
-	"uniform float x_bias;\n"
-	"uniform float x_scale;\n"
-	"uniform float y_bias;\n"
-	"uniform float y_scale;\n"
 	"void main()\n"
 	"{\n"
-	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
-	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
-	"			   0,\n"
-	"			   1);\n"
-	"	gl_TexCoord[0] = vec4(gl_MultiTexCoord0.xy, 0, 1);\n"
+	"	gl_Position = gl_Vertex;\n"
+	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
 	"}\n";
     const char *tile_fs =
 	"uniform sampler2D sampler;\n"
@@ -76,8 +69,7 @@ glamor_init_tile_shader(ScreenPtr screen)
 	glGetUniformLocationARB(glamor_priv->tile_prog, "sampler");
     glUseProgramObjectARB(glamor_priv->tile_prog);
     glUniform1iARB(sampler_uniform_location, 0);
-    glamor_get_transform_uniform_locations(glamor_priv->tile_prog,
-					   &glamor_priv->tile_transform);
+    glUseProgramObjectARB(0);
 }
 
 void
@@ -97,6 +89,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     int tile_y1 = tile_y;
     int tile_y2 = tile_y + height;
     glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
+    float vertices[4][2];
+    float source_texcoords[4][2];
 
     if (glamor_priv->tile_prog == 0) {
 	ErrorF("Tiling unsupported\n");
@@ -105,32 +99,56 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
     if (!glamor_set_destination_pixmap(pixmap))
 	goto fail;
-    if (tile_priv->fb == 0) {
-	ErrorF("Non-FBO tile pixmap\n");
+
+    if (tile_priv->tex == 0) {
+	ErrorF("Non-texture tile pixmap\n");
 	goto fail;
     }
+
     if (!glamor_set_planemask(pixmap, planemask))
 	goto fail;
     glamor_set_alu(alu);
+
     glUseProgramObjectARB(glamor_priv->tile_prog);
-    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform);
 
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tile_priv->tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     glEnable(GL_TEXTURE_2D);
 
-    glBegin(GL_TRIANGLE_FAN);
-    glMultiTexCoord2f(0, tile_x1, tile_y1);
-    glVertex2f(x1, y1);
-    glMultiTexCoord2f(0, tile_x1, tile_y2);
-    glVertex2f(x1, y2);
-    glMultiTexCoord2f(0, tile_x2, tile_y2);
-    glVertex2f(x2, y2);
-    glMultiTexCoord2f(0, tile_x2, tile_y1);
-    glVertex2f(x2, y1);
-    glEnd();
+    vertices[0][0] = v_from_x_coord_x(pixmap, x1);
+    vertices[0][1] = v_from_x_coord_y(pixmap, y1);
+    vertices[1][0] = v_from_x_coord_x(pixmap, x2);
+    vertices[1][1] = v_from_x_coord_y(pixmap, y1);
+    vertices[2][0] = v_from_x_coord_x(pixmap, x2);
+    vertices[2][1] = v_from_x_coord_y(pixmap, y2);
+    vertices[3][0] = v_from_x_coord_x(pixmap, x1);
+    vertices[3][1] = v_from_x_coord_y(pixmap, y2);
+
+    source_texcoords[0][0] = t_from_x_coord_x(tile, tile_x1);
+    source_texcoords[0][1] = t_from_x_coord_y(tile, tile_y1);
+    source_texcoords[1][0] = t_from_x_coord_x(tile, tile_x2);
+    source_texcoords[1][1] = t_from_x_coord_y(tile, tile_y1);
+    source_texcoords[2][0] = t_from_x_coord_x(tile, tile_x2);
+    source_texcoords[2][1] = t_from_x_coord_y(tile, tile_y2);
+    source_texcoords[3][0] = t_from_x_coord_x(tile, tile_x1);
+    source_texcoords[3][1] = t_from_x_coord_y(tile, tile_y2);
+
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
+
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glClientActiveTexture(GL_TEXTURE0);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_VERTEX_ARRAY);
 
     glUseProgramObjectARB(0);
     glDisable(GL_TEXTURE_2D);
commit 86a206525350b7e82ab0e432ad0fb8858960857d
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 13:40:28 2010 -0800

    glamor: Fix off-by-one in CopyPixels CopyArea path.
    
    Fixes window dragging in uncomposited metacity.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 94e987c..b7762cc 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -76,7 +76,7 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
     glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
 
     for (i = 0; i < nbox; i++) {
-	int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2 + y_off;
+	int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off;
 	glRasterPos2i(box[i].x1 + x_off,
 		      flip_y1);
 	glCopyPixels(box[i].x1 + dx + x_off,
commit be82a0624207b5f367b97c25ac7d7dbd8a518597
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 13:21:47 2010 -0800

    glamor: Fix screen_x/screen_y handling for compositing.
    
    It's not an offset from pixmap coords to composited pixmap coords,
    it's an offset from screen-relative window drawable coords to
    composited pixmap coords.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 578ad30..94e987c 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -41,9 +41,8 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
 			      int dx,
 			      int dy)
 {
-    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-    int i;
+    int x_off, y_off, i;
 
     if (src != dst) {
 	glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n");
@@ -74,12 +73,14 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src,
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
 
+    glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
+
     for (i = 0; i < nbox; i++) {
-	int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2;
-	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x,
-		      flip_y1 - dst_pixmap->screen_x);
-	glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x,
-		     flip_y1 - dy - src_pixmap->screen_y,
+	int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2 + y_off;
+	glRasterPos2i(box[i].x1 + x_off,
+		      flip_y1);
+	glCopyPixels(box[i].x1 + dx + x_off,
+		     flip_y1 - dy,
 		     box[i].x2 - box[i].x1,
 		     box[i].y2 - box[i].y1,
 		     GL_COLOR);
@@ -104,6 +105,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     int i;
     float vertices[4][2], texcoords[4][2];
     glamor_pixmap_private *src_pixmap_priv;
+    int src_x_off, src_y_off, dst_x_off, dst_y_off;
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
@@ -126,6 +128,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 	    goto fail;
     }
 
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    dx += src_x_off;
+    dy += src_y_off;
+
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
     glEnable(GL_TEXTURE_2D);
@@ -143,14 +150,14 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glUseProgramObjectARB(glamor_priv->finish_access_prog);
 
     for (i = 0; i < nbox; i++) {
-	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1);
-	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1);
-	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2);
-	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1);
-	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2);
-	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2);
-	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1);
-	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2);
+	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
+	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
+	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1 + dst_y_off);
+	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2 + dst_x_off);
+	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
+	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1 + dst_x_off);
+	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2 + dst_y_off);
 
 	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
 	texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index b0a64f2..a4036c8 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -52,6 +52,27 @@ glamor_get_drawable_location(const DrawablePtr drawable)
 	return 'f';
 }
 
+/**
+ * Sets the offsets to add to coordinates to make them address the same bits in
+ * the backing drawable. These coordinates are nonzero only for redirected
+ * windows.
+ */
+void
+glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
+			   int *x, int *y)
+{
+#ifdef COMPOSITE
+    if (drawable->type == DRAWABLE_WINDOW) {
+	*x = -pixmap->screen_x;
+	*y = -pixmap->screen_y;
+	return;
+    }
+#endif
+
+    *x = 0;
+    *y = 0;
+}
+
 Bool
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 1b601ee..d2e8e88 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -41,12 +41,15 @@ glamor_fill(DrawablePtr drawable,
 	    int height)
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
+    int x_off, y_off;
+
+    glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off);
 
     switch (gc->fillStyle) {
     case FillSolid:
 	glamor_solid(dst_pixmap,
-		     x - dst_pixmap->screen_x,
-		     y - dst_pixmap->screen_y,
+		     x + x_off,
+		     y + y_off,
 		     width,
 		     height,
 		     gc->alu,
@@ -57,28 +60,28 @@ glamor_fill(DrawablePtr drawable,
     case FillOpaqueStippled:
 	glamor_stipple(dst_pixmap,
 		       gc->stipple,
-		       x - dst_pixmap->screen_x,
-		       y - dst_pixmap->screen_y,
+		       x+ x_off,
+		       y + y_off,
 		       width,
 		       height,
 		       gc->alu,
 		       gc->planemask,
 		       gc->fgPixel,
 		       gc->bgPixel,
-		       gc->patOrg.x - dst_pixmap->screen_x,
-		       gc->patOrg.y - dst_pixmap->screen_y);
+		       gc->patOrg.x + x_off,
+		       gc->patOrg.y + y_off);
 	break;
     case FillTiled:
 	glamor_tile(dst_pixmap,
 		    gc->tile.pixmap,
-		    x - dst_pixmap->screen_x,
-		    y - dst_pixmap->screen_y,
+		    x + x_off,
+		    y + y_off,
 		    width,
 		    height,
 		    gc->alu,
 		    gc->planemask,
-		    gc->patOrg.x - dst_pixmap->screen_y,
-		    gc->patOrg.y - dst_pixmap->screen_y);
+		    gc->patOrg.x,
+		    gc->patOrg.y);
 	break;
     }
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 6e92b4d..92ffba5 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -55,6 +55,7 @@ glamor_get_spans(DrawablePtr drawable,
     GLenum format, type;
     int i, j;
     uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
+    int x_off, y_off;
 
     goto fail;
 
@@ -86,9 +87,11 @@ glamor_get_spans(DrawablePtr drawable,
     if (!glamor_set_destination_pixmap(pixmap))
 	goto fail;
 
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
     for (i = 0; i < count; i++) {
-	glReadPixels(points[i].x - pixmap->screen_x,
-		     points[i].y - pixmap->screen_y,
+	glReadPixels(points[i].x + x_off,
+		     points[i].y + y_off,
 		     widths[i],
 		     1,
 		     format, type,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 283f7ea..c69ff98 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -200,25 +200,25 @@ glamor_fallback(char *format, ...)
 static inline float
 v_from_x_coord_x(PixmapPtr pixmap, int x)
 {
-    return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
+    return (float)x / pixmap->drawable.width * 2.0 - 1.0;
 }
 
 static inline float
 v_from_x_coord_y(PixmapPtr pixmap, int y)
 {
-    return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
+    return (float)y / pixmap->drawable.height * -2.0 + 1.0;
 }
 
 static inline float
 t_from_x_coord_x(PixmapPtr pixmap, int x)
 {
-    return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
+    return (float)x / pixmap->drawable.width;
 }
 
 static inline float
 t_from_x_coord_y(PixmapPtr pixmap, int y)
 {
-    return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
+    return 1.0 - (float)y / pixmap->drawable.height;
 }
 
 /* glamor.c */
@@ -254,6 +254,8 @@ Bool glamor_prepare_access_gc(GCPtr gc);
 void glamor_finish_access_gc(GCPtr gc);
 void glamor_init_finish_access_shaders(ScreenPtr screen);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
+void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
+				int *x, int *y);
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 5379921..b71644f 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -244,6 +244,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int nbox;
     int bpp = drawable->bitsPerPixel;
     int src_stride = PixmapBytePad(w, drawable->depth);
+    int x_off, y_off;
 
     goto fail;
 
@@ -297,6 +298,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     x += drawable->x;
     y += drawable->y;
 
+    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
+
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp);
     if (bpp == 1)
@@ -325,7 +328,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	    continue;
 
 	src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
-	glRasterPos2i(x1 - pixmap->screen_x, y1 - pixmap->screen_y);
+	glRasterPos2i(x1 + x_off, y1 + y_off);
 	glDrawPixels(x2 - x1,
 		     y2 - y1,
 		     format, type,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index cb9da1e..35e3e0a 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -533,6 +533,7 @@ glamor_composite_with_shader(CARD8 op,
     float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2];
     int i;
     BoxPtr box;
+    int dst_x_off, dst_y_off;
 
     memset(&key, 0, sizeof(key));
     if (!source->pDrawable) {
@@ -673,16 +674,33 @@ glamor_composite_with_shader(CARD8 op,
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     }
 
+    glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
+			       &dst_x_off, &dst_y_off);
+    if (source_pixmap) {
+	int dx, dy;
+
+	glamor_get_drawable_deltas(source->pDrawable, source_pixmap, &dx, &dy);
+	x_source += dx;
+	y_source += dy;
+    }
+    if (mask_pixmap) {
+	int dx, dy;
+
+	glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap, &dx, &dy);
+	x_mask += dx;
+	y_mask += dy;
+    }
+
     box = REGION_RECTS(&region);
     for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-	vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
-	vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
-	vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
-	vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
-	vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
-	vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
-	vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
-	vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
+	vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off);
+	vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off);
+	vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off);
+	vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1 + dst_y_off);
+	vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2 + dst_x_off);
+	vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off);
+	vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1 + dst_x_off);
+	vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2 + dst_y_off);
 
 	if (key.source != SHADER_SOURCE_SOLID) {
 	    int tx1 = box[i].x1 + x_source - x_dest;
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 32f7bc5..54aa266 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -42,6 +42,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     int wmax = 0;
     RegionPtr clip = fbGetCompositeClip(gc);
     BoxRec *pbox;
+    int x_off, y_off;
 
     goto fail;
 
@@ -82,6 +83,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     glamor_set_alu(gc->alu);
     if (!glamor_set_planemask(dest_pixmap, gc->planemask))
 	goto fail;
+
+    glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
+
     for (i = 0; i < n; i++) {
 	if (temp_src) {
 	    for (j = 0; j < widths[i]; j++) {
@@ -98,12 +102,12 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    if (pbox->y1 > points[i].y)
 		break;
 	    glScissor(pbox->x1,
-		      points[i].y - dest_pixmap->screen_y,
+		      points[i].y + y_off,
 		      pbox->x2 - pbox->x1,
 		      1);
 	    glEnable(GL_SCISSOR_TEST);
-	    glRasterPos2i(points[i].x - dest_pixmap->screen_x,
-			  points[i].y - dest_pixmap->screen_y);
+	    glRasterPos2i(points[i].x + x_off,
+			  points[i].y + y_off);
 	    glDrawPixels(widths[i],
 			 1,
 			 format, type,
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 517dbd3..01c4b7a 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -92,10 +92,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     int x2 = x + width;
     int y1 = y;
     int y2 = y + height;
-    int tile_x1 = tile_x - tile->screen_x;
-    int tile_x2 = tile_x - tile->screen_x + width;
-    int tile_y1 = tile_y - tile->screen_y;
-    int tile_y2 = tile_y - tile->screen_y + height;
+    int tile_x1 = tile_x;
+    int tile_x2 = tile_x + width;
+    int tile_y1 = tile_y;
+    int tile_y2 = tile_y + height;
     glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
 
     if (glamor_priv->tile_prog == 0) {
commit 5360b1e8bbae571b120999e7eec7cd2826601497
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 09:47:38 2010 -0800

    glamor: Implement glCopyPixels based src == dest CopyArea acceleration

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index f21752b..578ad30 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -32,18 +32,70 @@
  * GC CopyArea implementation
  */
 
-void
-glamor_copy_n_to_n(DrawablePtr src,
-		 DrawablePtr dst,
-		 GCPtr gc,
-		 BoxPtr box,
-		 int nbox,
-		 int		dx,
-		 int		dy,
-		 Bool		reverse,
-		 Bool		upsidedown,
-		 Pixel		bitplane,
-		 void		*closure)
+static Bool
+glamor_copy_n_to_n_copypixels(DrawablePtr src,
+			      DrawablePtr dst,
+			      GCPtr gc,
+			      BoxPtr box,
+			      int nbox,
+			      int dx,
+			      int dy)
+{
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    int i;
+
+    if (src != dst) {
+	glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n");
+	return FALSE;
+    }
+
+    if (gc) {
+	if (gc->alu != GXcopy) {
+	    glamor_fallback("glamor_copy_n_to_n_copypixels(): non-copy ALU\n");
+	    return FALSE;
+	}
+	if (!glamor_pm_is_solid(dst, gc->planemask)) {
+	    glamor_fallback("glamor_copy_n_to_n_copypixels(): "
+			    "non-solid planemask\n");
+	    return FALSE;
+	}
+    }
+
+    if (!glamor_set_destination_pixmap(dst_pixmap))
+	return FALSE;
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glOrtho(0, dst_pixmap->drawable.width,
+	    0, dst_pixmap->drawable.height,
+	    -1, 1);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+
+    for (i = 0; i < nbox; i++) {
+	int flip_y1 = dst_pixmap->drawable.height - 1 - box[i].y2;
+	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x,
+		      flip_y1 - dst_pixmap->screen_x);
+	glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x,
+		     flip_y1 - dy - src_pixmap->screen_y,
+		     box[i].x2 - box[i].x1,
+		     box[i].y2 - box[i].y1,
+		     GL_COLOR);
+    }
+
+    return TRUE;
+}
+
+static Bool
+glamor_copy_n_to_n_textured(DrawablePtr src,
+			      DrawablePtr dst,
+			      GCPtr gc,
+			      BoxPtr box,
+			      int nbox,
+			      int dx,
+			      int dy)
 {
     glamor_screen_private *glamor_priv =
 	glamor_get_screen_private(dst->pScreen);
@@ -116,22 +168,33 @@ glamor_copy_n_to_n(DrawablePtr src,
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDisable(GL_TEXTURE_2D);
+    return TRUE;
 
-#if 0
-    for (i = 0; i < nbox; i++) {
-	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x,
-		      box[i].y1 - dst_pixmap->screen_y);
-	glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x,
-		     box[i].y1 + dy - src_pixmap->screen_y,
-		     box[i].x2 - box[i].x1,
-		     box[i].y2 - box[i].y1,
-		     GL_COLOR);
-    }
-#endif
+fail:
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(dst_pixmap, ~0);
+    return FALSE;
+}
 
-    return;
+void
+glamor_copy_n_to_n(DrawablePtr src,
+		 DrawablePtr dst,
+		 GCPtr gc,
+		 BoxPtr box,
+		 int nbox,
+		 int		dx,
+		 int		dy,
+		 Bool		reverse,
+		 Bool		upsidedown,
+		 Pixel		bitplane,
+		 void		*closure)
+{
+    if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy))
+	return;
+
+    if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy))
+	return;
 
-fail:
     glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
 		    glamor_get_drawable_location(dst));
@@ -144,8 +207,6 @@ fail:
 	}
 	glamor_finish_access(dst);
     }
-    glamor_set_alu(GXcopy);
-    glamor_set_planemask(dst_pixmap, ~0);
 }
 
 RegionPtr
commit 0565c1d789ed82c533f860713d66b4941c299f9c
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 22:35:04 2010 -0800

    glamor: Add support for accel of x8r8g8b8 source pictures.
    
    There's a limitation still for RepeatNone, but this fixes a bunch of
    fallbacks for gnome-terminal.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 95aad7d..283f7ea 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -100,6 +100,7 @@ typedef struct {
 
 enum shader_source {
     SHADER_SOURCE_SOLID,
+    SHADER_SOURCE_TEXTURE,
     SHADER_SOURCE_TEXTURE_ALPHA,
     SHADER_SOURCE_COUNT,
 };
@@ -107,6 +108,7 @@ enum shader_source {
 enum shader_mask {
     SHADER_MASK_NONE,
     SHADER_MASK_SOLID,
+    SHADER_MASK_TEXTURE,
     SHADER_MASK_TEXTURE_ALPHA,
     SHADER_MASK_COUNT,
 };
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 0f4f4c0..cb9da1e 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -82,8 +82,14 @@ glamor_create_composite_fs(struct shader_key *key)
 	"{\n";
     const char *source_alpha_pixmap_fetch =
 	"	vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
+    const char *source_pixmap_fetch =
+	"	vec4 source = vec4(texture2D(source_sampler, "
+	"				     gl_TexCoord[0].xy).rgb, 1.0);\n";
     const char *mask_alpha_pixmap_fetch =
 	"	vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
+    const char *mask_pixmap_fetch =
+	"	vec4 mask = vec4(texture2D(mask_sampler, "
+	"				   gl_TexCoord[1].xy).rgb, 1.0);\n";
     const char *source_in_mask =
 	"	gl_FragColor = source * mask.a;\n";
     const char *source_only =
@@ -106,9 +112,12 @@ glamor_create_composite_fs(struct shader_key *key)
 	source_setup = source_pixmap_header;
 	source_fetch = source_alpha_pixmap_fetch;
 	break;
-	FatalError("Bad composite shader source");
+    case SHADER_SOURCE_TEXTURE:
+	source_setup = source_pixmap_header;
+	source_fetch = source_pixmap_fetch;
+	break;
     default:
-	FatalError("Bad composite source mask");
+	FatalError("Bad composite shader source");
     }
 
     switch (key->mask) {
@@ -121,6 +130,10 @@ glamor_create_composite_fs(struct shader_key *key)
 	mask_setup = mask_pixmap_header;
 	mask_fetch = mask_alpha_pixmap_fetch;
 	break;
+    case SHADER_MASK_TEXTURE:
+	mask_setup = mask_pixmap_header;
+	mask_fetch = mask_pixmap_fetch;
+	break;
     default:
 	FatalError("Bad composite shader mask");
     }
@@ -446,6 +459,14 @@ good_source_format(PicturePtr picture)
     case PICT_a8:
     case PICT_a8r8g8b8:
 	return TRUE;
+    case PICT_x8r8g8b8:
+	/* In order to support formats with no alpha, we have to wire the
+	 * alpha to 1 in the shader, which conflicts with
+	 * GL_CLAMP_TO_BORDERing to transparent.  We could possibly compute
+	 * coverage of the texels in the sampling area if we need to, but
+	 * that isn't implemented today.
+	 */
+	return (picture->repeatType != RepeatNone);
     default:
 	glamor_fallback("Bad source format 0x%08x\n", picture->format);
 	return FALSE;
@@ -459,6 +480,14 @@ good_mask_format(PicturePtr picture)
     case PICT_a8:
     case PICT_a8r8g8b8:
 	return TRUE;
+    case PICT_x8r8g8b8:
+	/* In order to support formats with no alpha, we have to wire the
+	 * alpha to 1 in the shader, which conflicts with
+	 * GL_CLAMP_TO_BORDERing to transparent.  We could possibly compute
+	 * coverage of the texels in the sampling area if we need to, but
+	 * that isn't implemented today.
+	 */
+	return (picture->repeatType != RepeatNone);
     default:
 	glamor_fallback("Bad mask format 0x%08x\n", picture->format);
 	return FALSE;
@@ -514,7 +543,11 @@ glamor_composite_with_shader(CARD8 op,
 	    goto fail;
 	}
     } else {
-	key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+	if (PICT_FORMAT_A(source->format) != 0) {
+	    key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+	} else {
+	    key.source = SHADER_SOURCE_TEXTURE;
+	}
     }
     if (mask) {
 	if (!mask->pDrawable) {
@@ -525,7 +558,11 @@ glamor_composite_with_shader(CARD8 op,
 		goto fail;
 	    }
 	} else {
-	    key.mask = SHADER_MASK_TEXTURE_ALPHA;
+	    if (PICT_FORMAT_A(mask->format) != 0) {
+		key.mask = SHADER_MASK_TEXTURE_ALPHA;
+	    } else {
+		key.mask = SHADER_MASK_TEXTURE;
+	    }
 	}
     } else {
 	key.mask = SHADER_MASK_NONE;
@@ -539,7 +576,8 @@ glamor_composite_with_shader(CARD8 op,
 	goto fail;
     }
 
-    if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
+    if (key.source == SHADER_SOURCE_TEXTURE ||
+	key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
 	source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 	source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 	if (source_pixmap == dest_pixmap) {
@@ -553,7 +591,8 @@ glamor_composite_with_shader(CARD8 op,
 	if (!good_source_format(source))
 	    goto fail;
     }
-    if (key.mask == SHADER_MASK_TEXTURE_ALPHA) {
+    if (key.mask == SHADER_MASK_TEXTURE ||
+	key.mask == SHADER_MASK_TEXTURE_ALPHA) {
 	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 	if (mask_pixmap == dest_pixmap) {
commit e6bf50573650f03c8130b7783485b24e98e15c79
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 09:23:09 2010 -0800

    glamor: Set active texture on glamor_copy_n_to_n setup.
    
    Fixes failure in rendercheck -t blend -o src

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 695edc3..f21752b 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -74,6 +74,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 	    goto fail;
     }
 
+    glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
     glEnable(GL_TEXTURE_2D);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
commit be64167fea3c74447ed3c5116b97473676c25b29
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Feb 11 09:20:50 2010 -0800

    glamor: Don't try to CopyArea from a Solid source picture.
    
    Fixes failure with rendercheck.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f432b5f..0f4f4c0 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -406,6 +406,9 @@ glamor_composite_with_copy(CARD8 op,
 {
     RegionRec region;
 
+    if (!source->pDrawable)
+	return FALSE;
+
     if (!compatible_formats(op, dest, source))
 	return FALSE;
 
commit 126fc09cb5bf8c38b73f1c2cd2a0ef588c3265e8
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 22:35:04 2010 -0800

    glamor: Rework the Render shader setup to be easily modified, like cairo-gl.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index dc1a5ca..95aad7d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -98,6 +98,19 @@ typedef struct {
 
 #define GLAMOR_NUM_GLYPH_CACHES 4
 
+enum shader_source {
+    SHADER_SOURCE_SOLID,
+    SHADER_SOURCE_TEXTURE_ALPHA,
+    SHADER_SOURCE_COUNT,
+};
+
+enum shader_mask {
+    SHADER_MASK_NONE,
+    SHADER_MASK_SOLID,
+    SHADER_MASK_TEXTURE_ALPHA,
+    SHADER_MASK_COUNT,
+};
+
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
@@ -130,7 +143,8 @@ typedef struct glamor_screen_private {
     GLint put_image_xybitmap_bg_uniform_location;
 
     /* glamor_composite */
-    glamor_composite_shader composite_shader[8];
+    glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
+					    [SHADER_MASK_COUNT];
 
     glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
 } glamor_screen_private;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e4a9441..f432b5f 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -39,9 +39,8 @@
 #include "glu3/glu3.h"
 
 struct shader_key {
-    Bool solid_source;
-    Bool has_mask;
-    Bool solid_mask;
+    enum shader_source source;
+    enum shader_mask mask;
 };
 
 struct blendinfo {
@@ -67,29 +66,6 @@ static struct blendinfo composite_op_info[] = {
     [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
 };
 
-#define SOLID_SOURCE_INDEX	1
-#define HAS_MASK_INDEX		2
-#define SOLID_MASK_INDEX	3
-
-static glamor_composite_shader *
-glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
-{
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    int index = 0;
-
-    if (key->solid_source)
-	index += SOLID_SOURCE_INDEX;
-    if (key->has_mask) {
-	index += HAS_MASK_INDEX;
-	if (key->solid_mask)
-	    index += SOLID_MASK_INDEX;
-    }
-
-    assert(index < ARRAY_SIZE(glamor_priv->composite_shader));
-
-    return &glamor_priv->composite_shader[index];
-}
-
 static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
@@ -104,12 +80,12 @@ glamor_create_composite_fs(struct shader_key *key)
     const char *main_opening =
 	"void main()\n"
 	"{\n";
-    const char *source_pixmap_fetch =
+    const char *source_alpha_pixmap_fetch =
 	"	vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
-    const char *mask_pixmap_fetch =
+    const char *mask_alpha_pixmap_fetch =
 	"	vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
     const char *source_in_mask =
-	"	gl_FragColor = source * mask.w;\n";
+	"	gl_FragColor = source * mask.a;\n";
     const char *source_only =
 	"	gl_FragColor = source;\n";
     const char *main_closing =
@@ -119,29 +95,49 @@ glamor_create_composite_fs(struct shader_key *key)
     const char *source_fetch = "";
     const char *mask_setup = "";
     const char *mask_fetch = "";
+    const char *in;
     GLuint prog;
 
-    if (key->solid_source) {
+    switch (key->source) {
+    case SHADER_SOURCE_SOLID:
 	source_setup = source_solid_header;
-    } else {
+	break;
+    case SHADER_SOURCE_TEXTURE_ALPHA:
 	source_setup = source_pixmap_header;
-	source_fetch = source_pixmap_fetch;
+	source_fetch = source_alpha_pixmap_fetch;
+	break;
+	FatalError("Bad composite shader source");
+    default:
+	FatalError("Bad composite source mask");
     }
-    if (key->has_mask) {
-	if (key->solid_mask) {
-	    mask_setup = mask_solid_header;
-	} else {
-	    mask_setup = mask_pixmap_header;
-	    mask_fetch = mask_pixmap_fetch;
-	}
+
+    switch (key->mask) {
+    case SHADER_MASK_NONE:
+	break;
+    case SHADER_MASK_SOLID:
+	mask_setup = mask_solid_header;
+	break;
+    case SHADER_MASK_TEXTURE_ALPHA:
+	mask_setup = mask_pixmap_header;
+	mask_fetch = mask_alpha_pixmap_fetch;
+	break;
+    default:
+	FatalError("Bad composite shader mask");
+    }
+
+    if (key->mask == SHADER_MASK_NONE) {
+	in = source_only;
+    } else {
+	in = source_in_mask;
     }
+
     source = XNFprintf("%s%s%s%s%s%s%s",
 		       source_setup,
 		       mask_setup,
 		       main_opening,
 		       source_fetch,
 		       mask_fetch,
-		       key->has_mask ? source_in_mask : source_only,
+		       in,
 		       main_closing);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
@@ -156,19 +152,28 @@ glamor_create_composite_vs(struct shader_key *key)
     const char *main_opening =
 	"void main()\n"
 	"{\n"
-	"	gl_Position = gl_Vertex;\n"
+	"	gl_Position = gl_Vertex;\n";
+    const char *source_coords =
 	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n";
     const char *mask_coords =
 	"	gl_TexCoord[1] = gl_MultiTexCoord1;\n";
     const char *main_closing =
 	"}\n";
+    const char *source_coords_setup = "";
+    const char *mask_coords_setup = "";
     char *source;
     GLuint prog;
-    Bool compute_mask_coords = key->has_mask && !key->solid_mask;
 
-    source = XNFprintf("%s%s%s",
+    if (key->source != SHADER_SOURCE_SOLID)
+	source_coords_setup = source_coords;
+
+    if (key->mask != SHADER_MASK_NONE && key->mask != SHADER_MASK_SOLID)
+	mask_coords_setup = mask_coords;
+
+    source = XNFprintf("%s%s%s%s",
 		       main_opening,
-		       compute_mask_coords ? mask_coords : "",
+		       source_coords_setup,
+		       mask_coords_setup,
 		       main_closing);
 
     prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
@@ -178,13 +183,11 @@ glamor_create_composite_vs(struct shader_key *key)
 }
 
 static void
-glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
+glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
+			       glamor_composite_shader *shader)
 {
     GLuint vs, fs, prog;
     GLint source_sampler_uniform_location, mask_sampler_uniform_location;
-    glamor_composite_shader *shader;
-
-    shader = glamor_lookup_composite_shader(screen, key);
 
     vs = glamor_create_composite_vs(key);
     if (vs == 0)
@@ -202,7 +205,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
 
     glUseProgramObjectARB(prog);
 
-    if (key->solid_source) {
+    if (key->source == SHADER_SOURCE_SOLID) {
 	shader->source_uniform_location = glGetUniformLocationARB(prog,
 								  "source");
     } else {
@@ -211,8 +214,8 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
 	glUniform1i(source_sampler_uniform_location, 0);
     }
 
-    if (key->has_mask) {
-	if (key->solid_mask) {
+    if (key->mask != SHADER_MASK_NONE) {
+	if (key->mask == SHADER_MASK_SOLID) {
 	    shader->mask_uniform_location = glGetUniformLocationARB(prog,
 								    "mask");
 	} else {
@@ -223,27 +226,22 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
     }
 }
 
-void
-glamor_init_composite_shaders(ScreenPtr screen)
+static glamor_composite_shader *
+glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
 {
-    struct shader_key key;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    glamor_composite_shader *shader;
 
-    memset(&key, 0, sizeof(key));
-    key.has_mask = FALSE;
-    glamor_create_composite_shader(screen, &key);
-    key.has_mask = TRUE;
-    glamor_create_composite_shader(screen, &key);
-    key.solid_mask = TRUE;
-    glamor_create_composite_shader(screen, &key);
+    shader = &glamor_priv->composite_shader[key->source][key->mask];
+    if (shader->prog == 0)
+	glamor_create_composite_shader(screen, key, shader);
 
-    memset(&key, 0, sizeof(key));
-    key.solid_source = TRUE;
-    key.has_mask = FALSE;
-    glamor_create_composite_shader(screen, &key);
-    key.has_mask = TRUE;
-    glamor_create_composite_shader(screen, &key);
-    key.solid_mask = TRUE;
-    glamor_create_composite_shader(screen, &key);
+    return shader;
+}
+
+void
+glamor_init_composite_shaders(ScreenPtr screen)
+{
 }
 
 static Bool
@@ -505,33 +503,40 @@ glamor_composite_with_shader(CARD8 op,
     BoxPtr box;
 
     memset(&key, 0, sizeof(key));
-    key.has_mask = (mask != NULL);
     if (!source->pDrawable) {
 	if (source->pSourcePict->type == SourcePictTypeSolidFill) {
-	    key.solid_source = TRUE;
+	    key.source = SHADER_SOURCE_SOLID;
 	} else {
-	    ErrorF("gradient source\n");
+	    glamor_fallback("gradient source\n");
 	    goto fail;
 	}
-    }
-    if (mask && !mask->pDrawable) {
-	if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
-	    key.solid_mask = TRUE;
+    } else {
+	key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+    }
+    if (mask) {
+	if (!mask->pDrawable) {
+	    if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
+		key.mask = SHADER_MASK_SOLID;
+	    } else {
+		glamor_fallback("gradient mask\n");
+		goto fail;
+	    }
 	} else {
-	    ErrorF("gradient mask\n");
-	    goto fail;
+	    key.mask = SHADER_MASK_TEXTURE_ALPHA;
 	}
+    } else {
+	key.mask = SHADER_MASK_NONE;
     }
     if (source->alphaMap) {
-	ErrorF("source alphaMap\n");
+	glamor_fallback("source alphaMap\n");
 	goto fail;
     }
     if (mask && mask->alphaMap) {
-	ErrorF("mask alphaMap\n");
+	glamor_fallback("mask alphaMap\n");
 	goto fail;
     }
 
-    if (!key.solid_source) {
+    if (key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
 	source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 	source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 	if (source_pixmap == dest_pixmap) {
@@ -545,7 +550,7 @@ glamor_composite_with_shader(CARD8 op,
 	if (!good_source_format(source))
 	    goto fail;
     }
-    if (mask && !key.solid_mask) {
+    if (key.mask == SHADER_MASK_TEXTURE_ALPHA) {
 	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 	if (mask_pixmap == dest_pixmap) {
@@ -589,13 +594,13 @@ glamor_composite_with_shader(CARD8 op,
 	y_mask += mask->pDrawable->y;
     }
 
-    if (key.solid_source) {
+    if (key.source == SHADER_SOURCE_SOLID) {
 	glamor_set_composite_solid(source, shader->source_uniform_location);
     } else {
 	glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
     }
-    if (key.has_mask) {
-	if (key.solid_mask) {
+    if (key.mask != SHADER_MASK_NONE) {
+	if (key.mask == SHADER_MASK_SOLID) {
 	    glamor_set_composite_solid(mask, shader->mask_uniform_location);
 	} else {
 	    glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
@@ -614,13 +619,13 @@ glamor_composite_with_shader(CARD8 op,
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
 
-    if (!key.solid_source) {
+    if (key.source != SHADER_SOURCE_SOLID) {
 	glClientActiveTexture(GL_TEXTURE0);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     }
 
-    if (key.has_mask && !key.solid_mask) {
+    if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
 	glClientActiveTexture(GL_TEXTURE1);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -637,7 +642,7 @@ glamor_composite_with_shader(CARD8 op,
 	vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
 	vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
 
-	if (!key.solid_source) {
+	if (key.source != SHADER_SOURCE_SOLID) {
 	    int tx1 = box[i].x1 + x_source - x_dest;
 	    int ty1 = box[i].y1 + y_source - y_dest;
 	    int tx2 = box[i].x2 + x_source - x_dest;
@@ -652,7 +657,7 @@ glamor_composite_with_shader(CARD8 op,
 	    source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2);
 	}
 
-	if (key.has_mask && !key.solid_mask) {
+	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
 	    int tx1 = box[i].x1 + x_mask - x_dest;
 	    int ty1 = box[i].y1 + y_mask - y_dest;
 	    int tx2 = box[i].x2 + x_mask - x_dest;
commit f4a3194837e640997c0c3a775f48a49800e213c6
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 23:17:09 2010 -0600

    glamor: Add the glyph cache from UXA (de-camelCased).
    
    This doesn't yet have an optimized glamor_composite_rects()
    implementation, but it does triple the speed of x11perf -aa10text.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 17139c0..e823234 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -23,6 +23,7 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_glyphs.c \
 	glamor_polyfillrect.c \
 	glamor_polylines.c \
 	glamor_putimage.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7bc75aa..03db7ec 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -222,6 +222,8 @@ glamor_init(ScreenPtr screen)
     ps->Composite = glamor_composite;
     glamor_priv->saved_trapezoids = ps->Trapezoids;
     ps->Trapezoids = glamor_trapezoids;
+    glamor_priv->saved_glyphs = ps->Glyphs;
+    ps->Glyphs = glamor_glyphs;
 #endif
 
     glamor_init_solid_shader(screen);
@@ -230,6 +232,8 @@ glamor_init(ScreenPtr screen)
     glamor_init_composite_shaders(screen);
     glamor_init_finish_access_shaders(screen);
 
+    glamor_glyphs_init(screen);
+
     return TRUE;
 
 fail:
@@ -246,6 +250,8 @@ glamor_fini(ScreenPtr screen)
     PictureScreenPtr	ps = GetPictureScreenIfSet(screen);
 #endif
 
+    glamor_glyphs_fini(screen);
+
     screen->CreateGC = glamor_priv->saved_create_gc;
     screen->CreatePixmap = glamor_priv->saved_create_pixmap;
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
@@ -255,5 +261,7 @@ glamor_fini(ScreenPtr screen)
     screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
 #ifdef RENDER
     ps->Composite = glamor_priv->saved_composite;
+    ps->Trapezoids = glamor_priv->saved_trapezoids;
+    ps->Glyphs = glamor_priv->saved_glyphs;
 #endif
 }
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
new file mode 100644
index 0000000..7b2d13d
--- /dev/null
+++ b/glamor/glamor_glyphs.c
@@ -0,0 +1,877 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ * Partly based on code Copyright © 2000 SuSE, 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 Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
+ * 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.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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: Owen Taylor <otaylor at fishsoup.net>
+ * Based on code by: Keith Packard
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+
+#include "mipict.h"
+
+#if DEBUG_GLYPH_CACHE
+#define DBG_GLYPH_CACHE(a) ErrorF a
+#else
+#define DBG_GLYPH_CACHE(a)
+#endif
+
+/* Width of the pixmaps we use for the caches; this should be less than
+ * max texture size of the driver; this may need to actually come from
+ * the driver.
+ */
+#define CACHE_PICTURE_WIDTH 1024
+
+/* Maximum number of glyphs we buffer on the stack before flushing
+ * rendering to the mask or destination surface.
+ */
+#define GLYPH_BUFFER_SIZE 256
+
+typedef struct {
+    PicturePtr source;
+    glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE];
+    int count;
+} glamor_glyph_buffer_t;
+
+typedef enum {
+    GLAMOR_GLYPH_SUCCESS,	/* Glyph added to render buffer */
+    GLAMOR_GLYPH_FAIL,		/* out of memory, etc */
+    GLAMOR_GLYPH_NEED_FLUSH,	/* would evict a glyph already in the buffer */
+} glamor_glyph_cache_result_t;
+
+void glamor_glyphs_init(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
+    int i = 0;
+
+    memset(glamor_screen->glyph_caches, 0, sizeof(glamor_screen->glyph_caches));
+
+    glamor_screen->glyph_caches[i].format = PICT_a8;
+    glamor_screen->glyph_caches[i].glyph_width =
+	glamor_screen->glyph_caches[i].glyph_height = 16;
+    i++;
+    glamor_screen->glyph_caches[i].format = PICT_a8;
+    glamor_screen->glyph_caches[i].glyph_width =
+	glamor_screen->glyph_caches[i].glyph_height = 32;
+    i++;
+    glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8;
+    glamor_screen->glyph_caches[i].glyph_width =
+	glamor_screen->glyph_caches[i].glyph_height = 16;
+    i++;
+    glamor_screen->glyph_caches[i].format = PICT_a8r8g8b8;
+    glamor_screen->glyph_caches[i].glyph_width =
+	glamor_screen->glyph_caches[i].glyph_height = 32;
+    i++;
+
+    assert(i == GLAMOR_NUM_GLYPH_CACHES);
+
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_screen->glyph_caches[i].columns =
+	    CACHE_PICTURE_WIDTH / glamor_screen->glyph_caches[i].glyph_width;
+	glamor_screen->glyph_caches[i].size = 256;
+	glamor_screen->glyph_caches[i].hash_size = 557;
+    }
+}
+
+static void glamor_unrealize_glyph_caches(ScreenPtr screen, unsigned int format)
+{
+    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
+    int i;
+
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
+
+	if (cache->format != format)
+	    continue;
+
+	if (cache->picture) {
+	    FreePicture((pointer) cache->picture, (XID) 0);
+	    cache->picture = NULL;
+	}
+
+	if (cache->hash_entries) {
+	    xfree(cache->hash_entries);
+	    cache->hash_entries = NULL;
+	}
+
+	if (cache->glyphs) {
+	    xfree(cache->glyphs);
+	    cache->glyphs = NULL;
+	}
+	cache->glyph_count = 0;
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+/* All caches for a single format share a single pixmap for glyph storage,
+ * allowing mixing glyphs of different sizes without paying a penalty
+ * for switching between source pixmaps. (Note that for a size of font
+ * right at the border between two sizes, we might be switching for almost
+ * every glyph.)
+ *
+ * This function allocates the storage pixmap, and then fills in the
+ * rest of the allocated structures for all caches with the given format.
+ */
+static Bool glamor_realize_glyph_caches(ScreenPtr screen, unsigned int format)
+{
+    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
+    int depth = PIXMAN_FORMAT_DEPTH(format);
+    PictFormatPtr pict_format;
+    PixmapPtr pixmap;
+    PicturePtr picture;
+    CARD32 component_alpha;
+    int height;
+    int i;
+    int error;
+
+    pict_format = PictureMatchFormat(screen, depth, format);
+    if (!pict_format)
+	return FALSE;
+
+    /* Compute the total vertical size needed for the format */
+
+    height = 0;
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
+	int rows;
+
+	if (cache->format != format)
+	    continue;
+
+	cache->y_offset = height;
+
+	rows = (cache->size + cache->columns - 1) / cache->columns;
+	height += rows * cache->glyph_height;
+    }
+
+    /* Now allocate the pixmap and picture */
+
+    pixmap = screen->CreatePixmap(screen,
+				  CACHE_PICTURE_WIDTH,
+				  height, depth,
+				  0);
+    if (!pixmap)
+	return FALSE;
+
+    component_alpha = NeedsComponent(pict_format->format);
+    picture = CreatePicture(0, &pixmap->drawable, pict_format,
+			    CPComponentAlpha, &component_alpha,
+			    serverClient, &error);
+
+    screen->DestroyPixmap(pixmap);	/* picture holds a refcount */
+
+    if (!picture)
+	return FALSE;
+
+    /* And store the picture in all the caches for the format */
+
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
+	int j;
+
+	if (cache->format != format)
+	    continue;
+
+	cache->picture = picture;
+	cache->picture->refcnt++;
+	cache->hash_entries = xalloc(sizeof(int) * cache->hash_size);
+	cache->glyphs =
+	    xalloc(sizeof(glamor_cached_glyph_t) * cache->size);
+	cache->glyph_count = 0;
+
+	if (!cache->hash_entries || !cache->glyphs)
+	    goto bail;
+
+	for (j = 0; j < cache->hash_size; j++)
+	    cache->hash_entries[j] = -1;
+
+	cache->eviction_position = rand() % cache->size;
+    }
+
+    /* Each cache references the picture individually */
+    FreePicture(picture, 0);
+    return TRUE;
+
+ bail:
+    glamor_unrealize_glyph_caches(screen, format);
+    return FALSE;
+}
+
+void glamor_glyphs_fini(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
+    int i;
+
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
+
+	if (cache->picture)
+	    glamor_unrealize_glyph_caches(screen, cache->format);
+    }
+}
+
+static int
+glamor_glyph_cache_hash_lookup(glamor_glyph_cache_t * cache, GlyphPtr glyph)
+{
+    int slot;
+
+    slot = (*(CARD32 *) glyph->sha1) % cache->hash_size;
+
+    while (TRUE) {		/* hash table can never be full */
+	int entryPos = cache->hash_entries[slot];
+	if (entryPos == -1)
+	    return -1;
+
+	if (memcmp(glyph->sha1, cache->glyphs[entryPos].sha1,
+		   sizeof(glyph->sha1)) == 0) {
+	    return entryPos;
+	}
+
+	slot--;
+	if (slot < 0)
+	    slot = cache->hash_size - 1;
+    }
+}
+
+static void
+glamor_glyph_cache_hash_insert(glamor_glyph_cache_t * cache, GlyphPtr glyph, int pos)
+{
+    int slot;
+
+    memcpy(cache->glyphs[pos].sha1, glyph->sha1, sizeof(glyph->sha1));
+
+    slot = (*(CARD32 *) glyph->sha1) % cache->hash_size;
+
+    while (TRUE) {		/* hash table can never be full */
+	if (cache->hash_entries[slot] == -1) {
+	    cache->hash_entries[slot] = pos;
+	    return;
+	}
+
+	slot--;
+	if (slot < 0)
+	    slot = cache->hash_size - 1;
+    }
+}
+
+static void glamor_glyph_cache_hash_remove(glamor_glyph_cache_t * cache, int pos)
+{
+    int slot;
+    int emptied_slot = -1;
+
+    slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hash_size;
+
+    while (TRUE) {		/* hash table can never be full */
+	int entryPos = cache->hash_entries[slot];
+
+	if (entryPos == -1)
+	    return;
+
+	if (entryPos == pos) {
+	    cache->hash_entries[slot] = -1;
+	    emptied_slot = slot;
+	} else if (emptied_slot != -1) {
+	    /* See if we can move this entry into the emptied slot,
+	     * we can't do that if if entry would have hashed
+	     * between the current position and the emptied slot.
+	     * (taking wrapping into account). Bad positions
+	     * are:
+	     *
+	     * |   XXXXXXXXXX             |
+	     *     i         j
+	     *
+	     * |XXX                   XXXX|
+	     *     j                  i
+	     *
+	     * i - slot, j - emptied_slot
+	     *
+	     * (Knuth 6.4R)
+	     */
+
+	    int entry_slot = (*(CARD32 *) cache->glyphs[entryPos].sha1) %
+		cache->hash_size;
+
+	    if (!((entry_slot >= slot && entry_slot < emptied_slot) ||
+		  (emptied_slot < slot
+		   && (entry_slot < emptied_slot
+		       || entry_slot >= slot)))) {
+		cache->hash_entries[emptied_slot] = entryPos;
+		cache->hash_entries[slot] = -1;
+		emptied_slot = slot;
+	    }
+	}
+
+	slot--;
+	if (slot < 0)
+	    slot = cache->hash_size - 1;
+    }
+}
+
+#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyph_width)
+#define CACHE_Y(pos) (cache->y_offset + ((pos) / cache->columns) * cache->glyph_height)
+
+/* The most efficient thing to way to upload the glyph to the screen
+ * is to use CopyArea; glamor pixmaps are always offscreen.
+ */
+static Bool
+glamor_glyph_cache_upload_glyph(ScreenPtr screen,
+				glamor_glyph_cache_t * cache,
+				int pos, GlyphPtr glyph)
+{
+    PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
+    PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
+    PixmapPtr cache_pixmap = (PixmapPtr) cache->picture->pDrawable;
+    PixmapPtr scratch;
+    GCPtr gc;
+
+    /* UploadToScreen only works if bpp match */
+    if (glyph_pixmap->drawable.bitsPerPixel !=
+	cache_pixmap->drawable.bitsPerPixel)
+	return FALSE;
+
+    gc = GetScratchGC(cache_pixmap->drawable.depth, screen);
+    ValidateGC(&cache_pixmap->drawable, gc);
+
+    /* Create a temporary bo to stream the updates to the cache */
+    scratch = screen->CreatePixmap(screen,
+				   glyph->info.width,
+				   glyph->info.height,
+				   glyph_pixmap->drawable.depth,
+				   0);
+    if (scratch) {
+	(void)glamor_copy_area(&glyph_pixmap->drawable,
+			       &scratch->drawable,
+			       gc,
+			       0, 0,
+			       glyph->info.width, glyph->info.height,
+			       0, 0);
+    } else {
+	scratch = glyph_pixmap;
+    }
+
+    (void)glamor_copy_area(&scratch->drawable,
+			   &cache_pixmap->drawable,
+			   gc,
+			   0, 0, glyph->info.width, glyph->info.height,
+			   CACHE_X(pos), CACHE_Y(pos));
+
+    if (scratch != glyph_pixmap)
+	screen->DestroyPixmap(scratch);
+
+    FreeScratchGC(gc);
+
+    return TRUE;
+}
+
+static glamor_glyph_cache_result_t
+glamor_glyph_cache_buffer_glyph(ScreenPtr screen,
+				glamor_glyph_cache_t * cache,
+				glamor_glyph_buffer_t * buffer,
+				GlyphPtr glyph, int x_glyph, int y_glyph)
+{
+    glamor_composite_rect_t *rect;
+    int pos;
+
+    if (buffer->source && buffer->source != cache->picture)
+	return GLAMOR_GLYPH_NEED_FLUSH;
+
+    if (!cache->picture) {
+	if (!glamor_realize_glyph_caches(screen, cache->format))
+	    return GLAMOR_GLYPH_FAIL;
+    }
+
+    DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n",
+		     cache->glyph_width, cache->glyph_height,
+		     cache->format == PICT_a8 ? "A" : "ARGB",
+		     (long)*(CARD32 *) glyph->sha1));
+
+    pos = glamor_glyph_cache_hash_lookup(cache, glyph);
+    if (pos != -1) {
+	DBG_GLYPH_CACHE(("  found existing glyph at %d\n", pos));
+    } else {
+	if (cache->glyph_count < cache->size) {
+	    /* Space remaining; we fill from the start */
+	    pos = cache->glyph_count;
+	    cache->glyph_count++;
+	    DBG_GLYPH_CACHE(("  storing glyph in free space at %d\n", pos));
+
+	    glamor_glyph_cache_hash_insert(cache, glyph, pos);
+
+	} else {
+	    /* Need to evict an entry. We have to see if any glyphs
+	     * already in the output buffer were at this position in
+	     * the cache
+	     */
+
+	    pos = cache->eviction_position;
+	    DBG_GLYPH_CACHE(("  evicting glyph at %d\n", pos));
+	    if (buffer->count) {
+		int x, y;
+		int i;
+
+		x = CACHE_X(pos);
+		y = CACHE_Y(pos);
+
+		for (i = 0; i < buffer->count; i++) {
+		    if (buffer->rects[i].x_src == x
+			&& buffer->rects[i].y_src == y) {
+			DBG_GLYPH_CACHE(("  must flush buffer\n"));
+			return GLAMOR_GLYPH_NEED_FLUSH;
+		    }
+		}
+	    }
+
+	    /* OK, we're all set, swap in the new glyph */
+	    glamor_glyph_cache_hash_remove(cache, pos);
+	    glamor_glyph_cache_hash_insert(cache, glyph, pos);
+
+	    /* And pick a new eviction position */
+	    cache->eviction_position = rand() % cache->size;
+	}
+
+	/* Now actually upload the glyph into the cache picture; if
+	 * we can't do it with UploadToScreen (because the glyph is
+	 * offscreen, etc), we fall back to CompositePicture.
+	 */
+	if (!glamor_glyph_cache_upload_glyph(screen, cache, pos, glyph)) {
+	    CompositePicture(PictOpSrc,
+			     GlyphPicture(glyph)[screen->myNum],
+			     None,
+			     cache->picture,
+			     0, 0,
+			     0, 0,
+			     CACHE_X(pos),
+			     CACHE_Y(pos),
+			     glyph->info.width,
+			     glyph->info.height);
+	}
+
+    }
+
+    buffer->source = cache->picture;
+
+    rect = &buffer->rects[buffer->count];
+    rect->x_src = CACHE_X(pos);
+    rect->y_src = CACHE_Y(pos);
+    rect->x_dst = x_glyph - glyph->info.x;
+    rect->y_dst = y_glyph - glyph->info.y;
+    rect->width = glyph->info.width;
+    rect->height = glyph->info.height;
+
+    buffer->count++;
+
+    return GLAMOR_GLYPH_SUCCESS;
+}
+
+#undef CACHE_X
+#undef CACHE_Y
+
+static glamor_glyph_cache_result_t
+glamor_buffer_glyph(ScreenPtr screen,
+		    glamor_glyph_buffer_t *buffer,
+		    GlyphPtr glyph, int x_glyph, int y_glyph)
+{
+    glamor_screen_private *glamor_screen = glamor_get_screen_private(screen);
+    unsigned int format = (GlyphPicture(glyph)[screen->myNum])->format;
+    int width = glyph->info.width;
+    int height = glyph->info.height;
+    glamor_composite_rect_t *rect;
+    PicturePtr source;
+    int i;
+
+    if (buffer->count == GLYPH_BUFFER_SIZE)
+	return GLAMOR_GLYPH_NEED_FLUSH;
+
+    if (PICT_FORMAT_BPP(format) == 1)
+	format = PICT_a8;
+
+    for (i = 0; i < GLAMOR_NUM_GLYPH_CACHES; i++) {
+	glamor_glyph_cache_t *cache = &glamor_screen->glyph_caches[i];
+
+	if (format == cache->format &&
+	    width <= cache->glyph_width &&
+	    height <= cache->glyph_height) {
+	    glamor_glyph_cache_result_t result =
+		glamor_glyph_cache_buffer_glyph(screen,
+						&glamor_screen->glyph_caches[i],
+						buffer,
+						glyph, x_glyph,
+						y_glyph);
+	    switch (result) {
+	    case GLAMOR_GLYPH_FAIL:
+		break;
+	    case GLAMOR_GLYPH_SUCCESS:
+	    case GLAMOR_GLYPH_NEED_FLUSH:
+		return result;
+	    }
+	}
+    }
+
+    /* Couldn't find the glyph in the cache, use the glyph picture directly */
+
+    source = GlyphPicture(glyph)[screen->myNum];
+    if (buffer->source && buffer->source != source)
+	return GLAMOR_GLYPH_NEED_FLUSH;
+
+    buffer->source = source;
+
+    rect = &buffer->rects[buffer->count];
+    rect->x_src = 0;
+    rect->y_src = 0;
+    rect->x_dst = x_glyph - glyph->info.x;
+    rect->y_dst = y_glyph - glyph->info.y;
+    rect->width = glyph->info.width;
+    rect->height = glyph->info.height;
+
+    buffer->count++;
+
+    return GLAMOR_GLYPH_SUCCESS;
+}
+
+static void glamor_glyphs_to_mask(PicturePtr mask,
+				  glamor_glyph_buffer_t *buffer)
+{
+    glamor_composite_rects(PictOpAdd, buffer->source, mask,
+			   buffer->count, buffer->rects);
+
+    buffer->count = 0;
+    buffer->source = NULL;
+}
+
+static void
+glamor_glyphs_to_dst(CARD8 op,
+		     PicturePtr src,
+		     PicturePtr dst,
+		     glamor_glyph_buffer_t *buffer,
+		     INT16 x_src, INT16 y_src, INT16 x_dst, INT16 y_dst)
+{
+    int i;
+
+    for (i = 0; i < buffer->count; i++) {
+	glamor_composite_rect_t *rect = &buffer->rects[i];
+
+	CompositePicture(op,
+			 src,
+			 buffer->source,
+			 dst,
+			 x_src + rect->x_dst - x_dst,
+			 y_src + rect->y_dst - y_dst,
+			 rect->x_src,
+			 rect->y_src,
+			 rect->x_dst,
+			 rect->y_dst, rect->width, rect->height);
+    }
+
+    buffer->count = 0;
+    buffer->source = NULL;
+}
+
+/* Cut and paste from render/glyph.c - probably should export it instead */
+static void
+glamor_glyph_extents(int nlist,
+		     GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents)
+{
+    int x1, x2, y1, y2;
+    int n;
+    GlyphPtr glyph;
+    int x, y;
+
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--) {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--) {
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+/**
+ * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
+ * bounding box, which appears to be good enough to catch most cases at least.
+ */
+static Bool
+glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
+{
+    int x1, x2, y1, y2;
+    int n;
+    GlyphPtr glyph;
+    int x, y;
+    BoxRec extents;
+    Bool first = TRUE;
+
+    x = 0;
+    y = 0;
+    extents.x1 = 0;
+    extents.y1 = 0;
+    extents.x2 = 0;
+    extents.y2 = 0;
+    while (nlist--) {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--) {
+	    glyph = *glyphs++;
+
+	    if (glyph->info.width == 0 || glyph->info.height == 0) {
+		x += glyph->info.xOff;
+		y += glyph->info.yOff;
+		continue;
+	    }
+
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+
+	    if (first) {
+		extents.x1 = x1;
+		extents.y1 = y1;
+		extents.x2 = x2;
+		extents.y2 = y2;
+		first = FALSE;
+	    } else {
+		if (x1 < extents.x2 && x2 > extents.x1 &&
+		    y1 < extents.y2 && y2 > extents.y1) {
+		    return TRUE;
+		}
+
+		if (x1 < extents.x1)
+		    extents.x1 = x1;
+		if (x2 > extents.x2)
+		    extents.x2 = x2;
+		if (y1 < extents.y1)
+		    extents.y1 = y1;
+		if (y2 > extents.y2)
+		    extents.y2 = y2;
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+
+    return FALSE;
+}
+
+void
+glamor_glyphs(CARD8 op,
+	      PicturePtr src,
+	      PicturePtr dst,
+	      PictFormatPtr mask_format,
+	      INT16 x_src,
+	      INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+{
+    PicturePtr picture;
+    PixmapPtr mask_pixmap = 0;
+    PicturePtr mask;
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    int width = 0, height = 0;
+    int x, y;
+    int x_dst = list->xOff, y_dst = list->yOff;
+    int n;
+    GlyphPtr glyph;
+    int error;
+    BoxRec extents = { 0, 0, 0, 0 };
+    CARD32 component_alpha;
+    glamor_glyph_buffer_t buffer;
+
+    /* If we don't have a mask format but all the glyphs have the same format
+     * and don't intersect, use the glyph format as mask format for the full
+     * benefits of the glyph cache.
+     */
+    if (!mask_format) {
+	Bool same_format = TRUE;
+	int i;
+
+	mask_format = list[0].format;
+
+	for (i = 0; i < nlist; i++) {
+	    if (mask_format->format != list[i].format->format) {
+		same_format = FALSE;
+		break;
+	    }
+	}
+
+	if (!same_format || (mask_format->depth != 1 &&
+			     glamor_glyphs_intersect(nlist, list,
+						     glyphs))) {
+	    mask_format = NULL;
+	}
+    }
+
+    if (mask_format) {
+	GCPtr gc;
+	xRectangle rect;
+
+	glamor_glyph_extents(nlist, list, glyphs, &extents);
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+
+	if (mask_format->depth == 1) {
+	    PictFormatPtr a8Format =
+		PictureMatchFormat(screen, 8, PICT_a8);
+
+	    if (a8Format)
+		mask_format = a8Format;
+	}
+
+	mask_pixmap = screen->CreatePixmap(screen, width, height,
+					   mask_format->depth,
+					   CREATE_PIXMAP_USAGE_SCRATCH);
+	if (!mask_pixmap)
+	    return;
+	component_alpha = NeedsComponent(mask_format->format);
+	mask = CreatePicture(0, &mask_pixmap->drawable,
+			      mask_format, CPComponentAlpha,
+			      &component_alpha, serverClient, &error);
+	if (!mask) {
+	    screen->DestroyPixmap(mask_pixmap);
+	    return;
+	}
+	gc = GetScratchGC(mask_pixmap->drawable.depth, screen);
+	ValidateGC(&mask_pixmap->drawable, gc);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	gc->ops->PolyFillRect(&mask_pixmap->drawable, gc, 1, &rect);
+	FreeScratchGC(gc);
+	x = -extents.x1;
+	y = -extents.y1;
+    } else {
+	mask = dst;
+	x = 0;
+	y = 0;
+    }
+    buffer.count = 0;
+    buffer.source = NULL;
+    while (nlist--) {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	while (n--) {
+	    glyph = *glyphs++;
+	    picture = GlyphPicture(glyph)[screen->myNum];
+
+	    if (glyph->info.width > 0 && glyph->info.height > 0 &&
+		glamor_buffer_glyph(screen, &buffer, glyph, x,
+				    y) == GLAMOR_GLYPH_NEED_FLUSH) {
+		if (mask_format)
+		    glamor_glyphs_to_mask(mask, &buffer);
+		else
+		    glamor_glyphs_to_dst(op, src, dst,
+					 &buffer, x_src, y_src,
+					 x_dst, y_dst);
+
+		glamor_buffer_glyph(screen, &buffer, glyph, x, y);
+	    }
+
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+	list++;
+    }
+
+    if (buffer.count) {
+	if (mask_format)
+	    glamor_glyphs_to_mask(mask, &buffer);
+	else
+	    glamor_glyphs_to_dst(op, src, dst, &buffer,
+				 x_src, y_src, x_dst, y_dst);
+    }
+
+    if (mask_format) {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture(op,
+			 src,
+			 mask,
+			 dst,
+			 x_src + x - x_dst,
+			 y_src + y - y_dst, 0, 0, x, y, width, height);
+	FreePicture(mask, 0);
+	screen->DestroyPixmap(mask_pixmap);
+    }
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 526b2cf..dc1a5ca 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,6 +31,10 @@
 #include "glamor.h"
 #include <GL/glew.h>
 
+#ifdef RENDER
+#include "glyphstr.h"
+#endif
+
 typedef enum glamor_access {
     GLAMOR_ACCESS_RO,
     GLAMOR_ACCESS_RW,
@@ -52,6 +56,48 @@ typedef struct glamor_composite_shader {
     GLint mask_uniform_location;
 } glamor_composite_shader;
 
+typedef struct {
+    INT16 x_src;
+    INT16 y_src;
+    INT16 x_dst;
+    INT16 y_dst;
+    INT16 width;
+    INT16 height;
+} glamor_composite_rect_t;
+
+typedef struct {
+    unsigned char sha1[20];
+} glamor_cached_glyph_t;
+
+typedef struct {
+    /* The identity of the cache, statically configured at initialization */
+    unsigned int format;
+    int glyph_width;
+    int glyph_height;
+
+    /* Size of cache; eventually this should be dynamically determined */
+    int size;
+
+    /* Hash table mapping from glyph sha1 to position in the glyph; we use
+     * open addressing with a hash table size determined based on size and large
+     * enough so that we always have a good amount of free space, so we can
+     * use linear probing. (Linear probing is preferrable to double hashing
+     * here because it allows us to easily remove entries.)
+     */
+    int *hash_entries;
+    int hash_size;
+
+    glamor_cached_glyph_t *glyphs;
+    int glyph_count;		/* Current number of glyphs */
+
+    PicturePtr picture;	/* Where the glyphs of the cache are stored */
+    int y_offset;		/* y location within the picture where the cache starts */
+    int columns;		/* Number of columns the glyphs are layed out in */
+    int eviction_position;	/* Next random position to evict a glyph */
+} glamor_glyph_cache_t;
+
+#define GLAMOR_NUM_GLYPH_CACHES 4
+
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
@@ -60,6 +106,7 @@ typedef struct glamor_screen_private {
     GetImageProcPtr saved_get_image;
     CompositeProcPtr saved_composite;
     TrapezoidsProcPtr saved_trapezoids;
+    GlyphsProcPtr saved_glyphs;
     ChangeWindowAttributesProcPtr saved_change_window_attributes;
     CopyWindowProcPtr saved_copy_window;
     BitmapToRegionProcPtr saved_bitmap_to_region;
@@ -84,6 +131,8 @@ typedef struct glamor_screen_private {
 
     /* glamor_composite */
     glamor_composite_shader composite_shader[8];
+
+    glamor_glyph_cache_t glyph_caches[GLAMOR_NUM_GLYPH_CACHES];
 } glamor_screen_private;
 
 typedef struct glamor_pixmap_private {
@@ -241,6 +290,16 @@ glamor_get_spans(DrawablePtr drawable,
 		 int nspans,
 		 char *dst_start);
 
+/* glamor_glyphs.c */
+void glamor_glyphs_init(ScreenPtr screen);
+void glamor_glyphs_fini(ScreenPtr screen);
+void glamor_glyphs(CARD8 op,
+		   PicturePtr pSrc,
+		   PicturePtr pDst,
+		   PictFormatPtr maskFormat,
+		   INT16 xSrc,
+		   INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
+
 /* glamor_setspans.c */
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		      DDXPointPtr points, int *widths, int n, int sorted);
@@ -281,6 +340,9 @@ void glamor_trapezoids(CARD8 op,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		       int ntrap, xTrapezoid *traps);
 void glamor_init_composite_shaders(ScreenPtr screen);
+void glamor_composite_rects(CARD8 op,
+			    PicturePtr src, PicturePtr dst,
+			    int nrect, glamor_composite_rect_t *rects);
 
 /* glamor_tile.c */
 void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index be28bd4..e4a9441 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -921,4 +921,31 @@ glamor_trapezoids(CARD8 op,
     FreePicture(picture, 0);
 }
 
+void
+glamor_composite_rects(CARD8 op,
+		       PicturePtr src, PicturePtr dst,
+		       int nrect, glamor_composite_rect_t *rects)
+{
+    int n;
+    glamor_composite_rect_t *r;
+
+    ValidatePicture(src);
+    ValidatePicture(dst);
+
+    n = nrect;
+    r = rects;
+
+    while (n--) {
+	CompositePicture(op,
+			 src,
+			 NULL,
+			 dst,
+			 r->x_src, r->y_src,
+			 0, 0,
+			 r->x_dst, r->y_dst,
+			 r->width, r->height);
+	r++;
+    }
+}
+
 #endif /* RENDER */
commit 7e6432e7b94f7f99b257da8de53573108d30ae22
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 22:54:40 2010 -0600

    glamor: Fix up and enable accelerated composite.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index e07cf62..695edc3 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -32,30 +32,6 @@
  * GC CopyArea implementation
  */
 
-static float
-v_from_x_coord_x(PixmapPtr pixmap, int x)
-{
-    return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
-}
-
-static float
-v_from_x_coord_y(PixmapPtr pixmap, int y)
-{
-    return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
-}
-
-static float
-t_from_x_coord_x(PixmapPtr pixmap, int x)
-{
-    return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
-}
-
-static float
-t_from_x_coord_y(PixmapPtr pixmap, int y)
-{
-    return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
-}
-
 void
 glamor_copy_n_to_n(DrawablePtr src,
 		 DrawablePtr dst,
@@ -175,10 +151,12 @@ RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		 int srcx, int srcy, int width, int height, int dstx, int dsty)
 {
+#if 0
     ScreenPtr screen = dst->pScreen;
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
+#endif
     RegionPtr region;
 
     region = miDoCopy(src, dst, gc,
@@ -187,6 +165,7 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
     return region;
 
+#if 0
 fail:
     glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
@@ -201,4 +180,5 @@ fail:
 	glamor_finish_access(dst);
     }
     return region;
+#endif
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index adc6997..526b2cf 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -132,6 +132,30 @@ glamor_fallback(char *format, ...)
     va_end(ap);
 }
 
+static inline float
+v_from_x_coord_x(PixmapPtr pixmap, int x)
+{
+    return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
+}
+
+static inline float
+v_from_x_coord_y(PixmapPtr pixmap, int y)
+{
+    return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
+}
+
+static inline float
+t_from_x_coord_x(PixmapPtr pixmap, int x)
+{
+    return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
+}
+
+static inline float
+t_from_x_coord_y(PixmapPtr pixmap, int y)
+{
+    return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
+}
+
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index ba67d73..be28bd4 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -94,23 +94,20 @@ static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
     const char *source_pixmap_header =
-	"uniform sampler2D source_sampler;\n"
-	"varying vec4 source_coords;\n";
+	"uniform sampler2D source_sampler;\n";
     const char *source_solid_header =
 	"uniform vec4 source;\n";
     const char *mask_pixmap_header =
-	"uniform sampler2D mask_sampler;\n"
-	"varying vec4 mask_coords;\n";
+	"uniform sampler2D mask_sampler;\n";
     const char *mask_solid_header =
 	"uniform vec4 mask;\n";
     const char *main_opening =
 	"void main()\n"
 	"{\n";
     const char *source_pixmap_fetch =
-	"	vec4 source = texture2DProj(source_sampler, "
-	"				    source_coords.xyw);\n";
+	"	vec4 source = texture2D(source_sampler, gl_TexCoord[0].xy);\n";
     const char *mask_pixmap_fetch =
-	"	vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n";
+	"	vec4 mask = texture2D(mask_sampler, gl_TexCoord[1].xy);\n";
     const char *source_in_mask =
 	"	gl_FragColor = source * mask.w;\n";
     const char *source_only =
@@ -156,30 +153,20 @@ glamor_create_composite_fs(struct shader_key *key)
 static GLuint
 glamor_create_composite_vs(struct shader_key *key)
 {
-    const char *header =
-	"uniform mat4 dest_to_dest;\n"
-	"uniform mat4 dest_to_source;\n"
-	"varying vec4 source_coords;\n";
-    const char *mask_header =
-	"uniform mat4 dest_to_mask;\n"
-	"varying vec4 mask_coords;\n";
     const char *main_opening =
 	"void main()\n"
 	"{\n"
-	"	vec4 incoming_dest_coords = vec4(gl_Vertex.xy, 0, 1);\n"
-	"	gl_Position = dest_to_dest * incoming_dest_coords;\n"
-	"	source_coords = dest_to_source * incoming_dest_coords;\n";
+	"	gl_Position = gl_Vertex;\n"
+	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n";
     const char *mask_coords =
-	"	mask_coords = dest_to_mask * incoming_dest_coords;\n";
+	"	gl_TexCoord[1] = gl_MultiTexCoord1;\n";
     const char *main_closing =
 	"}\n";
     char *source;
     GLuint prog;
     Bool compute_mask_coords = key->has_mask && !key->solid_mask;
 
-    source = XNFprintf("%s%s%s%s%s",
-		       header,
-		       compute_mask_coords ? mask_header : "",
+    source = XNFprintf("%s%s%s",
 		       main_opening,
 		       compute_mask_coords ? mask_coords : "",
 		       main_closing);
@@ -214,8 +201,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
     shader->prog = prog;
 
     glUseProgramObjectARB(prog);
-    shader->dest_to_dest_uniform_location =
-	glGetUniformLocationARB(prog, "dest_to_dest");
 
     if (key->solid_source) {
 	shader->source_uniform_location = glGetUniformLocationARB(prog,
@@ -223,8 +208,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
     } else {
 	source_sampler_uniform_location = glGetUniformLocationARB(prog,
 								  "source_sampler");
-	shader->dest_to_source_uniform_location =
-	    glGetUniformLocationARB(prog, "dest_to_source");
 	glUniform1i(source_sampler_uniform_location, 0);
     }
 
@@ -236,8 +219,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
 	    mask_sampler_uniform_location = glGetUniformLocationARB(prog,
 								    "mask_sampler");
 	    glUniform1i(mask_sampler_uniform_location, 1);
-	    shader->dest_to_mask_uniform_location =
-		glGetUniformLocationARB(prog, "dest_to_mask");
 	}
     }
 }
@@ -255,6 +236,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
     key.solid_mask = TRUE;
     glamor_create_composite_shader(screen, &key);
 
+    memset(&key, 0, sizeof(key));
     key.solid_source = TRUE;
     key.has_mask = FALSE;
     glamor_create_composite_shader(screen, &key);
@@ -264,24 +246,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
     glamor_create_composite_shader(screen, &key);
 }
 
-static void
-glamor_set_composite_transform_matrix(GLUmat4 *m,
-				      PicturePtr picture,
-				      float x_source,
-				      float y_source)
-{
-    GLUmat4 temp;
-    DrawablePtr drawable = picture->pDrawable;
-    GLUvec4 scale = {{1.0f / drawable->width,
-		      1.0f / drawable->height,
-		      1.0,
-		      1.0}};
-
-    gluTranslate3f(m, -x_source, -y_source, 0.0);
-    gluScale4v(&temp, &scale);
-    gluMult4m_4m(m, &temp, m);
-}
-
 static Bool
 glamor_set_composite_op(ScreenPtr screen,
 			CARD8 op, PicturePtr dest, PicturePtr mask)
@@ -298,10 +262,6 @@ glamor_set_composite_op(ScreenPtr screen,
     source_blend = op_info->source_blend;
     dest_blend = op_info->dest_blend;
 
-    if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
-	op_info->source_alpha && source_blend != GL_ZERO) {
-    }
-
     /* If there's no dst alpha channel, adjust the blend op so that we'll treat
      * it as always 1.
      */
@@ -336,12 +296,8 @@ glamor_set_composite_op(ScreenPtr screen,
 
 static void
 glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
-			     glamor_pixmap_private *pixmap_priv,
-			     GLint transform_uniform_location,
-			     int x_translate, int y_translate)
+			     glamor_pixmap_private *pixmap_priv)
 {
-    GLUmat4 transform;
-
     glActiveTexture(GL_TEXTURE0 + unit);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     switch (picture->repeatType) {
@@ -376,13 +332,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
     }
 
     glEnable(GL_TEXTURE_2D);
-
-    glamor_set_composite_transform_matrix(&transform,
-					  picture,
-					  x_translate,
-					  y_translate);
-    glUniformMatrix4fvARB(transform_uniform_location, 1, 0,
-			  (float *)&transform);
 }
 
 static void
@@ -447,15 +396,15 @@ glamor_get_picture_location(PicturePtr picture)
 }
 
 static Bool
-glamor_composite_copy(CARD8 op,
-		      PicturePtr source,
-		      PicturePtr dest,
-		      INT16 x_source,
-		      INT16 y_source,
-		      INT16 x_dest,
-		      INT16 y_dest,
-		      CARD16 width,
-		      CARD16 height)
+glamor_composite_with_copy(CARD8 op,
+			   PicturePtr source,
+			   PicturePtr dest,
+			   INT16 x_source,
+			   INT16 y_source,
+			   INT16 x_dest,
+			   INT16 y_dest,
+			   CARD16 width,
+			   CARD16 height)
 {
     RegionRec region;
 
@@ -489,19 +438,59 @@ glamor_composite_copy(CARD8 op,
     return TRUE;
 }
 
-void
-glamor_composite(CARD8 op,
-		 PicturePtr source,
-		 PicturePtr mask,
-		 PicturePtr dest,
-		 INT16 x_source,
-		 INT16 y_source,
-		 INT16 x_mask,
-		 INT16 y_mask,
-		 INT16 x_dest,
-		 INT16 y_dest,
-		 CARD16 width,
-		 CARD16 height)
+static Bool
+good_source_format(PicturePtr picture)
+{
+    switch (picture->format) {
+    case PICT_a8:
+    case PICT_a8r8g8b8:
+	return TRUE;
+    default:
+	glamor_fallback("Bad source format 0x%08x\n", picture->format);
+	return FALSE;
+    }
+}
+
+static Bool
+good_mask_format(PicturePtr picture)
+{
+    switch (picture->format) {
+    case PICT_a8:
+    case PICT_a8r8g8b8:
+	return TRUE;
+    default:
+	glamor_fallback("Bad mask format 0x%08x\n", picture->format);
+	return FALSE;
+    }
+}
+
+static Bool
+good_dest_format(PicturePtr picture)
+{
+    switch (picture->format) {
+    case PICT_a8:
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+	return TRUE;
+    default:
+	glamor_fallback("Bad dest format 0x%08x\n", picture->format);
+	return FALSE;
+    }
+}
+
+static Bool
+glamor_composite_with_shader(CARD8 op,
+			     PicturePtr source,
+			     PicturePtr mask,
+			     PicturePtr dest,
+			     INT16 x_source,
+			     INT16 y_source,
+			     INT16 x_mask,
+			     INT16 y_mask,
+			     INT16 x_dest,
+			     INT16 y_dest,
+			     CARD16 width,
+			     CARD16 height)
 {
     ScreenPtr screen = dest->pDrawable->pScreen;
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
@@ -510,38 +499,10 @@ glamor_composite(CARD8 op,
     glamor_pixmap_private *mask_pixmap_priv = NULL;
     struct shader_key key;
     glamor_composite_shader *shader;
-    GLUmat4 dest_to_dest;
     RegionRec region;
+    float vertices[4][2], source_texcoords[4][2], mask_texcoords[4][2];
     int i;
-
-    /* Do two-pass PictOpOver componentAlpha, until we enable
-     * dual source color blending.
-     */
-    if (mask && mask->componentAlpha && op == PictOpOver) {
-	glamor_composite(PictOpOutReverse,
-			 source, mask, dest,
-			 x_source, y_source,
-			 x_mask, y_mask,
-			 x_dest, y_dest,
-			 width, height);
-	glamor_composite(PictOpAdd,
-			 source, mask, dest,
-			 x_source, y_source,
-			 x_mask, y_mask,
-			 x_dest, y_dest,
-			 width, height);
-	return;
-    }
-
-    if (!mask) {
-	if (glamor_composite_copy(op, source, dest,
-				  x_source, y_source,
-				  x_dest, y_dest,
-				  width, height))
-	    return;
-    }
-
-    goto fail;
+    BoxPtr box;
 
     memset(&key, 0, sizeof(key));
     key.has_mask = (mask != NULL);
@@ -581,6 +542,8 @@ glamor_composite(CARD8 op,
 	    glamor_fallback("glamor_composite(): no FBO in source\n");
 	    goto fail;
 	}
+	if (!good_source_format(source))
+	    goto fail;
     }
     if (mask && !key.solid_mask) {
 	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
@@ -593,7 +556,11 @@ glamor_composite(CARD8 op,
 	    glamor_fallback("glamor_composite(): no FBO in mask\n");
 	    goto fail;
 	}
+	if (!good_mask_format(mask))
+	    goto fail;
     }
+    if (!good_dest_format(dest))
+	goto fail;
 
     shader = glamor_lookup_composite_shader(screen, &key);
     if (shader->prog == 0) {
@@ -622,27 +589,16 @@ glamor_composite(CARD8 op,
 	y_mask += mask->pDrawable->y;
     }
 
-    gluOrtho6f(&dest_to_dest,
-	       dest_pixmap->screen_x, dest_pixmap->screen_x + width,
-	       dest_pixmap->screen_y, dest_pixmap->screen_y + height,
-	       -1, 1);
-    glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0,
-			  (float *)&dest_to_dest);
-
     if (key.solid_source) {
 	glamor_set_composite_solid(source, shader->source_uniform_location);
     } else {
-	glamor_set_composite_texture(screen, 0, source, source_pixmap_priv,
-				     shader->dest_to_source_uniform_location,
-				     x_source - x_dest, y_source - y_dest);
+	glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
     }
     if (key.has_mask) {
 	if (key.solid_mask) {
 	    glamor_set_composite_solid(mask, shader->mask_uniform_location);
 	} else {
-	    glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv,
-					 shader->dest_to_mask_uniform_location,
-					 x_mask - x_dest, y_mask - y_dest);
+	    glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
 	}
     }
 
@@ -652,25 +608,150 @@ glamor_composite(CARD8 op,
 				  x_mask, y_mask,
 				  x_dest, y_dest,
 				  width, height))
-	return;
+	goto done;
+
+
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
 
-    glBegin(GL_QUADS);
+    if (!key.solid_source) {
+	glClientActiveTexture(GL_TEXTURE0);
+	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, source_texcoords);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+
+    if (key.has_mask && !key.solid_mask) {
+	glClientActiveTexture(GL_TEXTURE1);
+	glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, mask_texcoords);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+
+    box = REGION_RECTS(&region);
     for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
-	BoxPtr box = &REGION_RECTS(&region)[i];
-	glVertex2i(box->x1, box->y1);
-	glVertex2i(box->x2, box->y1);
-	glVertex2i(box->x2, box->y2);
-	glVertex2i(box->x1, box->y2);
+	vertices[0][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
+	vertices[0][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
+	vertices[1][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
+	vertices[1][1] = v_from_x_coord_y(dest_pixmap, box[i].y1);
+	vertices[2][0] = v_from_x_coord_x(dest_pixmap, box[i].x2);
+	vertices[2][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
+	vertices[3][0] = v_from_x_coord_x(dest_pixmap, box[i].x1);
+	vertices[3][1] = v_from_x_coord_y(dest_pixmap, box[i].y2);
+
+	if (!key.solid_source) {
+	    int tx1 = box[i].x1 + x_source - x_dest;
+	    int ty1 = box[i].y1 + y_source - y_dest;
+	    int tx2 = box[i].x2 + x_source - x_dest;
+	    int ty2 = box[i].y2 + y_source - y_dest;
+	    source_texcoords[0][0] = t_from_x_coord_x(source_pixmap, tx1);
+	    source_texcoords[0][1] = t_from_x_coord_y(source_pixmap, ty1);
+	    source_texcoords[1][0] = t_from_x_coord_x(source_pixmap, tx2);
+	    source_texcoords[1][1] = t_from_x_coord_y(source_pixmap, ty1);
+	    source_texcoords[2][0] = t_from_x_coord_x(source_pixmap, tx2);
+	    source_texcoords[2][1] = t_from_x_coord_y(source_pixmap, ty2);
+	    source_texcoords[3][0] = t_from_x_coord_x(source_pixmap, tx1);
+	    source_texcoords[3][1] = t_from_x_coord_y(source_pixmap, ty2);
+	}
+
+	if (key.has_mask && !key.solid_mask) {
+	    int tx1 = box[i].x1 + x_mask - x_dest;
+	    int ty1 = box[i].y1 + y_mask - y_dest;
+	    int tx2 = box[i].x2 + x_mask - x_dest;
+	    int ty2 = box[i].y2 + y_mask - y_dest;
+	    mask_texcoords[0][0] = t_from_x_coord_x(mask_pixmap, tx1);
+	    mask_texcoords[0][1] = t_from_x_coord_y(mask_pixmap, ty1);
+	    mask_texcoords[1][0] = t_from_x_coord_x(mask_pixmap, tx2);
+	    mask_texcoords[1][1] = t_from_x_coord_y(mask_pixmap, ty1);
+	    mask_texcoords[2][0] = t_from_x_coord_x(mask_pixmap, tx2);
+	    mask_texcoords[2][1] = t_from_x_coord_y(mask_pixmap, ty2);
+	    mask_texcoords[3][0] = t_from_x_coord_x(mask_pixmap, tx1);
+	    mask_texcoords[3][1] = t_from_x_coord_y(mask_pixmap, ty2);
+	}
+#if 0
+ else memset(mask_texcoords, 0, sizeof(mask_texcoords));
+	for (i = 0; i < 4; i++) {
+	    ErrorF("%d: (%04.4f, %04.4f) (%04.4f, %04.4f) (%04.4f, %04.4f)\n",
+		   i,
+		   source_texcoords[i][0], source_texcoords[i][1],
+		   mask_texcoords[i][0], mask_texcoords[i][1],
+		   vertices[i][0], vertices[i][1]);
+	}
+#endif
+
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
-    glEnd();
 
+    glClientActiveTexture(GL_TEXTURE0);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glClientActiveTexture(GL_TEXTURE1);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_VERTEX_ARRAY);
+
+done:
+    REGION_UNINIT(dst->pDrawable->pScreen, &region);
     glDisable(GL_BLEND);
+    glActiveTexture(GL_TEXTURE0);
+    glDisable(GL_TEXTURE_2D);
+    glActiveTexture(GL_TEXTURE1);
+    glDisable(GL_TEXTURE_2D);
     glUseProgramObjectARB(0);
-    REGION_UNINIT(pDst->pDrawable->pScreen, &region);
-
-    return;
+    return TRUE;
 
 fail:
+    glDisable(GL_BLEND);
+    glUseProgramObjectARB(0);
+    return FALSE;
+}
+
+void
+glamor_composite(CARD8 op,
+		 PicturePtr source,
+		 PicturePtr mask,
+		 PicturePtr dest,
+		 INT16 x_source,
+		 INT16 y_source,
+		 INT16 x_mask,
+		 INT16 y_mask,
+		 INT16 x_dest,
+		 INT16 y_dest,
+		 CARD16 width,
+		 CARD16 height)
+{
+    /* Do two-pass PictOpOver componentAlpha, until we enable
+     * dual source color blending.
+     */
+    if (mask && mask->componentAlpha)
+	goto fail;
+    if (mask && mask->componentAlpha && op == PictOpOver) {
+	glamor_composite(PictOpOutReverse,
+			 source, mask, dest,
+			 x_source, y_source,
+			 x_mask, y_mask,
+			 x_dest, y_dest,
+			 width, height);
+	glamor_composite(PictOpAdd,
+			 source, mask, dest,
+			 x_source, y_source,
+			 x_mask, y_mask,
+			 x_dest, y_dest,
+			 width, height);
+	return;
+    }
+
+    if (!mask) {
+	if (glamor_composite_with_copy(op, source, dest,
+				       x_source, y_source,
+				       x_dest, y_dest,
+				       width, height))
+	    return;
+    }
+
+    if (glamor_composite_with_shader(op, source, mask, dest,
+				     x_source, y_source,
+				     x_mask, y_mask,
+				     x_dest, y_dest,
+				     width, height))
+	return;
+
     glamor_fallback("glamor_composite(): "
 		    "from picts %p/%p(%c,%c) to pict %p (%c)\n",
 		    source, mask,
@@ -678,8 +759,9 @@ fail:
 		    glamor_get_picture_location(mask),
 		    dest,
 		    glamor_get_picture_location(dest));
-
+fail:
     glUseProgramObjectARB(0);
+    glDisable(GL_BLEND);
     if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
 	if (source->pDrawable == NULL ||
 	    glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO))
commit a0b589e90a885cf20b349b95df31bb0823a1514b
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 22:49:27 2010 -0600

    glamor: Restore planemask to all-on when finishing a fill.

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 6290f12..1b601ee 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -172,6 +172,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glUseProgramObjectARB(0);
 fail:
     glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
 }
 
 /* Highlight places where we're doing it wrong. */
commit d8c2662bf452a82c8fcbdd1c95a40ee34d2c32ca
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 22:48:28 2010 -0600

    glamor: Set active texture in finishaccess drawing.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index ca7add4..b0a64f2 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -171,9 +171,6 @@ void
 glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				glamor_transform_uniforms *uniform_locations)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
     glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
     glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
     glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
@@ -489,6 +486,7 @@ glamor_finish_access(DrawablePtr drawable)
 		  pixmap->drawable.bitsPerPixel);
 
     glGenTextures(1, &tex);
+    glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
 		 pixmap->drawable.width, pixmap->drawable.height, 0,
commit 4f398b29dd42260d2c02e8e795546fd0623397b1
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 9 21:56:39 2010 -0600

    glamor: Align stride of fallback pixmap data to 32 bits.
    
    fb/pixman demand this alignment, and all sorts of things go badly otherwise.
    Fixes piglit x11-8bpp-7x8-draw.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7bb0934..7bc75aa 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -112,7 +112,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 			      0);
 
     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
-			       (w * pixmap->drawable.bitsPerPixel + 7) / 8,
+			       (((w * pixmap->drawable.bitsPerPixel +
+				  7) / 8) + 3) & ~3,
 			       NULL);
 
     return pixmap;
commit 15e58b5ffb427c6c6f5172ccd72758047b98024a
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 22:05:51 2010 +0100

    glamor: Split the copy path out into its own function.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 495f568..ba67d73 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -446,6 +446,49 @@ glamor_get_picture_location(PicturePtr picture)
     return glamor_get_drawable_location(picture->pDrawable);
 }
 
+static Bool
+glamor_composite_copy(CARD8 op,
+		      PicturePtr source,
+		      PicturePtr dest,
+		      INT16 x_source,
+		      INT16 y_source,
+		      INT16 x_dest,
+		      INT16 y_dest,
+		      CARD16 width,
+		      CARD16 height)
+{
+    RegionRec region;
+
+    if (!compatible_formats(op, dest, source))
+	return FALSE;
+
+    if (source->repeat || source->transform)
+	return FALSE;
+
+    x_dest += dest->pDrawable->x;
+    y_dest += dest->pDrawable->y;
+    x_source += source->pDrawable->x;
+    y_source += source->pDrawable->y;
+
+    if (!miComputeCompositeRegion(&region,
+				  source, NULL, dest,
+				  x_source, y_source,
+				  0, 0,
+				  x_dest, y_dest,
+				  width, height))
+	return TRUE;
+
+    glamor_copy_n_to_n(source->pDrawable,
+		       dest->pDrawable, NULL,
+		       REGION_RECTS(&region),
+		       REGION_NUM_RECTS(&region),
+		       x_source - x_dest, y_source - y_dest,
+		       FALSE, FALSE, 0, NULL);
+    REGION_UNINIT(dest->pDrawable->pScreen,
+		  &region);
+    return TRUE;
+}
+
 void
 glamor_composite(CARD8 op,
 		 PicturePtr source,
@@ -491,30 +534,11 @@ glamor_composite(CARD8 op,
     }
 
     if (!mask) {
-	if (compatible_formats (op, dest, source)) {
-	    if (!source->repeat && !source->transform) {
-		x_dest += dest->pDrawable->x;
-		y_dest += dest->pDrawable->y;
-		x_source += source->pDrawable->x;
-		y_source += source->pDrawable->y;
-
-		if (!miComputeCompositeRegion
-		    (&region,
-		     source, NULL, dest,
-		     x_source, y_source, 0, 0, x_dest, y_dest, width, height))
-		    return;
-
-		glamor_copy_n_to_n(source->pDrawable,
-				   dest->pDrawable, NULL,
-				   REGION_RECTS(&region),
-				   REGION_NUM_RECTS(&region),
-				   x_source - x_dest, y_source - y_dest,
-				   FALSE, FALSE, 0, NULL);
-		REGION_UNINIT(dest->pDrawable->pScreen,
-			      &region);
-		return;
-	    }
-	}
+	if (glamor_composite_copy(op, source, dest,
+				  x_source, y_source,
+				  x_dest, y_dest,
+				  width, height))
+	    return;
     }
 
     goto fail;
commit ad67299fa2afc8b42432d71d14163a36e013fef7
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 21:52:35 2010 +0100

    glamor: Provide more information about the operands to fallback composites.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index a7777fb..495f568 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -425,6 +425,27 @@ compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
     return 0;
 }
 
+static char
+glamor_get_picture_location(PicturePtr picture)
+{
+    if (picture == NULL)
+	return ' ';
+
+    if (picture->pDrawable == NULL) {
+	switch (picture->pSourcePict->type) {
+	case SourcePictTypeSolidFill:
+	    return 'c';
+	case SourcePictTypeLinear:
+	    return 'l';
+	case SourcePictTypeRadial:
+	    return 'r';
+	default:
+	    return '?';
+	}
+    }
+    return glamor_get_drawable_location(picture->pDrawable);
+}
+
 void
 glamor_composite(CARD8 op,
 		 PicturePtr source,
@@ -627,7 +648,12 @@ glamor_composite(CARD8 op,
 
 fail:
     glamor_fallback("glamor_composite(): "
-		    "from picts %p/%p to pict %p\n", source, mask, dest);
+		    "from picts %p/%p(%c,%c) to pict %p (%c)\n",
+		    source, mask,
+		    glamor_get_picture_location(source),
+		    glamor_get_picture_location(mask),
+		    dest,
+		    glamor_get_picture_location(dest));
 
     glUseProgramObjectARB(0);
     if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
commit 4811e428a9206ef59487fb0d3fab160a19845d46
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 21:46:49 2010 +0100

    glamor: Pull in UXA code for dumping some composites down to copy_n_to_n.
    
    Window dragging with metacity+gnome-terminal+xcompmgr is almost credible.

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index f9e7341..a7777fb 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -399,6 +399,32 @@ glamor_set_composite_solid(PicturePtr picture, GLint uniform_location)
     glUniform4fvARB(uniform_location, 1, color);
 }
 
+static int
+compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
+{
+    if (op == PictOpSrc) {
+	if (src->format == dst->format)
+	    return 1;
+
+	if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
+	    return 1;
+
+	if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
+	    return 1;
+    } else if (op == PictOpOver) {
+	if (src->alphaMap || dst->alphaMap)
+	    return 0;
+
+	if (src->format != dst->format)
+	    return 0;
+
+	if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
+	    return 1;
+    }
+
+    return 0;
+}
+
 void
 glamor_composite(CARD8 op,
 		 PicturePtr source,
@@ -424,8 +450,6 @@ glamor_composite(CARD8 op,
     RegionRec region;
     int i;
 
-    goto fail;
-
     /* Do two-pass PictOpOver componentAlpha, until we enable
      * dual source color blending.
      */
@@ -445,6 +469,35 @@ glamor_composite(CARD8 op,
 	return;
     }
 
+    if (!mask) {
+	if (compatible_formats (op, dest, source)) {
+	    if (!source->repeat && !source->transform) {
+		x_dest += dest->pDrawable->x;
+		y_dest += dest->pDrawable->y;
+		x_source += source->pDrawable->x;
+		y_source += source->pDrawable->y;
+
+		if (!miComputeCompositeRegion
+		    (&region,
+		     source, NULL, dest,
+		     x_source, y_source, 0, 0, x_dest, y_dest, width, height))
+		    return;
+
+		glamor_copy_n_to_n(source->pDrawable,
+				   dest->pDrawable, NULL,
+				   REGION_RECTS(&region),
+				   REGION_NUM_RECTS(&region),
+				   x_source - x_dest, y_source - y_dest,
+				   FALSE, FALSE, 0, NULL);
+		REGION_UNINIT(dest->pDrawable->pScreen,
+			      &region);
+		return;
+	    }
+	}
+    }
+
+    goto fail;
+
     memset(&key, 0, sizeof(key));
     key.has_mask = (mask != NULL);
     if (!source->pDrawable) {
commit 35847c578e9c35a3c90da792c34c1cb0cc536261
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 21:24:15 2010 +0100

    glamor: Add acceleration for copyarea not from the screen.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 7f14f2a..e07cf62 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -32,6 +32,30 @@
  * GC CopyArea implementation
  */
 
+static float
+v_from_x_coord_x(PixmapPtr pixmap, int x)
+{
+    return (float)(x - pixmap->screen_x) / pixmap->drawable.width * 2.0 - 1.0;
+}
+
+static float
+v_from_x_coord_y(PixmapPtr pixmap, int y)
+{
+    return (float)(y - pixmap->screen_y) / pixmap->drawable.height * -2.0 + 1.0;
+}
+
+static float
+t_from_x_coord_x(PixmapPtr pixmap, int x)
+{
+    return (float)(x - pixmap->screen_x) / pixmap->drawable.width;
+}
+
+static float
+t_from_x_coord_y(PixmapPtr pixmap, int y)
+{
+    return 1.0 - (float)(y - pixmap->screen_y) / pixmap->drawable.height;
+}
+
 void
 glamor_copy_n_to_n(DrawablePtr src,
 		 DrawablePtr dst,
@@ -45,16 +69,78 @@ glamor_copy_n_to_n(DrawablePtr src,
 		 Pixel		bitplane,
 		 void		*closure)
 {
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(dst->pScreen);
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int i;
+    float vertices[4][2], texcoords[4][2];
+    glamor_pixmap_private *src_pixmap_priv;
 
-    goto fail;
+    src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
 
-    glamor_set_alu(gc->alu);
-    if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+    if (src == dst) {
+	glamor_fallback("glamor_copy_n_to_n with same src/dst\n");
 	goto fail;
+    }
+
+    if (!src_pixmap_priv || !src_pixmap_priv->tex) {
+	glamor_fallback("glamor_copy_n_to_n with non-texture src\n");
+	goto fail;
+    }
+
+    if (!glamor_set_destination_pixmap(dst_pixmap))
+	goto fail;
+
+    if (gc) {
+	glamor_set_alu(gc->alu);
+	if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+	    goto fail;
+    }
+
+    glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
+    glEnable(GL_TEXTURE_2D);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
 
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    assert(GLEW_ARB_fragment_shader);
+    glUseProgramObjectARB(glamor_priv->finish_access_prog);
+
+    for (i = 0; i < nbox; i++) {
+	vertices[0][0] = v_from_x_coord_x(dst_pixmap, box[i].x1);
+	vertices[0][1] = v_from_x_coord_y(dst_pixmap, box[i].y1);
+	vertices[1][0] = v_from_x_coord_x(dst_pixmap, box[i].x2);
+	vertices[1][1] = v_from_x_coord_y(dst_pixmap, box[i].y1);
+	vertices[2][0] = v_from_x_coord_x(dst_pixmap, box[i].x2);
+	vertices[2][1] = v_from_x_coord_y(dst_pixmap, box[i].y2);
+	vertices[3][0] = v_from_x_coord_x(dst_pixmap, box[i].x1);
+	vertices[3][1] = v_from_x_coord_y(dst_pixmap, box[i].y2);
+
+	texcoords[0][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
+	texcoords[0][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
+	texcoords[1][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
+	texcoords[1][1] = t_from_x_coord_y(src_pixmap, box[i].y1 + dy);
+	texcoords[2][0] = t_from_x_coord_x(src_pixmap, box[i].x2 + dx);
+	texcoords[2][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
+	texcoords[3][0] = t_from_x_coord_x(src_pixmap, box[i].x1 + dx);
+	texcoords[3][1] = t_from_x_coord_y(src_pixmap, box[i].y2 + dy);
+	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    glUseProgramObjectARB(0);
+
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisable(GL_TEXTURE_2D);
+
+#if 0
     for (i = 0; i < nbox; i++) {
 	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x,
 		      box[i].y1 - dst_pixmap->screen_y);
@@ -64,9 +150,12 @@ glamor_copy_n_to_n(DrawablePtr src,
 		     box[i].y2 - box[i].y1,
 		     GL_COLOR);
     }
+#endif
+
+    return;
 
 fail:
-    glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
+    glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst,
 		    glamor_get_drawable_location(src),
 		    glamor_get_drawable_location(dst));
     if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
@@ -89,31 +178,9 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     ScreenPtr screen = dst->pScreen;
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
     RegionPtr region;
 
-    if (!GLEW_EXT_framebuffer_blit) {
-	glamor_fallback("glamor_copy_area(): "
-			"EXT_framebuffer_blit unsupported\n");
-	goto fail;
-    }
-
-    if (!glamor_set_destination_pixmap(dst_pixmap))
-	goto fail;
-
-    if (src_priv == NULL) {
-	glamor_fallback("glamor_copy_area(): no src pixmap priv");
-	goto fail;
-    }
-
-    if (src_priv->fb == 0 && src_pixmap != screen_pixmap) {
-	glamor_fallback("glamor_copy_area(): no src fbo");
-	goto fail;
-    }
-
-    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb);
-
     region = miDoCopy(src, dst, gc,
 		      srcx, srcy, width, height,
 		      dstx, dsty, glamor_copy_n_to_n, 0, NULL);
commit 647b9fb49a5bb636c9b0da6b708083328238543a
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 20:12:44 2010 +0100

    glamor: Add CopyWindow implementation so it doesn't crash.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index ce78692..17139c0 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -18,6 +18,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
 libglamor_la_SOURCES = \
 	glamor.c \
 	glamor_copyarea.c \
+	glamor_copywindow.c \
 	glamor_core.c \
 	glamor_fill.c \
 	glamor_fillspans.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index ba16d63..7bb0934 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -210,6 +210,9 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes;
     screen->ChangeWindowAttributes = glamor_change_window_attributes;
 
+    glamor_priv->saved_copy_window = screen->CopyWindow;
+    screen->CopyWindow = glamor_copy_window;
+
     glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion;
     screen->BitmapToRegion = glamor_bitmap_to_region;
 
@@ -247,6 +250,7 @@ glamor_fini(ScreenPtr screen)
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
     screen->GetSpans = glamor_priv->saved_get_spans;
     screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes;
+    screen->CopyWindow = glamor_priv->saved_copy_window;
     screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
 #ifdef RENDER
     ps->Composite = glamor_priv->saved_composite;
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index b0f6a7e..7f14f2a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -32,7 +32,7 @@
  * GC CopyArea implementation
  */
 
-static void
+void
 glamor_copy_n_to_n(DrawablePtr src,
 		 DrawablePtr dst,
 		 GCPtr gc,
@@ -49,6 +49,8 @@ glamor_copy_n_to_n(DrawablePtr src,
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
     int i;
 
+    goto fail;
+
     glamor_set_alu(gc->alu);
     if (!glamor_set_planemask(dst_pixmap, gc->planemask))
 	goto fail;
@@ -64,6 +66,18 @@ glamor_copy_n_to_n(DrawablePtr src,
     }
 
 fail:
+    glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
+		    glamor_get_drawable_location(src),
+		    glamor_get_drawable_location(dst));
+    if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+	    fbCopyNtoN(src, dst, gc, box, nbox,
+		       dx, dy, reverse, upsidedown, bitplane,
+		       closure);
+	    glamor_finish_access(src);
+	}
+	glamor_finish_access(dst);
+    }
     glamor_set_alu(GXcopy);
     glamor_set_planemask(dst_pixmap, ~0);
 }
@@ -79,8 +93,6 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
     RegionPtr region;
 
-    goto fail;
-
     if (!GLEW_EXT_framebuffer_blit) {
 	glamor_fallback("glamor_copy_area(): "
 			"EXT_framebuffer_blit unsupported\n");
diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c
new file mode 100644
index 0000000..1e840a9
--- /dev/null
+++ b/glamor/glamor_copywindow.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_copywindow.c
+ *
+ * Screen CopyWindow implementation.
+ */
+
+void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
+			RegionPtr src_region)
+{
+    RegionRec dst_region;
+    int dx, dy;
+    PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
+
+    dx = old_origin.x - win->drawable.x;
+    dy = old_origin.y - win->drawable.y;
+    REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
+
+    REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
+
+    REGION_INTERSECT(win->drawable.pScreen, &dst_region, &win->borderClip,
+		     src_region);
+#ifdef COMPOSITE
+    if (pixmap->screen_x || pixmap->screen_y)
+	REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
+			 -pixmap->screen_x, -pixmap->screen_y);
+#endif
+
+    miCopyRegion(&pixmap->drawable, &pixmap->drawable,
+		 NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL);
+
+    REGION_UNINIT(win->drawable.pScreen, &dst_region);
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index dc3b778..adc6997 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -61,6 +61,7 @@ typedef struct glamor_screen_private {
     CompositeProcPtr saved_composite;
     TrapezoidsProcPtr saved_trapezoids;
     ChangeWindowAttributesProcPtr saved_change_window_attributes;
+    CopyWindowProcPtr saved_copy_window;
     BitmapToRegionProcPtr saved_bitmap_to_region;
 
     /* glamor_finishaccess */
@@ -138,6 +139,23 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		 int srcx, int srcy, int width, int height, int dstx, int dsty);
+void
+glamor_copy_n_to_n(DrawablePtr src,
+		   DrawablePtr dst,
+		   GCPtr gc,
+		   BoxPtr box,
+		   int nbox,
+		   int		dx,
+		   int		dy,
+		   Bool		reverse,
+		   Bool		upsidedown,
+		   Pixel		bitplane,
+		   void		*closure);
+
+/* glamor_copywindow.c */
+void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
+			RegionPtr src_region);
+
 /* glamor_core.c */
 Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
 void glamor_finish_access(DrawablePtr drawable);
commit 95d4a5a6ab58625d8205461157263bfb635ccd1a
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 19:38:00 2010 +0100

    glamor: Enable fill acceleration and flip opposite for pixmaps too.
    
    Here's my theory for the flipping: It doesn't really matter which
    orientation we store the pixmaps if we don't scan them out.  We have
    to flip coordinates for the window system framebuffer.  Doing so for
    everything else makes things consistent.  I'm not sure how this will
    interact with future GLX integration, though.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4ec8540..ca7add4 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -177,12 +177,7 @@ glamor_set_transform_for_pixmap(PixmapPtr pixmap,
     glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
     glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
     glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
-    if (pixmap == screen_pixmap)
-	glUniform1fARB(uniform_locations->y_scale,
-		       -2.0f / pixmap->drawable.height);
-    else
-	glUniform1fARB(uniform_locations->y_scale,
-		       2.0f / pixmap->drawable.height);
+    glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
 }
 
 GLint
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index b3418a9..6290f12 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -42,8 +42,6 @@ glamor_fill(DrawablePtr drawable,
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
 
-    assert(0);
-
     switch (gc->fillStyle) {
     case FillSolid:
 	glamor_solid(dst_pixmap,
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index dc3c0e6..62e0a0f 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -52,7 +52,8 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     int		    xorg, yorg;
     int		    n;
 
-    goto fail;
+    if (gc->fillStyle != FillSolid)
+	goto fail;
 
     xorg = drawable->x;
     yorg = drawable->y;
commit 5332547a0ac6ae6b9f1a6c6428e6fdbdf303108f
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 17:14:34 2010 +0100

    glamor: Fix prepare_access on 1bpp data.
    
    Apparently I don't have anything hitting this path, so I'm not sure if
    it's good or not.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4d03bd7..4ec8540 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -351,15 +351,16 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	    for (y = 0; y < pixmap->drawable.height; y++) {
 		uint8_t *read_row = read +
 		    read_stride * (pixmap->drawable.height - y - 1);
+		uint8_t *write_row = data + y * stride;
 
 		for (x = 0; x < pixmap->drawable.width; x++) {
 		    int index = x / 8;
 		    int bit = 1 << (x % 8);
 
 		    if (read_row[x])
-			data[index] |= bit;
+			write_row[index] |= bit;
 		    else
-			data[index] &= ~bit;
+			write_row[index] &= ~bit;
 		}
 	    }
 	} else {
commit c3c3a6349766b4fdee080ff203fb548725e42e50
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 15:34:45 2010 +0100

    glamor: Use the pixmap stride in fallbacks instead of trying to guess it.
    
    Mostly fixes gnome-terminal text.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index f35baaf..4d03bd7 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -293,7 +293,7 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	    return TRUE;
     }
 
-    stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
+    stride = pixmap->devKind;
     read_stride = stride;
 
     data = xalloc(stride * pixmap->drawable.height);
@@ -476,7 +476,7 @@ glamor_finish_access(DrawablePtr drawable)
 	return;
     }
 
-    stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
+    stride = pixmap->devKind;
 
     glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
     glEnableClientState(GL_VERTEX_ARRAY);
commit 45de3d24b44aa3feabdda0e377d637f498e03eb0
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 14:40:06 2010 +0100

    glamor: Replace the glDrawPixels in glamor_finish_access with GLSL.
    
    Root weave displays. \o/

diff --git a/glamor/glamor.c b/glamor/glamor.c
index a2cd02a..ba16d63 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -224,6 +224,7 @@ glamor_init(ScreenPtr screen)
     glamor_init_tile_shader(screen);
     glamor_init_putimage_shaders(screen);
     glamor_init_composite_shaders(screen);
+    glamor_init_finish_access_shaders(screen);
 
     return TRUE;
 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 9d0e40f..f35baaf 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -379,12 +379,66 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 }
 
 void
+glamor_init_finish_access_shaders(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    const char *vs_source =
+	"void main()\n"
+	"{\n"
+	"	gl_Position = gl_Vertex;\n"
+	"	gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+	"}\n";
+    const char *fs_source =
+	"varying vec2 texcoords;\n"
+	"uniform sampler2D sampler;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
+	"}\n";
+    GLint fs_prog, vs_prog;
+
+    glamor_priv->finish_access_prog = glCreateProgramObjectARB();
+    if (GLEW_ARB_fragment_shader) {
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
+	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
+	glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog);
+    } else {
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+	glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
+    }
+
+    glamor_link_glsl_prog(glamor_priv->finish_access_prog);
+
+    if (GLEW_ARB_fragment_shader) {
+	GLint sampler_uniform_location;
+
+	sampler_uniform_location =
+	    glGetUniformLocationARB(glamor_priv->finish_access_prog, "sampler");
+	glUseProgramObjectARB(glamor_priv->finish_access_prog);
+	glUniform1iARB(sampler_uniform_location, 0);
+	glUseProgramObjectARB(0);
+    }
+}
+
+void
 glamor_finish_access(DrawablePtr drawable)
 {
+    glamor_screen_private *glamor_priv =
+	glamor_get_screen_private(drawable->pScreen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     unsigned int stride;
     GLenum format, type;
+    static float vertices[4][2] = {{-1, -1},
+				   { 1, -1},
+				   { 1,  1},
+				   {-1,  1}};
+    static float texcoords[4][2] = {{0, 1},
+				    {1, 1},
+				    {1, 0},
+				    {0, 0}};
+    GLuint tex;
 
     if (pixmap_priv == NULL)
 	return;
@@ -397,6 +451,10 @@ glamor_finish_access(DrawablePtr drawable)
 	    return;
     }
 
+    /* Check if finish_access was already called once on this */
+    if (pixmap->devPrivate.ptr == NULL)
+	return;
+
     switch (drawable->depth) {
     case 1:
 	format = GL_COLOR_INDEX;
@@ -420,18 +478,44 @@ glamor_finish_access(DrawablePtr drawable)
 
     stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
 
+    glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+    glEnableClientState(GL_VERTEX_ARRAY);
+
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
+
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
 
-    glRasterPos2i(0, 0);
-    glDrawPixels(pixmap->drawable.width, pixmap->drawable.height,
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+		 pixmap->drawable.width, pixmap->drawable.height, 0,
 		 format, type, pixmap->devPrivate.ptr);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glEnable(GL_TEXTURE_2D);
+
+    assert(GLEW_ARB_fragment_shader);
+    glUseProgramObjectARB(glamor_priv->finish_access_prog);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+    glDisable(GL_TEXTURE_2D);
+    glUseProgramObjectARB(0);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDeleteTextures(1, &tex);
 
     xfree(pixmap->devPrivate.ptr);
     pixmap->devPrivate.ptr = NULL;
 }
+
 /**
  * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
  * current fill style.
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2045ed6..dc3b778 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -63,6 +63,9 @@ typedef struct glamor_screen_private {
     ChangeWindowAttributesProcPtr saved_change_window_attributes;
     BitmapToRegionProcPtr saved_bitmap_to_region;
 
+    /* glamor_finishaccess */
+    GLint finish_access_prog;
+
     /* glamor_solid */
     GLint solid_prog;
     GLint solid_color_uniform_location;
@@ -142,6 +145,7 @@ Bool glamor_prepare_access_window(WindowPtr window);
 void glamor_finish_access_window(WindowPtr window);
 Bool glamor_prepare_access_gc(GCPtr gc);
 void glamor_finish_access_gc(GCPtr gc);
+void glamor_init_finish_access_shaders(ScreenPtr screen);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
commit d8d3fa10346302384b8e62967c5a67893ed1c67b
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 14:53:41 2010 +0100

    glamor: All the fallbacks in the world.
    
    Bringup is really not flying when I can't see anything.  So dump back
    to all software so I can turn on a bit at a time.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 077c44f..b0f6a7e 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -79,6 +79,8 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
     RegionPtr region;
 
+    goto fail;
+
     if (!GLEW_EXT_framebuffer_blit) {
 	glamor_fallback("glamor_copy_area(): "
 			"EXT_framebuffer_blit unsupported\n");
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 6290f12..b3418a9 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -42,6 +42,8 @@ glamor_fill(DrawablePtr drawable,
 {
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
 
+    assert(0);
+
     switch (gc->fillStyle) {
     case FillSolid:
 	glamor_solid(dst_pixmap,
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index 120e346..9b070ec 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -45,6 +45,8 @@ glamor_fill_spans(DrawablePtr drawable,
     int fullX1, fullX2, fullY1;
     int partX1, partX2;
 
+    goto fail;
+
     extents = REGION_EXTENTS(gc->pScreen, clip);
     extentX1 = extents->x1;
     extentY1 = extents->y1;
@@ -97,4 +99,15 @@ glamor_fill_spans(DrawablePtr drawable,
 	    }
 	}
     }
+    return;
+fail:
+    glamor_fallback("to %p (%c)\n", drawable,
+		    glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access_gc(gc)) {
+	    fbFillSpans(drawable, gc, n, points, widths, sorted);
+	    glamor_finish_access_gc(gc);
+	}
+	glamor_finish_access(drawable);
+    }
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 8339eb1..6e92b4d 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -56,6 +56,8 @@ glamor_get_spans(DrawablePtr drawable,
     int i, j;
     uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
 
+    goto fail;
+
     switch (drawable->depth) {
     case 1:
 	temp_dst = xalloc(wmax);
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
index ae8963d..dc3c0e6 100644
--- a/glamor/glamor_polyfillrect.c
+++ b/glamor/glamor_polyfillrect.c
@@ -52,6 +52,8 @@ glamor_poly_fill_rect(DrawablePtr drawable,
     int		    xorg, yorg;
     int		    n;
 
+    goto fail;
+
     xorg = drawable->x;
     yorg = drawable->y;
 
@@ -115,4 +117,17 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 	    }
 	}
     }
+    return;
+
+fail:
+    glamor_fallback("glamor_poly_fill_rect() to %p (%c)\n",
+		    drawable, glamor_get_drawable_location(drawable));
+
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access_gc(gc)) {
+	    fbPolyFillRect(drawable, gc, nrect, prect );
+	    glamor_finish_access_gc(gc);
+	}
+	glamor_finish_access(drawable);
+    }
 }
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 39f120e..5379921 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -245,6 +245,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int bpp = drawable->bitsPerPixel;
     int src_stride = PixmapBytePad(w, drawable->depth);
 
+    goto fail;
+
     if (!glamor_set_destination_pixmap(pixmap)) {
 	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
 		   image_format, bits);
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index b6f6b86..f9e7341 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -424,6 +424,8 @@ glamor_composite(CARD8 op,
     RegionRec region;
     int i;
 
+    goto fail;
+
     /* Do two-pass PictOpOver componentAlpha, until we enable
      * dual source color blending.
      */
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 0bd0ac1..32f7bc5 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -43,6 +43,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     RegionPtr clip = fbGetCompositeClip(gc);
     BoxRec *pbox;
 
+    goto fail;
+
     for (i = 0 ; i < n; i++) {
 	if (wmax < widths[i])
 	    wmax = widths[i];
commit 745502af962a2bb475c0c667c3091c2c080771dc
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 13:27:47 2010 +0100

    glamor: Add check for EXT_bgra which we rely on.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 507a19b..a2cd02a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -181,6 +181,10 @@ glamor_init(ScreenPtr screen)
 	ErrorF("GL_ARB_pixel_buffer_object required\n");
 	goto fail;
     }
+    if (!GLEW_EXT_bgra) {
+	ErrorF("GL_EXT_bgra required\n");
+	goto fail;
+    }
 
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
commit 6ce378f11ff396f350cbaa280086f6f9600da29e
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 13:15:38 2010 +0100

    glamor: Add fallback support for glamor_get_spans().

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 76c6cce..8339eb1 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -76,14 +76,13 @@ glamor_get_spans(DrawablePtr drawable,
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 	break;
     default:
-	ErrorF("Unknown getspans depth %d\n", drawable->depth);
-	return;
+	glamor_fallback("glamor_get_spans(): "
+			"Unknown getspans depth %d\n", drawable->depth);
+	goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(pixmap)) {
-	fbGetSpans(drawable, wmax, points, widths, count, dst);
-	return;
-    }
+    if (!glamor_set_destination_pixmap(pixmap))
+	goto fail;
 
     for (i = 0; i < count; i++) {
 	glReadPixels(points[i].x - pixmap->screen_x,
@@ -102,4 +101,14 @@ glamor_get_spans(DrawablePtr drawable,
 	}
     }
     xfree(temp_dst);
+    return;
+
+fail:
+    free(temp_dst);
+    glamor_fallback("glamor_get_spans() from %p (%c)\n", drawable,
+		    glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
+	fbGetSpans(drawable, wmax, points, widths, count, dst);
+	glamor_finish_access(drawable);
+    }
 }
commit ec526eab8f02e0bcce859a1b7ebaf6c5bccc5e87
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 13:05:13 2010 +0100

    ephyr: Hook the glamor into damage and draw into the backbuffer.
    
    This should avoid a bunch of absurdity with GLX front buffer handling,
    fix exposes, and improve performance.  For now we're copying the whole
    buffer while glamor is developed.

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 16959d7..1aacc5f 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -395,9 +395,6 @@ ephyrSetInternalDamage (ScreenPtr pScreen)
   EphyrScrPriv	*scrpriv = screen->driver;
   PixmapPtr      pPixmap = NULL;
 
-  if (ephyrFuncs.initAccel == ephyr_glamor_init)
-      return TRUE;
-
   scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
 				   (DamageDestroyFunc) 0,
 				   DamageReportNone,
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index cd15212..9dcde8d 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -201,6 +201,7 @@ Bool ephyr_glamor_init(ScreenPtr pScreen);
 void ephyr_glamor_enable(ScreenPtr pScreen);
 void ephyr_glamor_disable(ScreenPtr pScreen);
 void ephyr_glamor_fini(ScreenPtr pScreen);
+void ephyr_glamor_host_paint_rect(ScreenPtr pScreen);
 
 /*ephyvideo.c*/
 
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index c7c7929..15dfc70 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -767,6 +767,11 @@ hostx_screen_init (EphyrScreenInfo screen,
 static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
                                     int x,     int y,
                                     int width, int height);
+static void
+ephyr_glamor_paint_rect (EphyrScreenInfo screen,
+			 int sx,    int sy,
+			 int dx,    int dy,
+			 int width, int height);
 
 void
 hostx_paint_rect (EphyrScreenInfo screen,
@@ -778,6 +783,11 @@ hostx_paint_rect (EphyrScreenInfo screen,
 
   EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
 
+  if (ephyr_glamor) {
+      ephyr_glamor_paint_rect(screen, sx, sy, dx, dy, width, height);
+      return;
+  }
+
   /*
    *  Copy the image data updated by the shadow layer
    *  on to the window
@@ -1464,6 +1474,7 @@ ephyr_glamor_get_visual(void)
 		     GLX_RED_SIZE, 1,
 		     GLX_GREEN_SIZE, 1,
 		     GLX_BLUE_SIZE, 1,
+		     GLX_DOUBLEBUFFER, 1,
 		     None};
     XVisualInfo *visual_info;
     int event_base = 0, error_base = 0;
@@ -1495,3 +1506,29 @@ ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
     if (!glXMakeCurrent(dpy, host_screen->win, ctx))
 	errx(1, "glXMakeCurrent failed\n");
 }
+
+static void
+ephyr_glamor_paint_rect (EphyrScreenInfo screen,
+			 int sx,    int sy,
+			 int dx,    int dy,
+			 int width, int height)
+{
+    struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+    static PFNGLXCOPYSUBBUFFERMESAPROC pglXCopySubBufferMESA = NULL;
+
+    if (!pglXCopySubBufferMESA) {
+	pglXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)
+	    glXGetProcAddressARB((const GLubyte*)"glXCopySubBufferMESA");
+	assert(pglXCopySubBufferMESA);
+    }
+
+    /* Always copy the full screen until we get things rendering correctly. */
+#if 0
+    pglXCopySubBufferMESA(HostX.dpy, host_screen->win,
+			  sx, sy, width, height);
+#else
+    pglXCopySubBufferMESA(HostX.dpy, host_screen->win,
+			  0, 0,
+			  host_screen->win_width, host_screen->win_height);
+#endif
+}
commit b5087ff9b1e5495c742e581f586c055de878dd4b
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 12:47:59 2010 +0100

    glamor: Fix the row length of 1bpp prepare_access.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index b0653d8..9d0e40f 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -323,9 +323,12 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
-		  pixmap->drawable.bitsPerPixel);
-
+    if (drawable->depth != 1) {
+	glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
+		      pixmap->drawable.bitsPerPixel);
+    } else {
+	glPixelStorei(GL_PACK_ROW_LENGTH, read_stride);
+    }
     if (GLEW_MESA_pack_invert && drawable->depth != 1) {
 	glPixelStorei(GL_PACK_INVERT_MESA, 1);
 	glReadPixels(0, 0,
commit e93070affdf64c47be02684e7902a61e7ae9fa33
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 12:44:03 2010 +0100

    glamor: Fix up the access flags for glamor_prepare_access().

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 431cb41..b0653d8 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -337,12 +337,12 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
 	glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
 			read_stride * pixmap->drawable.height,
-			NULL, GL_DYNAMIC_DRAW_ARB);
+			NULL, GL_STREAM_READ_ARB);
 	glReadPixels(0, 0,
 		     pixmap->drawable.width, pixmap->drawable.height,
 		     format, type, 0);
 
-	read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
+	read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY_ARB);
 
 	if (pixmap->drawable.depth == 1) {
 	    for (y = 0; y < pixmap->drawable.height; y++) {
commit 0e56c182c3b06f5b02d357e2b8e930a580bd0274
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 12:16:30 2010 +0100

    glamor: Add fallback support to glamor_put_image().

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 55854da..39f120e 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -224,7 +224,13 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
 fail:
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
-    glamor_solid_fail_region(pixmap, x, y, w, h);
+
+    glamor_fallback("glamor_put_image(): to %p (%c)\n",
+		    drawable, glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits);
+	glamor_finish_access(drawable);
+    }
 }
 
 void
@@ -331,5 +337,11 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 fail:
     glamor_set_planemask(pixmap, ~0);
-    glamor_solid_fail_region(pixmap, x, y, w, h);
+    glamor_fallback("glamor_put_image(): to %p (%c)\n",
+		    drawable, glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format,
+		   bits);
+	glamor_finish_access(drawable);
+    }
 }
commit 22cad98975091ed724a37ec940946cd2899ebcbf
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 12:13:15 2010 +0100

    glamor: Add fallback support to glamor_set_spans().

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 66ec3da..0bd0ac1 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -68,8 +68,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
 	break;
     default:
-	ErrorF("Unknown setspans depth %d\n", drawable->depth);
-	return;
+	glamor_fallback("glamor_set_spans()Unknown depth %d\n",
+			drawable->depth);
+	goto fail;
     }
 
     if (!glamor_set_destination_pixmap(dest_pixmap))
@@ -117,4 +118,11 @@ fail:
     glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
     xfree(temp_src);
+
+    glamor_fallback("glamor_set_spans(): to %p (%c)\n",
+		    drawable, glamor_get_drawable_location(drawable));
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
+	glamor_finish_access(drawable);
+    }
 }
commit 55dac9b42e18dcc1586770d31ee265178e68b744
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 12:09:52 2010 +0100

    glamor: Add glamor_prepare_access_gc() from UXA.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 5afbf39..431cb41 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -429,6 +429,42 @@ glamor_finish_access(DrawablePtr drawable)
     xfree(pixmap->devPrivate.ptr);
     pixmap->devPrivate.ptr = NULL;
 }
+/**
+ * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
+ * current fill style.
+ *
+ * Solid doesn't use an extra pixmap source, so we don't worry about them.
+ * Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry
+ * about them.
+ */
+Bool
+glamor_prepare_access_gc(GCPtr gc)
+{
+    if (gc->stipple)
+	if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
+	    return FALSE;
+    if (gc->fillStyle == FillTiled) {
+	if (!glamor_prepare_access (&gc->tile.pixmap->drawable,
+				    GLAMOR_ACCESS_RO)) {
+	    if (gc->stipple)
+		glamor_finish_access(&gc->stipple->drawable);
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+/**
+ * Finishes access to the tile in the GC, if used.
+ */
+void
+glamor_finish_access_gc(GCPtr gc)
+{
+	if (gc->fillStyle == FillTiled)
+		glamor_finish_access(&gc->tile.pixmap->drawable);
+	if (gc->stipple)
+		glamor_finish_access(&gc->stipple->drawable);
+}
 
 void
 glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b470be5..2045ed6 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -140,6 +140,8 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
 void glamor_finish_access(DrawablePtr drawable);
 Bool glamor_prepare_access_window(WindowPtr window);
 void glamor_finish_access_window(WindowPtr window);
+Bool glamor_prepare_access_gc(GCPtr gc);
+void glamor_finish_access_gc(GCPtr gc);
 const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
commit 72a757ba00232fe8b42b977f5210fa119495b05e
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 11:58:52 2010 +0100

    glamor: Use GL_MESA_pack_invert to avoid complexity in prepare_access.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 32a09b6..5afbf39 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -293,25 +293,24 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	    return TRUE;
     }
 
-    stride = PixmapBytePad(drawable->width, drawable->depth);
+    stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
     read_stride = stride;
 
-    data = xalloc(stride * drawable->height);
+    data = xalloc(stride * pixmap->drawable.height);
 
     switch (drawable->depth) {
     case 1:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
-	read_stride = drawable->width;
+	read_stride = pixmap->drawable.width;
 	break;
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
 	break;
     case 24:
-	format = GL_RGB;
-	type = GL_UNSIGNED_BYTE;
-	break;
+	assert(drawable->bitsPerPixel == 32);
+	/* FALLTHROUGH */
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -323,47 +322,55 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     }
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glGenBuffersARB(1, &pixmap_priv->pbo);
-    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-    glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
-		    read_stride * pixmap->drawable.height,
-		    NULL, GL_DYNAMIC_DRAW_ARB);
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
     glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
 
-    glReadPixels(0, 0,
-		 pixmap->drawable.width, pixmap->drawable.height,
-		 format, type, 0);
-
-    read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
-
-    if (pixmap->drawable.depth == 1) {
-	for (y = 0; y < pixmap->drawable.height; y++) {
-	    uint8_t *read_row = read + read_stride * (pixmap->drawable.height -
-						      y - 1);
-
-	    for (x = 0; x < pixmap->drawable.width; x++) {
-		int index = x / 8;
-		int bit = 1 << (x % 8);
-
-		if (read_row[x])
-		    data[index] |= bit;
-		else
-		    data[index] &= ~bit;
+    if (GLEW_MESA_pack_invert && drawable->depth != 1) {
+	glPixelStorei(GL_PACK_INVERT_MESA, 1);
+	glReadPixels(0, 0,
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     format, type, data);
+	glPixelStorei(GL_PACK_INVERT_MESA, 0);
+    } else {
+	glGenBuffersARB(1, &pixmap_priv->pbo);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+	glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
+			read_stride * pixmap->drawable.height,
+			NULL, GL_DYNAMIC_DRAW_ARB);
+	glReadPixels(0, 0,
+		     pixmap->drawable.width, pixmap->drawable.height,
+		     format, type, 0);
+
+	read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
+
+	if (pixmap->drawable.depth == 1) {
+	    for (y = 0; y < pixmap->drawable.height; y++) {
+		uint8_t *read_row = read +
+		    read_stride * (pixmap->drawable.height - y - 1);
+
+		for (x = 0; x < pixmap->drawable.width; x++) {
+		    int index = x / 8;
+		    int bit = 1 << (x % 8);
+
+		    if (read_row[x])
+			data[index] |= bit;
+		    else
+			data[index] &= ~bit;
+		}
 	    }
+	} else {
+	    for (y = 0; y < pixmap->drawable.height; y++)
+		memcpy(data + y * stride,
+		       read + (pixmap->drawable.height - y - 1) * stride, stride);
 	}
-    } else {
-	for (y = 0; y < pixmap->drawable.height; y++)
-	    memcpy(data + y * stride,
-		   read + (pixmap->drawable.height - y - 1) * stride, stride);
+	glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
+	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
+	glDeleteBuffersARB(1, &pixmap_priv->pbo);
+	pixmap_priv->pbo = 0;
     }
-    pixmap->devPrivate.ptr = data;
 
-    glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
-    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
-    glDeleteBuffersARB(1, &pixmap_priv->pbo);
-    pixmap_priv->pbo = 0;
+    pixmap->devPrivate.ptr = data;
 
     return TRUE;
 }
@@ -397,9 +404,8 @@ glamor_finish_access(DrawablePtr drawable)
 	type = GL_UNSIGNED_BYTE;
 	break;
     case 24:
-	format = GL_RGB;
-	type = GL_UNSIGNED_BYTE;
-	break;
+	assert(drawable->bitsPerPixel == 32);
+	/* FALLTHROUGH */
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -409,7 +415,7 @@ glamor_finish_access(DrawablePtr drawable)
 	return;
     }
 
-    stride = PixmapBytePad(drawable->width, drawable->depth);
+    stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
commit e9d4794cd0bc6c8790204405fe09f968edfa409d
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 11:23:14 2010 +0100

    glamor: Add fallbacks for Render.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2ee16ef..b470be5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -123,8 +123,8 @@ glamor_fallback(char *format, ...)
     va_list ap;
 
     va_start(ap, format);
-    LogMessageVerb(X_INFO, 1, "glamor fallback: ");
-    LogVMessageVerb(X_INFO, 1, format, ap);
+    LogMessageVerb(X_INFO, 0, "fallback: ");
+    LogVMessageVerb(X_NONE, 0, format, ap);
     va_end(ap);
 }
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2ebb4c5..b6f6b86 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -25,7 +25,6 @@
  *
  */
 
-
 /** @file glamor_render.c
  *
  * Render acceleration implementation
@@ -35,6 +34,7 @@
 
 #ifdef RENDER
 #include "mipict.h"
+#include "fbpict.h"
 
 #include "glu3/glu3.h"
 
@@ -474,11 +474,11 @@ glamor_composite(CARD8 op,
 	source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
 	source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 	if (source_pixmap == dest_pixmap) {
-	    ErrorF("source == dest\n");
+	    glamor_fallback("glamor_composite(): source == dest\n");
 	    goto fail;
 	}
 	if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
-	    ErrorF("no FBO in source\n");
+	    glamor_fallback("glamor_composite(): no FBO in source\n");
 	    goto fail;
 	}
     }
@@ -486,18 +486,19 @@ glamor_composite(CARD8 op,
 	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 	if (mask_pixmap == dest_pixmap) {
-	    ErrorF("mask == dest\n");
+	    glamor_fallback("glamor_composite(): mask == dest\n");
 	    goto fail;
 	}
 	if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) {
-	    ErrorF("no FBO in mask\n");
+	    glamor_fallback("glamor_composite(): no FBO in mask\n");
 	    goto fail;
 	}
     }
 
     shader = glamor_lookup_composite_shader(screen, &key);
     if (shader->prog == 0) {
-	ErrorF("No program compiled for this render accel mode\n");
+	glamor_fallback("glamor_composite(): "
+			"no shader program for this render acccel mode\n");
 	goto fail;
     }
 
@@ -570,9 +571,31 @@ glamor_composite(CARD8 op,
     return;
 
 fail:
-    glamor_set_composite_op(screen, PictOpSrc, dest, mask);
+    glamor_fallback("glamor_composite(): "
+		    "from picts %p/%p to pict %p\n", source, mask, dest);
+
     glUseProgramObjectARB(0);
-    glamor_solid_fail_region(dest_pixmap, x_dest, y_dest, width, height);
+    if (glamor_prepare_access(dest->pDrawable, GLAMOR_ACCESS_RW)) {
+	if (source->pDrawable == NULL ||
+	    glamor_prepare_access(source->pDrawable, GLAMOR_ACCESS_RO))
+	{
+	    if (!mask || mask->pDrawable == NULL ||
+		glamor_prepare_access(mask->pDrawable, GLAMOR_ACCESS_RO))
+	    {
+		fbComposite(op,
+			    source, mask, dest,
+			    x_source, y_source,
+			    x_mask, y_mask,
+			    x_dest, y_dest,
+			    width, height);
+		if (mask && mask->pDrawable != NULL)
+		    glamor_finish_access(mask->pDrawable);
+	    }
+	    if (source->pDrawable != NULL)
+		glamor_finish_access(source->pDrawable);
+	}
+	glamor_finish_access(dest->pDrawable);
+    }
 }
 
 
commit de675893b7ce2880289cce13be6190d55f4fc29c
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 10:16:21 2010 +0100

    glamor: Add fallbacks for glamor_copy_area().

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index c89dffc..077c44f 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -80,27 +80,22 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     RegionPtr region;
 
     if (!GLEW_EXT_framebuffer_blit) {
-	ErrorF("EXT_framebuffer_blit unsupported\n");
+	glamor_fallback("glamor_copy_area(): "
+			"EXT_framebuffer_blit unsupported\n");
 	goto fail;
     }
 
-    if (!glamor_set_destination_pixmap(dst_pixmap)) {
-	/*
-	return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
-			srcx, srcy, width, height,
-			dstx, dsty, fbCopyNtoN, 0, NULL);
-	*/
-	return NULL;
-    }
+    if (!glamor_set_destination_pixmap(dst_pixmap))
+	goto fail;
 
     if (src_priv == NULL) {
-	ErrorF("glamor_copy_area: no src pixmap priv?");
+	glamor_fallback("glamor_copy_area(): no src pixmap priv");
 	goto fail;
     }
 
     if (src_priv->fb == 0 && src_pixmap != screen_pixmap) {
-	ErrorF("glamor_copy_area: No src FBO\n");
-	return NULL;
+	glamor_fallback("glamor_copy_area(): no src fbo");
+	goto fail;
     }
 
     glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb);
@@ -112,5 +107,17 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     return region;
 
 fail:
-    return NULL;
+    glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst,
+		    glamor_get_drawable_location(src),
+		    glamor_get_drawable_location(dst));
+    region = NULL;
+    if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
+	if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
+	    region = fbCopyArea(src, dst, gc, srcx, srcy, width, height,
+				dstx, dsty);
+	    glamor_finish_access(src);
+	}
+	glamor_finish_access(dst);
+    }
+    return region;
 }
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 4ae0d6c..32a09b6 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -39,13 +39,26 @@
 
 #include "glamor_priv.h"
 
+const Bool
+glamor_get_drawable_location(const DrawablePtr drawable)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (pixmap_priv == NULL)
+	return 'm';
+    if (pixmap_priv->fb == 0)
+	return 's';
+    else
+	return 'f';
+}
+
 Bool
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 
     if (pixmap_priv == NULL) {
-	ErrorF("no pixmap priv?");
+	glamor_fallback("glamor_set_destination_pixmap(): no pixmap priv");
 	return FALSE;
     }
 
@@ -54,7 +67,7 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
 	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
 
 	if (pixmap != screen_pixmap) {
-	    ErrorF("No FBO\n");
+	    glamor_fallback("glamor_set_destination_pixmap(): no fbo");
 	    return FALSE;
 	}
     }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ad68c12..2ee16ef 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -117,6 +117,17 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
 	FbFullMask(drawable->depth);
 }
 
+static inline void
+glamor_fallback(char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    LogMessageVerb(X_INFO, 1, "glamor fallback: ");
+    LogVMessageVerb(X_INFO, 1, format, ap);
+    va_end(ap);
+}
+
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
@@ -129,6 +140,7 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
 void glamor_finish_access(DrawablePtr drawable);
 Bool glamor_prepare_access_window(WindowPtr window);
 void glamor_finish_access_window(WindowPtr window);
+const Bool glamor_get_drawable_location(const DrawablePtr drawable);
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
commit ca58607a44c310ef369a097a06be83aa2a9e1c5b
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Feb 8 09:58:55 2010 +0100

    glamor: Move glamor_poly_lines to a separate file.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 838aedc..ce78692 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -23,6 +23,7 @@ libglamor_la_SOURCES = \
 	glamor_fillspans.c \
 	glamor_getspans.c \
 	glamor_polyfillrect.c \
+	glamor_polylines.c \
 	glamor_putimage.c \
 	glamor_setspans.c \
 	glamor_render.c \
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 3c98b5c..4ae0d6c 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -265,8 +265,9 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    unsigned int stride;
+    unsigned int stride, read_stride, x, y;
     GLenum format, type;
+    uint8_t *data, *read;
 
     if (pixmap_priv == NULL)
 	return TRUE;
@@ -280,11 +281,15 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
     }
 
     stride = PixmapBytePad(drawable->width, drawable->depth);
+    read_stride = stride;
+
+    data = xalloc(stride * drawable->height);
 
     switch (drawable->depth) {
     case 1:
-	format = GL_COLOR_INDEX;
-	type = GL_BITMAP;
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	read_stride = drawable->width;
 	break;
     case 8:
 	format = GL_ALPHA;
@@ -300,24 +305,52 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
 	break;
     default:
 	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth);
+	xfree(data);
 	return FALSE;
     }
 
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
     glGenBuffersARB(1, &pixmap_priv->pbo);
     glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
-    glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, stride * drawable->height,
+    glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
+		    read_stride * pixmap->drawable.height,
 		    NULL, GL_DYNAMIC_DRAW_ARB);
     glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    glPixelStorei(GL_PACK_ROW_LENGTH, stride * 8 /
+    glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
 
     glReadPixels(0, 0,
 		 pixmap->drawable.width, pixmap->drawable.height,
 		 format, type, 0);
 
-    pixmap->devPrivate.ptr = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT,
-					    GL_READ_WRITE_ARB);
+    read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
+
+    if (pixmap->drawable.depth == 1) {
+	for (y = 0; y < pixmap->drawable.height; y++) {
+	    uint8_t *read_row = read + read_stride * (pixmap->drawable.height -
+						      y - 1);
+
+	    for (x = 0; x < pixmap->drawable.width; x++) {
+		int index = x / 8;
+		int bit = 1 << (x % 8);
+
+		if (read_row[x])
+		    data[index] |= bit;
+		else
+		    data[index] &= ~bit;
+	    }
+	}
+    } else {
+	for (y = 0; y < pixmap->drawable.height; y++)
+	    memcpy(data + y * stride,
+		   read + (pixmap->drawable.height - y - 1) * stride, stride);
+    }
+    pixmap->devPrivate.ptr = data;
+
+    glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
+    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+    pixmap_priv->pbo = 0;
 
     return TRUE;
 }
@@ -341,13 +374,6 @@ glamor_finish_access(DrawablePtr drawable)
 	    return;
     }
 
-    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
-    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
-    glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
-    pixmap->devPrivate.ptr = NULL;
-
-    stride = PixmapBytePad(drawable->width, drawable->depth);
-
     switch (drawable->depth) {
     case 1:
 	format = GL_COLOR_INDEX;
@@ -370,17 +396,19 @@ glamor_finish_access(DrawablePtr drawable)
 	return;
     }
 
+    stride = PixmapBytePad(drawable->width, drawable->depth);
+
     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
-    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 /
 		  pixmap->drawable.bitsPerPixel);
 
     glRasterPos2i(0, 0);
     glDrawPixels(pixmap->drawable.width, pixmap->drawable.height,
-		 format, type, 0);
-    glDeleteBuffersARB(1, &pixmap_priv->pbo);
-    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+		 format, type, pixmap->devPrivate.ptr);
+
+    xfree(pixmap->devPrivate.ptr);
+    pixmap->devPrivate.ptr = NULL;
 }
 
 void
@@ -394,75 +422,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
     glamor_solid_fail_region(pixmap, x, y, width, height);
 }
 
-/**
- * glamor_poly_lines() checks if it can accelerate the lines as a group of
- * horizontal or vertical lines (rectangles), and uses existing rectangle fill
- * acceleration if so.
- */
-static void
-glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		  DDXPointPtr points)
-{
-    xRectangle *rects;
-    int x1, x2, y1, y2;
-    int i;
-
-    /* Don't try to do wide lines or non-solid fill style. */
-    if (gc->lineWidth != 0) {
-	ErrorF("stub wide polylines\n");
-	return;
-    }
-    if (gc->lineStyle != LineSolid ||
-	gc->fillStyle != FillSolid) {
-	ErrorF("stub poly_line non-solid fill\n");
-	return;
-    }
-
-    rects = xalloc(sizeof(xRectangle) * (n - 1));
-    x1 = points[0].x;
-    y1 = points[0].y;
-    /* If we have any non-horizontal/vertical, fall back. */
-    for (i = 0; i < n - 1; i++) {
-	if (mode == CoordModePrevious) {
-	    x2 = x1 + points[i + 1].x;
-	    y2 = y1 + points[i + 1].y;
-	} else {
-	    x2 = points[i + 1].x;
-	    y2 = points[i + 1].y;
-	}
-
-	if (x1 != x2 && y1 != y2) {
-	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
-	    xfree(rects);
-
-	    ErrorF("stub diagonal poly_line\n");
-	    glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1);
-	    return;
-	}
-
-	if (x1 < x2) {
-	    rects[i].x = x1;
-	    rects[i].width = x2 - x1 + 1;
-	} else {
-	    rects[i].x = x2;
-	    rects[i].width = x1 - x2 + 1;
-	}
-	if (y1 < y2) {
-	    rects[i].y = y1;
-	    rects[i].height = y2 - y1 + 1;
-	} else {
-	    rects[i].y = y2;
-	    rects[i].height = y1 - y2 + 1;
-	}
-
-	x1 = x2;
-	y1 = y2;
-    }
-    gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
-    xfree(rects);
-}
-
 GCOps glamor_gc_ops = {
     .FillSpans = glamor_fill_spans,
     .SetSpans = glamor_set_spans,
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
new file mode 100644
index 0000000..48e62f4
--- /dev/null
+++ b/glamor/glamor_polylines.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_polylines.c
+ *
+ * GC PolyFillRect implementation, taken straight from fb_fill.c
+ */
+
+/**
+ * glamor_poly_lines() checks if it can accelerate the lines as a group of
+ * horizontal or vertical lines (rectangles), and uses existing rectangle fill
+ * acceleration if so.
+ */
+void
+glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		  DDXPointPtr points)
+{
+    xRectangle *rects;
+    int x1, x2, y1, y2;
+    int i;
+
+    /* Don't try to do wide lines or non-solid fill style. */
+    if (gc->lineWidth != 0) {
+	ErrorF("stub wide polylines\n");
+	return;
+    }
+    if (gc->lineStyle != LineSolid ||
+	gc->fillStyle != FillSolid) {
+	ErrorF("stub poly_line non-solid fill\n");
+	return;
+    }
+
+    rects = xalloc(sizeof(xRectangle) * (n - 1));
+    x1 = points[0].x;
+    y1 = points[0].y;
+    /* If we have any non-horizontal/vertical, fall back. */
+    for (i = 0; i < n - 1; i++) {
+	if (mode == CoordModePrevious) {
+	    x2 = x1 + points[i + 1].x;
+	    y2 = y1 + points[i + 1].y;
+	} else {
+	    x2 = points[i + 1].x;
+	    y2 = points[i + 1].y;
+	}
+
+	if (x1 != x2 && y1 != y2) {
+	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
+	    xfree(rects);
+
+	    ErrorF("stub diagonal poly_line\n");
+	    glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1);
+	    return;
+	}
+
+	if (x1 < x2) {
+	    rects[i].x = x1;
+	    rects[i].width = x2 - x1 + 1;
+	} else {
+	    rects[i].x = x2;
+	    rects[i].width = x1 - x2 + 1;
+	}
+	if (y1 < y2) {
+	    rects[i].y = y1;
+	    rects[i].height = y2 - y1 + 1;
+	} else {
+	    rects[i].y = y2;
+	    rects[i].height = y1 - y2 + 1;
+	}
+
+	x1 = x2;
+	y1 = y2;
+    }
+    gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
+    xfree(rects);
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 81bb035..ad68c12 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -192,6 +192,11 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 		      int nrect,
 		      xRectangle *prect);
 
+/* glamor_polylines.c */
+void
+glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		  DDXPointPtr points);
+
 /* glamor_putimage.c */
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
commit 800fd4f8494ad6f0984073406b3dec584ba63648
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 22 15:41:18 2009 -0700

    glamor: Fix the type for copyarea.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 6f2911a..c89dffc 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -60,7 +60,7 @@ glamor_copy_n_to_n(DrawablePtr src,
 		     box[i].y1 + dy - src_pixmap->screen_y,
 		     box[i].x2 - box[i].x1,
 		     box[i].y2 - box[i].y1,
-		     GL_RGBA);
+		     GL_COLOR);
     }
 
 fail:
commit c4343dfa0a2b40d46d3feb14f1df9fae0fd4a214
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 22 12:08:19 2009 -0700

    glamor: Add prepare/finishaccess code based on UXA.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 71c8ab2..507a19b 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -177,6 +177,10 @@ glamor_init(ScreenPtr screen)
 	ErrorF("GL_ARB_vertex_shader required\n");
 	goto fail;
     }
+    if (!GLEW_ARB_pixel_buffer_object) {
+	ErrorF("GL_ARB_pixel_buffer_object required\n");
+	goto fail;
+    }
 
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
@@ -199,6 +203,12 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_get_image = screen->GetImage;
     screen->GetImage = miGetImage;
 
+    glamor_priv->saved_change_window_attributes = screen->ChangeWindowAttributes;
+    screen->ChangeWindowAttributes = glamor_change_window_attributes;
+
+    glamor_priv->saved_bitmap_to_region = screen->BitmapToRegion;
+    screen->BitmapToRegion = glamor_bitmap_to_region;
+
 #ifdef RENDER
     glamor_priv->saved_composite = ps->Composite;
     ps->Composite = glamor_composite;
@@ -231,6 +241,8 @@ glamor_fini(ScreenPtr screen)
     screen->CreatePixmap = glamor_priv->saved_create_pixmap;
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
     screen->GetSpans = glamor_priv->saved_get_spans;
+    screen->ChangeWindowAttributes = glamor_priv->saved_change_window_attributes;
+    screen->BitmapToRegion = glamor_priv->saved_bitmap_to_region;
 #ifdef RENDER
     ps->Composite = glamor_priv->saved_composite;
 #endif
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index c31e23c..3c98b5c 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -260,6 +260,129 @@ glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
     }
 }
 
+Bool
+glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    unsigned int stride;
+    GLenum format, type;
+
+    if (pixmap_priv == NULL)
+	return TRUE;
+
+    if (pixmap_priv->fb == 0) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (pixmap != screen_pixmap)
+	    return TRUE;
+    }
+
+    stride = PixmapBytePad(drawable->width, drawable->depth);
+
+    switch (drawable->depth) {
+    case 1:
+	format = GL_COLOR_INDEX;
+	type = GL_BITMAP;
+	break;
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 24:
+	format = GL_RGB;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown prepareaccess depth %d\n", drawable->depth);
+	return FALSE;
+    }
+
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glGenBuffersARB(1, &pixmap_priv->pbo);
+    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
+    glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, stride * drawable->height,
+		    NULL, GL_DYNAMIC_DRAW_ARB);
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    glPixelStorei(GL_PACK_ROW_LENGTH, stride * 8 /
+		  pixmap->drawable.bitsPerPixel);
+
+    glReadPixels(0, 0,
+		 pixmap->drawable.width, pixmap->drawable.height,
+		 format, type, 0);
+
+    pixmap->devPrivate.ptr = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT,
+					    GL_READ_WRITE_ARB);
+
+    return TRUE;
+}
+
+void
+glamor_finish_access(DrawablePtr drawable)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    unsigned int stride;
+    GLenum format, type;
+
+    if (pixmap_priv == NULL)
+	return;
+
+    if (pixmap_priv->fb == 0) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (pixmap != screen_pixmap)
+	    return;
+    }
+
+    glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
+    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+    glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
+    pixmap->devPrivate.ptr = NULL;
+
+    stride = PixmapBytePad(drawable->width, drawable->depth);
+
+    switch (drawable->depth) {
+    case 1:
+	format = GL_COLOR_INDEX;
+	type = GL_BITMAP;
+	break;
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 24:
+	format = GL_RGB;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown finishaccess depth %d\n", drawable->depth);
+	return;
+    }
+
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pixmap_priv->pbo);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 /
+		  pixmap->drawable.bitsPerPixel);
+
+    glRasterPos2i(0, 0);
+    glDrawPixels(pixmap->drawable.width, pixmap->drawable.height,
+		 format, type, 0);
+    glDeleteBuffersARB(1, &pixmap_priv->pbo);
+    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+}
+
 void
 glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 	       int x, int y, int width, int height,
@@ -364,13 +487,78 @@ GCOps glamor_gc_ops = {
 };
 
 /**
- * exaValidateGC() sets the ops to EXA's implementations, which may be
+ * uxa_validate_gc() sets the ops to glamor's implementations, which may be
  * accelerated or may sync the card and fall back to fb.
  */
 static void
 glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
 {
-    fbValidateGC(gc, changes, drawable);
+    /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
+     * Preempt fbValidateGC by doing its work and masking the change out, so
+     * that we can do the Prepare/finish_access.
+     */
+#ifdef FB_24_32BIT
+    if ((changes & GCTile) && fbGetRotatedPixmap(gc)) {
+	gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc));
+	fbGetRotatedPixmap(gc) = 0;
+    }
+
+    if (gc->fillStyle == FillTiled) {
+	PixmapPtr old_tile, new_tile;
+
+	old_tile = gc->tile.pixmap;
+	if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) {
+	    new_tile = fbGetRotatedPixmap(gc);
+	    if (!new_tile ||
+		new_tile ->drawable.bitsPerPixel != drawable->bitsPerPixel)
+	    {
+		if (new_tile)
+		    gc->pScreen->DestroyPixmap(new_tile);
+		/* fb24_32ReformatTile will do direct access of a newly-
+		 * allocated pixmap.
+		 */
+		if (glamor_prepare_access(&old_tile->drawable,
+					  GLAMOR_ACCESS_RO)) {
+		    new_tile = fb24_32ReformatTile(old_tile,
+						   drawable->bitsPerPixel);
+		    glamor_finish_access(&old_tile->drawable);
+		}
+	    }
+	    if (new_tile) {
+		fbGetRotatedPixmap(gc) = old_tile;
+		gc->tile.pixmap = new_tile;
+		changes |= GCTile;
+	    }
+	}
+    }
+#endif
+    if (changes & GCTile) {
+	if (!gc->tileIsPixel && FbEvenTile(gc->tile.pixmap->drawable.width *
+					   drawable->bitsPerPixel))
+	{
+	    if (glamor_prepare_access(&gc->tile.pixmap->drawable,
+				      GLAMOR_ACCESS_RW)) {
+		fbPadPixmap(gc->tile.pixmap);
+		glamor_finish_access(&gc->tile.pixmap->drawable);
+	    }
+	}
+	/* Mask out the GCTile change notification, now that we've done FB's
+	 * job for it.
+	 */
+	changes &= ~GCTile;
+    }
+
+    if (changes & GCStipple && gc->stipple) {
+	/* We can't inline stipple handling like we do for GCTile because
+	 * it sets fbgc privates.
+	 */
+	if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
+	    fbValidateGC(gc, changes, drawable);
+	    glamor_finish_access(&gc->stipple->drawable);
+	}
+    } else {
+	fbValidateGC(gc, changes, drawable);
+    }
 
     gc->ops = &glamor_gc_ops;
 }
@@ -399,3 +587,56 @@ glamor_create_gc(GCPtr gc)
 
     return TRUE;
 }
+
+Bool
+glamor_prepare_access_window(WindowPtr window)
+{
+    if (window->backgroundState == BackgroundPixmap) {
+        if (!glamor_prepare_access(&window->background.pixmap->drawable,
+				   GLAMOR_ACCESS_RO))
+	    return FALSE;
+    }
+
+    if (window->borderIsPixel == FALSE) {
+        if (!glamor_prepare_access(&window->border.pixmap->drawable,
+				   GLAMOR_ACCESS_RO)) {
+	    if (window->backgroundState == BackgroundPixmap)
+		glamor_finish_access(&window->background.pixmap->drawable);
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+void
+glamor_finish_access_window(WindowPtr window)
+{
+    if (window->backgroundState == BackgroundPixmap)
+        glamor_finish_access(&window->background.pixmap->drawable);
+
+    if (window->borderIsPixel == FALSE)
+        glamor_finish_access(&window->border.pixmap->drawable);
+}
+
+Bool
+glamor_change_window_attributes(WindowPtr window, unsigned long mask)
+{
+    Bool ret;
+
+    if (!glamor_prepare_access_window(window))
+	return FALSE;
+    ret = fbChangeWindowAttributes(window, mask);
+    glamor_finish_access_window(window);
+    return ret;
+}
+
+RegionPtr
+glamor_bitmap_to_region(PixmapPtr pixmap)
+{
+  RegionPtr ret;
+  if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
+    return NULL;
+  ret = fbPixmapToRegion(pixmap);
+  glamor_finish_access(&pixmap->drawable);
+  return ret;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 93a0115..81bb035 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,6 +31,11 @@
 #include "glamor.h"
 #include <GL/glew.h>
 
+typedef enum glamor_access {
+    GLAMOR_ACCESS_RO,
+    GLAMOR_ACCESS_RW,
+} glamor_access_t;
+
 typedef struct glamor_transform_uniforms {
     GLint x_bias;
     GLint x_scale;
@@ -55,6 +60,8 @@ typedef struct glamor_screen_private {
     GetImageProcPtr saved_get_image;
     CompositeProcPtr saved_composite;
     TrapezoidsProcPtr saved_trapezoids;
+    ChangeWindowAttributesProcPtr saved_change_window_attributes;
+    BitmapToRegionProcPtr saved_bitmap_to_region;
 
     /* glamor_solid */
     GLint solid_prog;
@@ -78,6 +85,7 @@ typedef struct glamor_screen_private {
 typedef struct glamor_pixmap_private {
     GLuint tex;
     GLuint fb;
+    GLuint pbo;
 } glamor_pixmap_private;
 
 extern DevPrivateKey glamor_screen_private_key;
@@ -117,6 +125,10 @@ RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		 int srcx, int srcy, int width, int height, int dstx, int dsty);
 /* glamor_core.c */
+Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
+void glamor_finish_access(DrawablePtr drawable);
+Bool glamor_prepare_access_window(WindowPtr window);
+void glamor_finish_access_window(WindowPtr window);
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
@@ -134,6 +146,8 @@ void glamor_get_transform_uniform_locations(GLint prog,
 					    glamor_transform_uniforms *uniform_locations);
 void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				     glamor_transform_uniforms *uniform_locations);
+Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
+RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 
 /* glamor_fill.c */
 void glamor_fill(DrawablePtr drawable,
commit f17473cdd5f93a2bf3a7b6a14bd5acd965e8e9f0
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 22 10:55:04 2009 -0700

    glamor: Fix pixmap private getter in copyarea.

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 8768922..6f2911a 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -76,7 +76,7 @@ glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
     PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
-    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src);
+    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
     RegionPtr region;
 
     if (!GLEW_EXT_framebuffer_blit) {
commit 5915b4c0cfcfb25a68b77b29a4d7b39b7f6b4822
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Sep 4 18:43:52 2009 -0700

    glamor: Add support for solid source pictures.

diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1e2a173..93a0115 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -43,6 +43,8 @@ typedef struct glamor_composite_shader {
     GLint dest_to_dest_uniform_location;
     GLint dest_to_source_uniform_location;
     GLint dest_to_mask_uniform_location;
+    GLint source_uniform_location;
+    GLint mask_uniform_location;
 } glamor_composite_shader;
 
 typedef struct glamor_screen_private {
@@ -70,7 +72,7 @@ typedef struct glamor_screen_private {
     GLint put_image_xybitmap_bg_uniform_location;
 
     /* glamor_composite */
-    glamor_composite_shader composite_shader[2];
+    glamor_composite_shader composite_shader[8];
 } glamor_screen_private;
 
 typedef struct glamor_pixmap_private {
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index d0c9557..2ebb4c5 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -39,7 +39,9 @@
 #include "glu3/glu3.h"
 
 struct shader_key {
+    Bool solid_source;
     Bool has_mask;
+    Bool solid_mask;
 };
 
 struct blendinfo {
@@ -65,7 +67,9 @@ static struct blendinfo composite_op_info[] = {
     [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
 };
 
-#define HAS_MASK_INDEX    1
+#define SOLID_SOURCE_INDEX	1
+#define HAS_MASK_INDEX		2
+#define SOLID_MASK_INDEX	3
 
 static glamor_composite_shader *
 glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
@@ -73,8 +77,13 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     int index = 0;
 
-    if (key->has_mask)
+    if (key->solid_source)
+	index += SOLID_SOURCE_INDEX;
+    if (key->has_mask) {
 	index += HAS_MASK_INDEX;
+	if (key->solid_mask)
+	    index += SOLID_MASK_INDEX;
+    }
 
     assert(index < ARRAY_SIZE(glamor_priv->composite_shader));
 
@@ -84,31 +93,58 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
 static GLuint
 glamor_create_composite_fs(struct shader_key *key)
 {
-    const char *header =
+    const char *source_pixmap_header =
 	"uniform sampler2D source_sampler;\n"
 	"varying vec4 source_coords;\n";
-    const char *mask_header =
+    const char *source_solid_header =
+	"uniform vec4 source;\n";
+    const char *mask_pixmap_header =
 	"uniform sampler2D mask_sampler;\n"
 	"varying vec4 mask_coords;\n";
+    const char *mask_solid_header =
+	"uniform vec4 mask;\n";
     const char *main_opening =
 	"void main()\n"
-	"{\n"
-	"	vec4 result;\n"
-	"	result = texture2DProj(source_sampler, source_coords.xyw);\n";
+	"{\n";
+    const char *source_pixmap_fetch =
+	"	vec4 source = texture2DProj(source_sampler, "
+	"				    source_coords.xyw);\n";
+    const char *mask_pixmap_fetch =
+	"	vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n";
     const char *source_in_mask =
-	"	vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n"
-	"	result = result * mask.w;\n";
+	"	gl_FragColor = source * mask.w;\n";
+    const char *source_only =
+	"	gl_FragColor = source;\n";
     const char *main_closing =
-	"	gl_FragColor = result;\n"
 	"}\n";
     char *source;
+    const char *source_setup = "";
+    const char *source_fetch = "";
+    const char *mask_setup = "";
+    const char *mask_fetch = "";
     GLuint prog;
 
-    source = XNFprintf("%s%s%s%s%s",
-		       header,
-		       key->has_mask ? mask_header : "",
+    if (key->solid_source) {
+	source_setup = source_solid_header;
+    } else {
+	source_setup = source_pixmap_header;
+	source_fetch = source_pixmap_fetch;
+    }
+    if (key->has_mask) {
+	if (key->solid_mask) {
+	    mask_setup = mask_solid_header;
+	} else {
+	    mask_setup = mask_pixmap_header;
+	    mask_fetch = mask_pixmap_fetch;
+	}
+    }
+    source = XNFprintf("%s%s%s%s%s%s%s",
+		       source_setup,
+		       mask_setup,
 		       main_opening,
-		       key->has_mask ? source_in_mask : "",
+		       source_fetch,
+		       mask_fetch,
+		       key->has_mask ? source_in_mask : source_only,
 		       main_closing);
 
     prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
@@ -139,12 +175,13 @@ glamor_create_composite_vs(struct shader_key *key)
 	"}\n";
     char *source;
     GLuint prog;
+    Bool compute_mask_coords = key->has_mask && !key->solid_mask;
 
     source = XNFprintf("%s%s%s%s%s",
 		       header,
-		       key->has_mask ? mask_header : "",
+		       compute_mask_coords ? mask_header : "",
 		       main_opening,
-		       key->has_mask ? mask_coords : "",
+		       compute_mask_coords ? mask_coords : "",
 		       main_closing);
 
     prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
@@ -177,20 +214,31 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
     shader->prog = prog;
 
     glUseProgramObjectARB(prog);
-    source_sampler_uniform_location = glGetUniformLocationARB(prog,
-							      "source_sampler");
     shader->dest_to_dest_uniform_location =
 	glGetUniformLocationARB(prog, "dest_to_dest");
-    shader->dest_to_source_uniform_location =
-	glGetUniformLocationARB(prog, "dest_to_source");
-    glUniform1i(source_sampler_uniform_location, 0);
+
+    if (key->solid_source) {
+	shader->source_uniform_location = glGetUniformLocationARB(prog,
+								  "source");
+    } else {
+	source_sampler_uniform_location = glGetUniformLocationARB(prog,
+								  "source_sampler");
+	shader->dest_to_source_uniform_location =
+	    glGetUniformLocationARB(prog, "dest_to_source");
+	glUniform1i(source_sampler_uniform_location, 0);
+    }
 
     if (key->has_mask) {
-	mask_sampler_uniform_location = glGetUniformLocationARB(prog,
-								"mask_sampler");
-	glUniform1i(mask_sampler_uniform_location, 1);
-	shader->dest_to_mask_uniform_location =
-	    glGetUniformLocationARB(prog, "dest_to_mask");
+	if (key->solid_mask) {
+	    shader->mask_uniform_location = glGetUniformLocationARB(prog,
+								    "mask");
+	} else {
+	    mask_sampler_uniform_location = glGetUniformLocationARB(prog,
+								    "mask_sampler");
+	    glUniform1i(mask_sampler_uniform_location, 1);
+	    shader->dest_to_mask_uniform_location =
+		glGetUniformLocationARB(prog, "dest_to_mask");
+	}
     }
 }
 
@@ -199,10 +247,21 @@ glamor_init_composite_shaders(ScreenPtr screen)
 {
     struct shader_key key;
 
+    memset(&key, 0, sizeof(key));
+    key.has_mask = FALSE;
+    glamor_create_composite_shader(screen, &key);
+    key.has_mask = TRUE;
+    glamor_create_composite_shader(screen, &key);
+    key.solid_mask = TRUE;
+    glamor_create_composite_shader(screen, &key);
+
+    key.solid_source = TRUE;
     key.has_mask = FALSE;
     glamor_create_composite_shader(screen, &key);
     key.has_mask = TRUE;
     glamor_create_composite_shader(screen, &key);
+    key.solid_mask = TRUE;
+    glamor_create_composite_shader(screen, &key);
 }
 
 static void
@@ -277,8 +336,12 @@ glamor_set_composite_op(ScreenPtr screen,
 
 static void
 glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
-			     glamor_pixmap_private *pixmap_priv)
+			     glamor_pixmap_private *pixmap_priv,
+			     GLint transform_uniform_location,
+			     int x_translate, int y_translate)
 {
+    GLUmat4 transform;
+
     glActiveTexture(GL_TEXTURE0 + unit);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
     switch (picture->repeatType) {
@@ -313,6 +376,27 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
     }
 
     glEnable(GL_TEXTURE_2D);
+
+    glamor_set_composite_transform_matrix(&transform,
+					  picture,
+					  x_translate,
+					  y_translate);
+    glUniformMatrix4fvARB(transform_uniform_location, 1, 0,
+			  (float *)&transform);
+}
+
+static void
+glamor_set_composite_solid(PicturePtr picture, GLint uniform_location)
+{
+    CARD32 c = picture->pSourcePict->solidFill.color; /* a8r8g8b8 */
+    float color[4]; /* rgba */
+
+    color[0] = ((c >> 16) & 0xff) / 255.0;
+    color[1] = ((c >> 8) & 0xff) / 255.0;
+    color[2] = ((c >> 0) & 0xff) / 255.0;
+    color[3] = ((c >> 24) & 0xff) / 255.0;
+
+    glUniform4fvARB(uniform_location, 1, color);
 }
 
 void
@@ -332,10 +416,11 @@ glamor_composite(CARD8 op,
     ScreenPtr screen = dest->pDrawable->pScreen;
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
     PixmapPtr source_pixmap, mask_pixmap = NULL;
-    glamor_pixmap_private *source_pixmap_priv, *mask_pixmap_priv = NULL;
+    glamor_pixmap_private *source_pixmap_priv = NULL;
+    glamor_pixmap_private *mask_pixmap_priv = NULL;
     struct shader_key key;
     glamor_composite_shader *shader;
-    GLUmat4 dest_to_dest, dest_to_source, dest_to_mask;
+    GLUmat4 dest_to_dest;
     RegionRec region;
     int i;
 
@@ -358,14 +443,23 @@ glamor_composite(CARD8 op,
 	return;
     }
 
+    memset(&key, 0, sizeof(key));
     key.has_mask = (mask != NULL);
     if (!source->pDrawable) {
-	ErrorF("source-only source\n");
-	goto fail;
+	if (source->pSourcePict->type == SourcePictTypeSolidFill) {
+	    key.solid_source = TRUE;
+	} else {
+	    ErrorF("gradient source\n");
+	    goto fail;
+	}
     }
     if (mask && !mask->pDrawable) {
-	ErrorF("source-only mask\n");
-	goto fail;
+	if (mask->pSourcePict->type == SourcePictTypeSolidFill) {
+	    key.solid_mask = TRUE;
+	} else {
+	    ErrorF("gradient mask\n");
+	    goto fail;
+	}
     }
     if (source->alphaMap) {
 	ErrorF("source alphaMap\n");
@@ -376,17 +470,19 @@ glamor_composite(CARD8 op,
 	goto fail;
     }
 
-    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
-    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
-    if (source_pixmap == dest_pixmap) {
-	ErrorF("source == dest\n");
-	goto fail;
-    }
-    if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
-	ErrorF("no FBO in source\n");
-	goto fail;
+    if (!key.solid_source) {
+	source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+	source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+	if (source_pixmap == dest_pixmap) {
+	    ErrorF("source == dest\n");
+	    goto fail;
+	}
+	if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
+	    ErrorF("no FBO in source\n");
+	    goto fail;
+	}
     }
-    if (mask) {
+    if (mask && !key.solid_mask) {
 	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 	if (mask_pixmap == dest_pixmap) {
@@ -431,25 +527,23 @@ glamor_composite(CARD8 op,
 	       -1, 1);
     glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0,
 			  (float *)&dest_to_dest);
-    glamor_set_composite_transform_matrix(&dest_to_source,
-					  source,
-					  x_source - x_dest,
-					  y_source - x_dest);
-    glUniformMatrix4fvARB(shader->dest_to_source_uniform_location, 1, 0,
-			  (float *)&dest_to_source);
-
-    if (mask) {
-	glamor_set_composite_transform_matrix(&dest_to_mask,
-					      mask,
-					      x_mask - x_dest,
-					      y_mask - x_dest);
-	glUniformMatrix4fvARB(shader->dest_to_mask_uniform_location, 1, 0,
-			      (float *)&dest_to_mask);
-    }
 
-    glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
-    if (mask)
-	glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
+    if (key.solid_source) {
+	glamor_set_composite_solid(source, shader->source_uniform_location);
+    } else {
+	glamor_set_composite_texture(screen, 0, source, source_pixmap_priv,
+				     shader->dest_to_source_uniform_location,
+				     x_source - x_dest, y_source - y_dest);
+    }
+    if (key.has_mask) {
+	if (key.solid_mask) {
+	    glamor_set_composite_solid(mask, shader->mask_uniform_location);
+	} else {
+	    glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv,
+					 shader->dest_to_mask_uniform_location,
+					 x_mask - x_dest, y_mask - y_dest);
+	}
+    }
 
     if (!miComputeCompositeRegion(&region,
 				  source, mask, dest,
@@ -469,9 +563,9 @@ glamor_composite(CARD8 op,
     }
     glEnd();
 
-    glamor_set_composite_op(screen, PictOpSrc, dest, mask);
+    glDisable(GL_BLEND);
     glUseProgramObjectARB(0);
-		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+    REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 
     return;
 
commit 1159ebb30b7530c2f4612109306cf85a594dd530
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Sep 4 18:43:02 2009 -0700

    glamor: Add untested copyarea implementation

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 3035f63..838aedc 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -17,6 +17,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
+	glamor_copyarea.c \
 	glamor_core.c \
 	glamor_fill.c \
 	glamor_fillspans.c \
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
new file mode 100644
index 0000000..8768922
--- /dev/null
+++ b/glamor/glamor_copyarea.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_copyarea.c
+ *
+ * GC CopyArea implementation
+ */
+
+static void
+glamor_copy_n_to_n(DrawablePtr src,
+		 DrawablePtr dst,
+		 GCPtr gc,
+		 BoxPtr box,
+		 int nbox,
+		 int		dx,
+		 int		dy,
+		 Bool		reverse,
+		 Bool		upsidedown,
+		 Pixel		bitplane,
+		 void		*closure)
+{
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    int i;
+
+    glamor_set_alu(gc->alu);
+    if (!glamor_set_planemask(dst_pixmap, gc->planemask))
+	goto fail;
+
+    for (i = 0; i < nbox; i++) {
+	glRasterPos2i(box[i].x1 - dst_pixmap->screen_x,
+		      box[i].y1 - dst_pixmap->screen_y);
+	glCopyPixels(box[i].x1 + dx - src_pixmap->screen_x,
+		     box[i].y1 + dy - src_pixmap->screen_y,
+		     box[i].x2 - box[i].x1,
+		     box[i].y2 - box[i].y1,
+		     GL_RGBA);
+    }
+
+fail:
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(dst_pixmap, ~0);
+}
+
+RegionPtr
+glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+		 int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+    ScreenPtr screen = dst->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src);
+    RegionPtr region;
+
+    if (!GLEW_EXT_framebuffer_blit) {
+	ErrorF("EXT_framebuffer_blit unsupported\n");
+	goto fail;
+    }
+
+    if (!glamor_set_destination_pixmap(dst_pixmap)) {
+	/*
+	return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
+			srcx, srcy, width, height,
+			dstx, dsty, fbCopyNtoN, 0, NULL);
+	*/
+	return NULL;
+    }
+
+    if (src_priv == NULL) {
+	ErrorF("glamor_copy_area: no src pixmap priv?");
+	goto fail;
+    }
+
+    if (src_priv->fb == 0 && src_pixmap != screen_pixmap) {
+	ErrorF("glamor_copy_area: No src FBO\n");
+	return NULL;
+    }
+
+    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_priv->fb);
+
+    region = miDoCopy(src, dst, gc,
+		      srcx, srcy, width, height,
+		      dstx, dsty, glamor_copy_n_to_n, 0, NULL);
+
+    return region;
+
+fail:
+    return NULL;
+}
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 7b96d67..c31e23c 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -344,7 +344,7 @@ GCOps glamor_gc_ops = {
     .FillSpans = glamor_fill_spans,
     .SetSpans = glamor_set_spans,
     .PutImage = glamor_put_image,
-    .CopyArea = miCopyArea,
+    .CopyArea = glamor_copy_area,
     .CopyPlane = miCopyPlane,
     .PolyPoint = miPolyPoint,
     .Polylines = glamor_poly_lines,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3ad18b5..1e2a173 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -110,6 +110,10 @@ glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
+/* glamor_copyarea.c */
+RegionPtr
+glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+		 int srcx, int srcy, int width, int height, int dstx, int dsty);
 /* glamor_core.c */
 Bool glamor_create_gc(GCPtr gc);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
commit 936385142c12d074dcb603490517ac095840fa3f
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 25 17:24:30 2009 -0700

    glamor: Accelerate PolyFillRect using glamor_fill instead of spans.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 4d307fe..3035f63 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -21,6 +21,7 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_polyfillrect.c \
 	glamor_putimage.c \
 	glamor_setspans.c \
 	glamor_render.c \
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index addff1a..7b96d67 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -352,7 +352,7 @@ GCOps glamor_gc_ops = {
     .PolyRectangle = miPolyRectangle,
     .PolyArc = miPolyArc,
     .FillPolygon = miFillPolygon,
-    .PolyFillRect = miPolyFillRect,
+    .PolyFillRect = glamor_poly_fill_rect,
     .PolyFillArc = miPolyFillArc,
     .PolyText8 = miPolyText8,
     .PolyText16 = miPolyText16,
diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c
new file mode 100644
index 0000000..ae8963d
--- /dev/null
+++ b/glamor/glamor_polyfillrect.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_fillspans.c
+ *
+ * GC PolyFillRect implementation, taken straight from fb_fill.c
+ */
+
+void
+glamor_poly_fill_rect(DrawablePtr drawable,
+		      GCPtr gc,
+		      int nrect,
+		      xRectangle *prect)
+{
+    RegionPtr	    clip = fbGetCompositeClip(gc);
+    register BoxPtr box;
+    BoxPtr	    pextent;
+    int		    extentX1, extentX2, extentY1, extentY2;
+    int		    fullX1, fullX2, fullY1, fullY2;
+    int		    partX1, partX2, partY1, partY2;
+    int		    xorg, yorg;
+    int		    n;
+
+    xorg = drawable->x;
+    yorg = drawable->y;
+
+    pextent = REGION_EXTENTS(gc->pScreen, clip);
+    extentX1 = pextent->x1;
+    extentY1 = pextent->y1;
+    extentX2 = pextent->x2;
+    extentY2 = pextent->y2;
+    while (nrect--)
+    {
+	fullX1 = prect->x + xorg;
+	fullY1 = prect->y + yorg;
+	fullX2 = fullX1 + (int)prect->width;
+	fullY2 = fullY1 + (int)prect->height;
+	prect++;
+
+	if (fullX1 < extentX1)
+	    fullX1 = extentX1;
+
+	if (fullY1 < extentY1)
+	    fullY1 = extentY1;
+
+	if (fullX2 > extentX2)
+	    fullX2 = extentX2;
+
+	if (fullY2 > extentY2)
+	    fullY2 = extentY2;
+
+	if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
+	    continue;
+	n = REGION_NUM_RECTS(clip);
+	if (n == 1) {
+	    glamor_fill(drawable,
+			gc,
+			fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
+	} else {
+	    box = REGION_RECTS(clip);
+	    /* clip the rectangle to each box in the clip region
+	     * this is logically equivalent to calling Intersect()
+	     */
+	    while (n--) {
+		partX1 = box->x1;
+		if (partX1 < fullX1)
+		    partX1 = fullX1;
+		partY1 = box->y1;
+		if (partY1 < fullY1)
+		    partY1 = fullY1;
+		partX2 = box->x2;
+		if (partX2 > fullX2)
+		    partX2 = fullX2;
+		partY2 = box->y2;
+		if (partY2 > fullY2)
+		    partY2 = fullY2;
+
+		box++;
+
+		if (partX1 < partX2 && partY1 < partY2)
+		    glamor_fill(drawable, gc,
+				partX1, partY1,
+				partX2 - partX1, partY2 - partY1);
+	    }
+	}
+    }
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index b5ba82d..3ad18b5 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -165,6 +165,13 @@ glamor_get_spans(DrawablePtr drawable,
 void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		      DDXPointPtr points, int *widths, int n, int sorted);
 
+/* glamor_polyfillrect.c */
+void
+glamor_poly_fill_rect(DrawablePtr drawable,
+		      GCPtr gc,
+		      int nrect,
+		      xRectangle *prect);
+
 /* glamor_putimage.c */
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
commit 6dacc9b08c2af51c1826c20ccf12bb2c73856f25
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 25 17:01:43 2009 -0700

    glamor: Add untested PutImage 1bpp XYPixmap support.

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 0705235..55854da 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -252,18 +252,21 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	return;
     }
 
+    if (bpp == 1 && image_format == XYPixmap)
+	image_format = ZPixmap;
+
     if (!glamor_set_planemask(pixmap, gc->planemask))
 	goto fail;
     if (image_format != ZPixmap) {
 	ErrorF("putimage: non-ZPixmap\n");
 	goto fail;
     }
-    if (bpp < 8) {
-	ErrorF("putimage: bad bpp: %d\n", bpp);
-	goto fail;
-    }
 
     switch (drawable->depth) {
+    case 1:
+	format = GL_COLOR_INDEX;
+	type = GL_BITMAP;
+	break;
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
@@ -279,7 +282,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     default:
 	ErrorF("stub put_image depth %d\n", drawable->depth);
 	goto fail;
-	break;
     }
 
     glamor_set_alu(gc->alu);
@@ -288,7 +290,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     y += drawable->y;
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride / (bpp / 8));
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / bpp);
+    if (bpp == 1)
+	glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
     clip = fbGetCompositeClip(gc);
     for (nbox = REGION_NUM_RECTS(clip),
 	 pbox = REGION_RECTS(clip);
@@ -320,6 +324,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		     src);
     }
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
     glamor_set_alu(GXcopy);
     glamor_set_planemask(pixmap, ~0);
     return;
commit 854e9bd20a2d0f8ed636d4fba0ddfa4c71d54667
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 25 16:56:50 2009 -0700

    glamor: Add untested PutImage XYBitmap support.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 43e1c7d..71c8ab2 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -208,6 +208,7 @@ glamor_init(ScreenPtr screen)
 
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
+    glamor_init_putimage_shaders(screen);
     glamor_init_composite_shaders(screen);
 
     return TRUE;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 864be51..b5ba82d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -63,6 +63,12 @@ typedef struct glamor_screen_private {
     GLint tile_prog;
     glamor_transform_uniforms tile_transform;
 
+    /* glamor_putimage */
+    GLint put_image_xybitmap_prog;
+    glamor_transform_uniforms put_image_xybitmap_transform;
+    GLint put_image_xybitmap_fg_uniform_location;
+    GLint put_image_xybitmap_bg_uniform_location;
+
     /* glamor_composite */
     glamor_composite_shader composite_shader[2];
 } glamor_screen_private;
@@ -163,6 +169,7 @@ void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits);
+void glamor_init_putimage_shaders(ScreenPtr screen);
 
 /* glamor_render.c */
 void glamor_composite(CARD8 op,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index a0b8635..0705235 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -33,6 +33,201 @@
 #include "glamor_priv.h"
 
 void
+glamor_init_putimage_shaders(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    const char *xybitmap_vs =
+	"uniform float x_bias;\n"
+	"uniform float x_scale;\n"
+	"uniform float y_bias;\n"
+	"uniform float y_scale;\n"
+	"varying vec2 bitmap_coords;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
+	"			   0,\n"
+	"			   1);\n"
+	"	bitmap_coords = gl_MultiTexCoord0.xy;\n"
+	"}\n";
+    const char *xybitmap_fs =
+	"uniform vec4 fg, bg;\n"
+	"varying vec2 bitmap_coords;\n"
+	"uniform sampler2D bitmap_sampler;\n"
+	"void main()\n"
+	"{\n"
+	"	float bitmap_value = texture2D(bitmap_sampler,\n"
+	"				       bitmap_coords).x;\n"
+	"	gl_FragColor = mix(bg, fg, bitmap_value);\n"
+	"}\n";
+    GLint fs_prog, vs_prog, prog;
+    GLint sampler_uniform_location;
+
+    if (!GLEW_ARB_fragment_shader)
+	return;
+
+    prog = glCreateProgramObjectARB();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, xybitmap_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, xybitmap_fs);
+    glAttachObjectARB(prog, vs_prog);
+    glAttachObjectARB(prog, fs_prog);
+    glamor_link_glsl_prog(prog);
+
+    glUseProgramObjectARB(prog);
+    sampler_uniform_location = glGetUniformLocationARB(prog, "bitmap_sampler");
+    glUniform1iARB(sampler_uniform_location, 0);
+
+    glamor_priv->put_image_xybitmap_fg_uniform_location =
+	glGetUniformLocationARB(prog, "fg");
+    glamor_priv->put_image_xybitmap_bg_uniform_location =
+	glGetUniformLocationARB(prog, "bg");
+    glamor_get_transform_uniform_locations(prog,
+					   &glamor_priv->put_image_xybitmap_transform);
+    glamor_priv->put_image_xybitmap_prog = prog;
+    glUseProgramObjectARB(0);
+}
+
+static int
+y_flip(PixmapPtr pixmap, int y)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+    if (pixmap == screen_pixmap)
+	return (pixmap->drawable.height - 1) - y;
+    else
+	return y;
+}
+
+/* Do an XYBitmap putimage.  The bits are byte-aligned rows of bitmap
+ * data (where each row starts at a bit index of left_pad), and the
+ * destination gets filled with the gc's fg color where the bitmap is set
+ * and the bg color where the bitmap is unset.
+ *
+ * Implement this by passing the bitmap right through to GL, and sampling
+ * it to choose between fg and bg in the fragment shader.  The driver may
+ * be exploding the bitmap up to be an 8-bit alpha texture, in which
+ * case we might be better off just doing the fg/bg choosing in the CPU
+ * and just draw the resulting texture to the destination.
+ */
+static void
+glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
+			  int x, int y, int w, int h, int left_pad,
+			  int image_format, char *bits)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    float fg[4], bg[4];
+    GLuint tex;
+    unsigned int stride = PixmapBytePad(1, w + left_pad);
+    RegionPtr clip;
+    BoxPtr box;
+    int nbox;
+    float dest_coords[8] = {
+	x, y,
+	x + w, y,
+	x + w, y + h,
+	x, y + h,
+    };
+    const float bitmap_coords[8] = {
+	0.0, 0.0,
+	1.0, 0.0,
+	1.0, 1.0,
+	0.0, 1.0,
+    };
+
+    if (glamor_priv->put_image_xybitmap_prog == 0) {
+	ErrorF("no program for xybitmap putimage\n");
+	goto fail;
+    }
+
+    glamor_set_alu(gc->alu);
+    if (!glamor_set_planemask(pixmap, gc->planemask))
+	goto fail;
+
+    glUseProgramObjectARB(glamor_priv->put_image_xybitmap_prog);
+
+    glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
+    glUniform4fvARB(glamor_priv->put_image_xybitmap_fg_uniform_location,
+		    1, fg);
+    glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
+    glUniform4fvARB(glamor_priv->put_image_xybitmap_bg_uniform_location,
+		    1, bg);
+
+    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
+
+    glGenTextures(1, &tex);
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+		 w, h, 0,
+		 GL_COLOR_INDEX, GL_BITMAP, bits);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    glEnable(GL_TEXTURE_2D);
+
+    /* Now that we've set up our bitmap texture and the shader, shove
+     * the destination rectangle through the cliprects and run the
+     * shader on the resulting fragments.
+     */
+    glVertexPointer(2, GL_FLOAT, 0, dest_coords);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glClientActiveTexture(GL_TEXTURE0);
+    glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+    glEnable(GL_SCISSOR_TEST);
+    clip = fbGetCompositeClip(gc);
+    for (nbox = REGION_NUM_RECTS(clip),
+	 box = REGION_RECTS(clip);
+	 nbox--;
+	 box++)
+    {
+	int x1 = x;
+	int y1 = y;
+	int x2 = x + w;
+	int y2 = y + h;
+
+	if (x1 < box->x1)
+	    x1 = box->x1;
+	if (y1 < box->y1)
+	    y1 = box->y1;
+	if (x2 > box->x2)
+	    x2 = box->x2;
+	if (y2 > box->y2)
+	    y2 = box->y2;
+	if (x1 >= x2 || y1 >= y2)
+	    continue;
+
+	glScissor(box->x1,
+		  y_flip(pixmap, box->y1),
+		  box->x2 - box->x1,
+		  box->y2 - box->y1);
+	glDrawArrays(GL_QUADS, 0, 4);
+    }
+
+    glDisable(GL_SCISSOR_TEST);
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
+    glDeleteTextures(1, &tex);
+    glDisable(GL_TEXTURE_2D);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    return;
+
+fail:
+    glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
+    glamor_solid_fail_region(pixmap, x, y, w, h);
+}
+
+void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int left_pad, int image_format, char *bits)
 {
@@ -50,6 +245,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	return;
     }
 
+    if (image_format == XYBitmap) {
+	assert(depth == 1);
+	glamor_put_image_xybitmap(drawable, gc, x, y, w, h,
+				  left_pad, image_format, bits);
+	return;
+    }
+
     if (!glamor_set_planemask(pixmap, gc->planemask))
 	goto fail;
     if (image_format != ZPixmap) {
commit 8a53566acb5870816807425dc805df888fa42792
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 25 13:06:11 2009 -0700

    glamor: make the polylines complaint a little more useful.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 58cb357..addff1a 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -285,9 +285,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     int i;
 
     /* Don't try to do wide lines or non-solid fill style. */
-    if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
+    if (gc->lineWidth != 0) {
+	ErrorF("stub wide polylines\n");
+	return;
+    }
+    if (gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	ErrorF("stub poly_line depth %d\n", drawable->depth);
+	ErrorF("stub poly_line non-solid fill\n");
 	return;
     }
 
commit aa133069745fc59bb2f212b0816add9bae40c376
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 25 12:10:32 2009 -0700

    glamor: Start adding render acceleration support.
    
    This brings in idr's glu3 code.  We'll probably want to move to linking to
    it as a library, once an ABI-stable release is out.

diff --git a/configure.ac b/configure.ac
index 3954ecc..7a8e507 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2147,6 +2147,7 @@ Xi/Makefile
 xfixes/Makefile
 exa/Makefile
 glamor/Makefile
+glamor/glu3/Makefile
 hw/Makefile
 hw/xfree86/Makefile
 hw/xfree86/common/Makefile
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 098aa37..4d307fe 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -4,6 +4,8 @@ noinst_LTLIBRARIES = libglamor.la
 # built (in hw/xfree86/os-support/solaris) until after glamor is built
 SOLARIS_ASM_CFLAGS=""
 
+SUBDIRS = glu3
+
 if XORG
 sdk_HEADERS = glamor.h
 endif
@@ -24,3 +26,5 @@ libglamor_la_SOURCES = \
 	glamor_render.c \
 	glamor_tile.c \
 	glamor.h
+libglamor_la_LIBADD = \
+	glu3/libglu3.la
diff --git a/glamor/glamor.c b/glamor/glamor.c
index a03274a..43e1c7d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -208,6 +208,7 @@ glamor_init(ScreenPtr screen)
 
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
+    glamor_init_composite_shaders(screen);
 
     return TRUE;
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index d054372..864be51 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -38,6 +38,13 @@ typedef struct glamor_transform_uniforms {
     GLint y_scale;
 } glamor_transform_uniforms;
 
+typedef struct glamor_composite_shader {
+    GLuint prog;
+    GLint dest_to_dest_uniform_location;
+    GLint dest_to_source_uniform_location;
+    GLint dest_to_mask_uniform_location;
+} glamor_composite_shader;
+
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
@@ -52,8 +59,12 @@ typedef struct glamor_screen_private {
     GLint solid_color_uniform_location;
     glamor_transform_uniforms solid_transform;
 
+    /* glamor_tile */
     GLint tile_prog;
     glamor_transform_uniforms tile_transform;
+
+    /* glamor_composite */
+    glamor_composite_shader composite_shader[2];
 } glamor_screen_private;
 
 typedef struct glamor_pixmap_private {
@@ -75,6 +86,10 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
     return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
 }
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+
 /**
  * Returns TRUE if the given planemask covers all the significant bits in the
  * pixel values for pDrawable.
@@ -166,6 +181,7 @@ void glamor_trapezoids(CARD8 op,
 		       PicturePtr src, PicturePtr dst,
 		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
 		       int ntrap, xTrapezoid *traps);
+void glamor_init_composite_shaders(ScreenPtr screen);
 
 /* glamor_tile.c */
 void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
new file mode 100644
index 0000000..d0c9557
--- /dev/null
+++ b/glamor/glamor_render.c
@@ -0,0 +1,620 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+
+/** @file glamor_render.c
+ *
+ * Render acceleration implementation
+ */
+
+#include "glamor_priv.h"
+
+#ifdef RENDER
+#include "mipict.h"
+
+#include "glu3/glu3.h"
+
+struct shader_key {
+    Bool has_mask;
+};
+
+struct blendinfo {
+    Bool dest_alpha;
+    Bool source_alpha;
+    GLenum source_blend;
+    GLenum dest_blend;
+};
+
+static struct blendinfo composite_op_info[] = {
+    [PictOpClear] =       {0, 0, GL_ZERO,                GL_ZERO},
+    [PictOpSrc] =         {0, 0, GL_ONE,                 GL_ZERO},
+    [PictOpDst] =         {0, 0, GL_ZERO,                GL_ONE},
+    [PictOpOver] =        {0, 1, GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+    [PictOpIn] =          {1, 0, GL_DST_ALPHA,           GL_ZERO},
+    [PictOpInReverse] =   {0, 1, GL_ZERO,                GL_SRC_ALPHA},
+    [PictOpOut] =         {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+    [PictOpOutReverse] =  {0, 1, GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtop] =        {1, 1, GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+    [PictOpXor] =         {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+    [PictOpAdd] =         {0, 0, GL_ONE,                 GL_ONE},
+};
+
+#define HAS_MASK_INDEX    1
+
+static glamor_composite_shader *
+glamor_lookup_composite_shader(ScreenPtr screen, struct shader_key *key)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    int index = 0;
+
+    if (key->has_mask)
+	index += HAS_MASK_INDEX;
+
+    assert(index < ARRAY_SIZE(glamor_priv->composite_shader));
+
+    return &glamor_priv->composite_shader[index];
+}
+
+static GLuint
+glamor_create_composite_fs(struct shader_key *key)
+{
+    const char *header =
+	"uniform sampler2D source_sampler;\n"
+	"varying vec4 source_coords;\n";
+    const char *mask_header =
+	"uniform sampler2D mask_sampler;\n"
+	"varying vec4 mask_coords;\n";
+    const char *main_opening =
+	"void main()\n"
+	"{\n"
+	"	vec4 result;\n"
+	"	result = texture2DProj(source_sampler, source_coords.xyw);\n";
+    const char *source_in_mask =
+	"	vec4 mask = texture2DProj(mask_sampler, mask_coords.xyw);\n"
+	"	result = result * mask.w;\n";
+    const char *main_closing =
+	"	gl_FragColor = result;\n"
+	"}\n";
+    char *source;
+    GLuint prog;
+
+    source = XNFprintf("%s%s%s%s%s",
+		       header,
+		       key->has_mask ? mask_header : "",
+		       main_opening,
+		       key->has_mask ? source_in_mask : "",
+		       main_closing);
+
+    prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, source);
+    xfree(source);
+
+    return prog;
+}
+
+static GLuint
+glamor_create_composite_vs(struct shader_key *key)
+{
+    const char *header =
+	"uniform mat4 dest_to_dest;\n"
+	"uniform mat4 dest_to_source;\n"
+	"varying vec4 source_coords;\n";
+    const char *mask_header =
+	"uniform mat4 dest_to_mask;\n"
+	"varying vec4 mask_coords;\n";
+    const char *main_opening =
+	"void main()\n"
+	"{\n"
+	"	vec4 incoming_dest_coords = vec4(gl_Vertex.xy, 0, 1);\n"
+	"	gl_Position = dest_to_dest * incoming_dest_coords;\n"
+	"	source_coords = dest_to_source * incoming_dest_coords;\n";
+    const char *mask_coords =
+	"	mask_coords = dest_to_mask * incoming_dest_coords;\n";
+    const char *main_closing =
+	"}\n";
+    char *source;
+    GLuint prog;
+
+    source = XNFprintf("%s%s%s%s%s",
+		       header,
+		       key->has_mask ? mask_header : "",
+		       main_opening,
+		       key->has_mask ? mask_coords : "",
+		       main_closing);
+
+    prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, source);
+    xfree(source);
+
+    return prog;
+}
+
+static void
+glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key)
+{
+    GLuint vs, fs, prog;
+    GLint source_sampler_uniform_location, mask_sampler_uniform_location;
+    glamor_composite_shader *shader;
+
+    shader = glamor_lookup_composite_shader(screen, key);
+
+    vs = glamor_create_composite_vs(key);
+    if (vs == 0)
+	return;
+    fs = glamor_create_composite_fs(key);
+    if (fs == 0)
+	return;
+
+    prog = glCreateProgramObjectARB();
+    glAttachObjectARB(prog, vs);
+    glAttachObjectARB(prog, fs);
+    glamor_link_glsl_prog(prog);
+
+    shader->prog = prog;
+
+    glUseProgramObjectARB(prog);
+    source_sampler_uniform_location = glGetUniformLocationARB(prog,
+							      "source_sampler");
+    shader->dest_to_dest_uniform_location =
+	glGetUniformLocationARB(prog, "dest_to_dest");
+    shader->dest_to_source_uniform_location =
+	glGetUniformLocationARB(prog, "dest_to_source");
+    glUniform1i(source_sampler_uniform_location, 0);
+
+    if (key->has_mask) {
+	mask_sampler_uniform_location = glGetUniformLocationARB(prog,
+								"mask_sampler");
+	glUniform1i(mask_sampler_uniform_location, 1);
+	shader->dest_to_mask_uniform_location =
+	    glGetUniformLocationARB(prog, "dest_to_mask");
+    }
+}
+
+void
+glamor_init_composite_shaders(ScreenPtr screen)
+{
+    struct shader_key key;
+
+    key.has_mask = FALSE;
+    glamor_create_composite_shader(screen, &key);
+    key.has_mask = TRUE;
+    glamor_create_composite_shader(screen, &key);
+}
+
+static void
+glamor_set_composite_transform_matrix(GLUmat4 *m,
+				      PicturePtr picture,
+				      float x_source,
+				      float y_source)
+{
+    GLUmat4 temp;
+    DrawablePtr drawable = picture->pDrawable;
+    GLUvec4 scale = {{1.0f / drawable->width,
+		      1.0f / drawable->height,
+		      1.0,
+		      1.0}};
+
+    gluTranslate3f(m, -x_source, -y_source, 0.0);
+    gluScale4v(&temp, &scale);
+    gluMult4m_4m(m, &temp, m);
+}
+
+static Bool
+glamor_set_composite_op(ScreenPtr screen,
+			CARD8 op, PicturePtr dest, PicturePtr mask)
+{
+    GLenum source_blend, dest_blend;
+    struct blendinfo *op_info;
+
+    if (op >= ARRAY_SIZE(composite_op_info)) {
+	ErrorF("unsupported render op\n");
+	return GL_FALSE;
+    }
+    op_info = &composite_op_info[op];
+
+    source_blend = op_info->source_blend;
+    dest_blend = op_info->dest_blend;
+
+    if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
+	op_info->source_alpha && source_blend != GL_ZERO) {
+    }
+
+    /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+     * it as always 1.
+     */
+    if (PICT_FORMAT_A(dest->format) == 0 && op_info->dest_alpha) {
+        if (source_blend == GL_DST_ALPHA)
+            source_blend = GL_ONE;
+        else if (source_blend == GL_ONE_MINUS_DST_ALPHA)
+            source_blend = GL_ZERO;
+    }
+
+    /* Set up the source alpha value for blending in component alpha mode. */
+    if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) != 0 &&
+	op_info->source_alpha) {
+	if (source_blend != GL_ZERO) {
+	    ErrorF("Dual-source composite blending not supported\n");
+	    return GL_FALSE;
+	}
+	if (dest_blend == GL_SRC_ALPHA)
+	    dest_blend = GL_SRC_COLOR;
+	else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+	    dest_blend = GL_ONE_MINUS_SRC_COLOR;
+    }
+
+    if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
+	glDisable(GL_BLEND);
+    } else {
+	glEnable(GL_BLEND);
+	glBlendFunc(source_blend, dest_blend);
+    }
+    return TRUE;
+}
+
+static void
+glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
+			     glamor_pixmap_private *pixmap_priv)
+{
+    glActiveTexture(GL_TEXTURE0 + unit);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+    switch (picture->repeatType) {
+    case RepeatNone:
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+	break;
+    case RepeatNormal:
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	break;
+    case RepeatPad:
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	break;
+    case RepeatReflect:
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+	break;
+    }
+
+    switch (picture->filter) {
+    case PictFilterNearest:
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        break;
+    case PictFilterBilinear:
+    default:
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        break;
+    }
+
+    glEnable(GL_TEXTURE_2D);
+}
+
+void
+glamor_composite(CARD8 op,
+		 PicturePtr source,
+		 PicturePtr mask,
+		 PicturePtr dest,
+		 INT16 x_source,
+		 INT16 y_source,
+		 INT16 x_mask,
+		 INT16 y_mask,
+		 INT16 x_dest,
+		 INT16 y_dest,
+		 CARD16 width,
+		 CARD16 height)
+{
+    ScreenPtr screen = dest->pDrawable->pScreen;
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+    PixmapPtr source_pixmap, mask_pixmap = NULL;
+    glamor_pixmap_private *source_pixmap_priv, *mask_pixmap_priv = NULL;
+    struct shader_key key;
+    glamor_composite_shader *shader;
+    GLUmat4 dest_to_dest, dest_to_source, dest_to_mask;
+    RegionRec region;
+    int i;
+
+    /* Do two-pass PictOpOver componentAlpha, until we enable
+     * dual source color blending.
+     */
+    if (mask && mask->componentAlpha && op == PictOpOver) {
+	glamor_composite(PictOpOutReverse,
+			 source, mask, dest,
+			 x_source, y_source,
+			 x_mask, y_mask,
+			 x_dest, y_dest,
+			 width, height);
+	glamor_composite(PictOpAdd,
+			 source, mask, dest,
+			 x_source, y_source,
+			 x_mask, y_mask,
+			 x_dest, y_dest,
+			 width, height);
+	return;
+    }
+
+    key.has_mask = (mask != NULL);
+    if (!source->pDrawable) {
+	ErrorF("source-only source\n");
+	goto fail;
+    }
+    if (mask && !mask->pDrawable) {
+	ErrorF("source-only mask\n");
+	goto fail;
+    }
+    if (source->alphaMap) {
+	ErrorF("source alphaMap\n");
+	goto fail;
+    }
+    if (mask && mask->alphaMap) {
+	ErrorF("mask alphaMap\n");
+	goto fail;
+    }
+
+    source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+    source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+    if (source_pixmap == dest_pixmap) {
+	ErrorF("source == dest\n");
+	goto fail;
+    }
+    if (!source_pixmap_priv || source_pixmap_priv->tex == 0) {
+	ErrorF("no FBO in source\n");
+	goto fail;
+    }
+    if (mask) {
+	mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+	mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+	if (mask_pixmap == dest_pixmap) {
+	    ErrorF("mask == dest\n");
+	    goto fail;
+	}
+	if (!mask_pixmap_priv || mask_pixmap_priv->tex == 0) {
+	    ErrorF("no FBO in mask\n");
+	    goto fail;
+	}
+    }
+
+    shader = glamor_lookup_composite_shader(screen, &key);
+    if (shader->prog == 0) {
+	ErrorF("No program compiled for this render accel mode\n");
+	goto fail;
+    }
+
+    glUseProgramObjectARB(shader->prog);
+
+    if (!glamor_set_destination_pixmap(dest_pixmap))
+	goto fail;
+
+    if (!glamor_set_composite_op(screen, op, dest, mask)) {
+	goto fail;
+    }
+
+    x_dest += dest->pDrawable->x;
+    y_dest += dest->pDrawable->y;
+    if (source->pDrawable) {
+	x_source += source->pDrawable->x;
+	y_source += source->pDrawable->y;
+    }
+    if (mask && mask->pDrawable) {
+	x_mask += mask->pDrawable->x;
+	y_mask += mask->pDrawable->y;
+    }
+
+    gluOrtho6f(&dest_to_dest,
+	       dest_pixmap->screen_x, dest_pixmap->screen_x + width,
+	       dest_pixmap->screen_y, dest_pixmap->screen_y + height,
+	       -1, 1);
+    glUniformMatrix4fvARB(shader->dest_to_dest_uniform_location, 1, 0,
+			  (float *)&dest_to_dest);
+    glamor_set_composite_transform_matrix(&dest_to_source,
+					  source,
+					  x_source - x_dest,
+					  y_source - x_dest);
+    glUniformMatrix4fvARB(shader->dest_to_source_uniform_location, 1, 0,
+			  (float *)&dest_to_source);
+
+    if (mask) {
+	glamor_set_composite_transform_matrix(&dest_to_mask,
+					      mask,
+					      x_mask - x_dest,
+					      y_mask - x_dest);
+	glUniformMatrix4fvARB(shader->dest_to_mask_uniform_location, 1, 0,
+			      (float *)&dest_to_mask);
+    }
+
+    glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
+    if (mask)
+	glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
+
+    if (!miComputeCompositeRegion(&region,
+				  source, mask, dest,
+				  x_source, y_source,
+				  x_mask, y_mask,
+				  x_dest, y_dest,
+				  width, height))
+	return;
+
+    glBegin(GL_QUADS);
+    for (i = 0; i < REGION_NUM_RECTS(&region); i++) {
+	BoxPtr box = &REGION_RECTS(&region)[i];
+	glVertex2i(box->x1, box->y1);
+	glVertex2i(box->x2, box->y1);
+	glVertex2i(box->x2, box->y2);
+	glVertex2i(box->x1, box->y2);
+    }
+    glEnd();
+
+    glamor_set_composite_op(screen, PictOpSrc, dest, mask);
+    glUseProgramObjectARB(0);
+		REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+
+    return;
+
+fail:
+    glamor_set_composite_op(screen, PictOpSrc, dest, mask);
+    glUseProgramObjectARB(0);
+    glamor_solid_fail_region(dest_pixmap, x_dest, y_dest, width, height);
+}
+
+
+/**
+ * Creates an appropriate picture to upload our alpha mask into (which
+ * we calculated in system memory)
+ */
+static PicturePtr
+glamor_create_mask_picture(ScreenPtr screen,
+			   PicturePtr dst,
+			   PictFormatPtr pict_format,
+			   CARD16 width,
+			   CARD16 height)
+{
+    PixmapPtr pixmap;
+    PicturePtr picture;
+    int	error;
+
+    if (!pict_format) {
+	if (dst->polyEdge == PolyEdgeSharp)
+	    pict_format = PictureMatchFormat(screen, 1, PICT_a1);
+	else
+	    pict_format = PictureMatchFormat(screen, 8, PICT_a8);
+	if (!pict_format)
+	    return 0;
+    }
+
+    pixmap = screen->CreatePixmap(screen, width, height,
+				  pict_format->depth,
+				  0);
+    if (!pixmap)
+	return 0;
+    picture = CreatePicture(0, &pixmap->drawable, pict_format,
+			    0, 0, serverClient, &error);
+    screen->DestroyPixmap(pixmap);
+    return picture;
+}
+
+/**
+ * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid
+ * accumulation in system memory.
+ */
+void
+glamor_trapezoids(CARD8 op,
+		  PicturePtr src, PicturePtr dst,
+		  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		  int ntrap, xTrapezoid *traps)
+{
+    ScreenPtr screen = dst->pDrawable->pScreen;
+    BoxRec bounds;
+    PicturePtr picture;
+    INT16 x_dst, y_dst;
+    INT16 x_rel, y_rel;
+    int width, height, stride;
+    PixmapPtr pixmap;
+    GCPtr gc;
+    pixman_image_t *image;
+
+    /* If a mask format wasn't provided, we get to choose, but behavior should
+     * be as if there was no temporary mask the traps were accumulated into.
+     */
+    if (!mask_format) {
+	if (dst->polyEdge == PolyEdgeSharp)
+	    mask_format = PictureMatchFormat(screen, 1, PICT_a1);
+	else
+	    mask_format = PictureMatchFormat(screen, 8, PICT_a8);
+	for (; ntrap; ntrap--, traps++)
+	    glamor_trapezoids(op, src, dst, mask_format, x_src, y_src,
+			      1, traps);
+	return;
+    }
+
+    miTrapezoidBounds(ntrap, traps, &bounds);
+
+    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	return;
+
+    x_dst = traps[0].left.p1.x >> 16;
+    y_dst = traps[0].left.p1.y >> 16;
+
+    width = bounds.x2 - bounds.x1;
+    height = bounds.y2 - bounds.y1;
+    stride = (width * BitsPerPixel(mask_format->depth) + 7) / 8;
+
+    picture = glamor_create_mask_picture(screen, dst, mask_format,
+					 width, height);
+    if (!picture)
+	return;
+
+    image = pixman_image_create_bits(picture->format,
+				     width, height,
+				     NULL, stride);
+    if (!image) {
+	FreePicture(picture, 0);
+	return;
+    }
+
+    for (; ntrap; ntrap--, traps++)
+	pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps,
+				   -bounds.x1, -bounds.y1);
+
+    pixmap = GetScratchPixmapHeader(screen, width, height,
+				    mask_format->depth,
+				    BitsPerPixel(mask_format->depth),
+				    PixmapBytePad(width, mask_format->depth),
+				    pixman_image_get_data(image));
+    if (!pixmap) {
+	FreePicture(picture, 0);
+	pixman_image_unref(image);
+	return;
+    }
+
+    gc = GetScratchGC(picture->pDrawable->depth, screen);
+    if (!gc) {
+	FreeScratchPixmapHeader(pixmap);
+	pixman_image_unref (image);
+	FreePicture(picture, 0);
+	return;
+    }
+    ValidateGC(picture->pDrawable, gc);
+
+    gc->ops->CopyArea(&pixmap->drawable, picture->pDrawable,
+		      gc, 0, 0, width, height, 0, 0);
+
+    FreeScratchGC(gc);
+    FreeScratchPixmapHeader(pixmap);
+    pixman_image_unref(image);
+
+    x_rel = bounds.x1 + x_src - x_dst;
+    y_rel = bounds.y1 + y_src - y_dst;
+    CompositePicture(op, src, picture, dst,
+		     x_rel, y_rel,
+		     0, 0,
+		     bounds.x1, bounds.y1,
+		     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+    FreePicture(picture, 0);
+}
+
+#endif /* RENDER */
diff --git a/glamor/glu3/Makefile.am b/glamor/glu3/Makefile.am
new file mode 100644
index 0000000..7d141a7
--- /dev/null
+++ b/glamor/glu3/Makefile.am
@@ -0,0 +1,15 @@
+noinst_LTLIBRARIES = libglu3.la
+
+# Override these since glu3 doesn't need them and the needed files aren't
+# built (in hw/xfree86/os-support/solaris) until after glu3 is built
+SOLARIS_ASM_CFLAGS=""
+
+INCLUDES = \
+	$(XORG_INCS)
+
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
+
+libglu3_la_SOURCES = \
+	matrix.c \
+	glu3.h \
+	glu3_scalar.h
diff --git a/glamor/glu3/glu3.h b/glamor/glu3/glu3.h
new file mode 100644
index 0000000..29dba38
--- /dev/null
+++ b/glamor/glu3/glu3.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2009 Ian D. Romanick
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#ifndef __glu3_h__
+#define __glu3_h__
+
+#include <GL/gl.h>
+
+#define GLU_VERSION_3_0
+
+struct GLUmat4;
+
+struct GLUvec4 {
+	GLfloat values[4];
+
+#ifdef __cplusplus
+	inline GLUvec4(void)
+	{
+	}
+
+	inline GLUvec4(GLfloat x , GLfloat y, GLfloat z, GLfloat w)
+	{
+		values[0] = x;
+		values[1] = y;
+		values[2] = z;
+		values[3] = w;
+	}
+
+	inline GLUvec4(const GLUvec4 &v)
+	{
+		values[0] = v.values[0];
+		values[1] = v.values[1];
+		values[2] = v.values[2];
+		values[3] = v.values[3];
+	}
+
+	GLUvec4 operator *(const GLUmat4 &) const;
+	GLUvec4 operator *(const GLUvec4 &) const;
+	GLUvec4 operator *(GLfloat) const;
+
+	GLUvec4 operator +(const GLUvec4 &) const;
+	GLUvec4 operator -(const GLUvec4 &) const;
+#endif /* __cplusplus */
+};
+
+
+struct GLUmat4 {
+	struct GLUvec4 col[4];
+
+#ifdef __cplusplus
+	inline GLUmat4(void)
+	{
+	}
+
+	inline GLUmat4(const GLUvec4 & c0, const GLUvec4 & c1,
+		       const GLUvec4 & c2, const GLUvec4 & c3)
+	{
+		col[0] = c0;
+		col[1] = c1;
+		col[2] = c2;
+		col[3] = c3;
+	}
+
+	inline GLUmat4(const GLUmat4 &m)
+	{
+		col[0] = m.col[0];
+		col[1] = m.col[1];
+		col[2] = m.col[2];
+		col[3] = m.col[3];
+	}
+
+
+	GLUvec4 operator *(const GLUvec4 &) const;
+	GLUmat4 operator *(const GLUmat4 &) const;
+	GLUmat4 operator *(GLfloat) const;
+
+	GLUmat4 operator +(const GLUmat4 &) const;
+	GLUmat4 operator -(const GLUmat4 &) const;
+#endif	/* __cplusplus */
+};
+
+#define GLU_MAX_STACK_DEPTH 32
+
+struct GLUmat4Stack {
+	struct GLUmat4 stack[GLU_MAX_STACK_DEPTH];
+	unsigned top;
+
+#ifdef __cplusplus
+	GLUmat4Stack() : top(0)
+	{
+		/* empty */
+	}
+#endif	/* __cplusplus */
+};
+
+#ifndef __cplusplus
+typedef struct GLUvec4 GLUvec4;
+typedef struct GLUmat4 GLUmat4;
+typedef struct GLUmat4Stack GLUmat4Stack;
+#endif /*  __cplusplus */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GLfloat gluDot4_4v(const GLUvec4 *, const GLUvec4 *);
+GLfloat gluDot3_4v(const GLUvec4 *, const GLUvec4 *);
+GLfloat gluDot2_4v(const GLUvec4 *, const GLUvec4 *);
+
+void gluCross4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
+void gluNormalize4v(GLUvec4 *result, const GLUvec4 *);
+GLfloat gluLength4v(const GLUvec4 *);
+GLfloat gluLengthSqr4v(const GLUvec4 *);
+void gluOuter4v(GLUmat4 *result, const GLUvec4 *, const GLUvec4 *);
+
+
+void gluMult4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
+void gluDiv4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
+void gluAdd4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
+void gluSub4v_4v(GLUvec4 *result, const GLUvec4 *, const GLUvec4 *);
+
+void gluMult4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
+void gluDiv4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
+void gluAdd4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
+void gluSub4v_f(GLUvec4 *result, const GLUvec4 *, GLfloat);
+
+void gluMult4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
+void gluAdd4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
+void gluSub4m_4m(GLUmat4 *result, const GLUmat4 *, const GLUmat4 *);
+void gluMult4m_4v(GLUvec4 *result, const GLUmat4 *m, const GLUvec4 *v);
+
+void gluMult4m_f(GLUmat4 *result, const GLUmat4 *, GLfloat);
+
+void gluScale4v(GLUmat4 *result, const GLUvec4 *);
+void gluTranslate3f(GLUmat4 *result, GLfloat x, GLfloat y, GLfloat z);
+void gluTranslate4v(GLUmat4 *result, const GLUvec4 *);
+void gluRotate4v(GLUmat4 *result, const GLUvec4 *axis, GLfloat angle);
+void gluLookAt4v(GLUmat4 *result, const GLUvec4 *eye, const GLUvec4 *center,
+		 const GLUvec4 *up);
+void gluPerspective4f(GLUmat4 *result, GLfloat fovy, GLfloat aspect,
+		      GLfloat near, GLfloat far);
+void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m);
+void gluFrustum6f(GLUmat4 *result,
+		  GLfloat left, GLfloat right,
+		  GLfloat bottom, GLfloat top,
+		  GLfloat near, GLfloat far);
+void gluOrtho6f(GLUmat4 *result,
+		GLfloat left, GLfloat right,
+		GLfloat bottom, GLfloat top,
+		GLfloat near, GLfloat far);
+
+extern const GLUmat4 gluIdentityMatrix;
+
+#ifdef __cplusplus
+};
+#endif
+
+#ifdef __cplusplus
+GLfloat gluDot4(const GLUvec4 &, const GLUvec4 &);
+GLfloat gluDot3(const GLUvec4 &, const GLUvec4 &);
+GLfloat gluDot2(const GLUvec4 &, const GLUvec4 &);
+
+GLUvec4 gluCross(const GLUvec4 &, const GLUvec4 &);
+GLUvec4 gluNormalize(const GLUvec4 &);
+GLfloat gluLength(const GLUvec4 &);
+GLfloat gluLengthSqr(const GLUvec4 &);
+#endif /* __cplusplus */
+
+#include "glu3_scalar.h"
+
+#endif /* __glu3_h__ */
diff --git a/glamor/glu3/glu3_scalar.h b/glamor/glu3/glu3_scalar.h
new file mode 100644
index 0000000..3e87b8c
--- /dev/null
+++ b/glamor/glu3/glu3_scalar.h
@@ -0,0 +1,388 @@
+/*
+ * Copyright © 2009 Ian D. Romanick
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <math.h>
+#include <string.h>
+
+extern inline void gluMult4v_4v(GLUvec4 *result,
+				const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	result->values[0] = v1->values[0] * v2->values[0];
+	result->values[1] = v1->values[1] * v2->values[1];
+	result->values[2] = v1->values[2] * v2->values[2];
+	result->values[3] = v1->values[3] * v2->values[3];
+}
+
+
+extern inline void gluDiv4v_4v(GLUvec4 *result,
+			       const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	result->values[0] = v1->values[0] / v2->values[0];
+	result->values[1] = v1->values[1] / v2->values[1];
+	result->values[2] = v1->values[2] / v2->values[2];
+	result->values[3] = v1->values[3] / v2->values[3];
+}
+
+
+extern inline void gluAdd4v_4v(GLUvec4 *result,
+			       const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	result->values[0] = v1->values[0] + v2->values[0];
+	result->values[1] = v1->values[1] + v2->values[1];
+	result->values[2] = v1->values[2] + v2->values[2];
+	result->values[3] = v1->values[3] + v2->values[3];
+}
+
+
+extern inline void gluSub4v_4v(GLUvec4 *result,
+			       const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	result->values[0] = v1->values[0] - v2->values[0];
+	result->values[1] = v1->values[1] - v2->values[1];
+	result->values[2] = v1->values[2] - v2->values[2];
+	result->values[3] = v1->values[3] - v2->values[3];
+}
+
+
+extern inline void gluMult4v_f(GLUvec4 *result,
+			       const GLUvec4 *v1, GLfloat f)
+{
+	result->values[0] = v1->values[0] * f;
+	result->values[1] = v1->values[1] * f;
+	result->values[2] = v1->values[2] * f;
+	result->values[3] = v1->values[3] * f;
+}
+
+
+extern inline void gluDiv4v_f(GLUvec4 *result,
+			      const GLUvec4 *v1, GLfloat f)
+{
+	result->values[0] = v1->values[0] / f;
+	result->values[1] = v1->values[1] / f;
+	result->values[2] = v1->values[2] / f;
+	result->values[3] = v1->values[3] / f;
+}
+
+
+extern inline void gluAdd4v_f(GLUvec4 *result,
+			      const GLUvec4 *v1, GLfloat f)
+{
+	result->values[0] = v1->values[0] + f;
+	result->values[1] = v1->values[1] + f;
+	result->values[2] = v1->values[2] + f;
+	result->values[3] = v1->values[3] + f;
+}
+
+
+extern inline void gluSub4v_f(GLUvec4 *result,
+			      const GLUvec4 *v1, GLfloat f)
+{
+	result->values[0] = v1->values[0] - f;
+	result->values[1] = v1->values[1] - f;
+	result->values[2] = v1->values[2] - f;
+	result->values[3] = v1->values[3] - f;
+}
+
+
+extern inline void gluMult4m_f(GLUmat4 *result,
+			       const GLUmat4 *m, GLfloat f)
+{
+	GLUmat4 temp;
+
+	gluMult4v_f(& temp.col[0], & m->col[0], f);
+	gluMult4v_f(& temp.col[1], & m->col[1], f);
+	gluMult4v_f(& temp.col[2], & m->col[2], f);
+	gluMult4v_f(& temp.col[3], & m->col[3], f);
+	*result = temp;
+}
+
+
+extern inline void gluMult4m_4v(GLUvec4 *result,
+				const GLUmat4 *m, const GLUvec4 *v)
+{
+	GLUvec4 temp[6];
+	unsigned i;
+
+	for (i = 0; i < 4; i++) {
+		gluMult4v_f(& temp[i], & m->col[i], v->values[i]);
+	}
+
+	gluAdd4v_4v(& temp[4], & temp[0], & temp[1]);
+	gluAdd4v_4v(& temp[5], & temp[2], & temp[3]);
+	gluAdd4v_4v(result,    & temp[4], & temp[5]);
+}
+
+
+extern inline void gluAdd4m_4m(GLUmat4 *result,
+			       const GLUmat4 *m1, const GLUmat4 *m2)
+{
+	GLUmat4 temp;
+
+	gluAdd4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]);
+	gluAdd4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]);
+	gluAdd4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]);
+	gluAdd4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]);
+	*result = temp;
+}
+
+extern inline void gluSub4m_4m(GLUmat4 *result,
+			       const GLUmat4 *m1, const GLUmat4 *m2)
+{
+	GLUmat4 temp;
+
+	gluSub4v_4v(& temp.col[0], & m1->col[0], & m2->col[0]);
+	gluSub4v_4v(& temp.col[1], & m1->col[1], & m2->col[1]);
+	gluSub4v_4v(& temp.col[2], & m1->col[2], & m2->col[2]);
+	gluSub4v_4v(& temp.col[3], & m1->col[3], & m2->col[3]);
+	*result = temp;
+}
+
+extern inline GLfloat gluDot4_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	return v1->values[0] * v2->values[0]
+		+ v1->values[1] * v2->values[1]
+		+ v1->values[2] * v2->values[2]
+		+ v1->values[3] * v2->values[3];
+}
+
+
+extern inline GLfloat gluDot3_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	return v1->values[0] * v2->values[0]
+		+ v1->values[1] * v2->values[1]
+		+ v1->values[2] * v2->values[2];
+}
+
+
+extern inline GLfloat gluDot2_4v(const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	return v1->values[0] * v2->values[0]
+		+ v1->values[1] * v2->values[1];
+}
+
+
+extern inline void gluCross4v(GLUvec4 *result,
+			      const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	GLUvec4 temp;
+
+	temp.values[0] = (v1->values[1] * v2->values[2]) 
+		- (v1->values[2] * v2->values[1]);
+	temp.values[1] = (v1->values[2] * v2->values[0]) 
+		- (v1->values[0] * v2->values[2]);
+	temp.values[2] = (v1->values[0] * v2->values[1]) 
+		- (v1->values[1] * v2->values[0]);
+	temp.values[3] = 0.0;
+	*result = temp;
+}
+
+
+extern inline void gluOuter4v(GLUmat4 *result,
+			      const GLUvec4 *v1, const GLUvec4 *v2)
+{
+	GLUmat4 temp;
+
+	gluMult4v_f(& temp.col[0], v1, v2->values[0]);
+	gluMult4v_f(& temp.col[1], v1, v2->values[1]);
+	gluMult4v_f(& temp.col[2], v1, v2->values[2]);
+	gluMult4v_f(& temp.col[3], v1, v2->values[3]);
+	*result = temp;
+}
+
+
+extern inline GLfloat gluLengthSqr4v(const GLUvec4 *v)
+{
+	return gluDot4_4v(v, v);
+}
+
+
+extern inline GLfloat gluLength4v(const GLUvec4 *v)
+{
+	return sqrt(gluLengthSqr4v(v));
+}
+
+
+extern inline void gluNormalize4v(GLUvec4 *result, const GLUvec4 *v)
+{
+	gluDiv4v_f(result, v, gluLength4v(v));
+}
+
+
+
+extern inline void gluTranspose4m(GLUmat4 *result, const GLUmat4 *m)
+{
+	unsigned i;
+	unsigned j;
+	GLUmat4 temp;
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 4; j++) {
+			temp.col[i].values[j] = m->col[j].values[i];
+		}
+	}
+
+	*result = temp;
+}
+
+
+extern inline void gluMult4m_4m(GLUmat4 *result,
+				const GLUmat4 *m1, const GLUmat4 *m2)
+{
+	GLUmat4 temp;
+	unsigned i;
+
+	for (i = 0; i < 4; i++) {
+		gluMult4m_4v(& temp.col[i], m1, & m2->col[i]);
+	}
+
+	*result = temp;
+}
+
+
+
+extern inline void gluTranslate3f(GLUmat4 *result,
+				  GLfloat x, GLfloat y, GLfloat z)
+{
+	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
+	result->col[3].values[0] = x;
+	result->col[3].values[1] = y;
+	result->col[3].values[2] = z;
+}
+
+
+#ifdef __cplusplus
+extern inline GLfloat gluDot4(const GLUvec4 &v1, const GLUvec4 &v2)
+{
+	return v1.values[0] * v2.values[0]
+		+ v1.values[1] * v2.values[1]
+		+ v1.values[2] * v2.values[2]
+		+ v1.values[3] * v2.values[3];
+}
+
+
+extern inline GLfloat gluDot3(const GLUvec4 &v1, const GLUvec4 &v2)
+{
+	return v1.values[0] * v2.values[0]
+		+ v1.values[1] * v2.values[1]
+		+ v1.values[2] * v2.values[2];
+}
+
+
+extern inline GLfloat gluDot2(const GLUvec4 &v1, const GLUvec4 &v2)
+{
+	return v1.values[0] * v2.values[0]
+		+ v1.values[1] * v2.values[1];
+}
+
+
+inline GLUvec4 GLUvec4::operator+(const GLUvec4 &v) const
+{
+	return GLUvec4(values[0] + v.values[0],
+		       values[1] + v.values[1],
+		       values[2] + v.values[2],
+		       values[3] + v.values[3]);
+}
+
+
+inline GLUvec4 GLUvec4::operator-(const GLUvec4 &v) const
+{
+	return GLUvec4(values[0] - v.values[0],
+		       values[1] - v.values[1],
+		       values[2] - v.values[2],
+		       values[3] - v.values[3]);
+}
+
+
+inline GLUvec4 GLUvec4::operator*(const GLUvec4 &v) const
+{
+	return GLUvec4(values[0] * v.values[0],
+		       values[1] * v.values[1],
+		       values[2] * v.values[2],
+		       values[3] * v.values[3]);
+}
+
+
+inline GLUvec4 GLUvec4::operator*(GLfloat f) const
+{
+	return GLUvec4(values[0] * f,
+		       values[1] * f,
+		       values[2] * f,
+		       values[3] * f);
+}
+
+
+inline GLUvec4 GLUvec4::operator*(const GLUmat4 &m) const
+{
+	return GLUvec4(gluDot4(*this, m.col[0]),
+		       gluDot4(*this, m.col[1]),
+		       gluDot4(*this, m.col[2]),
+		       gluDot4(*this, m.col[3]));
+}
+
+
+inline GLUmat4 GLUmat4::operator+(const GLUmat4 &m) const
+{
+	GLUmat4 temp;
+
+	gluAdd4m_4m(& temp, this, &m);
+	return temp;
+}
+
+
+inline GLUmat4 GLUmat4::operator-(const GLUmat4 &m) const
+{
+	return GLUmat4(col[0] - m.col[0],
+		       col[1] - m.col[1],
+		       col[2] - m.col[2],
+		       col[3] - m.col[3]);
+}
+
+
+inline GLUmat4 GLUmat4::operator*(GLfloat f) const
+{
+	GLUmat4 temp;
+
+	gluMult4m_f(& temp, this, f);
+	return temp;
+}
+
+
+inline GLUvec4 GLUmat4::operator*(const GLUvec4 &v) const
+{
+	return (col[0] * v.values[0])
+		+ (col[1] * v.values[1])
+		+ (col[2] * v.values[2])
+		+ (col[3] * v.values[3]);
+}
+
+
+inline GLUmat4 GLUmat4::operator*(const GLUmat4 &m) const
+{
+	GLUmat4 temp;
+
+	gluMult4m_4m(& temp, this, &m);
+	return temp;
+}
+
+
+#endif /* __cplusplus */
diff --git a/glamor/glu3/matrix.c b/glamor/glu3/matrix.c
new file mode 100644
index 0000000..b3d5819
--- /dev/null
+++ b/glamor/glu3/matrix.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2009 Ian D. Romanick
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <string.h>
+#include "glu3.h"
+
+#define DEG2RAD(d) ((d) * M_PI / 180.0)
+
+const GLUmat4 gluIdentityMatrix = {
+	{
+		{ { 1.0f, 0.0f,  0.0f,  0.0f } },
+		{ { 0.0f, 1.0f,  0.0f,  0.0f } },
+		{ { 0.0f, 0.0f,  1.0f,  0.0f } },
+		{ { 0.0f, 0.0f,  0.0f,  1.0f } }
+	}
+};
+
+
+void gluTranslate4v(GLUmat4 *result, const GLUvec4 *t)
+{
+	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
+	result->col[3] = *t;
+	result->col[3].values[3] = 1.0f;
+}
+
+
+void gluScale4v(GLUmat4 *result, const GLUvec4 *t)
+{
+	memcpy(result, & gluIdentityMatrix, sizeof(gluIdentityMatrix));
+	result->col[0].values[0] = t->values[0];
+	result->col[1].values[1] = t->values[1];
+	result->col[2].values[2] = t->values[2];
+}
+
+
+void gluLookAt4v(GLUmat4 *result,
+		 const GLUvec4 *_eye,
+		 const GLUvec4 *_center,
+		 const GLUvec4 *_up)
+{
+	static const GLUvec4 col3 = { { 0.0f, 0.0f, 0.0f, 1.0f } };
+	const GLUvec4 e = { 
+		{ -_eye->values[0], -_eye->values[1], -_eye->values[2], 0.0f }
+	};
+	GLUmat4  translate;
+	GLUmat4  rotate;
+	GLUmat4  rotateT;
+	GLUvec4  f;
+	GLUvec4  s;
+	GLUvec4  u;
+	GLUvec4  center, up;
+
+	center = *_center;
+	center.values[3] = 0;
+	up = *_up;
+	up.values[3] = 0;
+
+	gluAdd4v_4v(& f, &center, &e);
+	gluNormalize4v(& f, & f);
+
+	gluNormalize4v(& u, &up);
+
+	gluCross4v(& s, & f, & u);
+	gluCross4v(& u, & s, & f);
+
+	rotate.col[0] = s;
+	rotate.col[1] = u;
+	rotate.col[2].values[0] = -f.values[0];
+	rotate.col[2].values[1] = -f.values[1];
+	rotate.col[2].values[2] = -f.values[2];
+	rotate.col[2].values[3] = 0.0f;
+	rotate.col[3] = col3;
+	gluTranspose4m(& rotateT, & rotate);
+
+	gluTranslate4v(& translate, & e);
+	gluMult4m_4m(result, & rotateT, & translate);
+}
+
+
+void gluRotate4v(GLUmat4 *result, const GLUvec4 *_axis, GLfloat angle)
+{
+	GLUvec4 axis;
+	const float c = cos(angle);
+	const float s = sin(angle);
+	const float one_c = 1.0 - c;
+
+	float xx;
+	float yy;
+	float zz;
+
+	float xs;
+	float ys;
+	float zs;
+
+	float xy;
+	float xz;
+	float yz;
+
+	/* Only normalize the 3-component axis.  A gluNormalize3v might be
+	 * appropriate to save us some computation.
+	 */
+	axis = *_axis;
+	axis.values[3] = 0;
+	gluNormalize4v(&axis, &axis);
+
+	xx = axis.values[0] * axis.values[0];
+	yy = axis.values[1] * axis.values[1];
+	zz = axis.values[2] * axis.values[2];
+
+	xs = axis.values[0] * s;
+	ys = axis.values[1] * s;
+	zs = axis.values[2] * s;
+
+	xy = axis.values[0] * axis.values[1];
+	xz = axis.values[0] * axis.values[2];
+	yz = axis.values[1] * axis.values[2];
+
+
+	result->col[0].values[0] = (one_c * xx) + c;
+	result->col[0].values[1] = (one_c * xy) + zs;
+	result->col[0].values[2] = (one_c * xz) - ys;
+	result->col[0].values[3] = 0.0;
+
+	result->col[1].values[0] = (one_c * xy) - zs;
+	result->col[1].values[1] = (one_c * yy) + c;
+	result->col[1].values[2] = (one_c * yz) + xs;
+	result->col[1].values[3] = 0.0;
+
+
+	result->col[2].values[0] = (one_c * xz) + ys;
+	result->col[2].values[1] = (one_c * yz) - xs;
+	result->col[2].values[2] = (one_c * zz) + c;
+	result->col[2].values[3] = 0.0;
+
+	result->col[3].values[0] = 0.0;
+	result->col[3].values[1] = 0.0;
+	result->col[3].values[2] = 0.0;
+	result->col[3].values[3] = 1.0;
+}
+
+
+void
+gluPerspective4f(GLUmat4 *result,
+		 GLfloat fovy, GLfloat aspect, GLfloat near, GLfloat far)
+{
+	const double sine = sin(DEG2RAD(fovy / 2.0));
+	const double cosine = cos(DEG2RAD(fovy / 2.0));
+	const double sine_aspect = sine * aspect;
+	const double dz = far - near;
+
+
+	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
+	if ((sine == 0.0) || (dz == 0.0) || (sine_aspect == 0.0)) {
+		return;
+	}
+
+	result->col[0].values[0] = cosine / sine_aspect;
+	result->col[1].values[1] = cosine / sine;
+	result->col[2].values[2] = -(far + near) / dz;
+	result->col[2].values[3] = -1.0;
+	result->col[3].values[2] = -2.0 * near * far / dz;
+	result->col[3].values[3] =  0.0;
+}
+
+void gluFrustum6f(GLUmat4 *result,
+		  GLfloat left, GLfloat right,
+		  GLfloat bottom, GLfloat top,
+		  GLfloat near, GLfloat far)
+{
+	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
+
+	result->col[0].values[0] = (2.0 * near) / (right - left);
+	result->col[1].values[1] = (2.0 * near) / (top - bottom);
+	result->col[2].values[0] = (right + left) / (right - left);
+	result->col[2].values[1] = (top + bottom) / (top - bottom);
+	result->col[2].values[2] = -(far + near) / (far - near);
+	result->col[2].values[3] = -1.0;
+	result->col[3].values[2] = -2.0 * near * far / (far - near);
+	result->col[3].values[3] =  0.0;
+}
+
+void gluOrtho6f(GLUmat4 *result,
+		GLfloat left, GLfloat right,
+		GLfloat bottom, GLfloat top,
+		GLfloat near, GLfloat far)
+{
+	memcpy(result, &gluIdentityMatrix, sizeof(gluIdentityMatrix));
+
+	result->col[0].values[0] = 2.0f / (right - left);
+	result->col[3].values[0] = -(right + left) / (right - left);
+
+	result->col[1].values[1] = 2.0f / (top - bottom);
+	result->col[3].values[1] = -(top + bottom) / (top - bottom);
+
+	result->col[2].values[2] = -2.0f / (far - near);
+	result->col[3].values[2] = -(far + near) / (far - near);
+}
commit 4a51cc0440c8d026fd8c82b40cfb188c6ea4a9f0
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 09:14:20 2009 -0700

    glamor: Add clipping to setspans.

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 65471e9..66ec3da 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -40,6 +40,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src;
     int i, j;
     int wmax = 0;
+    RegionPtr clip = fbGetCompositeClip(gc);
+    BoxRec *pbox;
 
     for (i = 0 ; i < n; i++) {
 	if (wmax < widths[i])
@@ -87,12 +89,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    }
 	}
 
-	glRasterPos2i(points[i].x - dest_pixmap->screen_x,
-		      points[i].y - dest_pixmap->screen_y);
-	glDrawPixels(widths[i],
-		     1,
-		     format, type,
-		     drawpixels_src);
+	n = REGION_NUM_RECTS(clip);
+	pbox = REGION_RECTS(clip);
+	while (n--) {
+	    if (pbox->y1 > points[i].y)
+		break;
+	    glScissor(pbox->x1,
+		      points[i].y - dest_pixmap->screen_y,
+		      pbox->x2 - pbox->x1,
+		      1);
+	    glEnable(GL_SCISSOR_TEST);
+	    glRasterPos2i(points[i].x - dest_pixmap->screen_x,
+			  points[i].y - dest_pixmap->screen_y);
+	    glDrawPixels(widths[i],
+			 1,
+			 format, type,
+			 drawpixels_src);
+	}
 	if (temp_src) {
 	    src += PixmapBytePad(widths[i], drawable->depth);
 	} else {
@@ -100,6 +113,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	}
     }
 fail:
+    glDisable(GL_SCISSOR_TEST);
     glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
     xfree(temp_src);
commit 5fadea5d9c02670c35ddf3e0f12f9d355b412103
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 09:10:14 2009 -0700

    glamor: Fix some screen_xy offsets to be the right way around.

diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 36f5c85..a0b8635 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -111,7 +111,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	    continue;
 
 	src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
-	glRasterPos2i(x1 + pixmap->screen_x, y1 + pixmap->screen_y);
+	glRasterPos2i(x1 - pixmap->screen_x, y1 - pixmap->screen_y);
 	glDrawPixels(x2 - x1,
 		     y2 - y1,
 		     format, type,
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index cb1fe2d..517dbd3 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -92,10 +92,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     int x2 = x + width;
     int y1 = y;
     int y2 = y + height;
-    int tile_x1 = tile_x + tile->screen_x;
-    int tile_x2 = tile_x + tile->screen_x + width;
-    int tile_y1 = tile_y + tile->screen_y;
-    int tile_y2 = tile_y + tile->screen_y + height;
+    int tile_x1 = tile_x - tile->screen_x;
+    int tile_x2 = tile_x - tile->screen_x + width;
+    int tile_y1 = tile_y - tile->screen_y;
+    int tile_y2 = tile_y - tile->screen_y + height;
     glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
 
     if (glamor_priv->tile_prog == 0) {
@@ -121,9 +121,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glEnable(GL_TEXTURE_2D);
 
-    tile_x += tile->screen_x;
-    tile_y += tile->screen_y;
-
     glBegin(GL_TRIANGLE_FAN);
     glMultiTexCoord2f(0, tile_x1, tile_y1);
     glVertex2f(x1, y1);
commit 44e4599b83cc330a7c9edd7e18266f222a69418a
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:59:52 2009 -0700

    glamor: Move planemask to a function in case I decide to fill it in.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 38829de..58cb357 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -68,6 +68,17 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
     return TRUE;
 }
 
+Bool
+glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
+{
+    if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+	return GL_TRUE;
+    }
+
+    ErrorF("unsupported planemask\n");
+    return GL_FALSE;
+}
+
 void
 glamor_set_alu(unsigned char alu)
 {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index f387dab..6290f12 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -154,6 +154,8 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     if (!glamor_set_destination_pixmap(pixmap))
 	return;
     glamor_set_alu(alu);
+    if (!glamor_set_planemask(pixmap, planemask))
+	goto fail;
 
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
@@ -168,6 +170,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glEnd();
 
     glUseProgramObjectARB(0);
+fail:
     glamor_set_alu(GXcopy);
 }
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3929819..d054372 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -102,6 +102,7 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 				    GLfloat *color);
 Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
 void glamor_set_alu(unsigned char alu);
+Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 void glamor_get_transform_uniform_locations(GLint prog,
 					    glamor_transform_uniforms *uniform_locations);
 void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index f1a4e94..36f5c85 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -50,17 +50,15 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	return;
     }
 
-    if (!glamor_pm_is_solid(drawable, gc->planemask)) {
-	ErrorF("putimage: non-solid planemask\n");
+    if (!glamor_set_planemask(pixmap, gc->planemask))
 	goto fail;
-    }
     if (image_format != ZPixmap) {
 	ErrorF("putimage: non-ZPixmap\n");
 	goto fail;
     }
     if (bpp < 8) {
 	ErrorF("putimage: bad bpp: %d\n", bpp);
-	return;
+	goto fail;
     }
 
     switch (drawable->depth) {
@@ -121,8 +119,10 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     }
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
     return;
 
 fail:
+    glamor_set_planemask(pixmap, ~0);
     glamor_solid_fail_region(pixmap, x, y, w, h);
 }
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index f81551a..65471e9 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -71,8 +71,12 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     }
 
     if (!glamor_set_destination_pixmap(dest_pixmap))
-	return;
+	goto fail;
+    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
+	goto fail;
     glamor_set_alu(gc->alu);
+    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
+	goto fail;
     for (i = 0; i < n; i++) {
 	if (temp_src) {
 	    for (j = 0; j < widths[i]; j++) {
@@ -95,6 +99,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
 	}
     }
+fail:
+    glamor_set_planemask(dest_pixmap, ~0);
     glamor_set_alu(GXcopy);
     xfree(temp_src);
 }
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index c33b3c1..cb1fe2d 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -109,11 +109,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	ErrorF("Non-FBO tile pixmap\n");
 	goto fail;
     }
-    if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) {
-	ErrorF("tile pm\n");
+    if (!glamor_set_planemask(pixmap, planemask))
 	goto fail;
-    }
-
     glamor_set_alu(alu);
     glUseProgramObjectARB(glamor_priv->tile_prog);
     glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform);
@@ -141,6 +138,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glUseProgramObjectARB(0);
     glDisable(GL_TEXTURE_2D);
     glamor_set_alu(GXcopy);
+    glamor_set_planemask(pixmap, ~0);
     return;
 
 fail:
commit 882411bef1091f97f61ae27a549970d87eef9cab
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:29:30 2009 -0700

    glamor: add alu support to setspans.

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index 48168a9..f81551a 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -72,6 +72,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 
     if (!glamor_set_destination_pixmap(dest_pixmap))
 	return;
+    glamor_set_alu(gc->alu);
     for (i = 0; i < n; i++) {
 	if (temp_src) {
 	    for (j = 0; j < widths[i]; j++) {
@@ -94,5 +95,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
 	}
     }
+    glamor_set_alu(GXcopy);
     xfree(temp_src);
 }
commit c70ce72fd74354a0b9731dc8d4451f6aaf951117
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:24:54 2009 -0700

    glamor: Give setspans the same format support as getspans.

diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
index bf9c508..48168a9 100644
--- a/glamor/glamor_setspans.c
+++ b/glamor/glamor_setspans.c
@@ -37,13 +37,30 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 {
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    int i;
+    uint8_t *temp_src = NULL, *drawpixels_src = (uint8_t *)src;
+    int i, j;
+    int wmax = 0;
+
+    for (i = 0 ; i < n; i++) {
+	if (wmax < widths[i])
+	    wmax = widths[i];
+    }
 
     switch (drawable->depth) {
+    case 1:
+	temp_src = xalloc(wmax);
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	drawpixels_src = temp_src;
+	break;
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
+	break;
     case 24:
+	format = GL_RGB;
+	type = GL_UNSIGNED_BYTE;
+	break;
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -56,12 +73,26 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     if (!glamor_set_destination_pixmap(dest_pixmap))
 	return;
     for (i = 0; i < n; i++) {
+	if (temp_src) {
+	    for (j = 0; j < widths[i]; j++) {
+		if (src[j / 8] & (1 << (j % 8)))
+		    temp_src[j] = 0xff;
+		else
+		    temp_src[j] = 0;
+	    }
+	}
+
 	glRasterPos2i(points[i].x - dest_pixmap->screen_x,
 		      points[i].y - dest_pixmap->screen_y);
 	glDrawPixels(widths[i],
 		     1,
 		     format, type,
-		     src);
-	src += PixmapBytePad(widths[i], drawable->depth);
+		     drawpixels_src);
+	if (temp_src) {
+	    src += PixmapBytePad(widths[i], drawable->depth);
+	} else {
+	    drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
+	}
     }
+    xfree(temp_src);
 }
commit d9eef95c74b7b04a3398b4cfc1a81b480838b25e
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:17:06 2009 -0700

    glamor: Fix bad fallthrough in getspans (accessing invalid memory).

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 21ba9f0..76c6cce 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -66,6 +66,7 @@ glamor_get_spans(DrawablePtr drawable,
     case 8:
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
+	break;
     case 24:
 	format = GL_RGB;
 	type = GL_UNSIGNED_BYTE;
commit 0360ba361a67f6cfa5c9c65590ed8440a153c16e
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:06:57 2009 -0700

    glamor: Fix memory leak in getspans.

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 9a7066c..21ba9f0 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -58,7 +58,7 @@ glamor_get_spans(DrawablePtr drawable,
 
     switch (drawable->depth) {
     case 1:
-	temp_dst = xalloc(4 * wmax);
+	temp_dst = xalloc(wmax);
 	format = GL_ALPHA;
 	type = GL_UNSIGNED_BYTE;
 	readpixels_dst = temp_dst;
@@ -100,4 +100,5 @@ glamor_get_spans(DrawablePtr drawable,
 	    readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
 	}
     }
+    xfree(temp_dst);
 }
commit cdb1fe6d9682616b1def52fa38b2dae623e2503f
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 08:03:17 2009 -0700

    glamor: Move setspans to a separate file.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 43512f7..098aa37 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -20,6 +20,7 @@ libglamor_la_SOURCES = \
 	glamor_fillspans.c \
 	glamor_getspans.c \
 	glamor_putimage.c \
+	glamor_setspans.c \
 	glamor_render.c \
 	glamor_tile.c \
 	glamor.h
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 055df39..38829de 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -260,41 +260,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
     glamor_solid_fail_region(pixmap, x, y, width, height);
 }
 
-static void
-glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		 DDXPointPtr points, int *widths, int n, int sorted)
-{
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-    GLenum format, type;
-    int i;
-
-    switch (drawable->depth) {
-    case 8:
-	format = GL_ALPHA;
-	type = GL_UNSIGNED_BYTE;
-    case 24:
-    case 32:
-	format = GL_BGRA;
-	type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	break;
-    default:
-	ErrorF("Unknown setspans depth %d\n", drawable->depth);
-	return;
-    }
-
-    if (!glamor_set_destination_pixmap(dest_pixmap))
-	return;
-    for (i = 0; i < n; i++) {
-	glRasterPos2i(points[i].x - dest_pixmap->screen_x,
-		      points[i].y - dest_pixmap->screen_y);
-	glDrawPixels(widths[i],
-		     1,
-		     format, type,
-		     src);
-	src += PixmapBytePad(widths[i], drawable->depth);
-    }
-}
-
 /**
  * glamor_poly_lines() checks if it can accelerate the lines as a group of
  * horizontal or vertical lines (rectangles), and uses existing rectangle fill
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 5d47c25..3929819 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -139,6 +139,10 @@ glamor_get_spans(DrawablePtr drawable,
 		 int nspans,
 		 char *dst_start);
 
+/* glamor_setspans.c */
+void glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+		      DDXPointPtr points, int *widths, int n, int sorted);
+
 /* glamor_putimage.c */
 void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c
new file mode 100644
index 0000000..bf9c508
--- /dev/null
+++ b/glamor/glamor_setspans.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+void
+glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+		 DDXPointPtr points, int *widths, int n, int sorted)
+{
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+    GLenum format, type;
+    int i;
+
+    switch (drawable->depth) {
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+    case 24:
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown setspans depth %d\n", drawable->depth);
+	return;
+    }
+
+    if (!glamor_set_destination_pixmap(dest_pixmap))
+	return;
+    for (i = 0; i < n; i++) {
+	glRasterPos2i(points[i].x - dest_pixmap->screen_x,
+		      points[i].y - dest_pixmap->screen_y);
+	glDrawPixels(widths[i],
+		     1,
+		     format, type,
+		     src);
+	src += PixmapBytePad(widths[i], drawable->depth);
+    }
+}
commit cfb8dea815086b9aafd27bd314e02739e04dfc7d
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 07:22:14 2009 -0700

    glamor: Hook up miGetImage to fix some invalid accesses.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 05e0551..a03274a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -196,6 +196,9 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_get_spans = screen->GetSpans;
     screen->GetSpans = glamor_get_spans;
 
+    glamor_priv->saved_get_image = screen->GetImage;
+    screen->GetImage = miGetImage;
+
 #ifdef RENDER
     glamor_priv->saved_composite = ps->Composite;
     ps->Composite = glamor_composite;
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6484c94..5d47c25 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -43,6 +43,7 @@ typedef struct glamor_screen_private {
     CreatePixmapProcPtr saved_create_pixmap;
     DestroyPixmapProcPtr saved_destroy_pixmap;
     GetSpansProcPtr saved_get_spans;
+    GetImageProcPtr saved_get_image;
     CompositeProcPtr saved_composite;
     TrapezoidsProcPtr saved_trapezoids;
 
commit e3c02c09c125bb5def1a70a1264ef34b18182afa
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 24 07:00:32 2009 -0700

    glamor: Add ALU support to solid, tile, and putimage.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index ba73c0b..055df39 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -69,6 +69,67 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
 }
 
 void
+glamor_set_alu(unsigned char alu)
+{
+    if (alu == GXcopy) {
+	glDisable(GL_LOGIC_OP);
+	return;
+    }
+
+    glEnable(GL_LOGIC_OP);
+
+    switch (alu) {
+    case GXclear:
+	glLogicOp(GL_CLEAR);
+	break;
+    case GXand:
+	glLogicOp(GL_AND);
+	break;
+    case GXandReverse:
+	glLogicOp(GL_AND_REVERSE);
+	break;
+    case GXandInverted:
+	glLogicOp(GL_AND_INVERTED);
+	break;
+    case GXnoop:
+	glLogicOp(GL_NOOP);
+	break;
+    case GXxor:
+	glLogicOp(GL_XOR);
+	break;
+    case GXor:
+	glLogicOp(GL_OR);
+	break;
+    case GXnor:
+	glLogicOp(GL_NOR);
+	break;
+    case GXequiv:
+	glLogicOp(GL_EQUIV);
+	break;
+    case GXinvert:
+	glLogicOp(GL_INVERT);
+	break;
+    case GXorReverse:
+	glLogicOp(GL_OR_REVERSE);
+	break;
+    case GXcopyInverted:
+	glLogicOp(GL_COPY_INVERTED);
+	break;
+    case GXorInverted:
+	glLogicOp(GL_OR_INVERTED);
+	break;
+    case GXnand:
+	glLogicOp(GL_NAND);
+	break;
+    case GXset:
+	glLogicOp(GL_SET);
+	break;
+    default:
+	FatalError("unknown logic op\n");
+    }
+}
+
+void
 glamor_get_transform_uniform_locations(GLint prog,
 				       glamor_transform_uniforms *uniform_locations)
 {
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 11d5f98..f387dab 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -153,6 +153,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 
     if (!glamor_set_destination_pixmap(pixmap))
 	return;
+    glamor_set_alu(alu);
 
     glUseProgramObjectARB(glamor_priv->solid_prog);
     glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
@@ -167,6 +168,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glEnd();
 
     glUseProgramObjectARB(0);
+    glamor_set_alu(GXcopy);
 }
 
 /* Highlight places where we're doing it wrong. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 74c1aea..6484c94 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -100,6 +100,7 @@ void glamor_link_glsl_prog(GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 				    GLfloat *color);
 Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
+void glamor_set_alu(unsigned char alu);
 void glamor_get_transform_uniform_locations(GLint prog,
 					    glamor_transform_uniforms *uniform_locations);
 void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index 2795d83..f1a4e94 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -44,10 +44,12 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     int bpp = drawable->bitsPerPixel;
     int src_stride = PixmapBytePad(w, drawable->depth);
 
-    if (gc->alu != GXcopy) {
-	ErrorF("putimage: non-copy alu\n");
-	goto fail;
+    if (!glamor_set_destination_pixmap(pixmap)) {
+	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
+		   image_format, bits);
+	return;
     }
+
     if (!glamor_pm_is_solid(drawable, gc->planemask)) {
 	ErrorF("putimage: non-solid planemask\n");
 	goto fail;
@@ -80,11 +82,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 	break;
     }
 
-    if (!glamor_set_destination_pixmap(pixmap)) {
-	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
-		   image_format, bits);
-	goto fail;
-    }
+    glamor_set_alu(gc->alu);
 
     x += drawable->x;
     y += drawable->y;
@@ -122,6 +120,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		     src);
     }
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glamor_set_alu(GXcopy);
     return;
 
 fail:
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index d476442..c33b3c1 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -109,15 +109,12 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	ErrorF("Non-FBO tile pixmap\n");
 	goto fail;
     }
-    if (alu != GXcopy) {
-	ErrorF("tile alu\n");
-	goto fail;
-    }
     if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) {
 	ErrorF("tile pm\n");
 	goto fail;
     }
 
+    glamor_set_alu(alu);
     glUseProgramObjectARB(glamor_priv->tile_prog);
     glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform);
 
@@ -143,6 +140,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
     glUseProgramObjectARB(0);
     glDisable(GL_TEXTURE_2D);
+    glamor_set_alu(GXcopy);
     return;
 
 fail:
commit 2b657d91d80a0a4d9fa2e390255ff87f51426b7c
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Aug 22 15:54:24 2009 -0700

    glamor: Add untested putimage support.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 3f5a200..43512f7 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -19,6 +19,7 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_putimage.c \
 	glamor_render.c \
 	glamor_tile.c \
 	glamor.h
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index ed6663e..ba73c0b 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -200,16 +200,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 }
 
 static void
-glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-		 int w, int h, int leftPad, int format, char *bits)
-{
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-
-    ErrorF("stub put_image depth %d\n", drawable->depth);
-    glamor_solid_fail_region(pixmap, x, y, w, h);
-}
-
-static void
 glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 DDXPointPtr points, int *widths, int n, int sorted)
 {
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index e8f486f..74c1aea 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -137,6 +137,11 @@ glamor_get_spans(DrawablePtr drawable,
 		 int nspans,
 		 char *dst_start);
 
+/* glamor_putimage.c */
+void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int leftPad, int format, char *bits);
+
 /* glamor_render.c */
 void glamor_composite(CARD8 op,
 		      PicturePtr pSrc,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
new file mode 100644
index 0000000..2795d83
--- /dev/null
+++ b/glamor/glamor_putimage.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+
+/** @file glamor_putaimge.c
+ *
+ * XPutImage implementation
+ */
+#include "glamor_priv.h"
+
+void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int left_pad, int image_format, char *bits)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    GLenum type, format;
+    RegionPtr clip;
+    BoxPtr pbox;
+    int nbox;
+    int bpp = drawable->bitsPerPixel;
+    int src_stride = PixmapBytePad(w, drawable->depth);
+
+    if (gc->alu != GXcopy) {
+	ErrorF("putimage: non-copy alu\n");
+	goto fail;
+    }
+    if (!glamor_pm_is_solid(drawable, gc->planemask)) {
+	ErrorF("putimage: non-solid planemask\n");
+	goto fail;
+    }
+    if (image_format != ZPixmap) {
+	ErrorF("putimage: non-ZPixmap\n");
+	goto fail;
+    }
+    if (bpp < 8) {
+	ErrorF("putimage: bad bpp: %d\n", bpp);
+	return;
+    }
+
+    switch (drawable->depth) {
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 24:
+	format = GL_RGB;
+	type = GL_UNSIGNED_BYTE;
+	break;
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("stub put_image depth %d\n", drawable->depth);
+	goto fail;
+	break;
+    }
+
+    if (!glamor_set_destination_pixmap(pixmap)) {
+	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
+		   image_format, bits);
+	goto fail;
+    }
+
+    x += drawable->x;
+    y += drawable->y;
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride / (bpp / 8));
+    clip = fbGetCompositeClip(gc);
+    for (nbox = REGION_NUM_RECTS(clip),
+	 pbox = REGION_RECTS(clip);
+	 nbox--;
+	 pbox++)
+    {
+	int x1 = x;
+	int y1 = y;
+	int x2 = x + w;
+	int y2 = y + h;
+	char *src;
+
+	if (x1 < pbox->x1)
+	    x1 = pbox->x1;
+	if (y1 < pbox->y1)
+	    y1 = pbox->y1;
+	if (x2 > pbox->x2)
+	    x2 = pbox->x2;
+	if (y2 > pbox->y2)
+	    y2 = pbox->y2;
+	if (x1 >= x2 || y1 >= y2)
+	    continue;
+
+	src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
+	glRasterPos2i(x1 + pixmap->screen_x, y1 + pixmap->screen_y);
+	glDrawPixels(x2 - x1,
+		     y2 - y1,
+		     format, type,
+		     src);
+    }
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    return;
+
+fail:
+    glamor_solid_fail_region(pixmap, x, y, w, h);
+}
commit f66e5c4145d003247447ac1bf93f9737c6eaa27c
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 21 10:05:32 2009 -0700

    glamor: Add 8bpp to get/setspans.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 5ecc894..ed6663e 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -218,6 +218,9 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     int i;
 
     switch (drawable->depth) {
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
     case 24:
     case 32:
 	format = GL_BGRA;
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 5853f94..9a7066c 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -63,6 +63,9 @@ glamor_get_spans(DrawablePtr drawable,
 	type = GL_UNSIGNED_BYTE;
 	readpixels_dst = temp_dst;
 	break;
+    case 8:
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
     case 24:
 	format = GL_RGB;
 	type = GL_UNSIGNED_BYTE;
commit 93ad09144213fe6b9ce8bea7ebfcc2d60887810b
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Aug 21 10:02:02 2009 -0700

    glamor: Add trapezoids code.
    
    This fixes segfaults on starting gnome-terminal.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index ff31f5d..05e0551 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -199,6 +199,8 @@ glamor_init(ScreenPtr screen)
 #ifdef RENDER
     glamor_priv->saved_composite = ps->Composite;
     ps->Composite = glamor_composite;
+    glamor_priv->saved_trapezoids = ps->Trapezoids;
+    ps->Trapezoids = glamor_trapezoids;
 #endif
 
     glamor_init_solid_shader(screen);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index aee8e2d..e8f486f 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -44,6 +44,7 @@ typedef struct glamor_screen_private {
     DestroyPixmapProcPtr saved_destroy_pixmap;
     GetSpansProcPtr saved_get_spans;
     CompositeProcPtr saved_composite;
+    TrapezoidsProcPtr saved_trapezoids;
 
     /* glamor_solid */
     GLint solid_prog;
@@ -149,6 +150,10 @@ void glamor_composite(CARD8 op,
 		      INT16 yDst,
 		      CARD16 width,
 		      CARD16 height);
+void glamor_trapezoids(CARD8 op,
+		       PicturePtr src, PicturePtr dst,
+		       PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
+		       int ntrap, xTrapezoid *traps);
 
 /* glamor_tile.c */
 void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
commit 60ca0260f23cac6577aa85aacb0e5644d5f1b349
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 17:17:43 2009 -0700

    glamor: Add more solid_fail_regions for software fallbacks.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 549a5f3..5ecc894 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -195,14 +195,18 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 	       unsigned long fg_pixel, unsigned long bg_pixel,
 	       int stipple_x, int stipple_y)
 {
-    ErrorF("stubbed out stipple\n");
+    ErrorF("stubbed out stipple depth %d\n", pixmap->drawable.depth);
+    glamor_solid_fail_region(pixmap, x, y, width, height);
 }
 
 static void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits)
 {
-    ErrorF("stub put_image\n");
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
+    ErrorF("stub put_image depth %d\n", drawable->depth);
+    glamor_solid_fail_region(pixmap, x, y, w, h);
 }
 
 static void
@@ -253,7 +257,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	ErrorF("stub poly_line\n");
+	ErrorF("stub poly_line depth %d\n", drawable->depth);
 	return;
     }
 
@@ -271,8 +275,12 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 	}
 
 	if (x1 != x2 && y1 != y2) {
+	    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
 	    xfree(rects);
-	    ErrorF("stub poly_line\n");
+
+	    ErrorF("stub diagonal poly_line\n");
+	    glamor_solid_fail_region(pixmap, x1, y1, x2 - x1, y2 - y1);
 	    return;
 	}
 
commit 7500ee2b0215932ecb6688f301fb4e6f080f8a66
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 17:05:00 2009 -0700

    glamor: Fill in 1 and 24-bit getspans.

diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index 8466208..5853f94 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -31,6 +31,18 @@
 
 #include "glamor_priv.h"
 
+static void
+set_bit(uint8_t *bitfield, unsigned int index, unsigned int val)
+{
+    int i = index / 8;
+    int mask = 1 << (index % 8);
+
+    if (val)
+	bitfield[i] |= mask;
+    else
+	bitfield[i] &= ~mask;
+}
+
 void
 glamor_get_spans(DrawablePtr drawable,
 		 int wmax,
@@ -41,10 +53,20 @@ glamor_get_spans(DrawablePtr drawable,
 {
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
     GLenum format, type;
-    int i;
+    int i, j;
+    uint8_t *temp_dst = NULL, *readpixels_dst = (uint8_t *)dst;
 
     switch (drawable->depth) {
+    case 1:
+	temp_dst = xalloc(4 * wmax);
+	format = GL_ALPHA;
+	type = GL_UNSIGNED_BYTE;
+	readpixels_dst = temp_dst;
+	break;
     case 24:
+	format = GL_RGB;
+	type = GL_UNSIGNED_BYTE;
+	break;
     case 32:
 	format = GL_BGRA;
 	type = GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -65,7 +87,14 @@ glamor_get_spans(DrawablePtr drawable,
 		     widths[i],
 		     1,
 		     format, type,
-		     dst);
-	dst += PixmapBytePad(widths[i], drawable->depth);
+		     readpixels_dst);
+	if (temp_dst) {
+	    for (j = 0; j < widths[i]; j++) {
+		set_bit((uint8_t *)dst, j, temp_dst[j] & 0x1);
+	    }
+	    dst += PixmapBytePad(widths[i], drawable->depth);
+	} else {
+	    readpixels_dst += PixmapBytePad(widths[i], drawable->depth);
+	}
     }
 }
commit f6cffbb2ba66948ad5cc1cbe20e12de204de175d
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 16:43:22 2009 -0700

    glamor: Add stub Composite support.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2453566..3f5a200 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -19,5 +19,6 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_render.c \
 	glamor_tile.c \
 	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 03886ad..ff31f5d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -147,6 +147,9 @@ Bool
 glamor_init(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv;
+#ifdef RENDER
+    PictureScreenPtr ps = GetPictureScreenIfSet(screen);
+#endif
 
     glamor_priv = xcalloc(1, sizeof(*glamor_priv));
     if (glamor_priv == NULL)
@@ -193,6 +196,11 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_get_spans = screen->GetSpans;
     screen->GetSpans = glamor_get_spans;
 
+#ifdef RENDER
+    glamor_priv->saved_composite = ps->Composite;
+    ps->Composite = glamor_composite;
+#endif
+
     glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
 
@@ -208,9 +216,15 @@ void
 glamor_fini(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+#ifdef RENDER
+    PictureScreenPtr	ps = GetPictureScreenIfSet(screen);
+#endif
 
     screen->CreateGC = glamor_priv->saved_create_gc;
     screen->CreatePixmap = glamor_priv->saved_create_pixmap;
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
     screen->GetSpans = glamor_priv->saved_get_spans;
+#ifdef RENDER
+    ps->Composite = glamor_priv->saved_composite;
+#endif
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 9bae814..aee8e2d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -43,6 +43,7 @@ typedef struct glamor_screen_private {
     CreatePixmapProcPtr saved_create_pixmap;
     DestroyPixmapProcPtr saved_destroy_pixmap;
     GetSpansProcPtr saved_get_spans;
+    CompositeProcPtr saved_composite;
 
     /* glamor_solid */
     GLint solid_prog;
@@ -135,6 +136,20 @@ glamor_get_spans(DrawablePtr drawable,
 		 int nspans,
 		 char *dst_start);
 
+/* glamor_render.c */
+void glamor_composite(CARD8 op,
+		      PicturePtr pSrc,
+		      PicturePtr pMask,
+		      PicturePtr pDst,
+		      INT16 xSrc,
+		      INT16 ySrc,
+		      INT16 xMask,
+		      INT16 yMask,
+		      INT16 xDst,
+		      INT16 yDst,
+		      CARD16 width,
+		      CARD16 height);
+
 /* glamor_tile.c */
 void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 int x, int y, int width, int height,
commit 2fa26c4958168064da95361db78ccc518c8f3ed8
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 16:43:03 2009 -0700

    glamor: Free resources when destroying pixmaps.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index c3e4eb9..03886ad 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -121,6 +121,13 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 static Bool
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
+    if (pixmap->refcnt == 1) {
+	glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	glDeleteFramebuffersEXT(1, &pixmap_priv->fb);
+	glDeleteTextures(1, &pixmap_priv->tex);
+    }
+
     return fbDestroyPixmap(pixmap);
 }
 
commit 16c3b929dd4cae6b40e847256db6ff32e63e9029
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 16:06:42 2009 -0700

    glamor: Add untested support for tile filling.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 2d9fdf5..2453566 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -19,4 +19,5 @@ libglamor_la_SOURCES = \
 	glamor_fill.c \
 	glamor_fillspans.c \
 	glamor_getspans.c \
+	glamor_tile.c \
 	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 7b81aba..c3e4eb9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -187,6 +187,7 @@ glamor_init(ScreenPtr screen)
     screen->GetSpans = glamor_get_spans;
 
     glamor_init_solid_shader(screen);
+    glamor_init_tile_shader(screen);
 
     return TRUE;
 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index e4aa95d..549a5f3 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -198,15 +198,6 @@ glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
     ErrorF("stubbed out stipple\n");
 }
 
-void
-glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
-	    int x, int y, int width, int height,
-	    unsigned char alu, unsigned long planemask,
-	    int tile_x, int tile_y)
-{
-    ErrorF("stubbed out tile\n");
-}
-
 static void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits)
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 0d87bd0..11d5f98 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -168,3 +168,23 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 
     glUseProgramObjectARB(0);
 }
+
+/* Highlight places where we're doing it wrong. */
+void
+glamor_solid_fail_region(PixmapPtr pixmap, int x, int y, int width, int height)
+{
+    unsigned long pixel;
+
+    switch (pixmap->drawable.depth) {
+    case 24:
+    case 32:
+	pixel = 0x00ff00ff; /* our favorite color */
+	break;
+    default:
+    case 8:
+	pixel = 0xd0d0d0d0;
+	break;
+    }
+
+    glamor_solid(pixmap, x, y, width, height, GXcopy, ~0, pixel);
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6d08b00..9bae814 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -48,6 +48,9 @@ typedef struct glamor_screen_private {
     GLint solid_prog;
     GLint solid_color_uniform_location;
     glamor_transform_uniforms solid_transform;
+
+    GLint tile_prog;
+    glamor_transform_uniforms tile_transform;
 } glamor_screen_private;
 
 typedef struct glamor_pixmap_private {
@@ -69,6 +72,17 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
     return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
 }
 
+/**
+ * Returns TRUE if the given planemask covers all the significant bits in the
+ * pixel values for pDrawable.
+ */
+static inline Bool
+glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
+{
+    return (planemask & FbFullMask(drawable->depth)) ==
+	FbFullMask(drawable->depth);
+}
+
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
@@ -79,10 +93,6 @@ void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    unsigned char alu, unsigned long planemask,
 		    unsigned long fg_pixel, unsigned long bg_pixel,
 		    int stipple_x, int stipple_y);
-void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
-		 int x, int y, int width, int height,
-		 unsigned char alu, unsigned long planemask,
-		 int tile_x, int tile_y);
 GLint glamor_compile_glsl_prog(GLenum type, const char *source);
 void glamor_link_glsl_prog(GLint prog);
 void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
@@ -103,6 +113,8 @@ void glamor_fill(DrawablePtr drawable,
 void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
 		  unsigned char alu, unsigned long planemask,
 		  unsigned long fg_pixel);
+void glamor_solid_fail_region(PixmapPtr pixmap,
+			      int x, int y, int width, int height);
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
@@ -123,4 +135,11 @@ glamor_get_spans(DrawablePtr drawable,
 		 int nspans,
 		 char *dst_start);
 
+/* glamor_tile.c */
+void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+		 int x, int y, int width, int height,
+		 unsigned char alu, unsigned long planemask,
+		 int tile_x, int tile_y);
+void glamor_init_tile_shader(ScreenPtr screen);
+
 #endif /* GLAMOR_PRIV_H */
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
new file mode 100644
index 0000000..d476442
--- /dev/null
+++ b/glamor/glamor_tile.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_tile.c
+ *
+ * Implements the basic fill-with-a-tile support used by multiple GC ops.
+ */
+
+void
+glamor_init_tile_shader(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    const char *tile_vs =
+	"uniform float x_bias;\n"
+	"uniform float x_scale;\n"
+	"uniform float y_bias;\n"
+	"uniform float y_scale;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
+	"			   0,\n"
+	"			   1);\n"
+	"	gl_TexCoord[0] = vec4(gl_MultiTexCoord0.xy, 0, 1);\n"
+	"}\n";
+    const char *tile_fs =
+	"uniform sampler2D sampler;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
+	"}\n";
+    GLint fs_prog, vs_prog;
+    GLint sampler_uniform_location;
+
+    if (!GLEW_ARB_fragment_shader)
+	return;
+
+    glamor_priv->tile_prog = glCreateProgramObjectARB();
+    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, tile_vs);
+    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, tile_fs);
+    glAttachObjectARB(glamor_priv->tile_prog, vs_prog);
+    glAttachObjectARB(glamor_priv->tile_prog, fs_prog);
+    glamor_link_glsl_prog(glamor_priv->tile_prog);
+
+    sampler_uniform_location =
+	glGetUniformLocationARB(glamor_priv->tile_prog, "sampler");
+    glUseProgramObjectARB(glamor_priv->tile_prog);
+    glUniform1iARB(sampler_uniform_location, 0);
+    glamor_get_transform_uniform_locations(glamor_priv->tile_prog,
+					   &glamor_priv->tile_transform);
+}
+
+void
+glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+	    int x, int y, int width, int height,
+	    unsigned char alu, unsigned long planemask,
+	    int tile_x, int tile_y)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    int x1 = x;
+    int x2 = x + width;
+    int y1 = y;
+    int y2 = y + height;
+    int tile_x1 = tile_x + tile->screen_x;
+    int tile_x2 = tile_x + tile->screen_x + width;
+    int tile_y1 = tile_y + tile->screen_y;
+    int tile_y2 = tile_y + tile->screen_y + height;
+    glamor_pixmap_private *tile_priv = glamor_get_pixmap_private(tile);
+
+    if (glamor_priv->tile_prog == 0) {
+	ErrorF("Tiling unsupported\n");
+	goto fail;
+    }
+
+    if (!glamor_set_destination_pixmap(pixmap))
+	goto fail;
+    if (tile_priv->fb == 0) {
+	ErrorF("Non-FBO tile pixmap\n");
+	goto fail;
+    }
+    if (alu != GXcopy) {
+	ErrorF("tile alu\n");
+	goto fail;
+    }
+    if (!glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+	ErrorF("tile pm\n");
+	goto fail;
+    }
+
+    glUseProgramObjectARB(glamor_priv->tile_prog);
+    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->tile_transform);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, tile_priv->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glEnable(GL_TEXTURE_2D);
+
+    tile_x += tile->screen_x;
+    tile_y += tile->screen_y;
+
+    glBegin(GL_TRIANGLE_FAN);
+    glMultiTexCoord2f(0, tile_x1, tile_y1);
+    glVertex2f(x1, y1);
+    glMultiTexCoord2f(0, tile_x1, tile_y2);
+    glVertex2f(x1, y2);
+    glMultiTexCoord2f(0, tile_x2, tile_y2);
+    glVertex2f(x2, y2);
+    glMultiTexCoord2f(0, tile_x2, tile_y1);
+    glVertex2f(x2, y1);
+    glEnd();
+
+    glUseProgramObjectARB(0);
+    glDisable(GL_TEXTURE_2D);
+    return;
+
+fail:
+    glamor_solid_fail_region(pixmap, x, y, width, height);
+    return;
+}
commit 8016135ec7616530e64d0019ce0401e62b25e483
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 15:37:22 2009 -0700

    glamor: Fill out glamor_get_color_4f_from_pixel() a bit.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index ffccd3e..e4aa95d 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -158,17 +158,33 @@ void
 glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
 			       GLfloat *color)
 {
-    if (pixmap->drawable.depth < 24) {
-	ErrorF("pixmap with bad depth\n");
-	color[0] = 1.0;
+    switch (pixmap->drawable.depth) {
+    case 1:
+	color[0] = 0.0;
 	color[1] = 0.0;
-	color[2] = 1.0;
-	color[3] = 1.0;
-    } else {
+	color[2] = 0.0;
+	color[3] = fg_pixel & 0x01;
+	break;
+    case 8:
+	color[0] = 0.0;
+	color[1] = 0.0;
+	color[2] = 0.0;
+	color[3] = (fg_pixel & 0xff) / 255.0;
+	break;
+    case 24:
+    case 32:
 	color[0] = ubyte_to_float(fg_pixel >> 16);
 	color[1] = ubyte_to_float(fg_pixel >> 8);
 	color[2] = ubyte_to_float(fg_pixel >> 0);
 	color[3] = ubyte_to_float(fg_pixel >> 24);
+	break;
+    default:
+	ErrorF("pixmap with bad depth: %d\n", pixmap->drawable.depth);
+	color[0] = 1.0;
+	color[1] = 0.0;
+	color[2] = 1.0;
+	color[3] = 1.0;
+	break;
     }
 }
 
commit 519103565c1b182014dea93c58917bf7e5a35fcb
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 15:28:13 2009 -0700

    glamor: Create FBOs for pixmaps.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0aa9db8..7b81aba 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -40,6 +40,8 @@
 
 static int glamor_screen_private_key_index;
 DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
+static int glamor_pixmap_private_key_index;
+DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 
 /**
  * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
@@ -63,9 +65,57 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
 
 static PixmapPtr
 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
-		     unsigned int usage_hint)
+		     unsigned int usage)
 {
-    return fbCreatePixmap(screen, w, h, depth, usage_hint);
+    PixmapPtr pixmap;
+    glamor_pixmap_private *pixmap_priv;
+    GLenum format;
+
+    if (w > 32767 || h > 32767)
+	return NullPixmap;
+
+    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (w == 0 || h == 0)
+	return pixmap;
+
+    /* We should probably take advantage of ARB_fbo's allowance of GL_ALPHA.
+     * FBOs, which EXT_fbo forgot to do.
+     */
+    switch (depth) {
+    case 24:
+	format = GL_RGB;
+	break;
+    default:
+	format = GL_RGBA;
+	break;
+    }
+
+    /* Create the texture used to store the pixmap's data. */
+    glGenTextures(1, &pixmap_priv->tex);
+    glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+		 format, GL_UNSIGNED_BYTE, NULL);
+
+    /* Create a framebuffer object wrapping the texture so that we can render
+     * to it.
+     */
+    glGenFramebuffersEXT(1, &pixmap_priv->fb);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+			      GL_COLOR_ATTACHMENT0_EXT,
+			      GL_TEXTURE_2D,
+			      pixmap_priv->tex,
+			      0);
+
+    screen->ModifyPixmapHeader(pixmap, w, h, 0, 0,
+			       (w * pixmap->drawable.bitsPerPixel + 7) / 8,
+			       NULL);
+
+    return pixmap;
 }
 
 static Bool
@@ -96,9 +146,19 @@ glamor_init(ScreenPtr screen)
 	return FALSE;
 
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
+    if (!dixRequestPrivate(glamor_pixmap_private_key,
+			   sizeof(glamor_pixmap_private))) {
+	LogMessage(X_WARNING,
+		   "glamor%d: Failed to allocate pixmap private\n",
+		   screen->myNum);
+    }
 
     glewInit();
 
+    if (!GLEW_EXT_framebuffer_object) {
+	ErrorF("GL_EXT_framebuffer_object required\n");
+	goto fail;
+    }
     if (!GLEW_ARB_shader_objects) {
 	ErrorF("GL_ARB_shader_objects required\n");
 	goto fail;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index c8b331a..ffccd3e 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -42,17 +42,28 @@
 Bool
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
 
-    if (pixmap != screen_pixmap) {
-	ErrorF("stubbed drawing to non-screen pixmap\n");
+    if (pixmap_priv == NULL) {
+	ErrorF("no pixmap priv?");
 	return FALSE;
     }
 
+    if (pixmap_priv->fb == 0) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (pixmap != screen_pixmap) {
+	    ErrorF("No FBO\n");
+	    return FALSE;
+	}
+    }
+
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+
     glViewport(0, 0,
-	       screen_pixmap->drawable.width,
-	       screen_pixmap->drawable.height);
+	       pixmap->drawable.width,
+	       pixmap->drawable.height);
 
     return TRUE;
 }
@@ -75,10 +86,18 @@ void
 glamor_set_transform_for_pixmap(PixmapPtr pixmap,
 				glamor_transform_uniforms *uniform_locations)
 {
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
     glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
     glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
     glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
-    glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
+    if (pixmap == screen_pixmap)
+	glUniform1fARB(uniform_locations->y_scale,
+		       -2.0f / pixmap->drawable.height);
+    else
+	glUniform1fARB(uniform_locations->y_scale,
+		       2.0f / pixmap->drawable.height);
 }
 
 GLint
@@ -176,53 +195,38 @@ static void
 glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 		 int w, int h, int leftPad, int format, char *bits)
 {
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-
-    if (screen_pixmap != dest_pixmap) {
-	fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
-    } else {
-	ErrorF("stub put_image\n");
-    }
+    ErrorF("stub put_image\n");
 }
 
 static void
 glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 		 DDXPointPtr points, int *widths, int n, int sorted)
 {
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+    GLenum format, type;
+    int i;
 
-    if (screen_pixmap != dest_pixmap) {
-	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
-    } else {
-	GLenum format, type;
-	int i;
-
-	switch (drawable->depth) {
-	case 24:
-	case 32:
-	    format = GL_BGRA;
-	    type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	    break;
-	default:
-	    ErrorF("Unknown setspans depth %d\n", drawable->depth);
-	    return;
-	}
+    switch (drawable->depth) {
+    case 24:
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown setspans depth %d\n", drawable->depth);
+	return;
+    }
 
-	if (!glamor_set_destination_pixmap(dest_pixmap))
-	    return;
-	for (i = 0; i < n; i++) {
-	    glRasterPos2i(points[i].x - dest_pixmap->screen_x,
-			  points[i].y - dest_pixmap->screen_y);
-	    glDrawPixels(widths[i],
-			 1,
-			 format, type,
-			 src);
-	    src += PixmapBytePad(widths[i], drawable->depth);
-	}
+    if (!glamor_set_destination_pixmap(dest_pixmap))
+	return;
+    for (i = 0; i < n; i++) {
+	glRasterPos2i(points[i].x - dest_pixmap->screen_x,
+		      points[i].y - dest_pixmap->screen_y);
+	glDrawPixels(widths[i],
+		     1,
+		     format, type,
+		     src);
+	src += PixmapBytePad(widths[i], drawable->depth);
     }
 }
 
@@ -235,9 +239,6 @@ static void
 glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 		  DDXPointPtr points)
 {
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
     xRectangle *rects;
     int x1, x2, y1, y2;
     int i;
@@ -245,10 +246,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	if (dest_pixmap != screen_pixmap)
-	    fbPolyLine(drawable, gc, mode, n, points);
-	else
-	    ErrorF("stub poly_line\n");
+	ErrorF("stub poly_line\n");
 	return;
     }
 
@@ -267,10 +265,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 
 	if (x1 != x2 && y1 != y2) {
 	    xfree(rects);
-	    if (dest_pixmap != screen_pixmap)
-		fbPolyLine(drawable, gc, mode, n, points);
-	    else
-		ErrorF("stub poly_line\n");
+	    ErrorF("stub poly_line\n");
 	    return;
 	}
 
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
index b0b704f..120e346 100644
--- a/glamor/glamor_fillspans.c
+++ b/glamor/glamor_fillspans.c
@@ -44,14 +44,6 @@ glamor_fill_spans(DrawablePtr drawable,
     int extentX1, extentX2, extentY1, extentY2;
     int fullX1, fullX2, fullY1;
     int partX1, partX2;
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
-
-    if (dest_pixmap != screen_pixmap) {
-	fbFillSpans(drawable, gc, n, points, widths, sorted);
-	return;
-    }
 
     extents = REGION_EXTENTS(gc->pScreen, clip);
     extentX1 = extents->x1;
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
index b10a29d..8466208 100644
--- a/glamor/glamor_getspans.c
+++ b/glamor/glamor_getspans.c
@@ -39,36 +39,33 @@ glamor_get_spans(DrawablePtr drawable,
 		 int count,
 		 char *dst)
 {
-    ScreenPtr screen = drawable->pScreen;
-    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    GLenum format, type;
+    int i;
 
-    if (screen_pixmap != pixmap) {
+    switch (drawable->depth) {
+    case 24:
+    case 32:
+	format = GL_BGRA;
+	type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	break;
+    default:
+	ErrorF("Unknown getspans depth %d\n", drawable->depth);
+	return;
+    }
+
+    if (!glamor_set_destination_pixmap(pixmap)) {
 	fbGetSpans(drawable, wmax, points, widths, count, dst);
 	return;
-    } else {
-	GLenum format, type;
-	int i;
-	switch (drawable->depth) {
-	case 24:
-	case 32:
-	    format = GL_BGRA;
-	    type = GL_UNSIGNED_INT_8_8_8_8_REV;
-	    break;
-	default:
-	    ErrorF("Unknown getspans depth %d\n", drawable->depth);
-	    return;
-	}
-	if (!glamor_set_destination_pixmap(pixmap))
-	    return;
-	for (i = 0; i < count; i++) {
-	    glReadPixels(points[i].x - pixmap->screen_x,
-			 points[i].y - pixmap->screen_y,
-			 widths[i],
-			 1,
-			 format, type,
-			 dst);
-	    dst += PixmapBytePad(widths[i], drawable->depth);
-	}
+    }
+
+    for (i = 0; i < count; i++) {
+	glReadPixels(points[i].x - pixmap->screen_x,
+		     points[i].y - pixmap->screen_y,
+		     widths[i],
+		     1,
+		     format, type,
+		     dst);
+	dst += PixmapBytePad(widths[i], drawable->depth);
     }
 }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 016a404..6d08b00 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -50,13 +50,24 @@ typedef struct glamor_screen_private {
     glamor_transform_uniforms solid_transform;
 } glamor_screen_private;
 
+typedef struct glamor_pixmap_private {
+    GLuint tex;
+    GLuint fb;
+} glamor_pixmap_private;
+
 extern DevPrivateKey glamor_screen_private_key;
+extern DevPrivateKey glamor_pixmap_private_key;
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
 {
     return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
 						     glamor_screen_private_key);
 }
+static inline glamor_pixmap_private *
+glamor_get_pixmap_private(PixmapPtr pixmap)
+{
+    return dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+}
 
 /* glamor.c */
 PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
commit f92d1478e984d57806731886820f47e1258b5115
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 14:45:47 2009 -0700

    glamor: Maybe fix up the format/type for setspans.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 9c892ea..c8b331a 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -198,8 +198,20 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
     if (screen_pixmap != dest_pixmap) {
 	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
     } else {
+	GLenum format, type;
 	int i;
 
+	switch (drawable->depth) {
+	case 24:
+	case 32:
+	    format = GL_BGRA;
+	    type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	    break;
+	default:
+	    ErrorF("Unknown setspans depth %d\n", drawable->depth);
+	    return;
+	}
+
 	if (!glamor_set_destination_pixmap(dest_pixmap))
 	    return;
 	for (i = 0; i < n; i++) {
@@ -207,7 +219,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 			  points[i].y - dest_pixmap->screen_y);
 	    glDrawPixels(widths[i],
 			 1,
-			 GL_RGBA, GL_UNSIGNED_BYTE,
+			 format, type,
 			 src);
 	    src += PixmapBytePad(widths[i], drawable->depth);
 	}
commit 4f139db92fb283792adae8d39a49a083e4382fb5
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 14:43:43 2009 -0700

    glamor: Add getspans implementation.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index b6a64fb..2d9fdf5 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -18,4 +18,5 @@ libglamor_la_SOURCES = \
 	glamor_core.c \
 	glamor_fill.c \
 	glamor_fillspans.c \
+	glamor_getspans.c \
 	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 050dd3d..0aa9db8 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -123,6 +123,9 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
     screen->DestroyPixmap = glamor_destroy_pixmap;
 
+    glamor_priv->saved_get_spans = screen->GetSpans;
+    screen->GetSpans = glamor_get_spans;
+
     glamor_init_solid_shader(screen);
 
     return TRUE;
@@ -141,4 +144,5 @@ glamor_fini(ScreenPtr screen)
     screen->CreateGC = glamor_priv->saved_create_gc;
     screen->CreatePixmap = glamor_priv->saved_create_pixmap;
     screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
+    screen->GetSpans = glamor_priv->saved_get_spans;
 }
diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c
new file mode 100644
index 0000000..b10a29d
--- /dev/null
+++ b/glamor/glamor_getspans.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+void
+glamor_get_spans(DrawablePtr drawable,
+		 int wmax,
+		 DDXPointPtr points,
+		 int *widths,
+		 int count,
+		 char *dst)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+
+    if (screen_pixmap != pixmap) {
+	fbGetSpans(drawable, wmax, points, widths, count, dst);
+	return;
+    } else {
+	GLenum format, type;
+	int i;
+	switch (drawable->depth) {
+	case 24:
+	case 32:
+	    format = GL_BGRA;
+	    type = GL_UNSIGNED_INT_8_8_8_8_REV;
+	    break;
+	default:
+	    ErrorF("Unknown getspans depth %d\n", drawable->depth);
+	    return;
+	}
+	if (!glamor_set_destination_pixmap(pixmap))
+	    return;
+	for (i = 0; i < count; i++) {
+	    glReadPixels(points[i].x - pixmap->screen_x,
+			 points[i].y - pixmap->screen_y,
+			 widths[i],
+			 1,
+			 format, type,
+			 dst);
+	    dst += PixmapBytePad(widths[i], drawable->depth);
+	}
+    }
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 3216a7a..016a404 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -42,6 +42,7 @@ typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
     DestroyPixmapProcPtr saved_destroy_pixmap;
+    GetSpansProcPtr saved_get_spans;
 
     /* glamor_solid */
     GLint solid_prog;
@@ -102,4 +103,13 @@ void glamor_fill_spans(DrawablePtr drawable,
 
 void glamor_init_solid_shader(ScreenPtr screen);
 
+/* glamor_getspans.c */
+void
+glamor_get_spans(DrawablePtr drawable,
+		 int wmax,
+		 DDXPointPtr points,
+		 int *widths,
+		 int nspans,
+		 char *dst_start);
+
 #endif /* GLAMOR_PRIV_H */
commit f1dbed5456e5a608425530e0dde2dc617a7c6115
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 12:32:53 2009 -0700

    glamor: Move to using shader objects.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 86a7694..050dd3d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -97,12 +97,21 @@ glamor_init(ScreenPtr screen)
 
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
 
+    glewInit();
+
+    if (!GLEW_ARB_shader_objects) {
+	ErrorF("GL_ARB_shader_objects required\n");
+	goto fail;
+    }
+    if (!GLEW_ARB_vertex_shader) {
+	ErrorF("GL_ARB_vertex_shader required\n");
+	goto fail;
+    }
+
     if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
 					glamor_wakeup_handler,
 					NULL)) {
-	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
-	xfree(glamor_priv);
-	return FALSE;
+	goto fail;
     }
 
     glamor_priv->saved_create_gc = screen->CreateGC;
@@ -114,9 +123,14 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
     screen->DestroyPixmap = glamor_destroy_pixmap;
 
-    glewInit();
+    glamor_init_solid_shader(screen);
 
     return TRUE;
+
+fail:
+    xfree(glamor_priv);
+    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
+    return FALSE;
 }
 
 void
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 7f97190..9c892ea 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -39,16 +39,7 @@
 
 #include "glamor_priv.h"
 
-static void
-glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel)
-{
-    glColor4ub((fg_pixel >> 16) & 0xff,
-	       (fg_pixel >> 8) & 0xff,
-	       (fg_pixel) & 0xff,
-	       (fg_pixel >> 24) & 0xff);
-}
-
-static Bool
+Bool
 glamor_set_destination_pixmap(PixmapPtr pixmap)
 {
     ScreenPtr screen = pixmap->drawable.pScreen;
@@ -63,37 +54,103 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
 	       screen_pixmap->drawable.width,
 	       screen_pixmap->drawable.height);
 
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(0, screen_pixmap->drawable.width,
-	    0, screen_pixmap->drawable.height,
-	    -1.0, 1.0);
+    return TRUE;
+}
 
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+void
+glamor_get_transform_uniform_locations(GLint prog,
+				       glamor_transform_uniforms *uniform_locations)
+{
+    uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
+    uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
+    uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
+    uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
+}
 
-    return TRUE;
+/* We don't use a full matrix for our transformations because it's
+ * wasteful when all we want is to rescale to NDC and possibly do a flip
+ * if it's the front buffer.
+ */
+void
+glamor_set_transform_for_pixmap(PixmapPtr pixmap,
+				glamor_transform_uniforms *uniform_locations)
+{
+    glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
+    glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
+    glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
+    glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
+}
+
+GLint
+glamor_compile_glsl_prog(GLenum type, const char *source)
+{
+    GLint ok;
+    GLint prog;
+
+    prog = glCreateShaderObjectARB(type);
+    glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
+    glCompileShaderARB(prog);
+    glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
+    if (!ok) {
+	GLchar *info;
+	GLint size;
+
+	glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+	info = malloc(size);
+
+	glGetInfoLogARB(prog, size, NULL, info);
+	ErrorF("Failed to compile %s: %s\n",
+	       type == GL_FRAGMENT_SHADER ? "FS" : "VS",
+	       info);
+	ErrorF("Program source:\n%s", source);
+	FatalError("GLSL compile failure\n");
+    }
+
+    return prog;
 }
 
 void
-glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-	     unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
+glamor_link_glsl_prog(GLint prog)
 {
-    int x1 = x;
-    int x2 = x + width;
-    int y1 = y;
-    int y2 = y + height;
+    GLint ok;
 
-    if (!glamor_set_destination_pixmap(pixmap))
-	return;
-    glamor_set_color_from_fgpixel(pixmap, fg_pixel);
-
-    glBegin(GL_TRIANGLE_FAN);
-    glVertex2f(x1, y1);
-    glVertex2f(x1, y2);
-    glVertex2f(x2, y2);
-    glVertex2f(x2, y1);
-    glEnd();
+    glLinkProgram(prog);
+    glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
+    if (!ok) {
+	GLchar *info;
+	GLint size;
+
+	glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
+	info = malloc(size);
+
+	glGetInfoLogARB(prog, size, NULL, info);
+	ErrorF("Failed to link: %s\n",
+	       info);
+	FatalError("GLSL link failure\n");
+    }
+}
+
+static float ubyte_to_float(uint8_t b)
+{
+    return b / 255.0f;
+}
+
+void
+glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
+			       GLfloat *color)
+{
+    if (pixmap->drawable.depth < 24) {
+	ErrorF("pixmap with bad depth\n");
+	color[0] = 1.0;
+	color[1] = 0.0;
+	color[2] = 1.0;
+	color[3] = 1.0;
+    } else {
+	color[0] = ubyte_to_float(fg_pixel >> 16);
+	color[1] = ubyte_to_float(fg_pixel >> 8);
+	color[2] = ubyte_to_float(fg_pixel >> 0);
+	color[3] = ubyte_to_float(fg_pixel >> 24);
+    }
 }
 
 void
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 36e7bad..0d87bd0 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -82,3 +82,89 @@ glamor_fill(DrawablePtr drawable,
 	break;
     }
 }
+
+void
+glamor_init_solid_shader(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    const char *solid_vs_only =
+	"uniform vec4 color;\n"
+	"uniform float x_bias;\n"
+	"uniform float x_scale;\n"
+	"uniform float y_bias;\n"
+	"uniform float y_scale;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
+	"			   0,\n"
+	"			   1);\n"
+	"	gl_Color = color;\n"
+	"}\n";
+    const char *solid_vs =
+	"uniform float x_bias;\n"
+	"uniform float x_scale;\n"
+	"uniform float y_bias;\n"
+	"uniform float y_scale;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
+	"			   (gl_Vertex.y + y_bias) * y_scale,\n"
+	"			   0,\n"
+	"			   1);\n"
+	"}\n";
+    const char *solid_fs =
+	"uniform vec4 color;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = color;\n"
+	"}\n";
+    GLint fs_prog, vs_prog;
+
+    glamor_priv->solid_prog = glCreateProgramObjectARB();
+    if (GLEW_ARB_fragment_shader) {
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs);
+	fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs);
+	glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
+	glAttachObjectARB(glamor_priv->solid_prog, fs_prog);
+    } else {
+	vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only);
+	glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
+    }
+    glamor_link_glsl_prog(glamor_priv->solid_prog);
+
+    glamor_priv->solid_color_uniform_location =
+	glGetUniformLocationARB(glamor_priv->solid_prog, "color");
+    glamor_get_transform_uniform_locations(glamor_priv->solid_prog,
+					   &glamor_priv->solid_transform);
+}
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+	     unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    int x1 = x;
+    int x2 = x + width;
+    int y1 = y;
+    int y2 = y + height;
+    GLfloat color[4];
+
+    if (!glamor_set_destination_pixmap(pixmap))
+	return;
+
+    glUseProgramObjectARB(glamor_priv->solid_prog);
+    glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
+    glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
+    glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
+
+    glBegin(GL_TRIANGLE_FAN);
+    glVertex2f(x1, y1);
+    glVertex2f(x1, y2);
+    glVertex2f(x2, y2);
+    glVertex2f(x2, y1);
+    glEnd();
+
+    glUseProgramObjectARB(0);
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 285799d..3216a7a 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,10 +31,22 @@
 #include "glamor.h"
 #include <GL/glew.h>
 
+typedef struct glamor_transform_uniforms {
+    GLint x_bias;
+    GLint x_scale;
+    GLint y_bias;
+    GLint y_scale;
+} glamor_transform_uniforms;
+
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
     CreatePixmapProcPtr saved_create_pixmap;
     DestroyPixmapProcPtr saved_destroy_pixmap;
+
+    /* glamor_solid */
+    GLint solid_prog;
+    GLint solid_color_uniform_location;
+    glamor_transform_uniforms solid_transform;
 } glamor_screen_private;
 
 extern DevPrivateKey glamor_screen_private_key;
@@ -50,9 +62,6 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
 /* glamor_core.c */
 Bool glamor_create_gc(GCPtr gc);
-void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-		  unsigned char alu, unsigned long planemask,
-		  unsigned long fg_pixel);
 void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
 		    int x, int y, int width, int height,
 		    unsigned char alu, unsigned long planemask,
@@ -62,6 +71,15 @@ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		 int x, int y, int width, int height,
 		 unsigned char alu, unsigned long planemask,
 		 int tile_x, int tile_y);
+GLint glamor_compile_glsl_prog(GLenum type, const char *source);
+void glamor_link_glsl_prog(GLint prog);
+void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
+				    GLfloat *color);
+Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
+void glamor_get_transform_uniform_locations(GLint prog,
+					    glamor_transform_uniforms *uniform_locations);
+void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
+				     glamor_transform_uniforms *uniform_locations);
 
 /* glamor_fill.c */
 void glamor_fill(DrawablePtr drawable,
@@ -70,6 +88,9 @@ void glamor_fill(DrawablePtr drawable,
 		 int y,
 		 int width,
 		 int height);
+void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+		  unsigned char alu, unsigned long planemask,
+		  unsigned long fg_pixel);
 
 /* glamor_fillspans.c */
 void glamor_fill_spans(DrawablePtr drawable,
@@ -79,4 +100,6 @@ void glamor_fill_spans(DrawablePtr drawable,
 		       int *widths,
 		       int sorted);
 
+void glamor_init_solid_shader(ScreenPtr screen);
+
 #endif /* GLAMOR_PRIV_H */
commit fbbdd788cbc822fc8a2d2726435bfa39e69a0e85
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 12:36:33 2009 -0700

    glamor: Fix up DrawPixels arguments to bear some relation to reality.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 39f36cd..7f97190 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -146,10 +146,11 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 	if (!glamor_set_destination_pixmap(dest_pixmap))
 	    return;
 	for (i = 0; i < n; i++) {
-	    glDrawPixels(points[i].x - dest_pixmap->screen_x,
-			 points[i].y - dest_pixmap->screen_y,
-			 widths[i],
+	    glRasterPos2i(points[i].x - dest_pixmap->screen_x,
+			  points[i].y - dest_pixmap->screen_y);
+	    glDrawPixels(widths[i],
 			 1,
+			 GL_RGBA, GL_UNSIGNED_BYTE,
 			 src);
 	    src += PixmapBytePad(widths[i], drawable->depth);
 	}
commit 74f262bcdb3d8ae769ef8975cf4a4b2ebaeb6b39
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 11:39:05 2009 -0700

    glamor: remove gratuitous flush.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 651414b..39f36cd 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -94,8 +94,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glVertex2f(x2, y2);
     glVertex2f(x2, y1);
     glEnd();
-
-    glFlush();
 }
 
 void
commit 399e00698976dd2e503b3a092bfe54ab24ea26d9
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 11:37:37 2009 -0700

    glamor: Fix up block/wakeup handler.
    
    Prototypes are fixed, and we don't need to flush on wakeup.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 08e7ff9..86a7694 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -75,15 +75,14 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
 }
 
 static void
-glamor_block_handler(void *data, OSTimePtr wt, void *last_select_mask)
+glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
     glFlush();
 }
 
 static void
-glamor_wakeup_handler(void *data, OSTimePtr wt, void *last_select_mask)
+glamor_wakeup_handler(void *data, int result, void *last_select_mask)
 {
-    glFlush();
 }
 
 /** Set up glamor for an already-configured GL context. */
commit 2e35ceca65bbebf07c15ea2cff932a8749955c2b
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 11:19:43 2009 -0700

    ephyr: Use GLEW.
    
    This will hide all sorts of extension stuff from us.

diff --git a/configure.ac b/configure.ac
index 10069be..3954ecc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2011,6 +2011,15 @@ if test "$KDRIVE" = yes; then
         AC_MSG_ERROR([Xephyr dependencies missing])
     fi
 
+    AC_CHECK_LIB(GLEW, glewInit, [
+      AC_CHECK_HEADER(GL/glew.h, [], [
+        AC_MSG_ERROR([requires glew http://glew.sourceforge.net/])
+      ])
+    ], [
+      AC_MSG_ERROR([requires glew http://glew.sourceforge.net/])
+    ])
+    XEPHYR_LIBS="$XEPHYR_LIBS -lGLEW"
+
     # Xephyr needs nanosleep() which is in librt on Solaris
     AC_CHECK_FUNC([nanosleep], [],
         AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
diff --git a/glamor/glamor.c b/glamor/glamor.c
index a457459..08e7ff9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -115,6 +115,8 @@ glamor_init(ScreenPtr screen)
     glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
     screen->DestroyPixmap = glamor_destroy_pixmap;
 
+    glewInit();
+
     return TRUE;
 }
 
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index eaa6b2d..651414b 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -36,7 +36,6 @@
 #endif
 
 #include <stdlib.h>
-#include "GL/gl.h"
 
 #include "glamor_priv.h"
 
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index ef043d0..285799d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -29,6 +29,7 @@
 #define GLAMOR_PRIV_H
 
 #include "glamor.h"
+#include <GL/glew.h>
 
 typedef struct glamor_screen_private {
     CreateGCProcPtr saved_create_gc;
commit 370df817ac0b346f1c7aa0b6e823c77797caaa9f
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 09:35:24 2009 -0700

    ephyr: Make sure a glamor-using window is created with a glx visual.

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 4b29181..9155d08 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -31,6 +31,7 @@
 
 extern Window EphyrPreExistingHostWin;
 extern Bool   EphyrWantGrayScale;
+extern Bool   ephyr_glamor;
 extern Bool   kdHasPointer;
 extern Bool   kdHasKbd;
 
@@ -223,6 +224,7 @@ ddxProcessArgument (int argc, char **argv, int i)
     }
   else if (!strcmp (argv[i], "-glamor"))
     {
+      ephyr_glamor = TRUE;
       ephyrFuncs.initAccel = ephyr_glamor_init;
       ephyrFuncs.enableAccel = ephyr_glamor_enable;
       ephyrFuncs.disableAccel = ephyr_glamor_disable;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index a854c88..c7c7929 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -97,6 +97,7 @@ struct EphyrHostXVars
   Display        *dpy;
   int             screen;
   Visual         *visual;
+  XVisualInfo    *visual_info;
   Window          winroot;
   GC              gc;
   int             depth;
@@ -125,10 +126,14 @@ extern int            monitorResolution;
 char           *ephyrResName = NULL;
 int             ephyrResNameFromCmd = 0;
 char	       *ephyrTitle = NULL;
+Bool ephyr_glamor = FALSE;
 
 static void
 hostx_set_fullscreen_hint(void);
 
+static void
+ephyr_glamor_get_visual(void);
+
 /* X Error traps */
 
 static int trapped_error_code = 0;
@@ -364,8 +369,11 @@ hostx_init (void)
   HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
   HostX.gc      = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
   HostX.depth   = DefaultDepth(HostX.dpy, HostX.screen);
-  HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen);
-
+  if (ephyr_glamor) {
+      ephyr_glamor_get_visual();
+  } else {
+      HostX.visual  = DefaultVisual(HostX.dpy, HostX.screen);
+  }
   class_hint = XAllocClassHint();
 
   for (index = 0 ; index < HostX.n_screens ; index++)
@@ -1448,22 +1456,18 @@ hostx_has_glx (void)
 
 #endif /* XF86DRI */
 
-void
-ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
+static void
+ephyr_glamor_get_visual(void)
 {
-    Display *dpy = hostx_get_display();
+    Display *dpy = HostX.dpy;
     int attribs[] = {GLX_RGBA,
 		     GLX_RED_SIZE, 1,
 		     GLX_GREEN_SIZE, 1,
 		     GLX_BLUE_SIZE, 1,
 		     None};
     XVisualInfo *visual_info;
-    GLXContext ctx;
-    struct EphyrHostScreen *host_screen;
     int event_base = 0, error_base = 0;
 
-    host_screen = host_screen_from_screen_info(ephyr_screen);
-
     if (!glXQueryExtension (dpy, &event_base, &error_base))
         errx(1, "Couldn't find GLX extension\n");
 
@@ -1471,12 +1475,23 @@ ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
     if (visual_info == NULL)
 	errx(1, "Couldn't get RGB visual\n");
 
-    ctx = glXCreateContext(dpy, visual_info, NULL, True);
+    HostX.visual_info = visual_info;
+    HostX.visual = visual_info->visual;
+}
+
+void
+ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
+{
+    Display *dpy = HostX.dpy;
+    GLXContext ctx;
+    struct EphyrHostScreen *host_screen;
+
+    host_screen = host_screen_from_screen_info(ephyr_screen);
+
+    ctx = glXCreateContext(dpy, HostX.visual_info, NULL, True);
     if (ctx == NULL)
 	errx(1, "glXCreateContext failed\n");
 
     if (!glXMakeCurrent(dpy, host_screen->win, ctx))
 	errx(1, "glXMakeCurrent failed\n");
-
-    XFree(visual_info);
 }
commit 08097434ecc6479dc69a408523f398284168697e
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 09:10:12 2009 -0700

    add fill files, merge with first real attempt at rendering.

diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
new file mode 100644
index 0000000..36e7bad
--- /dev/null
+++ b/glamor/glamor_fill.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glamor_priv.h"
+
+/** @file glamor_fillspans.c
+ *
+ * GC fill implementation, based loosely on fb_fill.c
+ */
+
+void
+glamor_fill(DrawablePtr drawable,
+	    GCPtr gc,
+	    int x,
+	    int y,
+	    int width,
+	    int height)
+{
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
+
+    switch (gc->fillStyle) {
+    case FillSolid:
+	glamor_solid(dst_pixmap,
+		     x - dst_pixmap->screen_x,
+		     y - dst_pixmap->screen_y,
+		     width,
+		     height,
+		     gc->alu,
+		     gc->planemask,
+		     gc->fgPixel);
+	break;
+    case FillStippled:
+    case FillOpaqueStippled:
+	glamor_stipple(dst_pixmap,
+		       gc->stipple,
+		       x - dst_pixmap->screen_x,
+		       y - dst_pixmap->screen_y,
+		       width,
+		       height,
+		       gc->alu,
+		       gc->planemask,
+		       gc->fgPixel,
+		       gc->bgPixel,
+		       gc->patOrg.x - dst_pixmap->screen_x,
+		       gc->patOrg.y - dst_pixmap->screen_y);
+	break;
+    case FillTiled:
+	glamor_tile(dst_pixmap,
+		    gc->tile.pixmap,
+		    x - dst_pixmap->screen_x,
+		    y - dst_pixmap->screen_y,
+		    width,
+		    height,
+		    gc->alu,
+		    gc->planemask,
+		    gc->patOrg.x - dst_pixmap->screen_y,
+		    gc->patOrg.y - dst_pixmap->screen_y);
+	break;
+    }
+}
diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c
new file mode 100644
index 0000000..b0b704f
--- /dev/null
+++ b/glamor/glamor_fillspans.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+/** @file glamor_fillspans.c
+ *
+ * FillSpans implementation, taken from fb_fillsp.c
+ */
+#include "glamor_priv.h"
+
+void
+glamor_fill_spans(DrawablePtr drawable,
+		  GCPtr	gc,
+		  int n,
+		  DDXPointPtr points,
+		  int *widths,
+		  int sorted)
+{
+    RegionPtr clip = gc->pCompositeClip;
+    BoxPtr extents, boxes;
+    int nbox;
+    int extentX1, extentX2, extentY1, extentY2;
+    int fullX1, fullX2, fullY1;
+    int partX1, partX2;
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+
+    if (dest_pixmap != screen_pixmap) {
+	fbFillSpans(drawable, gc, n, points, widths, sorted);
+	return;
+    }
+
+    extents = REGION_EXTENTS(gc->pScreen, clip);
+    extentX1 = extents->x1;
+    extentY1 = extents->y1;
+    extentX2 = extents->x2;
+    extentY2 = extents->y2;
+    while (n--) {
+	fullX1 = points->x;
+	fullY1 = points->y;
+	fullX2 = fullX1 + *widths;
+	points++;
+	widths++;
+
+	if (fullY1 < extentY1 || extentY2 <= fullY1)
+	    continue;
+
+	if (fullX1 < extentX1)
+	    fullX1 = extentX1;
+
+	if (fullX2 > extentX2)
+	    fullX2 = extentX2;
+
+	if (fullX1 >= fullX2)
+	    continue;
+
+	nbox = REGION_NUM_RECTS (clip);
+	if (nbox == 1) {
+	    glamor_fill(drawable,
+			gc,
+			fullX1, fullY1, fullX2-fullX1, 1);
+	} else {
+	    boxes = REGION_RECTS(clip);
+	    while(nbox--)
+	    {
+		if (boxes->y1 <= fullY1 && fullY1 < boxes->y2)
+		{
+		    partX1 = boxes->x1;
+		    if (partX1 < fullX1)
+			partX1 = fullX1;
+		    partX2 = boxes->x2;
+		    if (partX2 > fullX2)
+			partX2 = fullX2;
+		    if (partX2 > partX1)
+		    {
+			glamor_fill(drawable, gc,
+				    partX1, fullY1,
+				    partX2 - partX1, 1);
+		    }
+		}
+		boxes++;
+	    }
+	}
+    }
+}
commit e32efb02e5dff9124e8680f9a15d9d2b01db84c7
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Dec 20 14:48:18 2008 -0800

    ephyr: merge the host glamor bits into hostx.

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 349e86d..7e10d6b 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -24,8 +24,7 @@ bin_PROGRAMS = Xephyr
 
 HOSTX_SRCS =			\
 	hostx.c			\
-	hostx.h			\
-	ephyr_host_glamor.c
+	hostx.h
 
 HOSTVIDEO_SRCS =		\
 	ephyrvideo.c		\
diff --git a/hw/kdrive/ephyr/ephyr_host_glamor.c b/hw/kdrive/ephyr/ephyr_host_glamor.c
deleted file mode 100644
index f652bd0..0000000
--- a/hw/kdrive/ephyr/ephyr_host_glamor.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * 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 (including the next
- * paragraph) 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.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <err.h>
-#include "GL/glx.h"
-
-#include "hostx.h"
-
-void
-ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
-{
-    Display *dpy = hostx_get_display();
-    int attribs[] = {GLX_RGBA,
-		     GLX_RED_SIZE, 1,
-		     GLX_GREEN_SIZE, 1,
-		     GLX_BLUE_SIZE, 1,
-		     None};
-    XVisualInfo *visual_info;
-    GLXContext ctx;
-
-    visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
-    if (visual_info == NULL)
-	errx(1, "Couldn't get RGB visual\n");
-
-    ctx = glXCreateContext(dpy, visual_info, NULL, True);
-    if (ctx == NULL)
-	errx(1, "glXCreateContext failed\n");
-
-    glXMakeCurrent(dpy, hostx_get_window(DefaultScreen(dpy)), ctx);
-
-    XFree(visual_info);
-}
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 4caf451..a854c88 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -46,6 +46,7 @@
 #include <unistd.h>
 #include <string.h> 		/* for memset */
 #include <time.h>
+#include <err.h>
 
 #include <sys/ipc.h>
 #include <sys/shm.h>
@@ -61,6 +62,7 @@
 #include <GL/glx.h>
 #endif /* XF86DRI */
 #include "ephyrlog.h"
+#include "GL/glx.h"
 
 #ifdef XF86DRI
 extern Bool XF86DRIQueryExtension (Display *dpy,
@@ -1445,3 +1447,36 @@ hostx_has_glx (void)
 }
 
 #endif /* XF86DRI */
+
+void
+ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
+{
+    Display *dpy = hostx_get_display();
+    int attribs[] = {GLX_RGBA,
+		     GLX_RED_SIZE, 1,
+		     GLX_GREEN_SIZE, 1,
+		     GLX_BLUE_SIZE, 1,
+		     None};
+    XVisualInfo *visual_info;
+    GLXContext ctx;
+    struct EphyrHostScreen *host_screen;
+    int event_base = 0, error_base = 0;
+
+    host_screen = host_screen_from_screen_info(ephyr_screen);
+
+    if (!glXQueryExtension (dpy, &event_base, &error_base))
+        errx(1, "Couldn't find GLX extension\n");
+
+    visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
+    if (visual_info == NULL)
+	errx(1, "Couldn't get RGB visual\n");
+
+    ctx = glXCreateContext(dpy, visual_info, NULL, True);
+    if (ctx == NULL)
+	errx(1, "glXCreateContext failed\n");
+
+    if (!glXMakeCurrent(dpy, host_screen->win, ctx))
+	errx(1, "glXMakeCurrent failed\n");
+
+    XFree(visual_info);
+}
commit df083fab84cf57fc1a2e3cd98572039bc9fe20de
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Dec 20 13:43:52 2008 -0800

    glamor: first real attempt at rendering.

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 9ed4042..b6a64fb 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -16,4 +16,6 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
 libglamor_la_SOURCES = \
 	glamor.c \
 	glamor_core.c \
+	glamor_fill.c \
+	glamor_fillspans.c \
 	glamor.h
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index e49e9b5..eaa6b2d 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -36,22 +36,86 @@
 #endif
 
 #include <stdlib.h>
+#include "GL/gl.h"
 
 #include "glamor_priv.h"
 
 static void
-glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
-		  DDXPointPtr points, int *width, int sorted)
+glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel)
 {
-    ScreenPtr screen = drawable->pScreen;
+    glColor4ub((fg_pixel >> 16) & 0xff,
+	       (fg_pixel >> 8) & 0xff,
+	       (fg_pixel) & 0xff,
+	       (fg_pixel >> 24) & 0xff);
+}
+
+static Bool
+glamor_set_destination_pixmap(PixmapPtr pixmap)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 
-    if (1 || screen_pixmap != dest_pixmap) {
-	fbFillSpans(drawable, gc, n, points, width, sorted);
-    } else {
-	ErrorF("stub fill_spans\n");
+    if (pixmap != screen_pixmap) {
+	ErrorF("stubbed drawing to non-screen pixmap\n");
+	return FALSE;
     }
+
+    glViewport(0, 0,
+	       screen_pixmap->drawable.width,
+	       screen_pixmap->drawable.height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0, screen_pixmap->drawable.width,
+	    0, screen_pixmap->drawable.height,
+	    -1.0, 1.0);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    return TRUE;
+}
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+	     unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
+{
+    int x1 = x;
+    int x2 = x + width;
+    int y1 = y;
+    int y2 = y + height;
+
+    if (!glamor_set_destination_pixmap(pixmap))
+	return;
+    glamor_set_color_from_fgpixel(pixmap, fg_pixel);
+
+    glBegin(GL_TRIANGLE_FAN);
+    glVertex2f(x1, y1);
+    glVertex2f(x1, y2);
+    glVertex2f(x2, y2);
+    glVertex2f(x2, y1);
+    glEnd();
+
+    glFlush();
+}
+
+void
+glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
+	       int x, int y, int width, int height,
+	       unsigned char alu, unsigned long planemask,
+	       unsigned long fg_pixel, unsigned long bg_pixel,
+	       int stipple_x, int stipple_y)
+{
+    ErrorF("stubbed out stipple\n");
+}
+
+void
+glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+	    int x, int y, int width, int height,
+	    unsigned char alu, unsigned long planemask,
+	    int tile_x, int tile_y)
+{
+    ErrorF("stubbed out tile\n");
 }
 
 static void
@@ -62,7 +126,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 
-    if (1 || screen_pixmap != dest_pixmap) {
+    if (screen_pixmap != dest_pixmap) {
 	fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
     } else {
 	ErrorF("stub put_image\n");
@@ -71,20 +135,30 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
 
 static void
 glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
-		 DDXPointPtr points, int *width, int n, int sorted)
+		 DDXPointPtr points, int *widths, int n, int sorted)
 {
     ScreenPtr screen = drawable->pScreen;
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
     PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
 
-    if (1 || screen_pixmap != dest_pixmap) {
-	fbSetSpans(drawable, gc, src, points, width, n, sorted);
+    if (screen_pixmap != dest_pixmap) {
+	fbSetSpans(drawable, gc, src, points, widths, n, sorted);
     } else {
-	ErrorF("stub set_spans\n");
+	int i;
+
+	if (!glamor_set_destination_pixmap(dest_pixmap))
+	    return;
+	for (i = 0; i < n; i++) {
+	    glDrawPixels(points[i].x - dest_pixmap->screen_x,
+			 points[i].y - dest_pixmap->screen_y,
+			 widths[i],
+			 1,
+			 src);
+	    src += PixmapBytePad(widths[i], drawable->depth);
+	}
     }
 }
 
-
 /**
  * glamor_poly_lines() checks if it can accelerate the lines as a group of
  * horizontal or vertical lines (rectangles), and uses existing rectangle fill
@@ -104,7 +178,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
     /* Don't try to do wide lines or non-solid fill style. */
     if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
 	gc->fillStyle != FillSolid) {
-	if (1 || dest_pixmap != screen_pixmap)
+	if (dest_pixmap != screen_pixmap)
 	    fbPolyLine(drawable, gc, mode, n, points);
 	else
 	    ErrorF("stub poly_line\n");
@@ -126,7 +200,7 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
 
 	if (x1 != x2 && y1 != y2) {
 	    xfree(rects);
-	    if (1 || dest_pixmap != screen_pixmap)
+	    if (dest_pixmap != screen_pixmap)
 		fbPolyLine(drawable, gc, mode, n, points);
 	    else
 		ErrorF("stub poly_line\n");
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index fe597c2..ef043d0 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -49,5 +49,33 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
 
 /* glamor_core.c */
 Bool glamor_create_gc(GCPtr gc);
+void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+		  unsigned char alu, unsigned long planemask,
+		  unsigned long fg_pixel);
+void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
+		    int x, int y, int width, int height,
+		    unsigned char alu, unsigned long planemask,
+		    unsigned long fg_pixel, unsigned long bg_pixel,
+		    int stipple_x, int stipple_y);
+void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
+		 int x, int y, int width, int height,
+		 unsigned char alu, unsigned long planemask,
+		 int tile_x, int tile_y);
+
+/* glamor_fill.c */
+void glamor_fill(DrawablePtr drawable,
+		 GCPtr gc,
+		 int x,
+		 int y,
+		 int width,
+		 int height);
+
+/* glamor_fillspans.c */
+void glamor_fill_spans(DrawablePtr drawable,
+		       GCPtr	gc,
+		       int n,
+		       DDXPointPtr points,
+		       int *widths,
+		       int sorted);
 
 #endif /* GLAMOR_PRIV_H */
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 7ebf1c2..16959d7 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -394,7 +394,10 @@ ephyrSetInternalDamage (ScreenPtr pScreen)
   KdScreenInfo	*screen = pScreenPriv->screen;
   EphyrScrPriv	*scrpriv = screen->driver;
   PixmapPtr      pPixmap = NULL;
-  
+
+  if (ephyrFuncs.initAccel == ephyr_glamor_init)
+      return TRUE;
+
   scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
 				   (DamageDestroyFunc) 0,
 				   DamageReportNone,
commit 1b151f2e6aa581400b09220b87ae2d34a39aeb17
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Dec 20 13:48:39 2008 -0800

    glamor: glFlush from the blockhandler so rendering happens.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index ba27014..a457459 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -74,6 +74,18 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
     return fbDestroyPixmap(pixmap);
 }
 
+static void
+glamor_block_handler(void *data, OSTimePtr wt, void *last_select_mask)
+{
+    glFlush();
+}
+
+static void
+glamor_wakeup_handler(void *data, OSTimePtr wt, void *last_select_mask)
+{
+    glFlush();
+}
+
 /** Set up glamor for an already-configured GL context. */
 Bool
 glamor_init(ScreenPtr screen)
@@ -86,6 +98,14 @@ glamor_init(ScreenPtr screen)
 
     dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
 
+    if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
+					glamor_wakeup_handler,
+					NULL)) {
+	dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
+	xfree(glamor_priv);
+	return FALSE;
+    }
+
     glamor_priv->saved_create_gc = screen->CreateGC;
     screen->CreateGC = glamor_create_gc;
 
commit b530cdea4a8e05b1f487765b8dde42cde1a6fc98
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 16 15:20:49 2008 -0800

    glamor: Use a nicer struct initializer for gcops.

diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index a894e98..e49e9b5 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -86,13 +86,13 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
 
 
 /**
- * glamor_poly_line() checks if it can accelerate the lines as a group of
+ * glamor_poly_lines() checks if it can accelerate the lines as a group of
  * horizontal or vertical lines (rectangles), and uses existing rectangle fill
  * acceleration if so.
  */
 static void
-glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n,
-		 DDXPointPtr points)
+glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		  DDXPointPtr points)
 {
     ScreenPtr screen = drawable->pScreen;
     PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
@@ -156,26 +156,26 @@ glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n,
 }
 
 GCOps glamor_gc_ops = {
-    glamor_fill_spans,
-    glamor_set_spans,
-    glamor_put_image,
-    miCopyArea,
-    miCopyPlane,
-    miPolyPoint,
-    glamor_poly_line,
-    miPolySegment,
-    miPolyRectangle,
-    miPolyArc,
-    miFillPolygon,
-    miPolyFillRect,
-    miPolyFillArc,
-    miPolyText8,
-    miPolyText16,
-    miImageText8,
-    miImageText16,
-    miImageGlyphBlt,
-    miPolyGlyphBlt,
-    miPushPixels,
+    .FillSpans = glamor_fill_spans,
+    .SetSpans = glamor_set_spans,
+    .PutImage = glamor_put_image,
+    .CopyArea = miCopyArea,
+    .CopyPlane = miCopyPlane,
+    .PolyPoint = miPolyPoint,
+    .Polylines = glamor_poly_lines,
+    .PolySegment = miPolySegment,
+    .PolyRectangle = miPolyRectangle,
+    .PolyArc = miPolyArc,
+    .FillPolygon = miFillPolygon,
+    .PolyFillRect = miPolyFillRect,
+    .PolyFillArc = miPolyFillArc,
+    .PolyText8 = miPolyText8,
+    .PolyText16 = miPolyText16,
+    .ImageText8 = miImageText8,
+    .ImageText16 = miImageText16,
+    .ImageGlyphBlt = miImageGlyphBlt,
+    .PolyGlyphBlt = miPolyGlyphBlt,
+    .PushPixels = miPushPixels,
 };
 
 /**
commit 4d52ae7f2dca78d493e11375d764c978db5567ed
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 16 15:14:31 2008 -0800

    glamor: Start trying to hook up the rendering bits

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 8f4c607..9ed4042 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -15,4 +15,5 @@ AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
 
 libglamor_la_SOURCES = \
 	glamor.c \
+	glamor_core.c \
 	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 49771ce..ba27014 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -36,12 +36,74 @@
 
 #include <stdlib.h>
 
-#include "glamor.h"
+#include "glamor_priv.h"
+
+static int glamor_screen_private_key_index;
+DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
+
+/**
+ * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
+ *
+ * @param drawable the drawable being requested.
+ *
+ * This function returns the backing pixmap for a drawable, whether it is a
+ * redirected window, unredirected window, or already a pixmap.  Note that
+ * coordinate translation is needed when drawing to the backing pixmap of a
+ * redirected window, and the translation coordinates are provided by calling
+ * exaGetOffscreenPixmap() on the drawable.
+ */
+PixmapPtr
+glamor_get_drawable_pixmap(DrawablePtr drawable)
+{
+     if (drawable->type == DRAWABLE_WINDOW)
+	return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable);
+     else
+	return (PixmapPtr)drawable;
+}
+
+static PixmapPtr
+glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+		     unsigned int usage_hint)
+{
+    return fbCreatePixmap(screen, w, h, depth, usage_hint);
+}
+
+static Bool
+glamor_destroy_pixmap(PixmapPtr pixmap)
+{
+    return fbDestroyPixmap(pixmap);
+}
 
 /** Set up glamor for an already-configured GL context. */
 Bool
 glamor_init(ScreenPtr screen)
 {
-    return Success;
+    glamor_screen_private *glamor_priv;
+
+    glamor_priv = xcalloc(1, sizeof(*glamor_priv));
+    if (glamor_priv == NULL)
+	return FALSE;
+
+    dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
+
+    glamor_priv->saved_create_gc = screen->CreateGC;
+    screen->CreateGC = glamor_create_gc;
+
+    glamor_priv->saved_create_pixmap = screen->CreatePixmap;
+    screen->CreatePixmap = glamor_create_pixmap;
+
+    glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
+    screen->DestroyPixmap = glamor_destroy_pixmap;
+
+    return TRUE;
 }
 
+void
+glamor_fini(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    screen->CreateGC = glamor_priv->saved_create_gc;
+    screen->CreatePixmap = glamor_priv->saved_create_pixmap;
+    screen->DestroyPixmap = glamor_priv->saved_destroy_pixmap;
+}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index e6f3038..50617b8 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -38,3 +38,4 @@
 #endif /* GLAMOR_H */
 
 Bool glamor_init(ScreenPtr screen);
+void glamor_fini(ScreenPtr screen);
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
new file mode 100644
index 0000000..a894e98
--- /dev/null
+++ b/glamor/glamor_core.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2001 Keith Packard
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+/** @file glamor_core.c
+ *
+ * This file covers core X rendering in glamor.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "glamor_priv.h"
+
+static void
+glamor_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
+		  DDXPointPtr points, int *width, int sorted)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+
+    if (1 || screen_pixmap != dest_pixmap) {
+	fbFillSpans(drawable, gc, n, points, width, sorted);
+    } else {
+	ErrorF("stub fill_spans\n");
+    }
+}
+
+static void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+		 int w, int h, int leftPad, int format, char *bits)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+
+    if (1 || screen_pixmap != dest_pixmap) {
+	fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
+    } else {
+	ErrorF("stub put_image\n");
+    }
+}
+
+static void
+glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
+		 DDXPointPtr points, int *width, int n, int sorted)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+
+    if (1 || screen_pixmap != dest_pixmap) {
+	fbSetSpans(drawable, gc, src, points, width, n, sorted);
+    } else {
+	ErrorF("stub set_spans\n");
+    }
+}
+
+
+/**
+ * glamor_poly_line() checks if it can accelerate the lines as a group of
+ * horizontal or vertical lines (rectangles), and uses existing rectangle fill
+ * acceleration if so.
+ */
+static void
+glamor_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n,
+		 DDXPointPtr points)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
+    xRectangle *rects;
+    int x1, x2, y1, y2;
+    int i;
+
+    /* Don't try to do wide lines or non-solid fill style. */
+    if (gc->lineWidth != 0 || gc->lineStyle != LineSolid ||
+	gc->fillStyle != FillSolid) {
+	if (1 || dest_pixmap != screen_pixmap)
+	    fbPolyLine(drawable, gc, mode, n, points);
+	else
+	    ErrorF("stub poly_line\n");
+	return;
+    }
+
+    rects = xalloc(sizeof(xRectangle) * (n - 1));
+    x1 = points[0].x;
+    y1 = points[0].y;
+    /* If we have any non-horizontal/vertical, fall back. */
+    for (i = 0; i < n - 1; i++) {
+	if (mode == CoordModePrevious) {
+	    x2 = x1 + points[i + 1].x;
+	    y2 = y1 + points[i + 1].y;
+	} else {
+	    x2 = points[i + 1].x;
+	    y2 = points[i + 1].y;
+	}
+
+	if (x1 != x2 && y1 != y2) {
+	    xfree(rects);
+	    if (1 || dest_pixmap != screen_pixmap)
+		fbPolyLine(drawable, gc, mode, n, points);
+	    else
+		ErrorF("stub poly_line\n");
+	    return;
+	}
+
+	if (x1 < x2) {
+	    rects[i].x = x1;
+	    rects[i].width = x2 - x1 + 1;
+	} else {
+	    rects[i].x = x2;
+	    rects[i].width = x1 - x2 + 1;
+	}
+	if (y1 < y2) {
+	    rects[i].y = y1;
+	    rects[i].height = y2 - y1 + 1;
+	} else {
+	    rects[i].y = y2;
+	    rects[i].height = y1 - y2 + 1;
+	}
+
+	x1 = x2;
+	y1 = y2;
+    }
+    gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
+    xfree(rects);
+}
+
+GCOps glamor_gc_ops = {
+    glamor_fill_spans,
+    glamor_set_spans,
+    glamor_put_image,
+    miCopyArea,
+    miCopyPlane,
+    miPolyPoint,
+    glamor_poly_line,
+    miPolySegment,
+    miPolyRectangle,
+    miPolyArc,
+    miFillPolygon,
+    miPolyFillRect,
+    miPolyFillArc,
+    miPolyText8,
+    miPolyText16,
+    miImageText8,
+    miImageText16,
+    miImageGlyphBlt,
+    miPolyGlyphBlt,
+    miPushPixels,
+};
+
+/**
+ * exaValidateGC() sets the ops to EXA's implementations, which may be
+ * accelerated or may sync the card and fall back to fb.
+ */
+static void
+glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
+{
+    fbValidateGC(gc, changes, drawable);
+
+    gc->ops = &glamor_gc_ops;
+}
+
+static GCFuncs glamor_gc_funcs = {
+    glamor_validate_gc,
+    miChangeGC,
+    miCopyGC,
+    miDestroyGC,
+    miChangeClip,
+    miDestroyClip,
+    miCopyClip
+};
+
+/**
+ * exaCreateGC makes a new GC and hooks up its funcs handler, so that
+ * exaValidateGC() will get called.
+ */
+int
+glamor_create_gc(GCPtr gc)
+{
+    if (!fbCreateGC(gc))
+	return FALSE;
+
+    gc->funcs = &glamor_gc_funcs;
+
+    return TRUE;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
new file mode 100644
index 0000000..fe597c2
--- /dev/null
+++ b/glamor/glamor_priv.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifndef GLAMOR_PRIV_H
+#define GLAMOR_PRIV_H
+
+#include "glamor.h"
+
+typedef struct glamor_screen_private {
+    CreateGCProcPtr saved_create_gc;
+    CreatePixmapProcPtr saved_create_pixmap;
+    DestroyPixmapProcPtr saved_destroy_pixmap;
+} glamor_screen_private;
+
+extern DevPrivateKey glamor_screen_private_key;
+static inline glamor_screen_private *
+glamor_get_screen_private(ScreenPtr screen)
+{
+    return (glamor_screen_private *)dixLookupPrivate(&screen->devPrivates,
+						     glamor_screen_private_key);
+}
+
+/* glamor.c */
+PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
+
+/* glamor_core.c */
+Bool glamor_create_gc(GCPtr gc);
+
+#endif /* GLAMOR_PRIV_H */
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
index 2e2d946..70b4663 100644
--- a/hw/kdrive/ephyr/ephyr_glamor.c
+++ b/hw/kdrive/ephyr/ephyr_glamor.c
@@ -63,4 +63,5 @@ ephyr_glamor_disable(ScreenPtr screen)
 void
 ephyr_glamor_fini(ScreenPtr screen)
 {
+    glamor_fini(screen);
 }
diff --git a/hw/kdrive/ephyr/ephyr_host_glamor.c b/hw/kdrive/ephyr/ephyr_host_glamor.c
new file mode 100644
index 0000000..f652bd0
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyr_host_glamor.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <err.h>
+#include "GL/glx.h"
+
+#include "hostx.h"
+
+void
+ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen)
+{
+    Display *dpy = hostx_get_display();
+    int attribs[] = {GLX_RGBA,
+		     GLX_RED_SIZE, 1,
+		     GLX_GREEN_SIZE, 1,
+		     GLX_BLUE_SIZE, 1,
+		     None};
+    XVisualInfo *visual_info;
+    GLXContext ctx;
+
+    visual_info = glXChooseVisual(dpy, DefaultScreen(dpy), attribs);
+    if (visual_info == NULL)
+	errx(1, "Couldn't get RGB visual\n");
+
+    ctx = glXCreateContext(dpy, visual_info, NULL, True);
+    if (ctx == NULL)
+	errx(1, "glXCreateContext failed\n");
+
+    glXMakeCurrent(dpy, hostx_get_window(DefaultScreen(dpy)), ctx);
+
+    XFree(visual_info);
+}
commit 41e3e580de95fca3095d015ec8febe1a5f47cca3
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Aug 20 10:49:41 2009 -0700

    glamor: Use -lgl for Xephyr if GLX is unset.
    
    I'm experimenting with that because of conflicts with GL dispatch tables.

diff --git a/configure.ac b/configure.ac
index 85d5b70..10069be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1998,6 +1998,10 @@ if test "$KDRIVE" = yes; then
     if test "x$DRI" = xyes && test "x$GLX" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
     fi
+    # The glamor stuff requires libGL, but that conflicts with GLX currently.
+    if test "x$GLX" = xno; then
+        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS gl"
+    fi
 
     PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
     if test "x$XEPHYR" = xauto; then
commit 8885b3b1ffb45ae16484151ce533683af526f509
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 16 15:08:21 2008 -0800

    Add exa/glamor to _DEPENDENCIES so the bin gets rebuilt with the libs.

diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 027db13..349e86d 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -80,6 +80,8 @@ Xephyr_LDADD = 						\
 Xephyr_DEPENDENCIES =	\
 	libxephyr.la					\
 	libxephyr-hostx.la				\
+	$(top_builddir)/exa/libexa.la			\
+	$(top_builddir)/glamor/libglamor.la		\
 	$(LIBXEPHYR_HOSTXV)				\
 	$(LIBXEPHYR_HOSTDRI)				\
 	@KDRIVE_LOCAL_LIBS@
commit da6e0ffad2173d65f27feff36291f94e6aa06f88
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 16 14:00:05 2008 -0800

    More ephyr/glamor glue.

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 718cce3..49771ce 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -25,7 +25,7 @@
  *
  */
 
-/** @file
+/** @file glamor.c
  * This file covers the initialization and teardown of glamor, and has various
  * functions not responsible for performing rendering.
  */
@@ -35,3 +35,13 @@
 #endif
 
 #include <stdlib.h>
+
+#include "glamor.h"
+
+/** Set up glamor for an already-configured GL context. */
+Bool
+glamor_init(ScreenPtr screen)
+{
+    return Success;
+}
+
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 7aa4a73..e6f3038 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -24,3 +24,17 @@
  *    Eric Anholt <eric at anholt.net>
  *
  */
+
+#ifndef GLAMOR_H
+#define GLAMOR_H
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "picturestr.h"
+#include "fb.h"
+
+#endif /* GLAMOR_H */
+
+Bool glamor_init(ScreenPtr screen);
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 79e950b..027db13 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -24,7 +24,8 @@ bin_PROGRAMS = Xephyr
 
 HOSTX_SRCS =			\
 	hostx.c			\
-	hostx.h
+	hostx.h			\
+	ephyr_host_glamor.c
 
 HOSTVIDEO_SRCS =		\
 	ephyrvideo.c		\
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
index f4fb3df..2e2d946 100644
--- a/hw/kdrive/ephyr/ephyr_glamor.c
+++ b/hw/kdrive/ephyr/ephyr_glamor.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Intel Corporation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -30,7 +30,7 @@
 #endif
 
 #include "ephyr.h"
-/*#include "glamor.h"*/
+#include "glamor.h"
 
 /**
  * This function initializes EXA to use the fake acceleration implementation
@@ -38,22 +38,29 @@
  * correct driver with which to test changes to the EXA core.
  */
 Bool
-ephyr_glamor_init(ScreenPtr pScreen)
+ephyr_glamor_init(ScreenPtr screen)
 {
+    KdScreenPriv(screen);
+    KdScreenInfo *kd_screen = pScreenPriv->screen;
+
+    ephyr_glamor_host_create_context(kd_screen);
+
+    glamor_init(screen);
+
     return TRUE;
 }
 
 void
-ephyr_glamor_enable(ScreenPtr pScreen)
+ephyr_glamor_enable(ScreenPtr screen)
 {
 }
 
 void
-ephyr_glamor_disable(ScreenPtr pScreen)
+ephyr_glamor_disable(ScreenPtr screen)
 {
 }
 
 void
-ephyr_glamor_fini(ScreenPtr pScreen)
+ephyr_glamor_fini(ScreenPtr screen)
 {
 }
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 4257857..d5cb0fa 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -261,4 +261,7 @@ int hostx_has_dri (void) ;
 int hostx_has_glx (void) ;
 #endif /* XF86DRI */
 
+/* ephyr_glamor_host.c */
+void ephyr_glamor_host_create_context(EphyrScreenInfo ephyr_screen);
+
 #endif /*_XLIBS_STUFF_H_*/
commit 0ec823ce5b72bcf3be3923f2f23e5386feb0107b
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 16 12:30:14 2008 -0800

    Add build infrastructure for glamor.

diff --git a/Makefile.am b/Makefile.am
index cea140b..0c70163 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,6 +38,7 @@ SUBDIRS = \
 	$(COMPOSITE_DIR) \
 	$(GLX_DIR) \
 	exa \
+	glamor \
 	config \
 	hw \
 	test
@@ -88,6 +89,7 @@ DIST_SUBDIRS = \
 	composite \
 	glx \
 	exa \
+	glamor \
 	config \
 	hw \
 	test
diff --git a/configure.ac b/configure.ac
index b0d2643..85d5b70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2133,6 +2133,7 @@ Xext/Makefile
 Xi/Makefile
 xfixes/Makefile
 exa/Makefile
+glamor/Makefile
 hw/Makefile
 hw/xfree86/Makefile
 hw/xfree86/common/Makefile
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
new file mode 100644
index 0000000..8f4c607
--- /dev/null
+++ b/glamor/Makefile.am
@@ -0,0 +1,18 @@
+noinst_LTLIBRARIES = libglamor.la
+
+# Override these since glamor doesn't need them and the needed files aren't
+# built (in hw/xfree86/os-support/solaris) until after glamor is built
+SOLARIS_ASM_CFLAGS=""
+
+if XORG
+sdk_HEADERS = glamor.h
+endif
+
+INCLUDES = \
+	$(XORG_INCS)
+
+AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
+
+libglamor_la_SOURCES = \
+	glamor.c \
+	glamor.h
diff --git a/glamor/glamor.c b/glamor/glamor.c
new file mode 100644
index 0000000..718cce3
--- /dev/null
+++ b/glamor/glamor.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+/** @file
+ * This file covers the initialization and teardown of glamor, and has various
+ * functions not responsible for performing rendering.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
diff --git a/glamor/glamor.h b/glamor/glamor.h
new file mode 100644
index 0000000..7aa4a73
--- /dev/null
+++ b/glamor/glamor.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 9d9b64e..79e950b 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -7,7 +7,8 @@ INCLUDES = 			\
 	@XEPHYR_CFLAGS@		\
 	@DRIPROTO_CFLAGS@	\
 	-I$(top_srcdir)		\
-	-I$(top_srcdir)/exa
+	-I$(top_srcdir)/exa	\
+	-I$(top_srcdir)/glamor
 
 if XV
 LIBXEPHYR_HOSTXV=libxephyr-hostxv.la
@@ -47,6 +48,7 @@ XEPHYR_SRCS =			\
 	ephyr.h			\
 	ephyrlog.h		\
 	ephyr_draw.c		\
+	ephyr_glamor.c		\
 	os.c
 
 libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS)
@@ -70,6 +72,7 @@ Xephyr_LDADD = 						\
 	$(LIBXEPHYR_HOSTXV)				\
 	$(LIBXEPHYR_HOSTDRI)				\
 	$(top_builddir)/exa/libexa.la			\
+	$(top_builddir)/glamor/libglamor.la		\
 	@KDRIVE_LIBS@					\
 	@XEPHYR_LIBS@
 
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 2384800..cd15212 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -196,6 +196,12 @@ ephyrDrawDisable(ScreenPtr pScreen);
 void
 ephyrDrawFini(ScreenPtr pScreen);
 
+/* ephyr_glamor.c */
+Bool ephyr_glamor_init(ScreenPtr pScreen);
+void ephyr_glamor_enable(ScreenPtr pScreen);
+void ephyr_glamor_disable(ScreenPtr pScreen);
+void ephyr_glamor_fini(ScreenPtr pScreen);
+
 /*ephyvideo.c*/
 
 Bool ephyrInitVideo(ScreenPtr pScreen) ;
diff --git a/hw/kdrive/ephyr/ephyr_glamor.c b/hw/kdrive/ephyr/ephyr_glamor.c
new file mode 100644
index 0000000..f4fb3df
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyr_glamor.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "ephyr.h"
+/*#include "glamor.h"*/
+
+/**
+ * This function initializes EXA to use the fake acceleration implementation
+ * which just falls through to software.  The purpose is to have a reliable,
+ * correct driver with which to test changes to the EXA core.
+ */
+Bool
+ephyr_glamor_init(ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+void
+ephyr_glamor_enable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyr_glamor_disable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyr_glamor_fini(ScreenPtr pScreen)
+{
+}
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index b674bb8..4b29181 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -117,6 +117,7 @@ ddxUseMsg (void)
   ErrorF("-host-cursor         Re-use exisiting X host server cursor\n");
   ErrorF("-fullscreen          Attempt to run Xephyr fullscreen\n");
   ErrorF("-grayscale           Simulate 8bit grayscale\n");
+  ErrorF("-glamor              Enable 2D acceleration using glamor\n");
   ErrorF("-fakexa              Simulate acceleration using software rendering\n");
   ErrorF("-verbosity <level>   Set log verbosity level\n");
 #ifdef GLXEXT
@@ -220,6 +221,14 @@ ddxProcessArgument (int argc, char **argv, int i)
       EphyrWantGrayScale = 1;      
       return 1;
     }
+  else if (!strcmp (argv[i], "-glamor"))
+    {
+      ephyrFuncs.initAccel = ephyr_glamor_init;
+      ephyrFuncs.enableAccel = ephyr_glamor_enable;
+      ephyrFuncs.disableAccel = ephyr_glamor_disable;
+      ephyrFuncs.finiAccel = ephyr_glamor_fini;
+      return 1;
+    }
   else if (!strcmp (argv[i], "-fakexa"))
     {
       ephyrFuncs.initAccel = ephyrDrawInit;


More information about the xorg-commit mailing list