[PATCH 4/8] glamor: Use GL_RED instead of GL_ALPHA if we have texture_swizzle

Dave Airlie airlied at gmail.com
Mon Jan 18 16:56:52 PST 2016


From: Keith Packard <keithp at keithp.com>

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 <keithp at keithp.com>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 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



More information about the xorg-devel mailing list