Commit 67da52ec authored by Zhigang Gong's avatar Zhigang Gong Committed by Zhigang Gong

glamor: Add color conversion support by using new shader.

There are two places we need to do color conversion.

1. When upload a image data to a texture.
2. When download a texture to a memory buffer.

As the color format may not be supported in GLES2. We may
need to do the following two operations to convert dat.

a. revert argb to bgra / abgr to rgba.
b. swap argb to abgr / bgra to rgba.
Signed-off-by: Zhigang Gong's avatarZhigang Gong <zhigang.gong@gmail.com>
parent 0eea084d
......@@ -133,7 +133,6 @@ Bool
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
return glamor_download_pixmap_to_cpu(pixmap, access);
}
......@@ -154,17 +153,47 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
const char *fs_source =
"varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n"
"uniform int no_revert;"
"uniform int swap_rb;"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(sampler, source_texture);\n"
" if (no_revert == 1) \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
" else \n"
" gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = texture2D(sampler, source_texture).argb;\n"
" else \n"
" gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
" } \n"
"}\n";
const char *set_alpha_source =
"varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n"
"uniform int no_revert;"
"uniform int swap_rb;"
"void main()\n"
"{\n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
" if (no_revert == 1) \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
" else \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
" else \n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
" } \n"
"}\n";
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
GLint sampler_uniform_location;
......@@ -190,17 +219,31 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0");
glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
glamor_priv->finish_access_no_revert[0] =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
glamor_priv->finish_access_swap_rb[0] =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
sampler_uniform_location =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
glUseProgram(glamor_priv->finish_access_prog[0]);
glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_no_revert[0],1);
glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
glUseProgram(0);
glamor_priv->finish_access_no_revert[1] =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
glamor_priv->finish_access_swap_rb[1] =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
sampler_uniform_location =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
glUseProgram(glamor_priv->finish_access_prog[1]);
glUniform1i(glamor_priv->finish_access_no_revert[1],1);
glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
glUseProgram(0);
}
void
......@@ -224,8 +267,9 @@ glamor_finish_access(DrawablePtr drawable)
pixmap_priv->pbo_valid = FALSE;
glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0;
} else
} else {
free(pixmap->devPrivate.ptr);
}
pixmap->devPrivate.ptr = NULL;
}
......
......@@ -143,7 +143,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
GLfloat color[4];
float vertices[8];
GLfloat xscale, yscale;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("dest %p has no fbo.\n", pixmap);
goto fail;
......
This diff is collapsed.
......@@ -43,6 +43,7 @@
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
......@@ -236,6 +237,8 @@ typedef struct glamor_screen_private {
/* glamor_finishaccess */
GLint finish_access_prog[2];
GLint finish_access_no_revert[2];
GLint finish_access_swap_rb[2];
/* glamor_solid */
GLint solid_prog;
......@@ -408,13 +411,16 @@ format_for_pixmap(PixmapPtr pixmap)
*
* Return 0 if find a matched texture type. Otherwise return -1.
**/
#ifndef GLAMOR_GLES2
static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum *tex_format,
GLenum *tex_type,
int *no_alpha)
int *no_alpha,
int *no_revert)
{
*no_alpha = 0;
*no_revert = 1;
switch (format) {
case PICT_a1:
*tex_format = GL_COLOR_INDEX;
......@@ -497,13 +503,125 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
}
return 0;
}
#else
#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst)
static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum *tex_format,
GLenum *tex_type,
int *no_alpha,
int *no_revert)
{
*no_alpha = 0;
*no_revert = IS_LITTLE_ENDIAN;
switch (format) {
case PICT_b8g8r8x8:
*no_alpha = 1;
case PICT_b8g8r8a8:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_BYTE;
*no_revert = !IS_LITTLE_ENDIAN;
break;
case PICT_x8r8g8b8:
*no_alpha = 1;
case PICT_a8r8g8b8:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_BYTE;
break;
case PICT_x8b8g8r8:
*no_alpha = 1;
case PICT_a8b8g8r8:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE;
break;
case PICT_x2r10g10b10:
*no_alpha = 1;
case PICT_a2r10g10b10:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE;
break;
case PICT_x2b10g10r10:
*no_alpha = 1;
case PICT_a2b10g10r10:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE;
break;
case PICT_r5g6b5:
*tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = TRUE;
break;
case PICT_b5g6r5:
*tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = FALSE;
break;
case PICT_x1b5g5r5:
*no_alpha = 1;
case PICT_a1b5g5r5:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE;
break;
case PICT_x1r5g5b5:
*no_alpha = 1;
case PICT_a1r5g5b5:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE;
break;
case PICT_a8:
*tex_format = GL_ALPHA;
*tex_type = GL_UNSIGNED_BYTE;
*no_revert = TRUE;
break;
case PICT_x4r4g4b4:
*no_alpha = 1;
case PICT_a4r4g4b4:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
*no_revert = TRUE;
break;
case PICT_x4b4g4r4:
*no_alpha = 1;
case PICT_a4b4g4r4:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
*no_revert = TRUE;
break;
default:
LogMessageVerb(X_INFO, 0, "fail to get matched format for %x \n", format);
return -1;
}
return 0;
}
#endif
static inline int
glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
GLenum *format,
GLenum *type,
int *ax)
int *no_alpha,
int *no_revert)
{
glamor_pixmap_private *pixmap_priv;
PictFormatShort pict_format;
......@@ -515,7 +633,8 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
pict_format = format_for_depth(pixmap->drawable.depth);
return glamor_get_tex_format_type_from_pictformat(pict_format,
format, type, ax);
format, type,
no_alpha, no_revert);
}
......@@ -658,6 +777,11 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
* */
void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
PixmapPtr
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
GLenum *type, int no_alpha, int no_revert);
void glamor_set_alu(unsigned char alu);
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
void glamor_get_transform_uniform_locations(GLint prog,
......@@ -870,7 +994,7 @@ glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_pr
#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
#define GLAMOR_DELAYED_FILLING
//#define GLAMOR_DELAYED_FILLING
#include"glamor_utils.h"
......
......@@ -265,7 +265,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
float vertices[8], texcoords[8];
GLfloat xscale, yscale, txscale, tyscale;
GLuint tex;
int no_alpha;
int no_alpha, no_revert;
if (image_format == XYBitmap) {
assert(depth == 1);
goto fail;
......@@ -290,7 +290,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type,
&no_alpha
&no_alpha,
&no_revert
)) {
glamor_fallback("unknown depth. %d \n",
drawable->depth);
......@@ -300,14 +301,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
/* XXX consider to reuse a function to do the following work. */
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
#if 0
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float),
vertices);
......@@ -317,7 +310,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
2 * sizeof(float),
texcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
#endif
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
......@@ -333,20 +325,25 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
type = GL_UNSIGNED_BYTE;
iformat = format;
}
else {
iformat = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, iformat,
w, h, 0,
format, type, bits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D);
#endif
glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
x += drawable->x;
y += drawable->y;
......@@ -394,7 +391,9 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
#ifndef GLAMOR_GLES2
glDisable(GL_TEXTURE_2D);
#endif
glUseProgram(0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
......@@ -409,9 +408,9 @@ fail:
glamor_set_planemask(pixmap, ~0);
glamor_fallback("to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format,
if (glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RW)) {
fbPutImage(&pixmap->drawable, gc, depth, x, y, w, h, left_pad, image_format,
bits);
glamor_finish_access(drawable);
glamor_finish_access(&pixmap->drawable);
}
}
......@@ -38,7 +38,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
glamor_screen_private *glamor_priv;
GLenum format, type;
int no_alpha, i;
int no_alpha, no_revert, i;
uint8_t *drawpixels_src = (uint8_t *)src;
RegionPtr clip = fbGetCompositeClip(gc);
BoxRec *pbox;
......@@ -46,18 +46,23 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
glamor_priv = glamor_get_screen_private(drawable->pScreen);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
glamor_fallback("ES2 fallback.\n");
goto fail;
}
if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
&format,
&type,
&no_alpha
&no_alpha,
&no_revert
)) {
glamor_fallback("unknown depth. %d \n",
drawable->depth);
goto fail;
}
if (glamor_set_destination_pixmap(dest_pixmap))
goto fail;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment