From 9f53cc1c3369fc61630b238f1b347a92fabf5a5a Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Wed, 25 Apr 2012 22:35:12 +0800 Subject: [PATCH] glamor_render.c: Fixed repeatPad and repeatRelect. We should use difference calculation for these two repeat mode when we are a sub region within one texture. Signed-off-by: Zhigang Gong --- glamor/glamor_priv.h | 4 +- glamor/glamor_render.c | 119 +++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 35 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 36bd9cda4..169436cc9 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -80,6 +80,8 @@ typedef struct glamor_composite_shader { GLint mask_uniform_location; GLint source_wh; GLint mask_wh; + GLint source_repeat_mode; + GLint mask_repeat_mode; } glamor_composite_shader; typedef struct { @@ -742,7 +744,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, #define GLAMOR_PIXMAP_DYNAMIC_UPLOAD #define GLAMOR_DELAYED_FILLING #ifndef GLAMOR_GLES2 -#define GLAMOR_GRADIENT_SHADER +//#define GLAMOR_GRADIENT_SHADER #endif #endif /* GLAMOR_PRIV_H */ diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index fa6ef666b..d4ee78a69 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -70,13 +70,38 @@ static GLuint glamor_create_composite_fs(glamor_gl_dispatch * dispatch, struct shader_key *key) { + const char *repeat_define = + "#define RepeatNone 0\n" + "#define RepeatNormal 1\n" + "#define RepeatPad 2\n" + "#define RepeatReflect 3\n" + "uniform int source_repeat_mode;\n" + "uniform int mask_repeat_mode;\n"; const char *relocate_texture = GLAMOR_DEFAULT_PRECISION - "vec2 rel_tex_coord(vec2 texture, vec2 wh) \n" + "vec2 rel_tex_coord(vec2 texture, vec2 wh, int repeat) \n" "{\n" " vec2 rel_tex; \n" " rel_tex = texture * wh; \n" - " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n" + " 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" + " else if(rel_tex.x < 0.0) rel_tex.x = 0.0; \n" + " if (rel_tex.y > 1.0) rel_tex.y = 1.0; \n" + " else if(rel_tex.y < 0.0) rel_tex.y = 0.0; \n" + " rel_tex = rel_tex / wh; \n" + " } \n" + " else if(repeat == RepeatReflect) {\n" + " if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n" + " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n" + " else \n" + " rel_tex.x = fract(rel_tex.x)/wh.x;\n" + " if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n" + " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n" + " else \n" + " rel_tex.y = fract(rel_tex.y)/wh.y;\n" + " } \n" " return rel_tex; \n" "}\n"; const char *source_solid_fetch = @@ -90,21 +115,25 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, "uniform vec2 source_wh;" "vec4 get_source()\n" "{\n" - " if (source_wh.x < 0.0) \n" + " if (source_repeat_mode == RepeatNone) \n" " return texture2D(source_sampler, source_texture);\n" " else \n" - " return texture2D(source_sampler, rel_tex_coord(source_texture, source_wh));\n" + " return texture2D(source_sampler,\n" + " rel_tex_coord(source_texture,\n" + " source_wh, source_repeat_mode));\n" "}\n"; const char *source_pixmap_fetch = GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n" "uniform sampler2D source_sampler;\n" - "uniform vec2 source_wh;" + "uniform vec2 source_wh;\n" "vec4 get_source()\n" "{\n" - " if (source_wh.x < 0.0) \n" + " if (source_repeat_mode == RepeatNone) \n" " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n" " else \n" - " return vec4(texture2D(source_sampler, rel_tex_coord(source_texture, source_wh)).rgb, 1);\n" + " return vec4(texture2D(source_sampler, \n" + " rel_tex_coord(source_texture,\n" + " source_wh, source_repeat_mode)).rgb, 1);\n" "}\n"; const char *mask_solid_fetch = GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n" @@ -112,24 +141,28 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, const char *mask_alpha_pixmap_fetch = GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" - "uniform vec2 mask_wh;" + "uniform vec2 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_wh.x < 0.0) \n" + " if (mask_repeat_mode == RepeatNone) \n" " return texture2D(mask_sampler, mask_texture);\n" " else \n" - " return texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh));\n" + " return texture2D(mask_sampler, \n" + " rel_tex_coord(mask_texture, \n" + " mask_wh, mask_repeat_mode));\n" "}\n"; const char *mask_pixmap_fetch = GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n" "uniform sampler2D mask_sampler;\n" - "uniform vec2 mask_wh;" + "uniform vec2 mask_wh;\n" "vec4 get_mask()\n" "{\n" - " if (mask_wh.x < 0.0) \n" + " if (mask_repeat_mode == RepeatNone) \n" " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n" " else \n" - " return vec4(texture2D(mask_sampler, rel_tex_coord(mask_texture, mask_wh)).rgb, 1);\n" + " return vec4(texture2D(mask_sampler, \n" + " rel_tex_coord(mask_texture, \n" + " mask_wh, mask_repeat_mode)).rgb, 1);\n" "}\n"; const char *in_source_only = GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" @@ -196,7 +229,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch, FatalError("Bad composite IN type"); } - XNFasprintf(&source, "%s%s%s%s", relocate_texture, source_fetch, mask_fetch, in); + XNFasprintf(&source, "%s%s%s%s%s", repeat_define, relocate_texture, source_fetch, mask_fetch, in); prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, @@ -288,6 +321,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, dispatch->glGetUniformLocation(prog, "source_sampler"); dispatch->glUniform1i(source_sampler_uniform_location, 0); shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh"); + shader->source_repeat_mode = dispatch->glGetUniformLocation(prog, "source_repeat_mode"); } if (key->mask != SHADER_MASK_NONE) { @@ -301,6 +335,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, dispatch->glUniform1i (mask_sampler_uniform_location, 1); shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh"); + shader->mask_repeat_mode = dispatch->glGetUniformLocation(prog, "mask_repeat_mode"); } } @@ -482,7 +517,7 @@ static void glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glamor_pixmap_private * pixmap_priv, - GLuint wh_location) + GLuint wh_location, GLuint repeat_location) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -546,17 +581,18 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, #ifndef GLAMOR_GLES2 dispatch->glEnable(GL_TEXTURE_2D); #endif - if (picture->repeatType == RepeatNone) + if (picture->repeatType == RepeatNone) { has_repeat = picture->transform && !pixman_transform_is_int_translate(picture->transform); - else - has_repeat = TRUE; - if (has_repeat) { - wh[0] = (float)pixmap_priv->fbo->width / pixmap_priv->container->drawable.width; - wh[1] = (float)pixmap_priv->fbo->height / pixmap_priv->container->drawable.height; + if (has_repeat) + dispatch->glUniform1i(repeat_location, RepeatNormal); } - else - wh[0] = -1; + else { + has_repeat = TRUE; + dispatch->glUniform1i(repeat_location, picture->repeatType); + } + 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); glamor_put_dispatch(glamor_priv); } @@ -1111,7 +1147,8 @@ glamor_composite_with_shader(CARD8 op, shader->source_uniform_location); } else { glamor_set_composite_texture(screen, 0, source, - source_pixmap_priv, shader->source_wh); + source_pixmap_priv, shader->source_wh, + shader->source_repeat_mode); } if (key.mask != SHADER_MASK_NONE) { if (key.mask == SHADER_MASK_SOLID) { @@ -1120,7 +1157,8 @@ glamor_composite_with_shader(CARD8 op, shader->mask_uniform_location); } else { glamor_set_composite_texture(screen, 1, mask, - mask_pixmap_priv, shader->mask_wh); + mask_pixmap_priv, shader->mask_wh, + shader->mask_repeat_mode); } } @@ -2946,6 +2984,7 @@ _glamor_composite(CARD8 op, dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); /* Currently. Always fallback to cpu if destination is in CPU memory. */ + if (source->pDrawable) { source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); @@ -2967,6 +3006,10 @@ _glamor_composite(CARD8 op, if (op >= ARRAY_SIZE(composite_op_info)) goto fail; + /*XXXXX, maybe we can make a copy of dest pixmap.*/ + if (source_pixmap == dest_pixmap) + goto full_fallback; + if ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill)) || (source->pDrawable @@ -3050,6 +3093,7 @@ _glamor_composite(CARD8 op, height)) goto done; } + x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; if (temp_src->pDrawable) { @@ -3146,16 +3190,21 @@ fail: saved_ ##p ##_y = y_ ##p; \ if (p->pCompositeClip) \ pixman_region_translate (p->pCompositeClip, \ - p ##_x_off - x_ ##p, \ - p ##_y_off - y_ ##p); \ + -p->pDrawable->x - x_ ##p, \ + -p->pDrawable->y - y_ ##p); \ x_ ##p = 0; \ y_ ##p = 0; \ } } while(0) GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); + if (source->pDrawable) + GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO); + if (mask && mask->pDrawable) + GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); +full_fallback: if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_picture + if (source_pixmap == dest_pixmap || glamor_prepare_access_picture (source, GLAMOR_ACCESS_RO)) { if (!mask || glamor_prepare_access_picture(mask, @@ -3169,7 +3218,8 @@ fail: if (mask) glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO); } - glamor_finish_access_picture(source, GLAMOR_ACCESS_RO); + if (source_pixmap != dest_pixmap) + glamor_finish_access_picture(source, GLAMOR_ACCESS_RO); } glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW); } @@ -3180,15 +3230,18 @@ fail: y_ ##p = saved_ ##p ##_y; \ if (p->pCompositeClip) \ pixman_region_translate (p->pCompositeClip, \ - - p ## _x_off + x_ ##p, \ - - p ## _y_off + y_ ##p); \ + p->pDrawable->x + x_ ##p, \ + p->pDrawable->y + y_ ##p); \ p->pDrawable = saved_ ##p ##_drawable; \ glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap, \ x_ ##p + p ##_x_off + p->pDrawable->x, \ y_ ##p + p ##_y_off + p->pDrawable->y, \ width, height, access); \ }} while(0) - + if (mask && mask->pDrawable) + PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); + if (source->pDrawable) + PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO); PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); done: if (temp_src != source) @@ -3442,6 +3495,4 @@ glamor_composite_rects_nf (CARD8 op, return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE); } - - #endif /* RENDER */