[Glamor] [PATCH] glamor_tile/composite: Modify fs to re-calculate texture coords.

Zhigang Gong zhigang.gong at gmail.com
Sat Feb 11 16:33:05 PST 2012


Then we don't need to fixup the larger pixmap to the exact
size, just need to let the shader to re-calculate the correct
texture coords.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/glamor_gl_dispatch.c |    2 +
 src/glamor_gl_dispatch.h |    4 ++
 src/glamor_priv.h        |    3 ++
 src/glamor_render.c      |   85 +++++++++++++++++++++-------------------------
 src/glamor_tile.c        |   24 ++++++++-----
 5 files changed, 63 insertions(+), 55 deletions(-)

diff --git a/src/glamor_gl_dispatch.c b/src/glamor_gl_dispatch.c
index da66380..ef0ac43 100644
--- a/src/glamor_gl_dispatch.c
+++ b/src/glamor_gl_dispatch.c
@@ -66,6 +66,8 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
 	INIT_FUNC(dispatch, glUseProgram, get_proc_address);
 	INIT_FUNC(dispatch, glUniform1i, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4f, get_proc_address);
+	INIT_FUNC(dispatch, glUniform1fv, get_proc_address);
+	INIT_FUNC(dispatch, glUniform2fv, get_proc_address);
 	INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
 	INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
 	INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
diff --git a/src/glamor_gl_dispatch.h b/src/glamor_gl_dispatch.h
index 024de26..bd33bcc 100644
--- a/src/glamor_gl_dispatch.h
+++ b/src/glamor_gl_dispatch.h
@@ -94,6 +94,10 @@ typedef struct glamor_gl_dispatch {
 	void (*glUniform1i) (GLint location, GLint v0);
 	void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
 			     GLfloat v2, GLfloat v3);
+	void (*glUniform1fv) (GLint location, GLsizei count,
+			      const GLfloat * value);
+	void (*glUniform2fv) (GLint location, GLsizei count,
+			      const GLfloat * value);
 	void (*glUniform4fv) (GLint location, GLsizei count,
 			      const GLfloat * value);
 	 GLuint(*glCreateProgram) (void);
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index d04421b..152817d 100644
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -68,6 +68,8 @@ typedef struct glamor_composite_shader {
 	GLint dest_to_mask_uniform_location;
 	GLint source_uniform_location;
 	GLint mask_uniform_location;
+	GLint source_wh;
+	GLint mask_wh;
 } glamor_composite_shader;
 
 typedef struct {
@@ -207,6 +209,7 @@ typedef struct glamor_screen_private {
 
 	/* glamor_tile */
 	GLint tile_prog;
+	GLint tile_wh;
 
 	/* glamor_putimage */
 	GLint put_image_xybitmap_prog;
diff --git a/src/glamor_render.c b/src/glamor_render.c
index b240eac..c3e3e0a 100644
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -70,6 +70,15 @@ static GLuint
 glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 			   struct shader_key *key)
 {
+	const char *relocate_texture =
+	    GLAMOR_DEFAULT_PRECISION
+	    "vec2 rel_tex_coord(vec2 texture, vec2 wh) \n"
+	    "{\n"
+	    "   vec2 rel_tex; \n"
+	    "   rel_tex = texture * wh; \n"
+	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+            "   return rel_tex; \n"
+	    "}\n";
 	const char *source_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION
 	    "uniform vec4 source;\n"
@@ -78,26 +87,35 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 source_texture;\n"
 	    "uniform sampler2D source_sampler;\n"
+	    "uniform vec2 source_wh;"
 	    "vec4 get_source()\n"
-	    "{\n" "	return texture2D(source_sampler, source_texture);\n"
+	    "{\n" "	return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n"
 	    "}\n";
 	const char *source_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
-	    "uniform sampler2D source_sampler;\n" "vec4 get_source()\n"
+	    "uniform sampler2D source_sampler;\n"
+	    "uniform vec2 source_wh;"
+	    "vec4 get_source()\n"
 	    "{\n"
-	    "       return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
+	    "       return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *mask_solid_fetch =
 	    GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
 	    "vec4 get_mask()\n" "{\n" "	return mask;\n" "}\n";
 	const char *mask_alpha_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
-	    "	return texture2D(mask_sampler, mask_texture);\n" "}\n";
+	    "uniform sampler2D mask_sampler;\n"
+	    "uniform vec2 mask_wh;"
+	    "vec4 get_mask()\n"
+	    "{\n"
+	    "	return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n" "}\n";
 	const char *mask_pixmap_fetch =
 	    GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
-	    "uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
-	    "       return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
+	    "uniform sampler2D mask_sampler;\n"
+	    "uniform vec2 mask_wh;"
+	    "vec4 get_mask()\n"
+	    "{\n"
+	    "       return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n"
 	    "}\n";
 	const char *in_source_only =
 	    GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
@@ -164,7 +182,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
 		FatalError("Bad composite IN type");
 	}
 
-	XNFasprintf(&source, "%s%s%s", source_fetch, mask_fetch, in);
+	XNFasprintf(&source, "%s%s%s%s", relocate_texture, source_fetch, mask_fetch, in);
 
 
 	prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
@@ -220,8 +238,8 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 	GLuint vs, fs, prog;
 	GLint source_sampler_uniform_location,
 	    mask_sampler_uniform_location;
-	glamor_screen_private *glamor = glamor_get_screen_private(screen);
-	glamor_gl_dispatch *dispatch = &glamor->dispatch;
+	glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 
 	vs = glamor_create_composite_vs(dispatch, key);
 	if (vs == 0)
@@ -254,6 +272,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 		source_sampler_uniform_location =
 		    dispatch->glGetUniformLocation(prog, "source_sampler");
 		dispatch->glUniform1i(source_sampler_uniform_location, 0);
+		shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
 	}
 
 	if (key->mask != SHADER_MASK_NONE) {
@@ -266,6 +285,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
 							   "mask_sampler");
 			dispatch->glUniform1i
 			    (mask_sampler_uniform_location, 1);
+			shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
 		}
 	}
 }
@@ -445,42 +465,18 @@ 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 an exact 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)
+			     glamor_pixmap_private * pixmap_priv,
+			     GLuint wh_location)
 {
 	glamor_screen_private *glamor_priv =
 	    glamor_get_screen_private(screen);
 	glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
 	dispatch->glActiveTexture(GL_TEXTURE0 + unit);
 	dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
+	float wh[2];
+
 	switch (picture->repeatType) {
 	case RepeatNone:
 #ifndef GLAMOR_GLES2
@@ -533,6 +529,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
 #ifndef GLAMOR_GLES2
 	dispatch->glEnable(GL_TEXTURE_2D);
 #endif
+	wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width;
+	wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height;
+	dispatch->glUniform2fv(wh_location, 1, wh);
 }
 
 static void
@@ -1070,12 +1069,6 @@ 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);
 
@@ -1097,7 +1090,7 @@ glamor_composite_with_shader(CARD8 op,
 					   shader->source_uniform_location);
 	} else {
 		glamor_set_composite_texture(screen, 0, source,
-					     source_pixmap_priv);
+					     source_pixmap_priv, shader->source_wh);
 	}
 	if (key.mask != SHADER_MASK_NONE) {
 		if (key.mask == SHADER_MASK_SOLID) {
@@ -1106,7 +1099,7 @@ glamor_composite_with_shader(CARD8 op,
 						   shader->mask_uniform_location);
 		} else {
 			glamor_set_composite_texture(screen, 1, mask,
-						     mask_pixmap_priv);
+						     mask_pixmap_priv, shader->mask_wh);
 		}
 	}
 
diff --git a/src/glamor_tile.c b/src/glamor_tile.c
index 3087bea..718478f 100644
--- a/src/glamor_tile.c
+++ b/src/glamor_tile.c
@@ -53,8 +53,13 @@ glamor_init_tile_shader(ScreenPtr screen)
 	    GLAMOR_DEFAULT_PRECISION
 	    "varying vec2 tile_texture;\n"
 	    "uniform sampler2D sampler;\n"
+	    "uniform vec2	wh;"
 	    "void main()\n"
-	    "{\n" "	gl_FragColor = texture2D(sampler, tile_texture);\n"
+	    "{\n"
+	    "   vec2 rel_tex;"
+	    "   rel_tex = tile_texture * wh; \n"
+	    "   rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
+	    "	gl_FragColor = texture2D(sampler, rel_tex);\n"
 	    "}\n";
 	GLint fs_prog, vs_prog;
 	GLint sampler_uniform_location;
@@ -80,6 +85,10 @@ glamor_init_tile_shader(ScreenPtr screen)
 					   "sampler");
 	dispatch->glUseProgram(glamor_priv->tile_prog);
 	dispatch->glUniform1i(sampler_uniform_location, 0);
+
+	glamor_priv->tile_wh =
+	    dispatch->glGetUniformLocation(glamor_priv->tile_prog,
+					   "wh");
 	dispatch->glUseProgram(0);
 }
 
@@ -117,6 +126,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 	GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
 	glamor_pixmap_private *src_pixmap_priv;
 	glamor_pixmap_private *dst_pixmap_priv;
+	float wh[2];
 
 	src_pixmap_priv = glamor_get_pixmap_private(tile);
 	dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -144,14 +154,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 		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);
@@ -168,6 +170,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 				      &src_yscale);
 		dispatch->glUseProgram(glamor_priv->tile_prog);
 
+		wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
+		wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
+
+		dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
 		dispatch->glActiveTexture(GL_TEXTURE0);
 		dispatch->glBindTexture(GL_TEXTURE_2D,
 					src_pixmap_priv->fbo->tex);
-- 
1.7.4.4



More information about the Glamor mailing list