From 9dfd10dc75efdf4c26b7ff46b55e4a2d2453803b Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Fri, 27 Apr 2012 15:34:15 +0800 Subject: [PATCH] glamor_render: Fix the repeat none for GLES2. As GLES2 doesn't support clamp to the border, we have to handle it seprately from the normal case. Signed-off-by: Zhigang Gong --- glamor/glamor_render.c | 88 ++++++++++++++++++++++++++++-------------- glamor/glamor_utils.h | 11 ++++++ 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 21ef904ab..de01aab33 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -65,7 +65,7 @@ static struct blendinfo composite_op_info[] = { {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, }; - +#define RepeatFix 10 static GLuint glamor_create_composite_fs(glamor_gl_dispatch * dispatch, struct shader_key *key) @@ -75,6 +75,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "#define RepeatNormal 1\n" "#define RepeatPad 2\n" "#define RepeatReflect 3\n" + "#define RepeatFix 10\n" "uniform int source_repeat_mode;\n" "uniform int mask_repeat_mode;\n"; const char *relocate_texture = @@ -83,7 +84,9 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "{\n" " vec2 rel_tex; \n" " rel_tex = texture * wh; \n" - " if (repeat == RepeatNormal) \n" + " if (repeat == RepeatNone)\n" + " return rel_tex; \n" + " else if (repeat == RepeatNormal) \n" " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n" " else if(repeat == RepeatPad) { \n" " if (rel_tex.x > 1.0) rel_tex.x = 1.0; \n" @@ -104,6 +107,24 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, " } \n" " return rel_tex; \n" "}\n"; + /* The texture and the pixmap size is not match eaxctly, so can't sample it directly. + * rel_sampler will recalculate the texture coords.*/ + const char *rel_sampler = + " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec2 wh, int repeat, int set_alpha)\n" + "{\n" + " tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n" + " if (repeat == RepeatFix) {\n" + " if (!(tex.x >= 0.0 && tex.x <= 1.0 \n" + " && tex.y >= 0.0 && tex.y <= 1.0))\n" + " return vec4(0.0, 0.0, 0.0, set_alpha);\n" + " tex = (fract(tex) / wh);\n" + " }\n" + " if (set_alpha != 1)\n" + " return texture2D(tex_image, tex);\n" + " else\n" + " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n" + "}\n"; + const char *source_solid_fetch = GLAMOR_DEFAULT_PRECISION "uniform vec4 source;\n" @@ -115,12 +136,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "uniform vec2 source_wh;" "vec4 get_source()\n" "{\n" - " if (source_repeat_mode == RepeatNone) \n" + " if (source_repeat_mode < RepeatFix)\n" " return texture2D(source_sampler, source_texture);\n" - " else \n" - " return texture2D(source_sampler,\n" - " rel_tex_coord(source_texture,\n" - " source_wh, source_repeat_mode));\n" + " else \n" + " return rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode, 0);\n" "}\n"; const char *source_pixmap_fetch = GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" @@ -128,12 +148,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "uniform vec2 source_wh;\n" "vec4 get_source()\n" "{\n" - " if (source_repeat_mode == RepeatNone) \n" + " if (source_repeat_mode < RepeatFix) \n" " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" " else \n" - " return vec4(texture2D(source_sampler, \n" - " rel_tex_coord(source_texture,\n" - " source_wh, source_repeat_mode)).rgb, 1);\n" + " return rel_sampler(source_sampler, source_texture,\n" + " source_wh, source_repeat_mode, 1);\n" "}\n"; const char *mask_solid_fetch = GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" @@ -144,12 +163,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "uniform vec2 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_repeat_mode == RepeatNone) \n" + " if (mask_repeat_mode < RepeatFix) \n" " return texture2D(mask_sampler, mask_texture);\n" " else \n" - " return texture2D(mask_sampler, \n" - " rel_tex_coord(mask_texture, \n" - " mask_wh, mask_repeat_mode));\n" + " return rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode, 0);\n" "}\n"; const char *mask_pixmap_fetch = GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" @@ -157,12 +175,11 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "uniform vec2 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_repeat_mode == RepeatNone) \n" + " if (mask_repeat_mode < RepeatFix) \n" " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" " else \n" - " return vec4(texture2D(mask_sampler, \n" - " rel_tex_coord(mask_texture, \n" - " mask_wh, mask_repeat_mode)).rgb, 1);\n" + " return rel_sampler(mask_sampler, mask_texture,\n" + " mask_wh, mask_repeat_mode, 1);\n" "}\n"; const char *in_source_only = GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" @@ -229,7 +246,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, FatalError("Bad composite IN type"); } - XNFasprintf(&source, "%s%s%s%s%s", repeat_define, relocate_texture, source_fetch, mask_fetch, in); + XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture, rel_sampler,source_fetch, mask_fetch, in); prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, @@ -524,11 +541,12 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, glamor_gl_dispatch *dispatch; float wh[2]; Bool has_repeat; + int repeat_type; dispatch = glamor_get_dispatch(glamor_priv); dispatch->glActiveTexture(GL_TEXTURE0 + unit); dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex); - + repeat_type = picture->repeatType; switch (picture->repeatType) { case RepeatNone: #ifndef GLAMOR_GLES2 @@ -537,6 +555,11 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, GL_CLAMP_TO_BORDER); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); +#else + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); #endif break; case RepeatNormal: @@ -560,6 +583,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, } switch (picture->filter) { + default: case PictFilterNearest: dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, @@ -569,7 +593,6 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, GL_NEAREST); break; case PictFilterBilinear: - default: dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -581,14 +604,22 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, #ifndef GLAMOR_GLES2 dispatch->glEnable(GL_TEXTURE_2D); #endif - dispatch->glUniform1i(repeat_location, picture->repeatType); - if (picture->repeatType != RepeatNone) { - wh[0] = (float)pixmap_priv->fbo->width - / pixmap_priv->container->drawable.width; - wh[1] = (float)pixmap_priv->fbo->height - / pixmap_priv->container->drawable.height; + /* XXX may be we can eaxctly check whether we need to touch + * the out-of-box area then determine whether we need to fix. + * */ + if (repeat_type != RepeatNone) + repeat_type += RepeatFix; + else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + if (picture->transform + || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))) + repeat_type += RepeatFix; + } + + if (repeat_type >= RepeatFix) { + glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv); dispatch->glUniform2fv(wh_location, 1, wh); } + dispatch->glUniform1i(repeat_location, repeat_type); glamor_put_dispatch(glamor_priv); } @@ -694,6 +725,7 @@ glamor_composite_with_copy(CARD8 op, if (region.extents.y2 + y_source - y_dest > source->pDrawable->height) goto cleanup_region; } + ret = glamor_copy_n_to_n_nf(source->pDrawable, dest->pDrawable, NULL, REGION_RECTS(®ion), diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index c46849090..f39e3a532 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -18,6 +18,17 @@ *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \ } while(0) +#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv) \ + (priv->fbo->width != priv->container->drawable.width \ + || priv->fbo->height != priv->container->drawable.height) + +#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) do { \ + wh[0] = (float)priv->fbo->width \ + / priv->container->drawable.width; \ + wh[1] = (float)priv->fbo->height \ + / priv->container->drawable.height; \ + } while(0) + #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \ + ((float)xFixedFrac(_val_) / 65536.0))