[PATCH 4/8] glamor: Use GL_RED instead of GL_ALPHA if we have texture_swizzle (v2)
Dave Airlie
airlied at gmail.com
Mon Jan 18 23:02:30 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]
v2: consolidate setting swizzle into the texture creation code, it should
work fine there. Handle swizzle when setting color as well.
Signed-off-by: Keith Packard <keithp at keithp.com>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
glamor/glamor.c | 4 ++++
glamor/glamor_fbo.c | 4 ++++
glamor/glamor_picture.c | 22 ++++++++++++++--------
glamor/glamor_priv.h | 2 ++
glamor/glamor_transfer.c | 2 +-
glamor/glamor_transform.c | 6 ++++++
glamor/glamor_utils.h | 4 +++-
7 files changed, 34 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_fbo.c b/glamor/glamor_fbo.c
index b1b584d..1093ba9 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;
@@ -338,6 +340,8 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ if (format == glamor_priv->one_channel_format && format == GL_RED)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
glamor_priv->suppress_gl_out_of_memory_logging = true;
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
format, GL_UNSIGNED_BYTE, NULL);
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_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_transform.c b/glamor/glamor_transform.c
index f476a99..ad06943 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -111,12 +111,18 @@ glamor_set_color(PixmapPtr pixmap,
CARD32 pixel,
GLint uniform)
{
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private((pixmap)->drawable.pScreen);
float color[4];
glamor_get_rgba_from_pixel(pixel,
&color[0], &color[1], &color[2], &color[3],
format_for_pixmap(pixmap));
+ if ((pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8) &&
+ glamor_priv->one_channel_format == GL_RED)
+ color[0] = color[3];
+
glUniform4fv(uniform, 1, color);
}
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;
--
2.4.3
More information about the xorg-devel
mailing list