[Glamor] [PATCH] glamor_gles2: Fixed the broken fbo pool for GLES2.

zhigang.gong at linux.intel.com zhigang.gong at linux.intel.com
Thu Mar 29 05:25:25 PDT 2012


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

This commit fixes two bugs in GLES2 code path:

1. GLES2 has three possible fbo formats, GL_RGBA, GL_BGRA and GL_ALPHA
we need to add them to the fbo pool.

2. GLES2's preparing function for reading has a bug when got a different
size fbo from the fbo pool. Now fixed it.

Now, we are closer to pass render check with major color format:
a8r8g8b8,r8g8b8,a8b8g8r8,r8g8b8a8,b8g8r8a8,r5g6b5.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/glamor_fbo.c      |   44 +++++++++++++++++++++-----------------------
 src/glamor_getimage.c |    2 ++
 src/glamor_getspans.c |    2 ++
 src/glamor_pixmap.c   |   49 +++++++++++++++++++++++++------------------------
 src/glamor_priv.h     |    6 +++++-
 src/glamor_utils.h    |   26 +++++++++++++++++++++++++-
 6 files changed, 80 insertions(+), 49 deletions(-)

diff --git a/src/glamor_fbo.c b/src/glamor_fbo.c
index 4a7068f..ba67ae9 100644
--- a/src/glamor_fbo.c
+++ b/src/glamor_fbo.c
@@ -62,18 +62,6 @@ inline static int cache_hbucket(int size)
 		order = CACHE_BUCKET_HCOUNT - 1;
 	return order;
 }
-inline static int cache_format(GLenum format)
-{
-	switch (format) {
-#if 0
-	case GL_ALPHA:
-		return 1;
-#endif
-	case GL_RGBA:
-	default:
-		return 0;
-	}
-}
 
 glamor_pixmap_fbo *
 glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
@@ -82,25 +70,30 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 	struct xorg_list *cache;
 	glamor_pixmap_fbo *fbo_entry;
 	int size;
+	int n_format;
 #ifdef NO_FBO_CACHE
 	return NULL;
 #else
+	n_format = cache_format(format);
+	if (n_format == -1)
+		return NULL;
 	if (!(flag & GLAMOR_CACHE_TEXTURE))
-		cache = &glamor_priv->fbo_cache[cache_format(format)]
+		cache = &glamor_priv->fbo_cache[n_format]
 					       [cache_wbucket(w)]
 					       [cache_hbucket(h)];
 	else
-		cache = &glamor_priv->tex_cache[cache_format(format)]
+		cache = &glamor_priv->tex_cache[n_format]
 					       [cache_wbucket(w)]
 					       [cache_hbucket(h)];
 	if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
 		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
-				DEBUGF("Request w %d h %d \n", w, h);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+				DEBUGF("Request w %d h %d format %x \n", w, h, format);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
-					fbo_entry->fb, fbo_entry->tex);
+					fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+				assert(format == fbo_entry->format);
 				xorg_list_del(&fbo_entry->list);
 				return fbo_entry;
 			}
@@ -110,10 +103,11 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 		xorg_list_for_each_entry(fbo_entry, cache, list) {
 			if (fbo_entry->width == w && fbo_entry->height == h) {
 
-				DEBUGF("Request w %d h %d \n", w, h);
-				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
+				DEBUGF("Request w %d h %d format %x \n", w, h, format);
+				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
 					fbo_entry, fbo_entry->width, fbo_entry->height,
-					fbo_entry->fb, fbo_entry->tex);
+					fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+				assert(format == fbo_entry->format);
 				xorg_list_del(&fbo_entry->list);
 				return fbo_entry;
 			}
@@ -144,21 +138,25 @@ static void
 glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 {
 	struct xorg_list *cache;
+	int n_format;
+
 #ifdef NO_FBO_CACHE
 	glamor_purge_fbo(fbo);
 	return;
 #else
-	if (fbo->fb == 0) {
+	n_format = cache_format(fbo->format);
+
+	if (fbo->fb == 0 || n_format == -1) {
 		glamor_purge_fbo(fbo);
 		return;
 	}
 
 	if (fbo->fb)
-		cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
+		cache = &fbo->glamor_priv->fbo_cache[n_format]
 						    [cache_wbucket(fbo->width)]
 						    [cache_hbucket(fbo->height)];
 	else
-		cache = &fbo->glamor_priv->tex_cache[cache_format(fbo->format)]
+		cache = &fbo->glamor_priv->tex_cache[n_format]
 						    [cache_wbucket(fbo->width)]
 						    [cache_hbucket(fbo->height)];
 	DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
diff --git a/src/glamor_getimage.c b/src/glamor_getimage.c
index efbd1ba..7793eab 100644
--- a/src/glamor_getimage.c
+++ b/src/glamor_getimage.c
@@ -84,6 +84,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
 		    glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
 						   &tex_type, no_alpha,
 						   no_revert);
+		if (temp_pixmap == NULL)
+			goto fall_back;
 		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	}
diff --git a/src/glamor_getspans.c b/src/glamor_getspans.c
index 91030a3..65748e1 100644
--- a/src/glamor_getspans.c
+++ b/src/glamor_getspans.c
@@ -71,6 +71,8 @@ _glamor_get_spans(DrawablePtr drawable,
 		    glamor_es2_pixmap_read_prepare(pixmap, &format,
 						   &type, no_alpha,
 						   no_revert);
+		if (temp_pixmap == NULL)
+			goto fail;
 		pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
 		glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	}
diff --git a/src/glamor_pixmap.c b/src/glamor_pixmap.c
index 808e527..9d6a6b9 100644
--- a/src/glamor_pixmap.c
+++ b/src/glamor_pixmap.c
@@ -627,18 +627,12 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 	glamor_screen_private *glamor_priv;
 	ScreenPtr screen;
 	PixmapPtr temp_pixmap;
-	glamor_pixmap_private *temp_pixmap_priv;
+	glamor_pixmap_private *temp_pixmap_priv, *source_pixmap_priv;
 	glamor_gl_dispatch *dispatch;
-	static float vertices[8] = { -1, -1,
-		1, -1,
-		1, 1,
-		-1, 1
-	};
-	static float texcoords[8] = { 0, 0,
-		1, 0,
-		1, 1,
-		0, 1
-	};
+	float temp_xscale, temp_yscale, source_xscale, source_yscale;
+
+	static float vertices[8];
+	static float texcoords[8];
 
 	int swap_rb = 0;
 
@@ -651,33 +645,38 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
 		swap_rb = 1;
 	}
 
-
 	temp_pixmap = glamor_create_pixmap (screen,
 					    source->drawable.width,
 					    source->drawable.height,
 					    source->drawable.depth, 0);
+	if (temp_pixmap == NULL)
+		return NULL;
 
 	temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
+	source_pixmap_priv = glamor_get_pixmap_private(source);
 
 	dispatch = glamor_get_dispatch(glamor_priv);
-	dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MIN_FILTER,
-				  GL_NEAREST);
-	dispatch->glTexParameteri(GL_TEXTURE_2D,
-				  GL_TEXTURE_MAG_FILTER,
-				  GL_NEAREST);
-
-	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
-			       source->drawable.width,
-			       source->drawable.height, 0, *format, *type,
-			       NULL);
+	pixmap_priv_get_scale(temp_pixmap_priv, &temp_xscale, &temp_yscale);
+	glamor_set_normalize_vcoords(temp_xscale,
+				     temp_yscale,
+				     0, 0,
+				     temp_pixmap->drawable.width, temp_pixmap->drawable.height,
+				     glamor_priv->yInverted,
+				     vertices);
 
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					vertices);
 	dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
+	pixmap_priv_get_scale(source_pixmap_priv, &source_xscale, &source_yscale);
+	glamor_set_normalize_tcoords(source_xscale,
+				     source_yscale,
+				     0, 0,
+				     source->drawable.width, source->drawable.height,
+				     glamor_priv->yInverted,
+				     texcoords);
+
 	dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
 					GL_FALSE, 2 * sizeof(float),
 					texcoords);
@@ -768,6 +767,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 		    glamor_es2_pixmap_read_prepare(pixmap, &format,
 						   &type, no_alpha,
 						   no_revert);
+		if (temp_pixmap == NULL)
+			return FALSE;
 	}
 	switch (access) {
 	case GLAMOR_ACCESS_RO:
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 227c407..9fb5756 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -181,8 +181,12 @@ struct glamor_saved_procs {
 	DestroyPictureProcPtr destroy_picture;
 	UnrealizeGlyphProcPtr unrealize_glyph;
 };
-
+#ifdef GLAMOR_GLES2
+#define CACHE_FORMAT_COUNT 3
+#else
 #define CACHE_FORMAT_COUNT 1
+#endif
+
 #define CACHE_BUCKET_WCOUNT 4
 #define CACHE_BUCKET_HCOUNT 4
 
diff --git a/src/glamor_utils.h b/src/glamor_utils.h
index 252f34c..69d18ea 100644
--- a/src/glamor_utils.h
+++ b/src/glamor_utils.h
@@ -386,6 +386,17 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	}
 	return 0;
 }
+
+/* Currently, we use RGBA to represent all formats. */
+inline static int cache_format(GLenum format)
+{
+	switch (format) {
+	case GL_RGBA:
+		return 0;
+	default:
+		return -1;
+	}
+}
 #else
 #define IS_LITTLE_ENDIAN  (IMAGE_BYTE_ORDER == LSBFirst)
 
@@ -497,7 +508,20 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
 	return 0;
 }
 
-
+inline static int cache_format(GLenum format)
+{
+	switch (format) {
+	case GL_ALPHA:
+		return 2;
+	case GL_BGRA:
+		return 1;
+	case GL_RGB:
+	case GL_RGBA:
+		return 0;
+	default:
+		return -1;
+	}
+}
 #endif
 
 static inline int
-- 
1.7.4.4



More information about the Glamor mailing list