gles2: Fixed color conversion for the formats except 1555 and 2101010.

This patch fixed two major problems when we do the color convesion with
GLES2.

1. lack of necessary formats in FBO pool.
GLES2 has three different possible texture formats, GL_RGBA,
GL_BGRA and GL_ALPHA. Previous implementation only has one bucket
for all the three formats which may reuse a incorrect texture format
when do the cache lookup. After this fix, we can enable fbo safely
when running with GLES2.

2. Refine the format matching method in
glamor_get_tex_format_type_from_pictformat.
If both revertion and swap_rb are needed, for example use GL_RGBA
to represent PICT_b8g8r8a8. Then the downloading and uploading should
be handled differently.

    The picture's format is PICT_b8g8r8a8,
    Then the expecting color layout is as below (little endian):
    0   1       2       3   : address
    a   r       g       b

    Now the in GLES2 the supported color format is GL_RGBA, type is
    GL_UNSIGNED_TYPE, then we need to shuffle the fragment
    color as :
        frag_color = sample(texture).argb;
    before we use glReadPixel to get it back.

    For the uploading process, the shuffle is a revert shuffle.
    We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
    to a texture, then let's see
    0   1       2       3   : address
    a   r       g       b   : correct colors
    R   G       B       A   : GL_RGBA with GL_UNSIGNED_BYTE

    Now we need to shuffle again, the mapping rule is
    r = G, g = B, b = A, a = R. Then the uploading shuffle is as
    below:
        frag_color = sample(texture).gbar;

After this commit, gles2 version can pass render check with all
the formats except those 1555/2101010.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-04-05 21:53:44 +08:00 committed by Eric Anholt
parent 55fdc7b196
commit 3add375065
11 changed files with 365 additions and 223 deletions

View File

@ -84,6 +84,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv;
glamor_pixmap_fbo *fbo;
GLenum format;
glamor_priv = glamor_get_screen_private(screen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
@ -93,9 +94,10 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
glamor_destroy_fbo(fbo);
}
gl_iformat_for_depth(pixmap->drawable.depth, &format);
fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.depth, tex, 0);
format, tex, 0);
if (fbo == NULL) {
ErrorF("XXX fail to create fbo.\n");
@ -133,11 +135,14 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
glamor_pixmap_fbo *fbo;
int pitch;
int flag;
GLenum format;
if (w > 32767 || h > 32767)
return NullPixmap;
if (usage == GLAMOR_CREATE_PIXMAP_CPU || (w == 0 && h == 0))
if (usage == GLAMOR_CREATE_PIXMAP_CPU
|| (w == 0 && h == 0)
|| !glamor_check_pixmap_fbo_depth(depth))
return fbCreatePixmap(screen, w, h, depth, usage);
else
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
@ -154,7 +159,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pixmap_priv->glamor_priv = glamor_priv;
pixmap_priv->type = type;
fbo = glamor_create_fbo(glamor_priv, w, h, depth, usage);
gl_iformat_for_depth(depth, &format);
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
if (fbo == NULL) {
fbDestroyPixmap(pixmap);

View File

@ -239,12 +239,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
texcoords);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
dispatch->
glUniform1i(glamor_priv->finish_access_no_revert[0],
1);
dispatch->
glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
dispatch->glUniform1i(glamor_priv->finish_access_revert[0],
REVERT_NONE);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],
SWAP_NONE_UPLOADING);
} else {
GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv,
src_pixmap_priv);

View File

@ -107,6 +107,35 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
return glamor_download_pixmap_to_cpu(pixmap, access);
}
/*
* When downloading a unsupported color format to CPU memory,
we need to shuffle the color elements and then use a supported
color format to read it back to CPU memory.
For an example, the picture's format is PICT_b8g8r8a8,
Then the expecting color layout is as below (little endian):
0 1 2 3 : address
a r g b
Now the in GLES2 the supported color format is GL_RGBA, type is
GL_UNSIGNED_TYPE, then we need to shuffle the fragment
color as :
frag_color = sample(texture).argb;
before we use glReadPixel to get it back.
For the uploading process, the shuffle is a revert shuffle.
We still use GL_RGBA, GL_UNSIGNED_BYTE to upload the color
to a texture, then let's see
0 1 2 3 : address
a r g b : correct colors
R G B A : GL_RGBA with GL_UNSIGNED_BYTE
Now we need to shuffle again, the mapping rule is
r = G, g = B, b = A, a = R. Then the uploading shuffle is as
below:
frag_color = sample(texture).gbar;
*/
void
glamor_init_finish_access_shaders(ScreenPtr screen)
{
@ -121,53 +150,67 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
" gl_Position = v_position;\n"
" source_texture = v_texcoord0.xy;\n" "}\n";
const char *fs_source =
const char *common_source =
GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n"
"uniform int no_revert;\n"
"uniform int revert;\n"
"uniform int swap_rb;\n"
"#define REVERT_NONE 0\n"
"#define REVERT_NORMAL 1\n"
"#define SWAP_NONE_DOWNLOADING 0\n"
"#define SWAP_DOWNLOADING 1\n"
"#define SWAP_UPLOADING 2\n"
"#define SWAP_NONE_UPLOADING 3\n";
const char *fs_source =
"void main()\n"
"{\n"
" if (no_revert == 1) \n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
" gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
" else \n"
" gl_FragColor = texture2D(sampler, source_texture).rgba;\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"
" if (swap_rb == SWAP_DOWNLOADING) \n"
" gl_FragColor = texture2D(sampler, source_texture).argb;\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
" gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
" gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
" gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
" } \n" "}\n";
const char *set_alpha_source =
GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n"
"uniform sampler2D sampler;\n"
"uniform int no_revert;\n"
"uniform int swap_rb;\n"
"void main()\n"
"{\n"
" if (no_revert == 1) \n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if (swap_rb == 1) \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
" else \n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\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";
" if (swap_rb == SWAP_DOWNLOADING) \n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
" gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
" gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
" } \n"
"}\n";
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
GLint sampler_uniform_location;
char *source;
glamor_priv = glamor_get_screen_private(screen);
dispatch = glamor_get_dispatch(glamor_priv);
@ -176,8 +219,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
vs_source);
XNFasprintf(&source, "%s%s", common_source, fs_source);
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
fs_source);
source);
free(source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
vs_prog);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
@ -185,8 +232,12 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
vs_source);
XNFasprintf(&source, "%s%s", common_source, set_alpha_source);
set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
set_alpha_source);
source);
free(source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
avs_prog);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
@ -208,10 +259,10 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glamor_link_glsl_prog(dispatch,
glamor_priv->finish_access_prog[1]);
glamor_priv->finish_access_no_revert[0] =
glamor_priv->finish_access_revert[0] =
dispatch->
glGetUniformLocation(glamor_priv->finish_access_prog[0],
"no_revert");
"revert");
glamor_priv->finish_access_swap_rb[0] =
dispatch->
@ -223,14 +274,14 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
"sampler");
dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
dispatch->glUniform1i(sampler_uniform_location, 0);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
dispatch->glUniform1i(glamor_priv->finish_access_revert[0], 0);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
dispatch->glUseProgram(0);
glamor_priv->finish_access_no_revert[1] =
glamor_priv->finish_access_revert[1] =
dispatch->
glGetUniformLocation(glamor_priv->finish_access_prog[1],
"no_revert");
"revert");
glamor_priv->finish_access_swap_rb[1] =
dispatch->
glGetUniformLocation(glamor_priv->finish_access_prog[1],
@ -240,7 +291,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glGetUniformLocation(glamor_priv->finish_access_prog[1],
"sampler");
dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1], 1);
dispatch->glUniform1i(glamor_priv->finish_access_revert[1], 0);
dispatch->glUniform1i(sampler_uniform_location, 0);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
dispatch->glUseProgram(0);

View File

@ -62,18 +62,6 @@ inline static int cache_hbucket(int size)
order = CACHE_BUCKET_HCOUNT - 1;
return order;
}
inline static int cache_format(GLenum format)
{
switch (format) {
#if 0
case GL_ALPHA:
return 1;
#endif
case GL_RGBA:
default:
return 0;
}
}
glamor_pixmap_fbo *
glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
@ -82,23 +70,27 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
struct xorg_list *cache;
glamor_pixmap_fbo *fbo_entry;
int size;
int n_format;
#ifdef NO_FBO_CACHE
return NULL;
#else
n_format = cache_format(format);
if (n_format == -1)
return NULL;
if (!(flag & GLAMOR_CACHE_TEXTURE))
cache = &glamor_priv->fbo_cache[cache_format(format)]
cache = &glamor_priv->fbo_cache[n_format]
[cache_wbucket(w)]
[cache_hbucket(h)];
else
cache = &glamor_priv->tex_cache[cache_format(format)]
cache = &glamor_priv->tex_cache[n_format]
[cache_wbucket(w)]
[cache_hbucket(h)];
if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
xorg_list_for_each_entry(fbo_entry, cache, list) {
if (fbo_entry->width >= w && fbo_entry->height >= h) {
DEBUGF("Request w %d h %d \n", w, h);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
DEBUGF("Request w %d h %d format %x \n", w, h, format);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
fbo_entry, fbo_entry->width, fbo_entry->height,
fbo_entry->fb, fbo_entry->tex);
xorg_list_del(&fbo_entry->list);
@ -110,10 +102,11 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
xorg_list_for_each_entry(fbo_entry, cache, list) {
if (fbo_entry->width == w && fbo_entry->height == h) {
DEBUGF("Request w %d h %d \n", w, h);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
DEBUGF("Request w %d h %d format %x \n", w, h, format);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
fbo_entry, fbo_entry->width, fbo_entry->height,
fbo_entry->fb, fbo_entry->tex);
fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
assert(format == fbo_entry->format);
xorg_list_del(&fbo_entry->list);
return fbo_entry;
}
@ -144,21 +137,25 @@ static void
glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
{
struct xorg_list *cache;
int n_format;
#ifdef NO_FBO_CACHE
glamor_purge_fbo(fbo);
return;
#else
if (fbo->fb == 0) {
n_format = cache_format(fbo->format);
if (fbo->fb == 0 || n_format == -1) {
glamor_purge_fbo(fbo);
return;
}
if (fbo->fb)
cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
cache = &fbo->glamor_priv->fbo_cache[n_format]
[cache_wbucket(fbo->width)]
[cache_hbucket(fbo->height)];
else
cache = &fbo->glamor_priv->tex_cache[cache_format(fbo->format)]
cache = &fbo->glamor_priv->tex_cache[n_format]
[cache_wbucket(fbo->width)]
[cache_hbucket(fbo->height)];
DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
@ -170,17 +167,15 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
glamor_pixmap_fbo *
glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
int w, int h, int depth, GLint tex, int flag)
int w, int h, GLenum format, GLint tex, int flag)
{
glamor_pixmap_fbo *fbo;
GLenum format;
fbo = calloc(1, sizeof(*fbo));
if (fbo == NULL)
return NULL;
xorg_list_init(&fbo->list);
gl_iformat_for_depth(depth, &format);
fbo->tex = tex;
fbo->width = w;
@ -338,19 +333,18 @@ glamor_destroy_tex_obj(glamor_pixmap_fbo * tex_obj)
glamor_pixmap_fbo *
glamor_create_fbo(glamor_screen_private *glamor_priv,
int w, int h, int depth, int flag)
int w, int h,
GLenum format,
int flag)
{
glamor_gl_dispatch *dispatch;
glamor_pixmap_fbo *fbo;
GLenum format;
GLint tex;
int cache_flag;
if (!glamor_check_fbo_size(glamor_priv, w, h)
|| !glamor_check_fbo_depth(depth))
if (!glamor_check_fbo_size(glamor_priv, w, h))
return NULL;
gl_iformat_for_depth(depth, &format);
if (flag == GLAMOR_CREATE_FBO_NO_FBO)
goto new_fbo;
@ -374,7 +368,7 @@ new_fbo:
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
GL_UNSIGNED_BYTE, NULL);
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
glamor_put_dispatch(glamor_priv);
return fbo;

View File

@ -39,10 +39,11 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
struct glamor_screen_private *glamor_priv;
int x_off, y_off;
GLenum tex_format, tex_type;
int no_alpha, no_revert;
PixmapPtr temp_pixmap = NULL;
int no_alpha, revert;
glamor_pixmap_fbo *temp_fbo = NULL;
glamor_gl_dispatch * dispatch;
Bool ret = FALSE;
int swap_rb;
goto fall_back;
@ -69,7 +70,9 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
&tex_format,
&tex_type,
&no_alpha,
&no_revert)) {
&revert,
&swap_rb,
0)) {
glamor_fallback("unknown depth. %d \n", drawable->depth);
goto fall_back;
}
@ -78,14 +81,16 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
&& (glamor_tex_format_is_readable(format) || !no_revert)) {
&& ( swap_rb != SWAP_NONE_DOWNLOADING
|| revert != REVERT_NONE)) {
/* XXX prepare whole pixmap is not efficient. */
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
&tex_type, no_alpha,
no_revert);
pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
temp_fbo =
glamor_es2_pixmap_read_prepare(pixmap, tex_format,
tex_type, no_alpha,
revert, swap_rb);
if (temp_fbo == NULL)
goto fall_back;
}
int row_length = PixmapBytePad(w, drawable->depth);
@ -113,8 +118,8 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
tex_format,
tex_type, d);
glamor_put_dispatch(glamor_priv);
if (temp_pixmap)
glamor_destroy_pixmap(temp_pixmap);
if (temp_fbo)
glamor_destroy_fbo(temp_fbo);
ret = TRUE;

View File

@ -35,17 +35,18 @@ _glamor_get_spans(DrawablePtr drawable,
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
GLenum format, type;
int no_alpha, no_revert;
int no_alpha, revert;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch;
PixmapPtr temp_pixmap = NULL;
glamor_pixmap_fbo *temp_fbo = NULL;
int i;
uint8_t *readpixels_dst = (uint8_t *) dst;
int x_off, y_off;
Bool ret = FALSE;
int swap_rb;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("pixmap has no fbo.\n");
@ -55,24 +56,29 @@ _glamor_get_spans(DrawablePtr drawable,
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
&revert, &swap_rb, 0)) {
glamor_fallback("unknown depth. %d \n", drawable->depth);
goto fail;
}
if (revert > REVERT_NORMAL)
goto fail;
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
&& (!glamor_tex_format_is_readable(format) || !no_revert)) {
&& ( swap_rb != SWAP_NONE_DOWNLOADING
|| revert != REVERT_NONE)) {
/* XXX prepare whole pixmap is not efficient. */
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &format,
&type, no_alpha,
no_revert);
pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
temp_fbo =
glamor_es2_pixmap_read_prepare(pixmap, format,
type, no_alpha,
revert, swap_rb);
if (temp_fbo == NULL)
goto fail;
}
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
@ -94,8 +100,8 @@ _glamor_get_spans(DrawablePtr drawable,
PixmapBytePad(widths[i], drawable->depth);
}
glamor_put_dispatch(glamor_priv);
if (temp_pixmap)
glamor_destroy_pixmap(temp_pixmap);
if (temp_fbo)
glamor_destroy_fbo(temp_fbo);
ret = TRUE;
goto done;
@ -105,6 +111,7 @@ fail:
&& glamor_ddx_fallback_check_pixmap(drawable))
goto done;
ret = TRUE;
glamor_fallback("from %p (%c)\n", drawable,
glamor_get_drawable_location(drawable));
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {

View File

@ -89,10 +89,10 @@ glamor_validate_pixmap(PixmapPtr pixmap)
}
void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo)
{
glamor_gl_dispatch *dispatch = glamor_get_dispatch(pixmap_priv->glamor_priv);
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fbo->fb);
glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
#ifndef GLAMOR_GLES2
dispatch->glMatrixMode(GL_PROJECTION);
dispatch->glLoadIdentity();
@ -100,10 +100,16 @@ glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
dispatch->glLoadIdentity();
#endif
dispatch->glViewport(0, 0,
pixmap_priv->fbo->width,
pixmap_priv->fbo->height);
fbo->width,
fbo->height);
glamor_put_dispatch(pixmap_priv->glamor_priv);
glamor_put_dispatch(fbo->glamor_priv);
}
void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
{
glamor_set_destination_pixmap_fbo(pixmap_priv->fbo);
}
int
@ -280,9 +286,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
* */
static void
_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
GLenum type, int no_alpha, int no_revert,
int flip)
_glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
int no_alpha, int revert, int swap_rb)
{
glamor_pixmap_private *pixmap_priv =
@ -308,7 +313,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
if (!pixmap_priv)
return;
need_flip = (flip && !glamor_priv->yInverted);
need_flip = !glamor_priv->yInverted;
glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD,
"Uploading pixmap %p %dx%d depth%d.\n",
@ -319,7 +324,11 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
/* Try fast path firstly, upload the pixmap to the texture attached
* to the fbo directly. */
if (no_alpha == 0 && no_revert == 1 && !need_flip) {
if (no_alpha == 0
&& revert == REVERT_NONE
&& swap_rb == SWAP_NONE_UPLOADING
&& !need_flip) {
__glamor_upload_pixmap_to_texture(pixmap, format, type,
pixmap_priv->fbo->tex, 1);
return;
@ -365,10 +374,10 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
#endif
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->
finish_access_no_revert[no_alpha],
no_revert);
finish_access_revert[no_alpha],
revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
0);
swap_rb);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@ -441,18 +450,22 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
* 2. no_alpha != 0, we need to wire the alpha.
* */
static int
glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb)
{
int flag;
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv;
GLenum format;
glamor_pixmap_fbo *fbo;
GLenum iformat;
pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
if (!(no_alpha || !no_revert || !glamor_priv->yInverted)) {
if (!(no_alpha
|| (revert != REVERT_NONE)
|| (swap_rb != SWAP_NONE_UPLOADING)
|| !glamor_priv->yInverted)) {
/* We don't need a fbo, a simple texture uploading should work. */
if (pixmap_priv && pixmap_priv->fbo)
return 0;
@ -464,9 +477,15 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
flag = 0;
}
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
else
iformat = format;
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.depth,
iformat,
flag);
if (fbo == NULL) {
glamor_fallback
@ -485,20 +504,24 @@ enum glamor_pixmap_status
glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
{
GLenum format, type;
int no_alpha, no_revert;
int no_alpha, revert, swap_rb;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
&type,
&no_alpha,
&revert,
&swap_rb, 1)) {
glamor_fallback("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
return GLAMOR_UPLOAD_FAILED;
}
if (glamor_pixmap_upload_prepare(pixmap, no_alpha, no_revert))
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
return GLAMOR_UPLOAD_FAILED;
_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
no_revert, 1);
revert, swap_rb);
return GLAMOR_UPLOAD_DONE;
}
@ -523,21 +546,19 @@ void
glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
{
GLenum format, type;
int no_alpha, no_revert;
int no_alpha, revert, swap_rb;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
&revert, &swap_rb, 1)) {
ErrorF("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
assert(0);
}
in_restore = 1;
_glamor_upload_pixmap_to_texture(pixmap, format, type, no_alpha,
no_revert, 1);
in_restore = 0;
revert, swap_rb);
}
/*
@ -548,65 +569,56 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
* get a new temporary pixmap returned.
* */
PixmapPtr
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
GLenum * type, int no_alpha, int no_revert)
glamor_pixmap_fbo *
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
GLenum type, int no_alpha, int revert, int swap_rb)
{
glamor_pixmap_private *source_priv;
glamor_screen_private *glamor_priv;
ScreenPtr screen;
PixmapPtr temp_pixmap;
glamor_pixmap_private *temp_pixmap_priv;
glamor_pixmap_fbo *temp_fbo;
glamor_gl_dispatch *dispatch;
static float vertices[8] = { -1, -1,
1, -1,
1, 1,
-1, 1
};
static float texcoords[8] = { 0, 0,
1, 0,
1, 1,
0, 1
};
int swap_rb = 0;
float temp_xscale, temp_yscale, source_xscale, source_yscale;
static float vertices[8];
static float texcoords[8];
screen = source->drawable.pScreen;
glamor_priv = glamor_get_screen_private(screen);
source_priv = glamor_get_pixmap_private(source);
if (*format == GL_BGRA) {
*format = GL_RGBA;
swap_rb = 1;
}
temp_pixmap = glamor_create_pixmap (screen,
source->drawable.width,
source->drawable.height,
source->drawable.depth, 0);
temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
temp_fbo = glamor_create_fbo(glamor_priv,
source->drawable.width,
source->drawable.height,
format,
0);
if (temp_fbo == NULL)
return NULL;
dispatch = glamor_get_dispatch(glamor_priv);
dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->fbo->tex);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
temp_xscale = 1.0 / temp_fbo->width;
temp_yscale = 1.0 / temp_fbo->height;
dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format,
source->drawable.width,
source->drawable.height, 0, *format, *type,
NULL);
glamor_set_normalize_vcoords(temp_xscale,
temp_yscale,
0, 0,
source->drawable.width, source->drawable.height,
glamor_priv->yInverted,
vertices);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float),
vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
glamor_set_normalize_tcoords(source_xscale,
source_yscale,
0, 0,
source->drawable.width, source->drawable.height,
glamor_priv->yInverted,
texcoords);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float),
texcoords);
@ -621,12 +633,11 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
glamor_set_destination_pixmap_fbo(temp_fbo);
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->
finish_access_no_revert[no_alpha],
no_revert);
finish_access_revert[no_alpha],
revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
swap_rb);
@ -636,7 +647,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum * format,
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
glamor_put_dispatch(glamor_priv);
return temp_pixmap;
return temp_fbo;
}
@ -656,21 +667,23 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
glamor_get_pixmap_private(pixmap);
unsigned int stride, row_length, y;
GLenum format, type, gl_access, gl_usage;
int no_alpha, no_revert;
int no_alpha, revert, swap_rb;
uint8_t *data = NULL, *read;
PixmapPtr temp_pixmap = NULL;
ScreenPtr screen;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch;
glamor_pixmap_fbo *temp_fbo = NULL;
screen = pixmap->drawable.pScreen;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return TRUE;
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
&type,
&no_alpha,
&revert,
&swap_rb, 0)) {
ErrorF("Unknown pixmap depth %d.\n",
pixmap->drawable.depth);
assert(0); // Should never happen.
@ -692,11 +705,11 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
&& (!glamor_tex_format_is_readable(format) || !no_revert)) {
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &format,
&type, no_alpha,
no_revert);
&& (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, format,
type, no_alpha,
revert, swap_rb)))
return FALSE;
}
switch (access) {
case GLAMOR_ACCESS_RO:
@ -807,8 +820,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
pixmap->devPrivate.ptr = data;
if (temp_pixmap)
glamor_destroy_pixmap(temp_pixmap);
if (temp_fbo != NULL)
glamor_destroy_fbo(temp_fbo);
return TRUE;
}

View File

@ -182,7 +182,12 @@ struct glamor_saved_procs {
UnrealizeGlyphProcPtr unrealize_glyph;
};
#ifdef GLAMOR_GLES2
#define CACHE_FORMAT_COUNT 3
#else
#define CACHE_FORMAT_COUNT 1
#endif
#define CACHE_BUCKET_WCOUNT 4
#define CACHE_BUCKET_HCOUNT 4
@ -221,7 +226,7 @@ typedef struct glamor_screen_private {
/* shaders to restore a texture to another texture.*/
GLint finish_access_prog[2];
GLint finish_access_no_revert[2];
GLint finish_access_revert[2];
GLint finish_access_swap_rb[2];
/* glamor_tile */
@ -395,9 +400,9 @@ Bool glamor_destroy_pixmap(PixmapPtr pixmap);
glamor_pixmap_fbo* glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv);
void glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo);
glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
int w, int h, int depth, GLint tex, int flag);
int w, int h, GLenum format, GLint tex, int flag);
glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
int w, int h, int depth, int flag);
int w, int h, GLenum format, int flag);
void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
@ -451,6 +456,7 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
int glamor_set_destination_pixmap(PixmapPtr pixmap);
int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
pixmap_priv);
void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *);
/* nc means no check. caller must ensure this pixmap has valid fbo.
* usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
@ -458,10 +464,9 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *
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);
glamor_pixmap_fbo *
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum format,
GLenum type, int no_alpha, int revert, int swap_rb);
void glamor_set_alu(struct glamor_gl_dispatch *dispatch,
unsigned char alu);

View File

@ -264,8 +264,9 @@ _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, no_revert;
int no_alpha, revert;
Bool ret = FALSE;
int swap_rb;
if (image_format == XYBitmap) {
assert(depth == 1);
@ -289,7 +290,9 @@ _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_revert)) {
&revert,
&swap_rb,
1)) {
glamor_fallback("unknown depth. %d \n", drawable->depth);
goto fail;
}
@ -341,10 +344,10 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
#endif
dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
dispatch->glUniform1i(glamor_priv->
finish_access_no_revert[no_alpha],
no_revert);
finish_access_revert[no_alpha],
revert);
dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
0);
swap_rb);
x += drawable->x;
y += drawable->y;

View File

@ -38,12 +38,13 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch;
GLenum format, type;
int no_alpha, no_revert, i;
int no_alpha, revert, i;
uint8_t *drawpixels_src = (uint8_t *) src;
RegionPtr clip = fbGetCompositeClip(gc);
BoxRec *pbox;
int x_off, y_off;
Bool ret = FALSE;
int swap_rb;
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
@ -59,7 +60,9 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
if (glamor_get_tex_format_type_from_pixmap(dest_pixmap,
&format,
&type, &no_alpha,
&no_revert)) {
&revert,
&swap_rb,
1)) {
glamor_fallback("unknown depth. %d \n", drawable->depth);
goto fail;
}

View File

@ -194,14 +194,14 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
&& (_w_) < _glamor_->max_fbo_size \
&& (_h_) < _glamor_->max_fbo_size)
#define glamor_check_fbo_depth(_depth_) ( \
_depth_ == 8 \
|| _depth_ == 15 \
|| _depth_ == 16 \
|| _depth_ == 24 \
|| _depth_ == 30 \
|| _depth_ == 32)
/* For 1bpp pixmap, we don't store it as texture. */
#define glamor_check_pixmap_fbo_depth(_depth_) ( \
_depth_ == 8 \
|| _depth_ == 15 \
|| _depth_ == 16 \
|| _depth_ == 24 \
|| _depth_ == 30 \
|| _depth_ == 32)
#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
@ -286,6 +286,14 @@ format_for_pixmap(PixmapPtr pixmap)
return pict_format;
}
#define REVERT_NONE 0
#define REVERT_NORMAL 1
#define SWAP_NONE_DOWNLOADING 0
#define SWAP_DOWNLOADING 1
#define SWAP_UPLOADING 2
#define SWAP_NONE_UPLOADING 3
/*
* Map picture's format to the correct gl texture format and type.
* no_alpha is used to indicate whehter we need to wire alpha to 1.
@ -297,10 +305,15 @@ static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum * tex_format,
GLenum * tex_type,
int *no_alpha, int *no_revert)
int *no_alpha,
int *revert,
int *swap_rb,
int is_upload)
{
*no_alpha = 0;
*no_revert = 1;
*revert = REVERT_NONE;
*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
switch (format) {
case PICT_a1:
*tex_format = GL_COLOR_INDEX;
@ -385,6 +398,18 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
}
return 0;
}
/* Currently, we use RGBA to represent all formats. */
inline static int cache_format(GLenum format)
{
switch (format) {
case GL_RGBA:
return 0;
default:
return -1;
}
}
#else
#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst)
@ -392,25 +417,32 @@ static inline int
glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
GLenum * tex_format,
GLenum * tex_type,
int *no_alpha, int *no_revert)
int *no_alpha,
int *revert,
int *swap_rb,
int is_upload)
{
int need_swap_rb = 0;
*no_alpha = 0;
*no_revert = IS_LITTLE_ENDIAN;
*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
switch (format) {
case PICT_b8g8r8x8:
*no_alpha = 1;
case PICT_b8g8r8a8:
*tex_format = GL_BGRA;
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE;
*no_revert = !IS_LITTLE_ENDIAN;
need_swap_rb = 1;
*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
break;
case PICT_x8r8g8b8:
*no_alpha = 1;
case PICT_a8r8g8b8:
*tex_format = GL_BGRA;
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE;
need_swap_rb = 1;
break;
case PICT_x8b8g8r8:
@ -425,7 +457,7 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
case PICT_a2r10g10b10:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE;
*revert = REVERT_NONE;
break;
case PICT_x2b10g10r10:
@ -433,19 +465,20 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
case PICT_a2b10g10r10:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_10_10_10_2;
*no_revert = TRUE;
*revert = REVERT_NONE;
break;
case PICT_r5g6b5:
*tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = TRUE;
*revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
break;
case PICT_b5g6r5:
*tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
*no_revert = FALSE;
need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
break;
case PICT_x1b5g5r5:
@ -453,7 +486,7 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
case PICT_a1b5g5r5:
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE;
*revert = REVERT_NONE;
break;
case PICT_x1r5g5b5:
@ -461,29 +494,30 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
case PICT_a1r5g5b5:
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
*no_revert = TRUE;
*revert = REVERT_NONE;
break;
case PICT_a8:
*tex_format = GL_ALPHA;
*tex_type = GL_UNSIGNED_BYTE;
*no_revert = TRUE;
*revert = REVERT_NONE;
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;
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
need_swap_rb = 1;
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;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
*revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
break;
default:
@ -492,9 +526,27 @@ glamor_get_tex_format_type_from_pictformat(PictFormatShort format,
format);
return -1;
}
if (need_swap_rb)
*swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
else
*swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
return 0;
}
inline static int cache_format(GLenum format)
{
switch (format) {
case GL_ALPHA:
return 2;
case GL_RGB:
return 1;
case GL_RGBA:
return 0;
default:
return -1;
}
}
#endif
@ -503,7 +555,10 @@ static inline int
glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
GLenum * format,
GLenum * type,
int *no_alpha, int *no_revert)
int *no_alpha,
int *revert,
int *swap_rb,
int is_upload)
{
glamor_pixmap_private *pixmap_priv;
PictFormatShort pict_format;
@ -517,7 +572,9 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
return glamor_get_tex_format_type_from_pictformat(pict_format,
format, type,
no_alpha,
no_revert);
revert,
swap_rb,
is_upload);
}