[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