From: Keith Packard <[email protected]> GL_RED is supported by core profiles while GL_ALPHA is not; use GL_RED for one channel objects (depth 1 to 8), and then swizzle them into the alpha channel when used as a mask.
[airlied: updated to master, add swizzle to composited glyphs and xv paths] Signed-off-by: Keith Packard <[email protected]> Signed-off-by: Dave Airlie <[email protected]> --- glamor/glamor.c | 4 ++++ glamor/glamor_composite_glyphs.c | 5 +++++ glamor/glamor_fbo.c | 2 ++ glamor/glamor_picture.c | 22 ++++++++++++++-------- glamor/glamor_priv.h | 2 ++ glamor/glamor_render.c | 9 +++++++++ glamor/glamor_transfer.c | 2 +- glamor/glamor_utils.h | 4 +++- glamor/glamor_xv.c | 12 ++++++++++++ 9 files changed, 52 insertions(+), 10 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 8828ad3..7fa3a46 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -596,6 +596,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->max_fbo_size = MAX_FBO_SIZE; #endif + glamor_priv->one_channel_format = GL_ALPHA; + if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle")) + glamor_priv->one_channel_format = GL_RED; + glamor_set_debug_level(&glamor_debug_level); glamor_priv->saved_procs.create_screen_resources = diff --git a/glamor/glamor_composite_glyphs.c b/glamor/glamor_composite_glyphs.c index fb31340..5f0fda5 100644 --- a/glamor/glamor_composite_glyphs.c +++ b/glamor/glamor_composite_glyphs.c @@ -247,6 +247,11 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex); + if (glamor_priv->one_channel_format == GL_RED && + atlas->atlas->drawable.depth <= 8) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + } for (;;) { if (!glamor_use_program_render(prog, op, src, dst)) break; diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index b1b584d..3b16f82 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -75,6 +75,8 @@ cache_format(GLenum format) { switch (format) { case GL_ALPHA: + case GL_LUMINANCE: + case GL_RED: return 2; case GL_RGB: return 1; diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index 352858f..b069ce5 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -41,19 +41,21 @@ * Return 0 if find a matched texture type. Otherwise return -1. **/ static int -glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, +glamor_get_tex_format_type_from_pictformat_gl(ScreenPtr pScreen, + PictFormatShort format, GLenum *tex_format, GLenum *tex_type, int *no_alpha, int *revert, int *swap_rb, int is_upload) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); *no_alpha = 0; *revert = REVERT_NONE; *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING; switch (format) { case PICT_a1: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; break; @@ -111,7 +113,7 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case PICT_a8: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; break; case PICT_x4r4g4b4: @@ -137,13 +139,15 @@ glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format, #define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst) static int -glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format, +glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen, + PictFormatShort format, GLenum *tex_format, GLenum *tex_type, int *no_alpha, int *revert, int *swap_rb, int is_upload) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); int need_swap_rb = 0; *no_alpha = 0; @@ -264,13 +268,13 @@ glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format, break; case PICT_a1: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1; break; case PICT_a8: - *tex_format = GL_ALPHA; + *tex_format = glamor_priv->one_channel_format; *tex_type = GL_UNSIGNED_BYTE; *revert = REVERT_NONE; break; @@ -317,14 +321,16 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap, glamor_get_screen_private(pixmap->drawable.pScreen); if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { - return glamor_get_tex_format_type_from_pictformat_gl(pict_format, + return glamor_get_tex_format_type_from_pictformat_gl(pixmap->drawable.pScreen, + pict_format, format, type, no_alpha, revert, swap_rb, is_upload); } else { - return glamor_get_tex_format_type_from_pictformat_gles2(pict_format, + return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen, + pict_format, format, type, no_alpha, revert, diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index d26593d..d58c40f 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -212,6 +212,8 @@ typedef struct glamor_screen_private { Bool has_vertex_array_object; int max_fbo_size; + GLuint one_channel_format; + struct xorg_list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; unsigned long fbo_cache_watermark; diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index da3af4f..34bf118 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -519,6 +519,15 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit, } /* + * For pixmaps using GL_RED format, swizzle the RED channel into + * alpha when using the pixmap as a mask + */ + if (unit == 1 && glamor_priv->one_channel_format == GL_RED && + pixmap->drawable.depth <= 8) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + } + /* * GLES2 doesn't support RepeatNone. We need to fix it anyway. * **/ diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c index 155d7e0..91e1747 100644 --- a/glamor/glamor_transfer.c +++ b/glamor/glamor_transfer.c @@ -42,7 +42,7 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type) *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case 8: - *format = GL_ALPHA; + *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format; *type = GL_UNSIGNED_BYTE; break; default: diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index e648af2..d4366c1 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -757,7 +757,7 @@ gl_iformat_for_pixmap(PixmapPtr pixmap) if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) { - return GL_ALPHA; + return glamor_priv->one_channel_format; } else { return GL_RGBA; } @@ -867,6 +867,8 @@ glamor_pict_format_is_compatible(PicturePtr picture) return (picture->format == PICT_a8r8g8b8 || picture->format == PICT_x8r8g8b8); case GL_ALPHA: + case GL_RED: + case GL_LUMINANCE: return (picture->format == PICT_a8); default: return FALSE; diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index d9db574..7df7a67 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -315,6 +315,10 @@ glamor_xv_render(glamor_port_private *port_priv) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (glamor_priv->one_channel_format == GL_RED && + port_priv->src_pix[0]->drawable.depth <= 8) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -322,6 +326,10 @@ glamor_xv_render(glamor_port_private *port_priv) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (glamor_priv->one_channel_format == GL_RED && + port_priv->src_pix[1]->drawable.depth <= 8) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -329,6 +337,10 @@ glamor_xv_render(glamor_port_private *port_priv) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (glamor_priv->one_channel_format == GL_RED && + port_priv->src_pix[2]->drawable.depth <= 8) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler"); glUniform1i(sampler_loc, 0); sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler"); -- 2.4.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
