[Glamor] [PATCH 1/3] Modilfy the composite logic to two phases

junyan.he at linux.intel.com junyan.he at linux.intel.com
Mon Jun 4 13:48:11 PDT 2012


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

 We seperate the composite to two phases, firstly to
 select the shader according to source type and logic
 op, setting the right parameters. Then we emit the
 vertex array to generate the dest result.
 The reason why we do this is that the shader may be
 used to composite no only rect, trapezoid and triangle
 render function can also use it to render triangles and
 polygens. The old function glamor_composite_with_shader
 do the whole two phases work and can not match the
 new request.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 src/glamor_priv.h   |   19 ++++-
 src/glamor_render.c |  234 +++++++++++++++++++++++++++++----------------------
 2 files changed, 153 insertions(+), 100 deletions(-)

diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 76f75f9..ec8eadb 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -127,6 +127,12 @@ enum shader_in {
 	SHADER_IN_COUNT,
 };
 
+struct shader_key {
+	enum shader_source source;
+	enum shader_mask mask;
+	enum shader_in in;
+};
+
 enum gradient_shader {
 	SHADER_GRADIENT_LINEAR,
 	SHADER_GRADIENT_RADIAL,
@@ -158,6 +164,8 @@ enum glamor_gl_flavor {
 
 #define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
 
+#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
+
 typedef struct {
 	PicturePtr picture;	/* Where the glyphs of the cache are stored */
 	GlyphPtr *glyphs;
@@ -568,6 +576,15 @@ void glamor_composite_rects (CARD8         op,
 			     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);
+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,
@@ -762,7 +779,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 #ifndef GLAMOR_GLES2
 #define GLAMOR_GRADIENT_SHADER
-//#define GLAMOR_TRAPEZOID_SHADER
+#define GLAMOR_TRAPEZOID_SHADER
 #endif
 
 #endif				/* GLAMOR_PRIV_H */
diff --git a/src/glamor_render.c b/src/glamor_render.c
index ec23563..208e606 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -38,12 +38,6 @@
 #include "mipict.h"
 #include "fbpict.h"
 
-struct shader_key {
-	enum shader_source source;
-	enum shader_mask mask;
-	enum shader_in in;
-};
-
 struct blendinfo {
 	Bool dest_alpha;
 	Bool source_alpha;
@@ -380,8 +374,6 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
 	return shader;
 }
 
-#define GLAMOR_COMPOSITE_VBO_VERT_CNT 1024
-
 static void
 glamor_init_eb(unsigned short *eb, int vert_cnt)
 {
@@ -737,7 +729,7 @@ cleanup_region:
 	return ret;
 }
 
-static void
+void
 glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 {
 	glamor_screen_private *glamor_priv =
@@ -797,7 +789,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 	glamor_put_dispatch(glamor_priv);
 }
 
-static void
+void
 glamor_emit_composite_vert(ScreenPtr screen,
 			   const float *src_coords,
 			   const float *mask_coords,
@@ -929,58 +921,51 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
 	return FALSE;
 }
 
-static Bool
-glamor_composite_with_shader(CARD8 op,
-			     PicturePtr source,
-			     PicturePtr mask,
-			     PicturePtr dest,
-			     int nrect, glamor_composite_rect_t * rects)
+Bool glamor_composite_choose_shader(CARD8 op,
+                                    PicturePtr source,
+                                    PicturePtr mask,
+                                    PicturePtr dest,
+                                    struct shader_key *s_key,
+                                    PictFormatShort *psaved_source_format)
 {
 	ScreenPtr screen = dest->pDrawable->pScreen;
-	glamor_screen_private *glamor_priv =
-	    glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch;
-	PixmapPtr dest_pixmap =
-	    glamor_get_drawable_pixmap(dest->pDrawable);
-	PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr mask_pixmap = NULL;
+	PixmapPtr dest_pixmap = NULL;
 	glamor_pixmap_private *source_pixmap_priv = NULL;
 	glamor_pixmap_private *mask_pixmap_priv = NULL;
 	glamor_pixmap_private *dest_pixmap_priv = NULL;
-	GLfloat dst_xscale, dst_yscale;
-	GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale =
-	    1, src_yscale = 1;
-	struct shader_key key;
-	glamor_composite_shader *shader;
-	float vertices[8], source_texcoords[8], mask_texcoords[8];
-	int dest_x_off, dest_y_off;
-	int source_x_off, source_y_off;
-	int mask_x_off, mask_y_off;
 	enum glamor_pixmap_status source_status = GLAMOR_NONE;
 	enum glamor_pixmap_status mask_status = GLAMOR_NONE;
 	PictFormatShort saved_source_format = 0;
-	float src_matrix[9], mask_matrix[9];
-	GLfloat source_solid_color[4], mask_solid_color[4];
-	int vert_stride = 4;
-	int nrect_max;
+	struct shader_key key;
+	GLfloat source_solid_color[4];
+	GLfloat mask_solid_color[4];
+	glamor_composite_shader *shader = NULL;
+	glamor_gl_dispatch *dispatch = NULL;
 	Bool ret = FALSE;
 
+	dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
 	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+
 	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
 		glamor_fallback("dest has no fbo.\n");
 		goto fail;
 	}
+
 	memset(&key, 0, sizeof(key));
+
 	if (!source->pDrawable) {
 		if (source->pSourcePict->type == SourcePictTypeSolidFill) {
 			key.source = SHADER_SOURCE_SOLID;
-			glamor_get_rgba_from_pixel(source->
-						   pSourcePict->solidFill.
-						   color,
-						   &source_solid_color[0],
-						   &source_solid_color[1],
-						   &source_solid_color[2],
-						   &source_solid_color[3],
-						   PICT_a8r8g8b8);
+			glamor_get_rgba_from_pixel(
+			        source->pSourcePict->solidFill.color,
+			        &source_solid_color[0],
+			        &source_solid_color[1],
+			        &source_solid_color[2],
+			        &source_solid_color[3],
+			        PICT_a8r8g8b8);
 		} else {
 			glamor_fallback("gradient source\n");
 			goto fail;
@@ -988,17 +973,18 @@ glamor_composite_with_shader(CARD8 op,
 	} else {
 		key.source = SHADER_SOURCE_TEXTURE_ALPHA;
 	}
+
 	if (mask) {
 		if (!mask->pDrawable) {
 			if (mask->pSourcePict->type ==
-			    SourcePictTypeSolidFill) {
+			     SourcePictTypeSolidFill) {
 				key.mask = SHADER_MASK_SOLID;
-				glamor_get_rgba_from_pixel
-				    (mask->pSourcePict->solidFill.color,
-				     &mask_solid_color[0],
-				     &mask_solid_color[1],
-				     &mask_solid_color[2],
-				     &mask_solid_color[3], PICT_a8r8g8b8);
+				glamor_get_rgba_from_pixel(
+				       mask->pSourcePict->solidFill.color,
+				       &mask_solid_color[0],
+				       &mask_solid_color[1],
+				       &mask_solid_color[2],
+				       &mask_solid_color[3], PICT_a8r8g8b8);
 			} else {
 				glamor_fallback("gradient mask\n");
 				goto fail;
@@ -1013,14 +999,13 @@ glamor_composite_with_shader(CARD8 op,
 			if (op == PictOpClear)
 				key.mask = SHADER_MASK_NONE;
 			else if (op == PictOpSrc || op == PictOpAdd
-				 || op == PictOpIn || op == PictOpOut
-				 || op == PictOpOverReverse)
+			         || op == PictOpIn || op == PictOpOut
+			         || op == PictOpOverReverse)
 				key.in = SHADER_IN_CA_SOURCE;
 			else if (op == PictOpOutReverse || op == PictOpInReverse) {
 				key.in = SHADER_IN_CA_ALPHA;
 			} else {
-				glamor_fallback
-				    ("Unsupported component alpha op: %d\n", op);
+				glamor_fallback("Unsupported component alpha op: %d\n", op);
 				goto fail;
 			}
 		}
@@ -1037,8 +1022,9 @@ glamor_composite_with_shader(CARD8 op,
 		glamor_fallback("mask alphaMap\n");
 		goto fail;
 	}
+
 	if (key.source == SHADER_SOURCE_TEXTURE ||
-	    key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
+	     key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
 		source_pixmap =
 		    glamor_get_drawable_pixmap(source->pDrawable);
 		source_pixmap_priv =
@@ -1048,9 +1034,9 @@ glamor_composite_with_shader(CARD8 op,
 			goto fail;
 		}
 		if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
-			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex 
+			/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
 			 * equal to zero when the pixmap is screen pixmap. Then we may
-			 * refer the tex zero directly latter in the composition. 
+			 * refer the tex zero directly latter in the composition.
 			 * It seems that it works fine, but it may have potential problem*/
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 			source_status = GLAMOR_UPLOAD_PENDING;
@@ -1060,8 +1046,9 @@ glamor_composite_with_shader(CARD8 op,
 #endif
 		}
 	}
+
 	if (key.mask == SHADER_MASK_TEXTURE ||
-	    key.mask == SHADER_MASK_TEXTURE_ALPHA) {
+	     key.mask == SHADER_MASK_TEXTURE_ALPHA) {
 		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
 		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 		if (mask_pixmap == dest_pixmap) {
@@ -1077,49 +1064,48 @@ glamor_composite_with_shader(CARD8 op,
 #endif
 		}
 	}
+
 #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
 	if (source_status == GLAMOR_UPLOAD_PENDING
-	    && mask_status == GLAMOR_UPLOAD_PENDING
-	    && source_pixmap == mask_pixmap) {
+	     && mask_status == GLAMOR_UPLOAD_PENDING
+	     && source_pixmap == mask_pixmap) {
 
 		if (source->format != mask->format) {
 			saved_source_format = source->format;
 
-			if (!combine_pict_format
-			    (&source->format, source->format,
-			     mask->format, key.in)) {
-				glamor_fallback
-				    ("combine source %x mask %x failed.\n",
-				     source->format, mask->format);
+			if (!combine_pict_format(&source->format, source->format,
+			                         mask->format, key.in)) {
+				glamor_fallback("combine source %x mask %x failed.\n",
+				                source->format, mask->format);
 				goto fail;
 			}
 
 			if (source->format != saved_source_format) {
 				glamor_picture_format_fixup(source,
-							    source_pixmap_priv);
+				        source_pixmap_priv);
 			}
-			/* XXX  
+			/* XXX
 			 * By default, glamor_upload_picture_to_texture will wire alpha to 1
-			 * if one picture doesn't have alpha. So we don't do that again in 
+			 * if one picture doesn't have alpha. So we don't do that again in
 			 * rendering function. But here is a special case, as source and
-			 * mask share the same texture but may have different formats. For 
+			 * mask share the same texture but may have different formats. For
 			 * example, source doesn't have alpha, but mask has alpha. Then the
 			 * texture will have the alpha value for the mask. And will not wire
 			 * to 1 for the source. In this case, we have to use different shader
 			 * to wire the source's alpha to 1.
 			 *
-			 * But this may cause a potential problem if the source's repeat mode 
+			 * But this may cause a potential problem if the source's repeat mode
 			 * is REPEAT_NONE, and if the source is smaller than the dest, then
 			 * for the region not covered by the source may be painted incorrectly.
 			 * because we wire the alpha to 1.
 			 *
 			 **/
 			if (!PICT_FORMAT_A(saved_source_format)
-			    && PICT_FORMAT_A(mask->format))
+			     && PICT_FORMAT_A(mask->format))
 				key.source = SHADER_SOURCE_TEXTURE;
 
 			if (!PICT_FORMAT_A(mask->format)
-			    && PICT_FORMAT_A(saved_source_format))
+			     && PICT_FORMAT_A(saved_source_format))
 				key.mask = SHADER_MASK_TEXTURE;
 
 			mask_status = GLAMOR_NONE;
@@ -1127,16 +1113,14 @@ glamor_composite_with_shader(CARD8 op,
 
 		source_status = glamor_upload_picture_to_texture(source);
 		if (source_status != GLAMOR_UPLOAD_DONE) {
-			glamor_fallback
-			    ("Failed to upload source texture.\n");
+			glamor_fallback("Failed to upload source texture.\n");
 			goto fail;
 		}
 	} else {
 		if (source_status == GLAMOR_UPLOAD_PENDING) {
 			source_status = glamor_upload_picture_to_texture(source);
 			if (source_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback
-				    ("Failed to upload source texture.\n");
+				glamor_fallback("Failed to upload source texture.\n");
 				goto fail;
 			}
 		}
@@ -1144,8 +1128,7 @@ glamor_composite_with_shader(CARD8 op,
 		if (mask_status == GLAMOR_UPLOAD_PENDING) {
 			mask_status = glamor_upload_picture_to_texture(mask);
 			if (mask_status != GLAMOR_UPLOAD_DONE) {
-				glamor_fallback
-				    ("Failed to upload mask texture.\n");
+				glamor_fallback("Failed to upload mask texture.\n");
 				goto fail;
 			}
 		}
@@ -1155,14 +1138,14 @@ glamor_composite_with_shader(CARD8 op,
 	/*Before enter the rendering stage, we need to fixup
 	 * transformed source and mask, if the transform is not int translate. */
 	if (key.source != SHADER_SOURCE_SOLID
-	    && source->transform
-	    && !pixman_transform_is_int_translate(source->transform)) {
+	     && source->transform
+	     && !pixman_transform_is_int_translate(source->transform)) {
 		if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
 			goto fail;
 	}
 	if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
-	    && mask->transform
-	    && !pixman_transform_is_int_translate(mask->transform)) {
+	     && mask->transform
+	     && !pixman_transform_is_int_translate(mask->transform)) {
 		if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
 			goto fail;
 	}
@@ -1175,8 +1158,8 @@ glamor_composite_with_shader(CARD8 op,
 
 	shader = glamor_lookup_composite_shader(screen, &key);
 	if (shader->prog == 0) {
-		glamor_fallback
-		    ("no shader program for this render acccel mode\n");
+		glamor_fallback("no shader program for this"
+		                "render acccel mode\n");
 		goto fail;
 	}
 
@@ -1185,33 +1168,90 @@ glamor_composite_with_shader(CARD8 op,
 
 	if (key.source == SHADER_SOURCE_SOLID) {
 		glamor_set_composite_solid(dispatch, source_solid_color,
-					   shader->source_uniform_location);
+		        shader->source_uniform_location);
 	} else {
 		glamor_set_composite_texture(screen, 0, source,
-					     source_pixmap_priv, shader->source_wh,
-					     shader->source_repeat_mode);
+		        source_pixmap_priv, shader->source_wh,
+		        shader->source_repeat_mode);
 	}
+
 	if (key.mask != SHADER_MASK_NONE) {
 		if (key.mask == SHADER_MASK_SOLID) {
 			glamor_set_composite_solid(dispatch,
-						   mask_solid_color,
-						   shader->mask_uniform_location);
+			        mask_solid_color,
+			        shader->mask_uniform_location);
 		} else {
 			glamor_set_composite_texture(screen, 1, mask,
-						     mask_pixmap_priv, shader->mask_wh,
-						     shader->mask_repeat_mode);
+			        mask_pixmap_priv, shader->mask_wh,
+			        shader->mask_repeat_mode);
 		}
 	}
 
+	glamor_put_dispatch(glamor_priv);
+	ret = TRUE;
+	memcpy(s_key, &key, sizeof(key));
+	*psaved_source_format = saved_source_format;
+	goto done;
+
+fail:
+	if (saved_source_format)
+		source->format = saved_source_format;
+done:
+	return ret;
+}
+
+
+static Bool
+glamor_composite_with_shader(CARD8 op,
+			     PicturePtr source,
+			     PicturePtr mask,
+			     PicturePtr dest,
+			     int nrect, glamor_composite_rect_t * rects)
+{
+	ScreenPtr screen = dest->pDrawable->pScreen;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	PixmapPtr dest_pixmap = NULL;
+	PixmapPtr source_pixmap = NULL;
+	PixmapPtr mask_pixmap = NULL;
+	glamor_pixmap_private *source_pixmap_priv = NULL;
+	glamor_pixmap_private *mask_pixmap_priv = NULL;
+	glamor_pixmap_private *dest_pixmap_priv = NULL;
+	glamor_gl_dispatch *dispatch = NULL;
+	GLfloat dst_xscale, dst_yscale;
+	GLfloat mask_xscale = 1, mask_yscale = 1,
+	        src_xscale = 1, src_yscale = 1;
+	struct shader_key key;
+	float vertices[8], source_texcoords[8], mask_texcoords[8];
+	int dest_x_off, dest_y_off;
+	int source_x_off, source_y_off;
+	int mask_x_off, mask_y_off;
+	PictFormatShort saved_source_format = 0;
+	float src_matrix[9], mask_matrix[9];
+	int vert_stride = 4;
+	int nrect_max;
+	Bool ret = FALSE;
+
+	if(!glamor_composite_choose_shader(op, source, mask, dest,
+	                                   &key, &saved_source_format)) {
+		glamor_fallback("glamor_composite_choose_shader failed\n");
+		return ret;
+	}
+
+	dispatch = glamor_get_dispatch(glamor_priv);
+
 	glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
 	glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
 					key.mask != SHADER_MASK_SOLID);
 
+	dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
+	dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
 	glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
 				   &dest_x_off, &dest_y_off);
 	pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
 
 	if (glamor_priv->has_source_coords) {
+		source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
+		source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
 		glamor_get_drawable_deltas(source->pDrawable,
 					   source_pixmap, &source_x_off,
 					   &source_y_off);
@@ -1222,6 +1262,8 @@ glamor_composite_with_shader(CARD8 op,
 	}
 
 	if (glamor_priv->has_mask_coords) {
+		mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
+		mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
 		glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
 					   &mask_x_off, &mask_y_off);
 		pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
@@ -1329,16 +1371,10 @@ glamor_composite_with_shader(CARD8 op,
 	glamor_put_dispatch(glamor_priv);
 
 	ret = TRUE;
-	goto done;
-
-fail:
-	if (saved_source_format)
-		source->format = saved_source_format;
-done:
 	return ret;
 }
 
-static PicturePtr
+PicturePtr
 glamor_convert_gradient_picture(ScreenPtr screen,
                                 PicturePtr source,
                                 int x_source,
-- 
1.7.7.6



More information about the Glamor mailing list