[Glamor] [PATCH] glamor_close_screen: Detach screen fbo and release KHR image.

zhigang.gong at linux.intel.com zhigang.gong at linux.intel.com
Tue Jan 31 02:52:29 PST 2012


From: Zhigang Gong <zhigang.gong at linux.intel.com>

This commit move the calling to glamor_close_screen from
glamor_egl_free_screen to glamor_egl_close_screen, as this
is the right place to do this.
We should detach screen fbo and destroy the corresponding
KHR image at glamor_egl_close_screen stage. As latter
DDX driver will call DestroyPixmap to destroy screen pixmap,
if the fbo and image are still there but glamor screen private
data pointer has been freed, then it causes segfault.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/glamor.c      |    7 +++++++
 src/glamor_egl.c  |   42 ++++++++++++++++++++++++++----------------
 src/glamor_fbo.c  |    2 +-
 src/glamor_priv.h |    1 +
 4 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/glamor.c b/src/glamor.c
index 80434e9..6d35590 100644
--- a/src/glamor.c
+++ b/src/glamor.c
@@ -427,6 +427,9 @@ Bool
 glamor_close_screen(int idx, ScreenPtr screen)
 {
 	glamor_screen_private *glamor_priv;
+	PixmapPtr screen_pixmap;
+	glamor_pixmap_private *screen_pixmap_priv;
+	glamor_pixmap_fbo *fbo;
 	int flags;
 
 	glamor_priv = glamor_get_screen_private(screen);
@@ -457,6 +460,10 @@ glamor_close_screen(int idx, ScreenPtr screen)
 		ps->CreatePicture = glamor_priv->saved_procs.create_picture;
 	}
 #endif
+	screen_pixmap = screen->GetScreenPixmap(screen);
+	screen_pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
+	fbo = glamor_pixmap_detach_fbo(screen_pixmap_priv);
+	glamor_purge_fbo(fbo);
 	glamor_release_screen_priv(screen);
 
 	if (flags & GLAMOR_USE_SCREEN)
diff --git a/src/glamor_egl.c b/src/glamor_egl.c
index 71121bc..b773105 100644
--- a/src/glamor_egl.c
+++ b/src/glamor_egl.c
@@ -242,25 +242,32 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 	return TRUE;
 }
 
-void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+static void
+_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
 {
-	EGLImageKHR image;
 	ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+	EGLImageKHR image;
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
 
-	if (pixmap->refcnt == 1) {
-		image = dixLookupPrivate(&pixmap->devPrivates,
-					 glamor_egl_pixmap_private_key);
-		if (image != EGL_NO_IMAGE_KHR && image != NULL) {
-			/* Before destroy an image which was attached to 
- 			 * a texture. we must call glFlush to make sure the 
- 			 * operation on that texture has been done.*/
-			glamor_block_handler(pixmap->drawable.pScreen);
-			glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
-		}
+	image = dixLookupPrivate(&pixmap->devPrivates,
+				 glamor_egl_pixmap_private_key);
+	if (image != EGL_NO_IMAGE_KHR && image != NULL) {
+		/* Before destroy an image which was attached to
+		 * a texture. we must call glFlush to make sure the
+		 * operation on that texture has been done.*/
+		glamor_block_handler(pixmap->drawable.pScreen);
+		glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
+		dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
 	}
+}
+
+void
+glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+{
+
+	if (pixmap->refcnt == 1)
+		_glamor_egl_destroy_pixmap_image(pixmap);
 	glamor_destroy_textured_pixmap(pixmap);
 }
 
@@ -270,8 +277,13 @@ glamor_egl_close_screen(ScreenPtr screen)
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	struct glamor_egl_screen_private *glamor_egl =
 	    glamor_egl_get_screen_private(scrn);
-	glamor_fini(screen);
+	PixmapPtr screen_pixmap;
 
+	glamor_fini(screen);
+	glamor_close_screen(scrn->scrnIndex, screen);
+	screen_pixmap = screen->GetScreenPixmap(screen);
+	_glamor_egl_destroy_pixmap_image(screen_pixmap);
+
 	return TRUE;
 }
 
@@ -429,8 +441,6 @@ glamor_egl_free_screen(int scrnIndex, int flags)
 		}
 		free(glamor_egl);
 	}
-
-	glamor_close_screen(scrn->scrnIndex, scrn->pScreen);
 }
 
 Bool
diff --git a/src/glamor_fbo.c b/src/glamor_fbo.c
index ffda04a..2243564 100644
--- a/src/glamor_fbo.c
+++ b/src/glamor_fbo.c
@@ -123,7 +123,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	return NULL;
 }
 
-static void
+void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
 	glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 9c2881c..d8168a5 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -346,6 +346,7 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_pri
 glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
 				      int w, int h, int depth, int flag);
 void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
+void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
 
 void glamor_init_pixmap_fbo(ScreenPtr screen);
 void glamor_fini_pixmap_fbo(ScreenPtr screen);
-- 
1.7.4.4



More information about the Glamor mailing list