diff --git a/glamor/glamor.c b/glamor/glamor.c index 532b9efae..8fc3b0534 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -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); diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 87b53a983..b4880378c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -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); diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 0376388ca..f9c1db22f 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -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); diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index d212bd4a2..b15450a6d 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -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; diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c index efbd1baca..b1093e8e9 100644 --- a/glamor/glamor_getimage.c +++ b/glamor/glamor_getimage.c @@ -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; diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index 91030a3d4..8341df42e 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -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)) { diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 7f4a90b81..0570a9aaa 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -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; } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 54bbdb1ab..828b08ea0 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -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); diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 75e5b4cdd..e38c45aba 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -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; diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index a9471698a..b6847a908 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -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; } diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 29b7b12b8..35e8d612e 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -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); }