[Glamor] [PATCH 07/15] glamor-fbo-pool: Enable to reuse different size fbo/texture.

zhigang.gong at linux.intel.com zhigang.gong at linux.intel.com
Fri Jan 20 00:52:05 PST 2012


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

Fixup too special case, one is in tile and the other is in
composite. Both cases are due to repeat texture issue. Maybe
we can refine the shader to recalculate texture coords to
support partial texture's repeating.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/glamor_fbo.c    |    2 +-
 src/glamor_pixmap.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/glamor_priv.h   |    4 +++
 src/glamor_render.c |   33 ++++++++++++++++++++++++++
 src/glamor_tile.c   |   11 +++++++++
 5 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/src/glamor_fbo.c b/src/glamor_fbo.c
index cc7a14c..a168165 100644
--- a/src/glamor_fbo.c
+++ b/src/glamor_fbo.c
@@ -67,7 +67,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 				       [cache_hbucket(h)];
 	if (flag != GLAMOR_CACHE_EXACT_SIZE) {
 		list_for_each_entry(fbo_entry, cache, list) {
-			if (fbo_entry->width == w && fbo_entry->height == h) {
+			if (fbo_entry->width >= w && fbo_entry->height >= h) {
 
 				DEBUGF("Request w %d h %d \n", w, h);
 				DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
diff --git a/src/glamor_pixmap.c b/src/glamor_pixmap.c
index d0b3489..673971c 100644
--- a/src/glamor_pixmap.c
+++ b/src/glamor_pixmap.c
@@ -791,3 +791,66 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
 
 	return TRUE;
 }
+
+/* fixup a fbo to the exact size as the pixmap. */
+Bool
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
+{
+	glamor_screen_private *glamor_priv;
+	glamor_pixmap_fbo *old_fbo;
+	glamor_pixmap_fbo *new_fbo = NULL;
+	PixmapPtr scratch = NULL;
+	glamor_pixmap_private *scratch_priv;
+	DrawablePtr drawable;
+	GCPtr gc = NULL;
+	int ret = FALSE;
+
+	drawable = &pixmap_priv->container->drawable;
+
+	if (pixmap_priv->container->drawable.width == pixmap_priv->fbo->width
+	    && pixmap_priv->container->drawable.height == pixmap_priv->fbo->height)
+		return	TRUE;
+	
+	old_fbo = pixmap_priv->fbo;
+	glamor_priv = pixmap_priv->glamor_priv;
+
+	if (!old_fbo)
+		return FALSE;
+
+	gc = GetScratchGC(drawable->depth, screen);
+	if (!gc)
+		goto fail;
+
+	scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
+				       drawable->depth,
+				       GLAMOR_CREATE_PIXMAP_FIXUP);
+
+	scratch_priv = glamor_get_pixmap_private(scratch);
+
+	if (!scratch_priv || !scratch_priv->fbo)
+		goto fail;
+
+	ValidateGC(&scratch->drawable, gc);
+	glamor_copy_area(drawable,
+			 &scratch->drawable,
+			 gc, 0, 0,
+			 drawable->width, drawable->height,
+			 0, 0);
+	old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+	new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
+	glamor_pixmap_attach_fbo(pixmap_priv->container, new_fbo);
+	glamor_pixmap_attach_fbo(scratch, old_fbo);
+	
+	DEBUGF("old %dx%d type %d\n",
+		drawable->width, drawable->height, pixmap_priv->type);
+	DEBUGF("copy tex %d  %dx%d to tex %d %dx%d \n",
+		old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height);
+	ret = TRUE;
+fail:
+	if (gc)
+		FreeScratchGC(gc);
+	if (scratch)
+		glamor_destroy_pixmap(scratch);
+	
+	return ret;	
+}
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 0b08c37..ccca14f 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -594,6 +594,10 @@ void glamor_destroy_picture(PicturePtr picture);
 enum glamor_pixmap_status
  glamor_upload_picture_to_texture(PicturePtr picture);
 
+/* fixup a fbo to the exact size as the pixmap. */
+Bool
+glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
+
 void
 glamor_picture_format_fixup(PicturePtr picture,
 			    glamor_pixmap_private * pixmap_priv);
diff --git a/src/glamor_render.c b/src/glamor_render.c
index 19ed22e..abc0f06 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -409,6 +409,33 @@ glamor_set_composite_op(ScreenPtr screen,
 }
 
 static void
+glamor_composite_texture_fixup(ScreenPtr screen,
+			       PicturePtr picture,
+			       glamor_pixmap_private * pixmap_priv)
+{
+	glamor_screen_private *glamor_priv =
+	    glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
+	Bool has_repeat;
+	int width, height;
+
+	if (picture->repeatType == RepeatNone)
+		has_repeat = FALSE;
+	else
+		has_repeat = TRUE;
+
+	if (has_repeat 
+	    && ( (pixmap_priv->container->drawable.width != pixmap_priv->fbo->width)
+		 || (pixmap_priv->container->drawable.height != pixmap_priv->fbo->height))) {
+	/* Currently, we can't support repeat on partial texture, now redirect it
+ 	 * to a eact size fbo. */
+		DEBUGF("prepare to fixup texture \n");
+		if (!glamor_fixup_pixmap_priv(screen, pixmap_priv))
+			ErrorF("Failed to fixup a unmatch size of repeat picture. \n");
+	}
+}
+
+static void
 glamor_set_composite_texture(ScreenPtr screen, int unit,
 			     PicturePtr picture,
 			     glamor_pixmap_private * pixmap_priv)
@@ -979,6 +1006,12 @@ glamor_composite_with_shader(CARD8 op,
 		}
 	}
 #endif
+
+	if (key.source != SHADER_SOURCE_SOLID)
+		glamor_composite_texture_fixup(screen, source, source_pixmap_priv);
+	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID)
+		glamor_composite_texture_fixup(screen, mask, mask_pixmap_priv);
+
 	glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
 	glamor_validate_pixmap(dest_pixmap);
 	if (!glamor_set_composite_op(screen, op, dest, mask)) {
diff --git a/src/glamor_tile.c b/src/glamor_tile.c
index 7e0e6ac..71ee611 100644
--- a/src/glamor_tile.c
+++ b/src/glamor_tile.c
@@ -127,8 +127,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	if (((tile_x != 0) && (tile_x + width > tile->drawable.width))
 	    || ((tile_y != 0)
 		&& (tile_y + height > tile->drawable.height))) {
+		/* XXX We can recreate a new pixmap here to avoid partial tiling. */
 		goto fail;
 	}
+ 
 	if (glamor_priv->tile_prog == 0) {
 		glamor_fallback("Tiling unsupported\n");
 		goto fail;
@@ -148,6 +150,15 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		glamor_fallback("unsupported planemask %lx\n", planemask);
 		goto fail;
 	}
+
+	if (src_pixmap_priv->fbo->width != tile->drawable.width
+	    || src_pixmap_priv->fbo->height != tile->drawable.height) {
+		if (!glamor_fixup_pixmap_priv(screen, src_pixmap_priv)) {
+			glamor_fallback("Failed to create a fixup pixmap for partial tiling. \n");
+			goto fail;
+		}
+	}
+
 	if (alu != GXcopy) {
 		glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
 		glamor_validate_pixmap(tile);
-- 
1.7.4.4



More information about the Glamor mailing list