[Glamor] [PATCH] GLX wrapper

junyan.he at linux.intel.com junyan.he at linux.intel.com
Thu Jan 31 17:28:55 PST 2013


From: Junyan He <junyan.he at linux.intel.com>

This is just a simple prototype, need to discuss.
The major problems is:
1. The GLX's functions are not exported to the Global name
   space, so they are not linkable at run time and call the
   function provided by GLX can not be found if we call them
   in Glamor module. The error of symbol not find will occur.
   The modification to GLX seems not acceptiable to up stream.
   So I can just bypass it by call the dispatch function provided
   by glx module. This cause me to add a fake client for glamor
   internal. Now can call GLX's function succefully, but still
   problem when screen reset.
2. We do not know whether the GLX extension exists when do the
   screen init and so we can not call the glamor init function
   at the screen init stage. We have to split the init stage into
   several stags. Because the fake client can not be created before
   the server's 0 client, so we can just create the fake client
   when one first client connect. So some GL init logic can just
   be done after the first client connected.
   See the comment in intel_glamor.c:127.
3. The image to texture.
   I use glx's bind tex extension, it now can convert a screen bo
   to a texture in intel's driver, but still some problem about the offset.


---
 src/Makefile.am          |    6 +-
 src/glamor.c             |  232 ++++++++----
 src/glamor.h             |   31 +-
 src/glamor_core.c        |   16 +-
 src/glamor_egl.c         |   42 +--
 src/glamor_getimage.c    |    1 +
 src/glamor_gl_dispatch.c |    1 -
 src/glamor_gl_dispatch.h |   12 +-
 src/glamor_glx.c         |  909 ++++++++++++++++++++++++++++++++++++++++++++++
 src/glamor_glx.h         |   57 +++
 src/glamor_priv.h        |   23 +-
 src/glamor_trapezoid.c   |    1 +
 src/glamor_utils.h       |   12 +-
 13 files changed, 1212 insertions(+), 131 deletions(-)
 mode change 100644 => 100755 src/glamor.c
 mode change 100644 => 100755 src/glamor.h
 mode change 100644 => 100755 src/glamor_compositerects.c
 mode change 100644 => 100755 src/glamor_core.c
 mode change 100644 => 100755 src/glamor_getimage.c
 mode change 100644 => 100755 src/glamor_getspans.c
 mode change 100644 => 100755 src/glamor_gl_dispatch.h
 create mode 100755 src/glamor_glx.c
 create mode 100755 src/glamor_glx.h
 mode change 100644 => 100755 src/glamor_priv.h
 mode change 100644 => 100755 src/glamor_render.c
 mode change 100644 => 100755 src/glamor_trapezoid.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 766aac7..0a0fca3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,8 +15,7 @@ instdir = $(moduledir)
 INCLUDES = \
 	$(XORG_INCS)
 
-AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
-
+AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS) $(GLX_DEFINES)
 libglamor_la_LDFLAGS = -avoid-version
 
 libglamor_la_SOURCES = \
@@ -49,6 +48,7 @@ libglamor_la_SOURCES = \
 	glamor_gl_dispatch.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
+	glamor_glx.c \
 	glamor.h
 
 sdk_HEADERS = glamor.h
@@ -59,7 +59,7 @@ module_LTLIBRARIES = $(LIBGLAMOREGL)
 libglamoregl_la_DEPENDENCIES = libglamor.la
 libglamoregl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor $(GLX_SYS_LIBS)
 libglamoregl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
-libglamoregl_la_CFLAGS = $(AM_CFLAGS) $(GLX_DEFINES) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
+libglamoregl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
 endif
 
 
diff --git a/src/glamor.c b/src/glamor.c
old mode 100644
new mode 100755
index d51811e..06ad7bf
--- a/src/glamor.c
+++ b/src/glamor.c
@@ -40,6 +40,10 @@ DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
 static DevPrivateKeyRec glamor_pixmap_private_key_index;
 DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
 
+/* For GLX and EGL to get the Image or GLXPixmap handle.*/
+static DevPrivateKeyRec glamor_gl_pixmap_private_key_rec;
+DevPrivateKey glamor_gl_pixmap_private_key = &glamor_gl_pixmap_private_key_rec;
+
 /**
  * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
  *
@@ -194,8 +198,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return pixmap;
 }
 
-void
-glamor_destroy_textured_pixmap(PixmapPtr pixmap)
+static void
+_glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 {
 	if (pixmap->refcnt == 1) {
 		glamor_pixmap_private *pixmap_priv;
@@ -206,10 +210,19 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
 	}
 }
 
-Bool
+void
 glamor_destroy_pixmap(PixmapPtr pixmap)
 {
-	glamor_destroy_textured_pixmap(pixmap);
+	if (pixmap->refcnt == 1) {
+		/* Unbinding the image of texture firstly.*/
+		if(glamor_screen_use_glx(pixmap->drawable.pScreen)) {
+			glamor_glx_destroy_textured_pixmap(pixmap);
+		} else {
+			glamor_egl_destroy_textured_pixmap(pixmap);
+		}
+	}
+
+	_glamor_destroy_textured_pixmap(pixmap);
 	return fbDestroyPixmap(pixmap);
 }
 
@@ -260,62 +273,56 @@ glamor_set_debug_level(int *debug_level)
 
 int glamor_debug_level;
 
-/** Set up glamor for an already-configured GL context. */
 Bool
-glamor_init(ScreenPtr screen, unsigned int flags)
+glamor_check_gl_version(ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
-	int gl_version;
-
-#ifdef RENDER
-	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
-	if (flags & ~GLAMOR_VALID_FLAGS) {
-		ErrorF("glamor_init: Invalid flags %x\n", flags);
-		return FALSE;
-	}
-	glamor_priv = calloc(1, sizeof(*glamor_priv));
-	if (glamor_priv == NULL)
-		return FALSE;
-
-	if (flags & GLAMOR_INVERTED_Y_AXIS) {
-		glamor_priv->yInverted = 1;
-	} else
-		glamor_priv->yInverted = 0;
-
-	if (!dixRegisterPrivateKey
-	    (glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate screen private\n",
-			   screen->myNum);
-		goto fail;
-	}
-
-	glamor_set_screen_private(screen, glamor_priv);
-
-	if (!dixRegisterPrivateKey
-	    (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate pixmap private\n",
-			   screen->myNum);
-		goto fail;;
-	}
+	Bool ret = TRUE;
+	
+	glamor_priv = glamor_get_screen_private(screen);
 
-	gl_version = glamor_gl_get_version();
+	glamor_priv->gl_version = glamor_gl_get_version(screen);
 
 #ifndef GLAMOR_GLES2
-	if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
+	if (glamor_priv->gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
 		ErrorF("Require OpenGL version 1.3 or latter.\n");
+		ret = FALSE;
 		goto fail;
 	}
 #else
-	if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
+	if (glamor_priv->gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
 		ErrorF("Require Open GLES2.0 or latter.\n");
+		ret = FALSE;
 		goto fail;
 	}
 #endif
 
-	glamor_gl_dispatch_init(screen, &glamor_priv->_dispatch, gl_version);
+fail:
+	return ret;
+}
+
+Bool
+glamor_gl_dispatch_init(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_priv = glamor_get_screen_private(screen);
+	Bool ret = FALSE;
+
+	if(!glamor_screen_use_glx(screen)) {
+		ret = glamor_egl_dispatch_init(screen, 
+		    &glamor_priv->_dispatch);
+	}
+
+	return ret;
+}
+
+Bool
+glamor_init_gl(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv;
+	Bool ret = TRUE;
+
+	glamor_priv = glamor_get_screen_private(screen);
 
 #ifdef GLAMOR_GLES2
 	if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
@@ -330,32 +337,65 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	    glamor_gl_has_extension("GL_EXT_framebuffer_blit");
 	glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
 					     &glamor_priv->max_fbo_size);
+
+	glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
+				     &glamor_priv->max_fbo_size);
+
 #ifdef MAX_FBO_SIZE
 	glamor_priv->max_fbo_size = MAX_FBO_SIZE;
 #endif
 
-	glamor_set_debug_level(&glamor_debug_level);
-
 #ifdef GLAMOR_GLES2
 	glamor_priv->gl_flavor = GLAMOR_GL_ES2;
 #else
 	glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
 #endif
-	/* If we are using egl screen, call egl screen init to
-	 * register correct close screen function. */
-	if (flags & GLAMOR_USE_EGL_SCREEN)
-		glamor_egl_screen_init(screen);
 
+#ifdef RENDER
+	glamor_init_composite_shaders(screen);
+#endif
+	glamor_init_pixmap_fbo(screen);
+	glamor_init_solid_shader(screen);
+	glamor_init_tile_shader(screen);
+#ifdef GLAMOR_TRAPEZOID_SHADER
+	glamor_init_trapezoid_shader(screen);
+#endif
+	glamor_init_putimage_shaders(screen);
+	glamor_init_finish_access_shaders(screen);
+#ifdef GLAMOR_GRADIENT_SHADER
+	glamor_init_gradient_shader(screen);
+#endif
+	glamor_pixmap_init(screen);
+	return TRUE;
+
+fail:
+	free(glamor_priv);
+	glamor_set_screen_private(screen, NULL);
+	return FALSE;
+}
+
+Bool
+glamor_post_init(ScreenPtr screen, unsigned int flags)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	glamor_screen_private *glamor_priv;
+	int gl_version;
+#ifdef RENDER
+	PictureScreenPtr ps = GetPictureScreenIfSet(screen);
+#endif
+
+	glamor_priv = glamor_get_screen_private(screen);
+	
 	glamor_priv->saved_procs.close_screen = screen->CloseScreen;
 	screen->CloseScreen = glamor_close_screen;
-
+	
 	if (flags & GLAMOR_USE_SCREEN) {
 		if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
-						    _glamor_wakeup_handler,
-						    glamor_priv)) {
+		                                    _glamor_wakeup_handler,
+		                                    glamor_priv)) {
 			goto fail;
 		}
-
+	
 		glamor_priv->saved_procs.create_gc = screen->CreateGC;
 		screen->CreateGC = glamor_create_gc;
 
@@ -387,12 +427,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 	if (flags & GLAMOR_USE_PICTURE_SCREEN) {
 		glamor_priv->saved_procs.composite = ps->Composite;
 		ps->Composite = glamor_composite;
-
-
+	
 		glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
 		ps->Trapezoids = glamor_trapezoids;
-
-
+	
 		glamor_priv->saved_procs.triangles = ps->Triangles;
 		ps->Triangles = glamor_triangles;
 
@@ -400,7 +438,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 		ps->AddTraps = glamor_add_traps;
 
 	}
-
+	
 	glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
 	ps->CompositeRects = glamor_composite_rectangles;
 
@@ -415,27 +453,68 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
 	glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
 	ps->DestroyPicture = glamor_destroy_picture;
-	glamor_init_composite_shaders(screen);
-#endif
-	glamor_init_pixmap_fbo(screen);
-	glamor_init_solid_shader(screen);
-	glamor_init_tile_shader(screen);
-#ifdef GLAMOR_TRAPEZOID_SHADER
-	glamor_init_trapezoid_shader(screen);
 #endif
-	glamor_init_putimage_shaders(screen);
-	glamor_init_finish_access_shaders(screen);
-#ifdef GLAMOR_GRADIENT_SHADER
-	glamor_init_gradient_shader(screen);
-#endif
-	glamor_pixmap_init(screen);
 
-	glamor_priv->flags = flags;
-	glamor_priv->screen = screen;
+	return TRUE;
+
+fail:
+	free(glamor_priv);
+	glamor_set_screen_private(screen, NULL);
+	return FALSE;
+}
 
+Bool
+glamor_screen_init(ScreenPtr screen, unsigned int flags)
+{
+	glamor_screen_private *glamor_priv;
+	int gl_version;
+
+	if (flags & ~GLAMOR_VALID_FLAGS) {
+		ErrorF("glamor_screen_init: Invalid flags %x\n", flags);
+		return FALSE;
+	}
+	glamor_priv = calloc(1, sizeof(*glamor_priv));
+	if (glamor_priv == NULL)
+		return FALSE;
+
+	if (flags & GLAMOR_INVERTED_Y_AXIS) {
+		glamor_priv->yInverted = 1;
+	} else
+		glamor_priv->yInverted = 0;
+
+	if (!dixRegisterPrivateKey
+	    (glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate screen private\n",
+			   screen->myNum);
+		goto fail;
+	}
+
+	glamor_set_screen_private(screen, glamor_priv);
+
+	if (!dixRegisterPrivateKey
+	    (glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate pixmap private\n",
+			   screen->myNum);
+		goto fail;;
+	}
+
+	if (!dixRegisterPrivateKey(
+	       &glamor_gl_pixmap_private_key_rec, PRIVATE_PIXMAP, 0)) {
+		LogMessage(X_WARNING,
+			   "glamor%d: Failed to allocate glx pixmap private\n",
+			   screen->myNum);
+		goto fail;;
+	}
+
+	glamor_set_debug_level(&glamor_debug_level);
+
+ 	glamor_priv->flags = flags;
+	glamor_priv->screen = screen;
 	return TRUE;
 
-      fail:
+fail:
 	free(glamor_priv);
 	glamor_set_screen_private(screen, NULL);
 	return FALSE;
@@ -542,3 +621,4 @@ glamor_fini(ScreenPtr screen)
 {
 	/* Do nothing currently. */
 }
+
diff --git a/src/glamor.h b/src/glamor.h
old mode 100644
new mode 100755
index bafd543..a0f1ffa
--- a/src/glamor.h
+++ b/src/glamor.h
@@ -63,13 +63,13 @@ typedef enum  glamor_pixmap_type {
 #define GLAMOR_INVERTED_Y_AXIS  	1
 #define GLAMOR_USE_SCREEN		(1 << 1)
 #define GLAMOR_USE_PICTURE_SCREEN 	(1 << 2)
-#define GLAMOR_USE_EGL_SCREEN		(1 << 3)
+#define GLAMOR_USE_GL_SCREEN		(1 << 3)
 #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
 				 | GLAMOR_USE_SCREEN 			\
                                  | GLAMOR_USE_PICTURE_SCREEN		\
-				 | GLAMOR_USE_EGL_SCREEN)
+				 | GLAMOR_USE_GL_SCREEN)
 
-/* @glamor_init: Initialize glamor internal data structure.
+/* @glamor_screen_init: Initialize glamor internal data structure.
  *
  * @screen: Current screen pointer.
  * @flags:  Please refer the flags description above.
@@ -93,8 +93,8 @@ typedef enum  glamor_pixmap_type {
  * 	driver's responsibility to determine how/when to jump to
  * 	glamor's picture compositing path.
  *
- * 	@GLAMOR_USE_EGL_SCREEN:
- * 	If you are using EGL layer, then please set this bit
+ * 	@GLAMOR_USE_GL_SCREEN:
+ * 	If you are using GL layer, then please set this bit
  * 	on, otherwise, clear it.
  *
  * This function initializes necessary internal data structure
@@ -104,8 +104,13 @@ typedef enum  glamor_pixmap_type {
  * be called after the DDX's screen initialization or at the last
  * step of the DDX's screen initialization.
  */
-extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
+extern _X_EXPORT Bool glamor_screen_init(ScreenPtr screen, unsigned int flags);
 extern _X_EXPORT void glamor_fini(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_check_gl_version(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_init_gl(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_gl_dispatch_init(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_post_init(ScreenPtr screen, unsigned int flags);
+extern _X_EXPORT Bool glamor_client_callback(ScreenPtr screen);
 
 /* This function is used to free the glamor private screen's
  * resources. If the DDX driver is not set GLAMOR_USE_SCREEN,
@@ -142,10 +147,10 @@ extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
 						unsigned int tex);
 
 extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type);
-extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
 extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
 extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 						unsigned int usage);
+extern _X_EXPORT void glamor_destroy_pixmap(PixmapPtr pixmap);
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
 
@@ -231,6 +236,18 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
 							int stride);
 
 extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
+
+
+/* @glamor_screen_use_glx:
+ *
+ * To check whether the GLX extension exists, if so, we will use glx
+ * and if not, we will use egl as GL layer wrapper for the screen.
+ */
+extern _X_EXPORT Bool glamor_screen_use_glx(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_glx_make_current(ScreenPtr screen);
+extern _X_EXPORT void glamor_glx_screen_init(ScreenPtr screen);
+extern _X_EXPORT Bool glamor_glx_init(ScrnInfoPtr scrn, int fd);
+
 #endif
 
 extern _X_EXPORT int glamor_create_gc(GCPtr gc);
diff --git a/src/glamor_compositerects.c b/src/glamor_compositerects.c
old mode 100644
new mode 100755
diff --git a/src/glamor_core.c b/src/glamor_core.c
old mode 100644
new mode 100755
index 22065bc..48e70f5
--- a/src/glamor_core.c
+++ b/src/glamor_core.c
@@ -586,12 +586,20 @@ glamor_gl_has_extension(const char *extension)
 }
 
 int
-glamor_gl_get_version(void)
+glamor_gl_get_version(ScreenPtr screen)
 {
+	glamor_screen_private *glamor_priv;
 	int major, minor;
-	const char *version = (const char *) glGetString(GL_VERSION);
-	const char *dot = version == NULL ? NULL : strchr(version, '.');
-	const char *major_start = dot;
+	const char *version;
+	const char *dot;
+	const char *major_start;
+
+	glamor_priv = glamor_get_screen_private(screen);
+
+	version = (const char *) glamor_priv->_dispatch.glGetString(GL_VERSION);
+	ErrorF("\n --- The GL version is %s\n", version);
+	dot = version == NULL ? NULL : strchr(version, '.');
+	major_start = dot;
 
 	/* Sanity check */
 	if (dot == NULL || dot == version || *(dot + 1) == '\0') {
diff --git a/src/glamor_egl.c b/src/glamor_egl.c
index a248aa2..c9937ea 100644
--- a/src/glamor_egl.c
+++ b/src/glamor_egl.c
@@ -65,10 +65,9 @@
 #include "glapi.h"
 #endif
 
-static const char glamor_name[] = "glamor";
+extern DevPrivateKey glamor_gl_pixmap_private_key;
 
-static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
-DevPrivateKey glamor_egl_pixmap_private_key = &glamor_egl_pixmap_private_key_index;
+static const char glamor_name[] = "glamor";
 
 static void
 glamor_identify(int flags)
@@ -234,7 +233,7 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
 	}
 
 	glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
-						    glamor_egl_pixmap_private_key);
+						    glamor_gl_pixmap_private_key);
 	glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
 	return TRUE;
 }
@@ -306,7 +305,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	glamor_create_texture_from_image(glamor_egl, image, &texture);
 	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
 	glamor_set_pixmap_texture(pixmap, texture);
-	dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
+	dixSetPrivate(&pixmap->devPrivates, glamor_gl_pixmap_private_key,
 		      image);
 	ret = TRUE;
 
@@ -324,14 +323,14 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 	    glamor_egl_get_screen_private(scrn);
 
 	image = dixLookupPrivate(&pixmap->devPrivates,
-				 glamor_egl_pixmap_private_key);
+				 glamor_gl_pixmap_private_key);
 	if (image != EGL_NO_IMAGE_KHR && image != NULL) {
 		/* Before destroy an image which was attached to
 		 * a texture. we must call glFlush to make sure the
 		 * operation on that texture has been done.*/
 		glamor_block_handler(pixmap->drawable.pScreen);
 		glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-		dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
+		dixSetPrivate(&pixmap->devPrivates, glamor_gl_pixmap_private_key, NULL);
 	}
 }
 
@@ -345,10 +344,10 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
 	EGLImageKHR new_front_image;
 
 	glamor_pixmap_exchange_fbos(front, back);
-	new_front_image = dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
-	old_front_image = dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
-	dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, new_front_image);
-	dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, old_front_image);
+	new_front_image = dixLookupPrivate(&back->devPrivates, glamor_gl_pixmap_private_key);
+	old_front_image = dixLookupPrivate(&front->devPrivates, glamor_gl_pixmap_private_key);
+	dixSetPrivate(&front->devPrivates, glamor_gl_pixmap_private_key, new_front_image);
+	dixSetPrivate(&back->devPrivates, glamor_gl_pixmap_private_key, old_front_image);
 	glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
 	glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
 	glamor_egl->front_image = new_front_image;
@@ -360,7 +359,6 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
 {
 	if (pixmap->refcnt == 1)
 		_glamor_egl_destroy_pixmap_image(pixmap);
-	glamor_destroy_textured_pixmap(pixmap);
 }
 
 static Bool
@@ -376,15 +374,15 @@ glamor_egl_close_screen(CLOSE_SCREEN_ARGS_DECL)
 	screen_pixmap = screen->GetScreenPixmap(screen);
 
 	glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image);
-	dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
+	dixSetPrivate(&screen_pixmap->devPrivates, glamor_gl_pixmap_private_key, NULL);
 	glamor_egl->front_image = NULL;
 	if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
 		back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
-					       glamor_egl_pixmap_private_key);
+					       glamor_gl_pixmap_private_key);
 		if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
 			glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
 			dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
-				      glamor_egl_pixmap_private_key, NULL);
+				      glamor_gl_pixmap_private_key, NULL);
 		}
 	}
 
@@ -573,26 +571,18 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
 Bool
 glamor_egl_init_textured_pixmap(ScreenPtr screen)
 {
-	if (!dixRegisterPrivateKey
-	    (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
-		LogMessage(X_WARNING,
-			   "glamor%d: Failed to allocate egl pixmap private\n",
-			   screen->myNum);
-		return FALSE;
-	}
 	return TRUE;
 }
 
 Bool
-glamor_gl_dispatch_init(ScreenPtr screen,
-			struct glamor_gl_dispatch *dispatch,
-			int gl_version)
+glamor_egl_dispatch_init(ScreenPtr screen,
+			struct glamor_gl_dispatch *dispatch)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 	if (!glamor_gl_dispatch_init_impl
-	    (dispatch, gl_version, (get_proc_address_t)eglGetProcAddress))
+	    (dispatch, (get_proc_address_t)eglGetProcAddress))
 		return FALSE;
 	glamor_egl->dispatch = dispatch;
 	return TRUE;
diff --git a/src/glamor_getimage.c b/src/glamor_getimage.c
old mode 100644
new mode 100755
index f446c83..05d943e
--- a/src/glamor_getimage.c
+++ b/src/glamor_getimage.c
@@ -45,6 +45,7 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 
 	if (format != ZPixmap)
 		goto fall_back;
+
 	pixmap = glamor_get_drawable_pixmap(drawable);
 	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
 
diff --git a/src/glamor_getspans.c b/src/glamor_getspans.c
old mode 100644
new mode 100755
diff --git a/src/glamor_gl_dispatch.c b/src/glamor_gl_dispatch.c
index f996504..df608a1 100644
--- a/src/glamor_gl_dispatch.c
+++ b/src/glamor_gl_dispatch.c
@@ -41,7 +41,6 @@
 
 _X_EXPORT Bool
 glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
-			     int gl_version,
 			     void *(*get_proc_address) (const char *))
 {
 #ifndef GLAMOR_GLES2
diff --git a/src/glamor_gl_dispatch.h b/src/glamor_gl_dispatch.h
old mode 100644
new mode 100755
index b3fc3a6..4a65a31
--- a/src/glamor_gl_dispatch.h
+++ b/src/glamor_gl_dispatch.h
@@ -1,3 +1,6 @@
+#ifndef _GLAMOR_GL_DISPATCH_H_
+#define _GLAMOR_GL_DISPATCH_H_
+
 typedef struct glamor_gl_dispatch {
 	/* Transformation functions */
 	void (*glMatrixMode) (GLenum mode);
@@ -119,7 +122,6 @@ typedef struct glamor_gl_dispatch {
 				     GLsizei * length, GLchar * infoLog);
 	GLint (*glGetUniformLocation) (GLuint program,
 				       const GLchar * name);
-
 } glamor_gl_dispatch;
 
 
@@ -127,11 +129,11 @@ 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);
+glamor_egl_dispatch_init(ScreenPtr screen,
+			struct glamor_gl_dispatch *dispatch);
+
+#endif
diff --git a/src/glamor_glx.c b/src/glamor_glx.c
new file mode 100755
index 0000000..1e03b5e
--- /dev/null
+++ b/src/glamor_glx.c
@@ -0,0 +1,909 @@
+/*
+ * Copyright © 2010 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Junyan He <junyan.he at linux.intel.com>
+ *
+ */
+
+/* We prefer to use egl to create the gl context, get gl function address
+   and other wrappers provided by egl. But the symbols such as
+   _glapi_get_proc_addres will collide with glx extension in xserver.
+   This cause the glamor_egl totally not work. The glx extension is
+   now enabled by default and so we have to run glamor on glx's utility
+   in this situation. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86.h>
+#include <dix.h>
+#include <GL/glxproto.h>
+#include <GL/glxtokens.h>
+
+#if GLAMOR_GLES2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#include <X11/Xtrans/Xtransint.h>
+
+#define GLAMOR_FOR_XORG
+
+#include "glamor.h"
+#include "glamor_gl_dispatch.h"
+#include "glamor_priv.h"
+#include "glapi.h"
+#include "glamor_glx.h"
+#include "compat-api.h"
+#include "compiler.h"
+
+#define GLAMOR_USE_GLX
+
+static int xf86GlamorGLXPrivateIndex = -1;
+
+Bool
+glamor_client_callback(ScreenPtr screen)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	Bool ret = FALSE;
+
+	if (!glamor_priv->in_valid_context) {
+		glamor_priv->in_valid_context = 1;
+		ret = glamor_glx_valid_context(glamor_priv->screen, glamor_priv);
+
+		if(ret)
+			ret = glamor_glx_create_textured_screen(glamor_priv->screen);
+
+		glamor_priv->in_valid_context = 0;
+	}
+
+	return ret;
+}
+
+static void
+glamor_glx_identify(int flags)
+{
+	xf86Msg(X_INFO, "Glamor: OpenGL accelerated X.org"
+	        "driver based, using GLX\n");
+}
+
+
+static struct glamor_glx_screen_private *
+glamor_glx_get_screen_private(ScrnInfoPtr scrn)
+{
+	struct glamor_glx_screen_private *glamor_glx = NULL;
+
+	if (unlikely(xf86GlamorGLXPrivateIndex == -1)) {
+		xf86GlamorGLXPrivateIndex =
+		    xf86AllocateScrnInfoPrivateIndex();
+
+		glamor_glx = calloc(sizeof(*glamor_glx), 1);
+		scrn->privates[xf86GlamorGLXPrivateIndex].ptr = glamor_glx;
+	}
+
+	glamor_glx = (struct glamor_glx_screen_private *)
+	             scrn->privates[xf86GlamorGLXPrivateIndex].ptr;
+
+	return glamor_glx;
+}
+
+Bool
+glamor_screen_use_glx(ScreenPtr screen)
+{
+#ifdef GLAMOR_USE_GLX
+	static int has_glx = -1;
+#else
+	static int has_glx = 0;
+#endif
+
+	if (unlikely(has_glx < 0)) {
+		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+		ExtensionEntry * ent;
+		ent = CheckExtension(GLX_EXTENSION_NAME);
+		has_glx = ent != NULL;
+
+		if (ent) {
+			struct glamor_glx_screen_private *glamor_glx =
+			    glamor_glx_get_screen_private(scrn);
+			glamor_glx->glx_major = ent->base;
+		}
+
+		ErrorF("The GLX extension %s, so using %s\n",
+		       has_glx ? "exists" : "not exists",
+		       has_glx ? "GLX" : "EGL");
+	}
+
+	return has_glx;
+}
+
+struct dummy_connectionOutput {
+	void *next;
+	int size;
+	unsigned char *buf;
+	int count;
+};
+
+/* The struct comply with OsCommRec, just hold
+   place here. */
+struct dummy_osComm {
+	int fd;
+	void *input;
+	void *output;
+	XID auth_id;
+	CARD32 conn_time;
+	struct _XtransConnInfo * trans_conn;
+	Bool local_client;
+};
+
+/* We use this callback to move the data to ourself and clean
+   the client output buffer to avoid write flush which will cause error. */
+static void
+glamor_glx_reply_callback(CallbackListPtr *list,
+                          pointer closure, pointer calldata)
+{
+	ReplyInfoRec *reply_info = (ReplyInfoRec *) calldata;
+	struct glamor_glx_screen_private *glamor_glx =
+	    (struct glamor_glx_screen_private *) closure;
+	int len;
+	struct dummy_osComm *co;
+	struct dummy_connectionOutput *oco;
+
+	if (glamor_glx->pclient != reply_info->client)
+		return;
+
+	assert(reply_info->bytesRemaining ==
+	       glamor_glx->pclient->replyBytesRemaining);
+
+	len = reply_info->dataLenBytes - reply_info->padBytes;
+
+	if (reply_info->startOfReply) {
+		if (glamor_glx->reply_msg) {
+			free(glamor_glx->reply_msg);
+			glamor_glx->reply_msg = NULL;
+			glamor_glx->reply_len = 0;
+			glamor_glx->reply_off = 0;
+		}
+
+		glamor_glx->reply_msg = calloc(1, reply_info->bytesRemaining +
+		        reply_info->dataLenBytes);
+		glamor_glx->reply_len = reply_info->bytesRemaining +
+		        reply_info->dataLenBytes;
+
+		memcpy(glamor_glx->reply_msg, reply_info->replyData, len);
+		memset(&glamor_glx->reply_msg[len], 0, reply_info->padBytes);
+		glamor_glx->reply_off = reply_info->dataLenBytes;
+	} else {
+		assert(glamor_glx->reply_msg);
+		assert(reply_info->dataLenBytes + glamor_glx->reply_off <=
+		       glamor_glx->reply_len);
+
+		memcpy(&glamor_glx->reply_msg[glamor_glx->reply_off],
+		       reply_info->replyData, len);
+		memset(&glamor_glx->reply_msg[glamor_glx->reply_off + len],
+		       0, reply_info->padBytes);
+		glamor_glx->reply_off += reply_info->dataLenBytes;
+	}
+
+	co = glamor_glx->pclient->osPrivate;
+	oco = co->output;
+
+	oco->count = oco->size - reply_info->dataLenBytes;
+
+	if (oco->count < 0) {
+		ErrorF("Oops, can't avoid flush error!\n");
+		oco->count = 0;
+	}
+}
+
+static char*
+glamor_glx_get_reply_msg(ScrnInfoPtr scrn)
+{
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	struct dummy_osComm *co;
+	struct dummy_connectionOutput *oco;
+	char * msg = NULL;
+
+	co = glamor_glx->pclient->osPrivate;
+	if (!co)
+		return NULL;
+
+	oco = co->output;
+	if (!oco)
+		return NULL;
+
+	if (glamor_glx->pclient->replyBytesRemaining) {
+		ErrorF("The reply message is not intact\n");
+		return NULL;
+	}
+
+	msg = glamor_glx->reply_msg;
+	return msg;
+}
+
+/* Because the APIs of glx are not exported, so we create a fake
+   client to call the GLX APIs by make fake requests. */
+static Bool
+glamor_glx_create_client(ScrnInfoPtr scrn)
+{
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	struct dummy_osComm * oc;
+	xConnClientPrefix *prefix;
+	xReq *req;
+
+	oc = malloc(sizeof(struct dummy_osComm));
+	if (!oc)
+		return FALSE;
+	oc->trans_conn = calloc(sizeof(struct _XtransConnInfo), 1);
+	oc->trans_conn->family = AF_UNIX;
+	oc->trans_conn->flags |= TRANS_NOXAUTH;
+	oc->fd = 0;
+	oc->input = NULL;
+	oc->output = NULL;
+	oc->auth_id = None;
+	oc->conn_time = 0; // Never timeout.
+
+	glamor_glx->pclient = NextAvailableClient((pointer) oc);
+
+	if (glamor_glx->pclient == NULL) {
+		free(oc);
+		ErrorF("glamor glx create fake client failed\n");
+		return FALSE;
+	}
+
+	/* All our resource are created at server end. */
+	glamor_glx->pclient->clientAsMask |= SERVER_BIT;
+
+	oc->local_client = TRUE;
+
+	if (!AddCallback(&ReplyCallback, glamor_glx_reply_callback,
+	                 glamor_glx)) {
+		ErrorF("glamor glx add reply callback failed. \n");
+		CloseDownClient(glamor_glx->pclient);
+		glamor_glx->pclient = NULL;
+		return FALSE;
+	}
+
+	glamor_glx->pclient->requestVector = ProcVector;
+	/* Set the ClientStateRunning and call callback again. */
+	glamor_glx->pclient->clientState = ClientStateRunning;
+	if (ClientStateCallback) {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = glamor_glx->pclient;
+		clientinfo.prefix = NULL;
+		clientinfo.setup = NULL;
+		CallCallbacks((&ClientStateCallback), (pointer) &glamor_glx->pclient);
+	}
+
+	ErrorF("Create client succeed!\n");
+	return TRUE;
+}
+
+static Bool
+glamor_glx_call_dispatch(ClientPtr client)
+{
+	client->sequence++;
+	client->majorOp = ((xReq *) client->requestBuffer)->reqType;
+	client->minorOp = 0;
+	if (client->majorOp >= EXTENSION_BASE) {
+		ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
+
+		if (ext)
+			client->minorOp = ext->MinorOpcode(client);
+	}
+
+	return (*client->requestVector[client->majorOp]) (client);
+}
+
+
+static Bool
+glamor_glx_choose_visual(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	xGLXGetFBConfigsReq* req = NULL;
+	xGLXGetFBConfigsReply* reply = NULL;
+	int i, j;
+	int visualID = -1;
+	int fbconfigID = -1;
+	int depthBits = 0;
+	VisualPtr pVisual;
+	CARD32 *buf;
+	int ret;
+
+	req = malloc(sizeof(xGLXGetFBConfigsReq));
+	if (!req)
+		return FALSE;
+
+	assert(glamor_glx->glx_major > EXTENSION_BASE);
+	req->reqType = glamor_glx->glx_major;
+	req->glxCode = X_GLXGetFBConfigs;
+	req->length = sizeof(xGLXGetFBConfigsReq);
+	req->screen = screen->myNum;
+
+	glamor_glx->pclient->req_len = req->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req;
+
+	ret = glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	glamor_glx->pclient->req_len = 0;
+	glamor_glx->pclient->requestBuffer = NULL;
+	free(req);
+
+	if (ret) {
+		ErrorF("Call getfbconfigs has error\n");
+		return FALSE;
+	}
+
+	reply = (xGLXGetFBConfigsReply *)glamor_glx_get_reply_msg(scrn);
+	if (!reply) {
+		ErrorF("Do not have getfbconfigs reply\n");
+		return FALSE;
+	}
+
+	DebugF("Get FBConfig number is %d, numAttribs is %d\n",
+	       (int)reply->numFBConfigs, (int)reply->numAttribs);
+
+	buf = (CARD32 *)(reply + 1);
+
+	/* We just choose RGBA 8bits, double buffer one. */
+	for (i = 0; i < reply->numFBConfigs; i++) {
+		assert(buf[0] == GLX_VISUAL_ID);
+
+		for (j = 0; j < reply->numAttribs; j++) {
+			if ((buf[2*j] == GLX_RGBA && buf[2*j + 1] != GL_TRUE)
+			     || (buf[2*j] == GLX_RED_SIZE && buf[2*j + 1] != 8)
+			     || (buf[2*j] == GLX_GREEN_SIZE && buf[2*j + 1] != 8)
+			     || (buf[2*j] == GLX_BLUE_SIZE && buf[2*j + 1] != 8)
+			     || (buf[2*j] == GLX_DOUBLEBUFFER && buf[2*j + 1] == 0)
+			     || (buf[2*j] == GLX_DRAWABLE_TYPE
+			         && buf[2*j + 1] & GLX_WINDOW_BIT == 0))
+				break;
+		}
+
+		if (j == reply->numAttribs) {/* find the visual ID. */
+			visualID = buf[1];
+			fbconfigID = buf[3];
+			depthBits = buf[37];
+			break;
+		}
+
+		buf += reply->numAttribs * 2;
+	}
+
+	if (visualID == -1) {
+		ErrorF("Can not find a visual\n");
+		return FALSE;
+	}
+
+	for (i = 0, pVisual = screen->visuals;
+	     i < screen->numVisuals; i++, pVisual++) {
+		if (pVisual->vid == visualID)
+			break;
+	}
+	if (i == screen->numVisuals) {
+		ErrorF("can not find match Visual\n");
+		return FALSE;
+	}
+
+	glamor_glx->visualID = visualID;
+	glamor_glx->fbconfigID = fbconfigID;
+	glamor_glx->depthBits = depthBits;
+
+	ErrorF("visualID = %d, fbconfigID = %d, depthBits = %d\n",
+	        visualID, fbconfigID, depthBits);
+	return TRUE;
+}
+
+static Bool
+glamor_glx_create_colormap(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	ColormapPtr pCmap;
+	VisualPtr pVisual;
+	int colormapID;
+	int i;
+
+	colormapID = FakeClientID(glamor_glx->pclient->index);
+
+	for (i = 0, pVisual = screen->visuals;
+	     i < screen->numVisuals; i++, pVisual++) {
+		if (pVisual->vid != glamor_glx->visualID)
+			continue;
+
+		if (CreateColormap(colormapID,
+		                   screen, pVisual, &pCmap,
+		                   0, glamor_glx->pclient->index)) {
+			ErrorF("Can not create color map\n");
+			return FALSE;
+		}
+
+		glamor_glx->colormapID = colormapID;
+		ErrorF("Create color map succeed!\n");
+		return TRUE;
+	}
+
+	ErrorF("Can not create color map, no match visualID\n");
+	return FALSE;
+}
+
+static Bool
+glamor_glx_create_context(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	xGLXCreateNewContextReq* req = NULL;
+	int ret;
+
+	req = malloc(sizeof(xGLXCreateNewContextReq));
+	if (!req)
+		return FALSE;
+
+	assert(glamor_glx->glx_major > EXTENSION_BASE);
+
+	req->reqType = glamor_glx->glx_major;
+	req->glxCode = X_GLXCreateNewContext;
+	req->length = sizeof(xGLXCreateNewContextReq);
+	req->context = FakeClientID(glamor_glx->pclient->index);
+	req->screen = screen->myNum;
+	req->fbconfig = glamor_glx->fbconfigID;
+	req->isDirect = FALSE;
+	req->shareList = 0;
+
+	glamor_glx->pclient->req_len = req->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req;
+
+	ret = glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	glamor_glx->pclient->req_len = 0;
+	glamor_glx->pclient->requestBuffer = NULL;
+	free(req);
+
+	if (ret) {
+		ErrorF("Create context have some error,"
+		       " error number is %d!\n", ret);
+		return FALSE;
+	}
+
+	glamor_glx->contextID = req->context;
+
+	ErrorF("Create context succeed!\n");
+	return TRUE;
+}
+
+Bool
+glamor_glx_make_current(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	xGLXMakeCurrentReq* req = NULL;
+	int ret;
+
+	req = malloc(sizeof(xGLXMakeCurrentReq));
+	if (!req)
+		return FALSE;
+
+	assert(glamor_glx->glx_major > EXTENSION_BASE);
+
+	req->reqType = glamor_glx->glx_major;
+	req->glxCode = X_GLXMakeCurrent;
+	req->length = sizeof(xGLXMakeCurrentReq);
+	req->context = glamor_glx->contextID;
+	req->drawable = glamor_glx->drawableID;
+	req->oldContextTag = 0;
+
+	glamor_glx->pclient->req_len = req->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req;
+
+	ret = glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	glamor_glx->pclient->req_len = 0;
+	glamor_glx->pclient->requestBuffer = NULL;
+	free(req);
+
+	if (ret) {
+		ErrorF("Make current have some error,"
+		       " error number is %d!\n", ret);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static Bool
+glamor_glx_close_screen(CLOSE_SCREEN_ARGS_DECL)
+{
+	ScrnInfoPtr scrn;
+	struct glamor_glx_screen_private *glamor_glx;
+
+	scrn = xf86Screens[screen->myNum];
+	glamor_glx = glamor_glx_get_screen_private(scrn);
+
+	screen->CloseScreen = glamor_glx->saved_close_screen;
+	return screen->CloseScreen(CLOSE_SCREEN_ARGS);
+}
+
+static void
+glamor_glx_free_screen(FREE_SCREEN_ARGS_DECL)
+{
+#if 0
+	ScrnInfoPtr scrn;
+	struct glamor_glx_screen_private *glamor_glx;
+	ClientPtr pclient = serverClient;
+	__GLXclientState * pclient_st = glxGetClient(pclient);
+	xGLXMakeCurrentReq cur_req;
+	xGLXDestroyContextReq dtr_ctx_req;
+	xGLXDestroyPixmapReq dtr_pix_req;
+	int ret;
+
+#ifndef XF86_SCRN_INTERFACE
+	scrn = xf86Screens[arg];
+#else
+	scrn = arg;
+#endif
+	glamor_glx = glamor_glx_get_screen_private(scrn);
+
+	if (glamor_glx->contextID) {
+		/* Unbind current. */
+		pclient->req_len = sizeof(xGLXMakeCurrentReq) >> 2;
+		memset(&cur_req, 0, sizeof(xGLXMakeCurrentReq));
+		cur_req.drawable = 0;
+		cur_req.context = 0;
+		cur_req.oldContextTag = glamor_glx->contextID;;
+
+		ret = __glXDisp_MakeCurrent(pclient_st, &cur_req);
+		if (ret) {
+			ErrorF("glx unbind current failed.\n");
+		}
+
+		/* Destroy the context. */
+		pclient->req_len = sizeof(xGLXDestroyContextReq) >> 2;
+		memset(&dtr_ctx_req, 0, sizeof(xGLXDestroyContextReq));
+		dtr_ctx_req.context = glamor_glx->contextID;
+
+		ret = __glXDisp_DestroyContext(pclient_st, &dtr_ctx_req);
+		if (ret) {
+			ErrorF("glx destroy context failed.\n");
+		}
+
+		/* Destroy the drawable. */
+		pclient->req_len = sizeof(xGLXDestroyPixmapReq) >> 2;
+		memset(&dtr_pix_req, 0, sizeof(xGLXDestroyPixmapReq));
+		dtr_pix_req.glxpixmap = glamor_glx->drawableID;
+		ret = __glXDisp_DestroyPixmap(pclient_st, &dtr_pix_req);
+		if (ret) {
+			ErrorF("glx destroy drawable failed.\n");
+		}
+	}
+
+	scrn->FreeScreen = glamor_glx->saved_free_screen;
+	free(glamor_glx);
+	scrn->FreeScreen(FREE_SCREEN_ARGS);
+#endif	
+}
+
+
+void
+glamor_glx_screen_init(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+
+	glamor_glx->saved_close_screen = screen->CloseScreen;
+	screen->CloseScreen = glamor_glx_close_screen;
+}
+
+Bool
+glamor_glx_init(ScrnInfoPtr scrn, int fd)
+{
+	ScreenPtr screen = scrn->pScreen;
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+
+	glamor_glx_identify(0);
+	glamor_glx->fd = fd;
+
+	return TRUE;
+}
+
+Bool
+glamor_glx_dispatch_init(ScreenPtr screen,
+        struct glamor_gl_dispatch *dispatch)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+
+	if (!glamor_gl_dispatch_init_impl
+	     (dispatch, (get_proc_address_t)_glapi_get_proc_address)) {
+		return FALSE;
+	}
+
+	glamor_glx->dispatch = dispatch;
+	return TRUE;
+}
+
+Bool
+glamor_glx_valid_context(ScreenPtr screen, glamor_screen_private *screen_priv)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	WindowPtr pWin;
+	XID vlist;
+	int err;
+	struct glamor_screen_private *priv =
+	      (struct glamor_screen_private *)screen_priv;
+
+	if (!glamor_glx_create_client(scrn) ||
+ 	      !glamor_glx_choose_visual(screen) ||
+	      !glamor_glx_create_colormap(screen) ||
+	      !glamor_glx_create_context(screen))
+	      return FALSE;
+
+	/* Make current call do not support surface less, so
+	   need to create a fake drawable for MakeCurrent call. */
+	vlist = glamor_glx->colormapID;
+	glamor_glx->drawableID = FakeClientID(0);
+
+	if (!AddResource(glamor_glx->drawableID, RT_WINDOW, (pointer) screen->root))
+		return FALSE;
+
+	if (!glamor_glx_make_current(screen))
+	    return FALSE;
+
+	glamor_glx->saved_free_screen = scrn->FreeScreen;
+	scrn->FreeScreen = glamor_glx_free_screen;
+
+	if(glamor_glx_dispatch_init(screen, &priv->_dispatch))
+	    return glamor_init_gl(screen);
+
+	return FALSE;
+}
+
+Bool
+glamor_glx_fixup_tex(PixmapPtr pixmap)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	glamor_pixmap_private *pixmap_priv = NULL;
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	int i = 0;
+	xGLXCreatePixmapReq* req = NULL;
+	xGLXVendorPrivateReq* req2 = NULL;
+	xGLXDestroyPixmapReq* dtr_req = NULL;
+	int ret;
+	GLuint texture;
+	CARD32* data = NULL;
+	CARD32 glxpixmap;
+	glamor_gl_dispatch *dispatch;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+	const int pixmapAttribs[] = {
+		GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+		GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+		None
+	};
+
+	pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+	if (pixmap_priv && pixmap_priv->base.gl_tex)
+		return;
+
+	glxpixmap = dixLookupPrivate(&pixmap->devPrivates,
+	                       glamor_gl_pixmap_private_key);
+	if(glxpixmap)
+		return;
+
+	while (pixmapAttribs[i * 2] != None)
+		i++;
+
+	req = malloc(sizeof(xGLXCreatePixmapReq) + i * 8);
+	if (!req)
+		return FALSE;
+
+	assert(glamor_glx->glx_major > EXTENSION_BASE);
+
+	req->reqType = glamor_glx->glx_major;
+	req->glxCode = X_GLXCreatePixmap;
+	req->length = sizeof(xGLXCreatePixmapReq) + i * 8;
+	req->screen = screen->myNum;
+	req->fbconfig = glamor_glx->fbconfigID;
+	req->pixmap = pixmap->drawable.id;
+	/* Add it to the resource table temp. */
+	AddResource(req->pixmap, RT_PIXMAP, (pointer) pixmap);
+	glxpixmap = req->glxpixmap = FakeClientID(glamor_glx->pclient->index);
+	req->numAttribs = i;
+	memcpy((char *)(req + 1), pixmapAttribs, 8 * i);
+
+	glamor_glx->pclient->req_len = req->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req;
+
+	ret = glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	glamor_glx->pclient->req_len = 0;
+	glamor_glx->pclient->requestBuffer = NULL;
+
+	if (ret) {
+		ErrorF("Create glx pixmap has some error,"
+		       " error number is %d!\n", ret);
+		free(req);
+		return FALSE;
+	}
+
+	/* Bind the pixmap to tex now. */
+	dispatch = glamor_get_dispatch(glamor_priv);
+
+	dispatch->glGenTextures(1, &texture);
+	dispatch->glBindTexture(GL_TEXTURE_2D, texture);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+	        GL_TEXTURE_MIN_FILTER,
+	        GL_NEAREST);
+	dispatch->glTexParameteri(GL_TEXTURE_2D,
+	        GL_TEXTURE_MAG_FILTER,
+	        GL_NEAREST);
+
+	req2 = malloc(sizeof(xGLXVendorPrivateReq) + 12);
+	if (!req2) {
+		free(req);
+		return FALSE;
+	}
+
+	req2->reqType = glamor_glx->glx_major;
+	req2->glxCode = X_GLXVendorPrivate;
+	req2->length = sizeof(xGLXVendorPrivateReq) + 12;
+	req2->vendorCode = X_GLXvop_BindTexImageEXT;
+	req2->contextTag = glamor_glx->contextID;
+	data = (CARD32 *) (req2 + 1);
+	*data = req->glxpixmap;
+	data++;
+	*data = GLX_FRONT_LEFT_EXT;
+	data++;
+	*data = 0; //num_attrib
+
+	glamor_glx->pclient->req_len = req2->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req2;
+
+	ret = glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	glamor_glx->pclient->req_len = 0;
+	glamor_glx->pclient->requestBuffer = NULL;
+
+	dispatch->glBindTexture(GL_TEXTURE_2D, 0);
+	glamor_put_dispatch(glamor_priv);
+
+	if (ret) {
+		/* Free the glxPixmap. */
+		dtr_req = malloc(sizeof(xGLXDestroyPixmapReq));
+		dtr_req->reqType = glamor_glx->glx_major;
+		dtr_req->glxCode = X_GLXDestroyPixmap;
+		dtr_req->length = sizeof(xGLXDestroyPixmapReq);
+		dtr_req->glxpixmap = req->glxpixmap;
+		glamor_glx->pclient->req_len = dtr_req->length >> 2;
+		glamor_glx->pclient->requestBuffer = (pointer)dtr_req;
+		glamor_glx_call_dispatch(glamor_glx->pclient);
+
+		ErrorF("Can not bind texture form pixmap,"
+		       " error number is %d!\n", ret);
+
+		free(req);
+		free(req2);
+		free(dtr_req);
+		return FALSE;
+	}
+
+	glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+	glamor_set_pixmap_texture(pixmap, texture);
+	free(req);
+	free(req2);
+
+	dixSetPrivate(&pixmap->devPrivates,
+	          glamor_gl_pixmap_private_key, glxpixmap);
+
+	return TRUE;
+}
+
+
+void
+glamor_glx_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	glamor_pixmap_private *pixmap_priv = NULL;
+	struct glamor_glx_screen_private *glamor_glx =
+	    glamor_glx_get_screen_private(scrn);
+	CARD32 glxpixmap;
+	xGLXVendorPrivateReq* req = NULL;
+	xGLXDestroyPixmapReq* dtr_req = NULL;
+	CARD32* data = NULL;
+
+	glxpixmap = dixLookupPrivate(&pixmap->devPrivates,
+	                       glamor_gl_pixmap_private_key);
+
+	req = malloc(sizeof(xGLXVendorPrivateReq) + 12);
+	if (!req) {
+		free(req);
+		return FALSE;
+	}
+
+	req->reqType = glamor_glx->glx_major;
+	req->glxCode = X_GLXVendorPrivate;
+	req->length = sizeof(xGLXVendorPrivateReq) + 8;
+	req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
+	req->contextTag = glamor_glx->contextID;
+	data = (CARD32 *) (req + 1);
+	*data = glxpixmap;
+	data++;
+	*data = GLX_FRONT_LEFT_EXT;
+	glamor_glx->pclient->req_len = req->length >> 2;
+	glamor_glx->pclient->requestBuffer = (pointer)req;
+	glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	dtr_req = malloc(sizeof(xGLXDestroyPixmapReq));
+	dtr_req->reqType = glamor_glx->glx_major;
+	dtr_req->glxCode = X_GLXDestroyPixmap;
+	dtr_req->length = sizeof(xGLXDestroyPixmapReq);
+	dtr_req->glxpixmap = glxpixmap;
+	glamor_glx_call_dispatch(glamor_glx->pclient);
+
+	free(req);
+	free(dtr_req);
+
+	dixSetPrivate(&pixmap->devPrivates,
+	          glamor_gl_pixmap_private_key, NULL);
+}
+
+
+Bool
+glamor_glx_create_textured_screen(ScreenPtr screen)
+{
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	PixmapPtr	screen_pixmap;
+
+	screen_pixmap = screen->GetScreenPixmap(screen);
+
+	if (!glamor_glx_fixup_tex(screen_pixmap)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create textured screen.");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
diff --git a/src/glamor_glx.h b/src/glamor_glx.h
new file mode 100755
index 0000000..9979028
--- /dev/null
+++ b/src/glamor_glx.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2010 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Junyan He <junyan.he at linux.intel.com>
+ *
+ */
+#ifndef GLAMOR_GLX_H
+#define GLAMOR_GLX_H
+
+/* Declare some glx functions prototype. */
+extern _glapi_proc _glapi_get_proc_address(const char *funcName);   
+
+/* ############################################################################################*/
+
+#define REPLY_MSG_LEN 4096;
+
+struct glamor_glx_screen_private {
+	struct glamor_gl_dispatch *dispatch;
+	ClientPtr pclient;
+	int glx_major;
+	int visualID;
+	int fbconfigID;
+	int depthBits;
+	char *reply_msg;
+	int reply_len;
+	int reply_off;
+	int fd;
+	int contextID;
+	int drawableID;
+	int colormapID;
+	CloseScreenProcPtr saved_close_screen;
+	xf86FreeScreenProc *saved_free_screen;
+};
+
+#endif /* end of GLAMOR_GLX_H */
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
old mode 100644
new mode 100755
index 6e80ebd..c77b3f0
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -242,9 +242,11 @@ struct glamor_saved_procs {
 
 typedef struct glamor_screen_private {
 	struct glamor_gl_dispatch _dispatch;
+	CreateWindowProcPtr WindowExposures;
 	int yInverted;
 	unsigned int tick;
 	enum glamor_gl_flavor gl_flavor;
+	int gl_version;
 	int has_pack_invert;
 	int has_fbo_blit;
 	int max_fbo_size;
@@ -304,6 +306,7 @@ typedef struct glamor_screen_private {
 	int state;
 	unsigned int render_idle_cnt;
 	ScreenPtr screen;
+	int in_valid_context;
 } glamor_screen_private;
 
 typedef enum glamor_access {
@@ -499,6 +502,8 @@ typedef enum glamor_pixmap_status {
 
 extern DevPrivateKey glamor_screen_private_key;
 extern DevPrivateKey glamor_pixmap_private_key;
+extern DevPrivateKey glamor_gl_pixmap_private_key;
+
 static inline glamor_screen_private *
 glamor_get_screen_private(ScreenPtr screen)
 {
@@ -515,8 +520,6 @@ glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
 		      priv);
 }
 
-
-
 static inline glamor_pixmap_private *
 glamor_get_pixmap_private(PixmapPtr pixmap)
 {
@@ -549,8 +552,6 @@ 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,
@@ -571,6 +572,18 @@ 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_glx.c */
+Bool
+glamor_glx_dispatch_init(ScreenPtr screen,
+			struct glamor_gl_dispatch *dispatch);
+Bool
+glamor_glx_valid_context(ScreenPtr screen, glamor_screen_private *priv);
+Bool
+glamor_glx_fixup_tex(PixmapPtr pixmap);
+Bool
+glamor_glx_create_textured_screen(ScreenPtr screen);
+
 /* glamor_copyarea.c */
 RegionPtr
 glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
@@ -629,7 +642,7 @@ 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);
+int glamor_gl_get_version(ScreenPtr screen);
 
 #define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
           ((major) * 256)                       \
diff --git a/src/glamor_render.c b/src/glamor_render.c
old mode 100644
new mode 100755
diff --git a/src/glamor_trapezoid.c b/src/glamor_trapezoid.c
old mode 100644
new mode 100755
index 57a178c..b16ee3f
--- a/src/glamor_trapezoid.c
+++ b/src/glamor_trapezoid.c
@@ -1733,6 +1733,7 @@ _glamor_trapezoids(CARD8 op,
 	}
 #endif
 
+fall_back:
 	if (!ret) {
 		DEBUGF("Fallback to sw rasterize of trapezoid\n");
 
diff --git a/src/glamor_utils.h b/src/glamor_utils.h
index 36beb49..c739f56 100644
--- a/src/glamor_utils.h
+++ b/src/glamor_utils.h
@@ -1794,19 +1794,23 @@ static inline unsigned long __fls(unsigned long x)
 
 static inline void glamor_make_current(ScreenPtr screen)
 {
-	glamor_egl_make_current(screen);
+	if (glamor_screen_use_glx(screen))
+		glamor_glx_make_current(screen);
+	else
+		glamor_egl_make_current(screen);
 }
 
 static inline void glamor_restore_current(ScreenPtr screen)
 {
-	glamor_egl_restore_context(screen);
+	if(!glamor_screen_use_glx(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)
+	if (glamor_priv->flags & GLAMOR_USE_GL_SCREEN)
 		glamor_make_current(glamor_priv->screen);
 
 	return &glamor_priv->_dispatch;
@@ -1815,7 +1819,7 @@ glamor_get_dispatch(glamor_screen_private *glamor_priv)
 static inline void
 glamor_put_dispatch(glamor_screen_private *glamor_priv)
 {
-	if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
+	if (glamor_priv->flags & GLAMOR_USE_GL_SCREEN)
 		glamor_restore_current(glamor_priv->screen);
 }
 #else
-- 
1.7.10.4



More information about the Glamor mailing list