glamor_tile/composite: Modify fs to re-calculate texture coords.
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@linux.intel.com>
This commit is contained in:
parent
556adfa6b9
commit
53387728dd
|
@ -66,6 +66,8 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
|
||||||
INIT_FUNC(dispatch, glUseProgram, get_proc_address);
|
INIT_FUNC(dispatch, glUseProgram, get_proc_address);
|
||||||
INIT_FUNC(dispatch, glUniform1i, get_proc_address);
|
INIT_FUNC(dispatch, glUniform1i, get_proc_address);
|
||||||
INIT_FUNC(dispatch, glUniform4f, 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, glUniform4fv, get_proc_address);
|
||||||
INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
|
INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
|
||||||
INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
|
INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
|
||||||
|
|
|
@ -94,6 +94,10 @@ typedef struct glamor_gl_dispatch {
|
||||||
void (*glUniform1i) (GLint location, GLint v0);
|
void (*glUniform1i) (GLint location, GLint v0);
|
||||||
void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
|
void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1,
|
||||||
GLfloat v2, GLfloat v3);
|
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,
|
void (*glUniform4fv) (GLint location, GLsizei count,
|
||||||
const GLfloat * value);
|
const GLfloat * value);
|
||||||
GLuint(*glCreateProgram) (void);
|
GLuint(*glCreateProgram) (void);
|
||||||
|
|
|
@ -64,6 +64,8 @@ typedef struct glamor_composite_shader {
|
||||||
GLint dest_to_mask_uniform_location;
|
GLint dest_to_mask_uniform_location;
|
||||||
GLint source_uniform_location;
|
GLint source_uniform_location;
|
||||||
GLint mask_uniform_location;
|
GLint mask_uniform_location;
|
||||||
|
GLint source_wh;
|
||||||
|
GLint mask_wh;
|
||||||
} glamor_composite_shader;
|
} glamor_composite_shader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -203,6 +205,7 @@ typedef struct glamor_screen_private {
|
||||||
|
|
||||||
/* glamor_tile */
|
/* glamor_tile */
|
||||||
GLint tile_prog;
|
GLint tile_prog;
|
||||||
|
GLint tile_wh;
|
||||||
|
|
||||||
/* glamor_putimage */
|
/* glamor_putimage */
|
||||||
GLint put_image_xybitmap_prog;
|
GLint put_image_xybitmap_prog;
|
||||||
|
|
|
@ -70,6 +70,15 @@ static GLuint
|
||||||
glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
|
glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
|
||||||
struct shader_key *key)
|
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 =
|
const char *source_solid_fetch =
|
||||||
GLAMOR_DEFAULT_PRECISION
|
GLAMOR_DEFAULT_PRECISION
|
||||||
"uniform vec4 source;\n"
|
"uniform vec4 source;\n"
|
||||||
|
@ -78,26 +87,35 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
|
||||||
GLAMOR_DEFAULT_PRECISION
|
GLAMOR_DEFAULT_PRECISION
|
||||||
"varying vec2 source_texture;\n"
|
"varying vec2 source_texture;\n"
|
||||||
"uniform sampler2D source_sampler;\n"
|
"uniform sampler2D source_sampler;\n"
|
||||||
|
"uniform vec2 source_wh;"
|
||||||
"vec4 get_source()\n"
|
"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";
|
"}\n";
|
||||||
const char *source_pixmap_fetch =
|
const char *source_pixmap_fetch =
|
||||||
GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture;\n"
|
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"
|
"{\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";
|
"}\n";
|
||||||
const char *mask_solid_fetch =
|
const char *mask_solid_fetch =
|
||||||
GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
|
GLAMOR_DEFAULT_PRECISION "uniform vec4 mask;\n"
|
||||||
"vec4 get_mask()\n" "{\n" " return mask;\n" "}\n";
|
"vec4 get_mask()\n" "{\n" " return mask;\n" "}\n";
|
||||||
const char *mask_alpha_pixmap_fetch =
|
const char *mask_alpha_pixmap_fetch =
|
||||||
GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
|
GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
|
||||||
"uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
|
"uniform sampler2D mask_sampler;\n"
|
||||||
" return texture2D(mask_sampler, mask_texture);\n" "}\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 =
|
const char *mask_pixmap_fetch =
|
||||||
GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
|
GLAMOR_DEFAULT_PRECISION "varying vec2 mask_texture;\n"
|
||||||
"uniform sampler2D mask_sampler;\n" "vec4 get_mask()\n" "{\n"
|
"uniform sampler2D mask_sampler;\n"
|
||||||
" return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\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";
|
"}\n";
|
||||||
const char *in_source_only =
|
const char *in_source_only =
|
||||||
GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
|
GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n"
|
||||||
|
@ -164,7 +182,7 @@ glamor_create_composite_fs(glamor_gl_dispatch * dispatch,
|
||||||
FatalError("Bad composite IN type");
|
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,
|
prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
|
||||||
|
@ -255,6 +273,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
|
||||||
source_sampler_uniform_location =
|
source_sampler_uniform_location =
|
||||||
dispatch->glGetUniformLocation(prog, "source_sampler");
|
dispatch->glGetUniformLocation(prog, "source_sampler");
|
||||||
dispatch->glUniform1i(source_sampler_uniform_location, 0);
|
dispatch->glUniform1i(source_sampler_uniform_location, 0);
|
||||||
|
shader->source_wh = dispatch->glGetUniformLocation(prog, "source_wh");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key->mask != SHADER_MASK_NONE) {
|
if (key->mask != SHADER_MASK_NONE) {
|
||||||
|
@ -267,6 +286,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
|
||||||
"mask_sampler");
|
"mask_sampler");
|
||||||
dispatch->glUniform1i
|
dispatch->glUniform1i
|
||||||
(mask_sampler_uniform_location, 1);
|
(mask_sampler_uniform_location, 1);
|
||||||
|
shader->mask_wh = dispatch->glGetUniformLocation(prog, "mask_wh");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,36 +469,11 @@ glamor_set_composite_op(ScreenPtr screen,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
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
|
static void
|
||||||
glamor_set_composite_texture(ScreenPtr screen, int unit,
|
glamor_set_composite_texture(ScreenPtr screen, int unit,
|
||||||
PicturePtr picture,
|
PicturePtr picture,
|
||||||
glamor_pixmap_private * pixmap_priv)
|
glamor_pixmap_private * pixmap_priv,
|
||||||
|
GLuint wh_location)
|
||||||
{
|
{
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
glamor_get_screen_private(screen);
|
glamor_get_screen_private(screen);
|
||||||
|
@ -487,6 +482,8 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
dispatch->glActiveTexture(GL_TEXTURE0 + unit);
|
dispatch->glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
|
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
|
||||||
|
float wh[2];
|
||||||
|
|
||||||
switch (picture->repeatType) {
|
switch (picture->repeatType) {
|
||||||
case RepeatNone:
|
case RepeatNone:
|
||||||
#ifndef GLAMOR_GLES2
|
#ifndef GLAMOR_GLES2
|
||||||
|
@ -539,6 +536,9 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
|
||||||
#ifndef GLAMOR_GLES2
|
#ifndef GLAMOR_GLES2
|
||||||
dispatch->glEnable(GL_TEXTURE_2D);
|
dispatch->glEnable(GL_TEXTURE_2D);
|
||||||
#endif
|
#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);
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,12 +1081,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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_set_destination_pixmap_priv_nc(dest_pixmap_priv);
|
||||||
glamor_validate_pixmap(dest_pixmap);
|
glamor_validate_pixmap(dest_pixmap);
|
||||||
|
|
||||||
|
@ -1109,7 +1103,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
shader->source_uniform_location);
|
shader->source_uniform_location);
|
||||||
} else {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 0, source,
|
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_NONE) {
|
||||||
if (key.mask == SHADER_MASK_SOLID) {
|
if (key.mask == SHADER_MASK_SOLID) {
|
||||||
|
@ -1118,7 +1112,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
shader->mask_uniform_location);
|
shader->mask_uniform_location);
|
||||||
} else {
|
} else {
|
||||||
glamor_set_composite_texture(screen, 1, mask,
|
glamor_set_composite_texture(screen, 1, mask,
|
||||||
mask_pixmap_priv);
|
mask_pixmap_priv, shader->mask_wh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,13 @@ glamor_init_tile_shader(ScreenPtr screen)
|
||||||
GLAMOR_DEFAULT_PRECISION
|
GLAMOR_DEFAULT_PRECISION
|
||||||
"varying vec2 tile_texture;\n"
|
"varying vec2 tile_texture;\n"
|
||||||
"uniform sampler2D sampler;\n"
|
"uniform sampler2D sampler;\n"
|
||||||
|
"uniform vec2 wh;"
|
||||||
"void main()\n"
|
"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";
|
"}\n";
|
||||||
GLint fs_prog, vs_prog;
|
GLint fs_prog, vs_prog;
|
||||||
GLint sampler_uniform_location;
|
GLint sampler_uniform_location;
|
||||||
|
@ -76,6 +81,10 @@ glamor_init_tile_shader(ScreenPtr screen)
|
||||||
"sampler");
|
"sampler");
|
||||||
dispatch->glUseProgram(glamor_priv->tile_prog);
|
dispatch->glUseProgram(glamor_priv->tile_prog);
|
||||||
dispatch->glUniform1i(sampler_uniform_location, 0);
|
dispatch->glUniform1i(sampler_uniform_location, 0);
|
||||||
|
|
||||||
|
glamor_priv->tile_wh =
|
||||||
|
dispatch->glGetUniformLocation(glamor_priv->tile_prog,
|
||||||
|
"wh");
|
||||||
dispatch->glUseProgram(0);
|
dispatch->glUseProgram(0);
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +124,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
glamor_pixmap_private *src_pixmap_priv;
|
||||||
glamor_pixmap_private *dst_pixmap_priv;
|
glamor_pixmap_private *dst_pixmap_priv;
|
||||||
|
float wh[2];
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
@ -142,14 +152,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
goto fail;
|
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) {
|
if (alu != GXcopy) {
|
||||||
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
|
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
|
||||||
glamor_validate_pixmap(tile);
|
glamor_validate_pixmap(tile);
|
||||||
|
@ -167,6 +169,10 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
&src_yscale);
|
&src_yscale);
|
||||||
dispatch->glUseProgram(glamor_priv->tile_prog);
|
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->glActiveTexture(GL_TEXTURE0);
|
||||||
dispatch->glBindTexture(GL_TEXTURE_2D,
|
dispatch->glBindTexture(GL_TEXTURE_2D,
|
||||||
src_pixmap_priv->fbo->tex);
|
src_pixmap_priv->fbo->tex);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user