diff -urN glamor-egl-0.5.0/src/compat-api.h glamor/src/compat-api.h
--- glamor-egl-0.5.0/src/compat-api.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/compat-api.h	2012-10-28 06:01:05.116598965 -0500
@@ -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@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 -urN glamor-egl-0.5.0/src/compiler.h glamor/src/compiler.h
--- glamor-egl-0.5.0/src/compiler.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/compiler.h	2012-10-28 06:01:05.116598965 -0500
@@ -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@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 -urN glamor-egl-0.5.0/src/glamor_debug.h glamor/src/glamor_debug.h
--- glamor-egl-0.5.0/src/glamor_debug.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glamor_debug.h	2012-10-28 06:01:05.119598968 -0500
@@ -0,0 +1,116 @@
+/*
+ * 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@gmail.com>
+ *
+ */
+
+#ifndef __GLAMOR_DEBUG_H__
+#define __GLAMOR_DEBUG_H__
+
+
+#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_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__ );			\
+    exit(1);                                            \
+  } while(0)
+
+
+
+
+#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)
+
+#define DEBUGF(str, ...)  do {} while(0)
+//#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
+#define DEBUGRegionPrint(x) do {} while (0)
+//#define DEBUGRegionPrint RegionPrint
+
+
+#endif
diff -urN glamor-egl-0.5.0/src/glamor_gl_dispatch.h glamor/src/glamor_gl_dispatch.h
--- glamor-egl-0.5.0/src/glamor_gl_dispatch.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glamor_gl_dispatch.h	2012-10-28 06:01:05.121598970 -0500
@@ -0,0 +1,137 @@
+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);
+
+	/* 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 -urN glamor-egl-0.5.0/src/glamor_glext.h glamor/src/glamor_glext.h
--- glamor-egl-0.5.0/src/glamor_glext.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glamor_glext.h	2012-10-28 06:01:05.121598970 -0500
@@ -0,0 +1,64 @@
+/*
+ * 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@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 -urN glamor-egl-0.5.0/src/glamor_priv.h glamor/src/glamor_priv.h
--- glamor-egl-0.5.0/src/glamor_priv.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glamor_priv.h	2012-10-28 06:01:05.123598972 -0500
@@ -0,0 +1,1016 @@
+/*
+ * 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@anholt.net>
+ *
+ */
+#ifndef GLAMOR_PRIV_H
+#define GLAMOR_PRIV_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "compiler.h"
+
+#include <xorg-server.h>
+#ifndef DEBUG
+#define NDEBUG
+#endif
+#include "glamor.h"
+#include "compat-api.h"
+
+#define GL_GLEXT_PROTOTYPES
+
+#ifdef GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#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"
+
+#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;
+
+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;
+		};
+	};
+} glamor_composite_shader;
+
+enum shader_source {
+	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,
+};
+
+enum shader_in {
+	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;
+};
+
+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,
+	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;
+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
+#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
+
+#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
+
+#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;
+} 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;
+};
+
+#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
+
+#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;
+	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;
+} glamor_screen_private;
+
+typedef enum glamor_access {
+	GLAMOR_ACCESS_RO,
+	GLAMOR_ACCESS_RW,
+	GLAMOR_ACCESS_WO,
+} glamor_access_t;
+
+#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.
+ * @tex:     attached texture.
+ * @fb:      attached fbo.
+ * @pbo:     attached pbo.
+ * @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 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;
+
+/*
+ * 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.
+ * @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_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_fbo *fbo;
+	PixmapPtr pixmap;
+	int drm_stride;
+	glamor_screen_private *glamor_priv;
+	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.
+ *
+ * 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);
+}
+
+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)
+{
+	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);
+
+/**
+ * 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;
+
+/* glamor.c */
+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);
+
+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);
+
+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);
+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, 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);
+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);
+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);
+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);
+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);
+
+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_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(const char *extension);
+int glamor_gl_get_version(void);
+
+#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
+          ((major) * 256)                       \
+        + ((minor) *   1))
+
+
+
+
+/* glamor_fill.c */
+Bool glamor_fill(DrawablePtr drawable,
+		 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);
+Bool
+glamor_solid_boxes(PixmapPtr pixmap,
+		   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);
+
+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);
+
+/* 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);
+
+/* glamor_setspans.c */
+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_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);
+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);
+
+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);
+
+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);
+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);
+
+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);
+
+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,
+                                const float *mask_coords,
+                                const float *dst_coords, int i);
+
+/* 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,
+		 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);
+
+/* 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
+
+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_fini(ScreenPtr screen);
+/** 
+ * 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);
+
+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 
+ * 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);
+
+/**
+ * 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.
+ */
+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);
+
+/**
+ * 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);
+
+/**
+ * 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.
+ **/
+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, 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
+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);
+
+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. 
+ * 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
+#define GLAMOR_GRADIENT_SHADER
+#define GLAMOR_TRAPEZOID_SHADER
+#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
+#define WALKAROUND_LARGE_TEXTURE_MAP
+#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 -urN glamor-egl-0.5.0/src/glamor_utils.h glamor/src/glamor_utils.h
--- glamor-egl-0.5.0/src/glamor_utils.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glamor_utils.h	2012-10-28 06:01:05.125598974 -0500
@@ -0,0 +1,1836 @@
+/*
+ * 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@linux.intel.com>
+ *
+ */
+
+#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_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 {									\
+    *(_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->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 (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 {						\
+		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;	\
+	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_)		\
+   do {								\
+	if (unlikely(_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))
+
+#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 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) {			\
+		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 { /* RepeatNormal*/				\
+		tx1 = (c - priv->box.x1);  			\
+		ty1 = (d - 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,		\
+				 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_;								\
+    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 (likely(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 (likely(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_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_ext( priv,		\
+						  matrix,		\
+						  xscale,		\
+						  yscale,		\
+                                                  tx1, ty1, tx2, ty2,   \
+                                                  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 + 1 * stride, tx2, ty1,	\
+				 yInverted);				\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
+				 texcoords + 2 * stride, tx2, ty2,	\
+				 yInverted);				\
+    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
+				 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,			\
+					 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_ext( priv,	\
+							 repeat_type,	\
+							 matrix,	\
+							 xscale,	\
+							 yscale,	\
+							 _x1_, _y1_,	\
+							 _x2_, _y2_,   	\
+							 yInverted,	\
+							 texcoords,	\
+							 stride)	\
+  do {									\
+    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 {								\
+    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 + 1 * stride, yInverted);	\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3,		\
+				 texcoords + 2 * stride, yInverted);	\
+    _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4,		\
+				 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, stride)	\
+  do {									\
+    /* 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 (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);\
+    }									\
+    else {								\
+      (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1);		\
+      (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\
+    }									\
+    (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 (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);		\
+	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 {									\
+	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 (unlikely(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,		\
+					    xscale, yscale,		\
+					    _x1_, _y1_, _x2_, _y2_,	\
+	                                    yInverted, vertices)	\
+  do {									\
+	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,		\
+						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 (likely(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)			\
+    do {							\
+	(vertices)[0] = (x1);					\
+	(vertices)[2] = (x2);					\
+	(vertices)[4] = (vertices)[2];				\
+	(vertices)[6] = (vertices)[0];				\
+	if (likely(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_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 {								\
+	(vertices)[0] = v_from_x_coord_x(xscale, x);			\
+	if (likely(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 {								\
+	(vertices)[0] = (x1);						\
+	(vertices)[2] = (x2);						\
+	(vertices)[6] = (vertices)[2];					\
+	(vertices)[4] = (vertices)[0];					\
+	if (likely(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_ext(priv, xscale, yscale,		\
+				     x1, y1, x2, y2,			\
+                                     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] = _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 (likely(yInverted)) {							\
+      (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] = _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)[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_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)	\
+    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 (likely(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 {							\
+        (pt)[0] = t_from_x_coord_x(xscale, x);			\
+        if (likely(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_circle_centre(width, height, x, y,	\
+				 yInverted, c)		\
+    do {						\
+        (c)[0] = (float)x;				\
+        if (likely(yInverted)) {				\
+            (c)[1] = (float)y;				\
+        } else {					\
+            (c)[1] = (float)height - (float)y;		\
+        }						\
+    } 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)
+			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;
+	}
+}
+
+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
+
+#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)
+
+/* 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->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.
+ */
+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 void
+gl_iformat_for_depth(int depth, GLenum * format)
+{
+	switch (depth) {
+#ifndef GLAMOR_GLES2
+	case 1:
+	case 8:
+		*format = GL_ALPHA;
+		break;
+#endif
+	default:
+		*format = GL_RGBA;
+		break;
+       }
+}
+
+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->base.picture->format;
+	else
+		pict_format = format_for_depth(pixmap->drawable.depth);
+
+	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
+#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;
+}
+
+/* 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)
+
+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;
+}
+
+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
+
+
+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,
+			   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;
+}
+
+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)
+{
+	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));
+}
+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)
+{
+	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)
+{
+	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;
+	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)
+{
+	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;
+	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)
+{
+	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)
+{
+	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)
+{
+	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;
+	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)
+{
+        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);
+}
+
+static inline void 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)
+{
+	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;
+}
+
+static inline void
+glamor_put_dispatch(glamor_screen_private *glamor_priv)
+{
+}
+
+#endif
+
+#endif
diff -urN glamor-egl-0.5.0/src/glapi.h glamor/src/glapi.h
--- glamor-egl-0.5.0/src/glapi.h	1969-12-31 18:00:00.000000000 -0600
+++ glamor/src/glapi.h	2012-10-28 06:01:05.125598974 -0500
@@ -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)  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() \
+     (likely(_glapi_Dispatch) ? _glapi_Dispatch : _glapi_get_dispatch())
+
+#  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))   \
+					_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
