diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index ece50c8cd2..01b26120eb 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -239,80 +239,39 @@ gdk_gl_context_upload_texture (GdkGLContext *context, { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); guchar *copy = NULL; - GLint gl_internalformat; - GLint gl_format; - GLint gl_type; + GLenum gl_internalformat; + GLenum gl_format; + GLenum gl_type; gsize bpp; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */ + if (!gdk_memory_format_gl_format (data_format, + priv->use_es, + &gl_internalformat, + &gl_format, + &gl_type)) { - gl_internalformat = GL_RGBA8; - gl_format = GL_BGRA; - gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */ - { - gl_internalformat = GL_RGBA8; - gl_format = GL_RGB; - gl_type = GL_UNSIGNED_BYTE; - } - else if (priv->use_es && data_format == GDK_MEMORY_B8G8R8) - { - gl_internalformat = GL_RGBA8; - gl_format = GL_BGR; - gl_type = GL_UNSIGNED_BYTE; - } - else if (data_format == GDK_MEMORY_R16G16B16) - { - gl_internalformat = GL_RGBA16; - gl_format = GL_RGB; - gl_type = GL_UNSIGNED_SHORT; - } - else if (data_format == GDK_MEMORY_R16G16B16A16_PREMULTIPLIED) - { - gl_internalformat = GL_RGBA16; - gl_format = GL_RGBA; - gl_type = GL_UNSIGNED_SHORT; - } - else if (data_format == GDK_MEMORY_R16G16B16_FLOAT) - { - gl_internalformat = GL_RGB16F; - gl_format = GL_RGB; - gl_type = GL_HALF_FLOAT; - } - else if (data_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED) - { - gl_internalformat = GL_RGBA16F; - gl_format = GL_RGBA; - gl_type = GL_HALF_FLOAT; - } - else if (data_format == GDK_MEMORY_R32G32B32_FLOAT) - { - gl_internalformat = GL_RGB32F; - gl_format = GL_RGB; - gl_type = GL_FLOAT; - } - else if (data_format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED) - { - gl_internalformat = GL_RGBA32F; - gl_format = GL_RGBA; - gl_type = GL_FLOAT; - } - else /* Fall-back, convert to GLES format */ - { - copy = g_malloc (width * height * 4); + copy = g_malloc_n (width * 4, height); gdk_memory_convert (copy, width * 4, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, - data, stride, data_format, + data, stride, + data_format, width, height); - data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; - stride = width * 4; data = copy; - gl_internalformat = GL_RGBA8; - gl_format = GL_RGBA; - gl_type = GL_UNSIGNED_BYTE; + data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; + if (!gdk_memory_format_gl_format (data_format, + priv->use_es, + &gl_internalformat, + &gl_format, + &gl_type)) + { + g_assert_not_reached (); + } + } + else + { + copy = NULL; } bpp = gdk_memory_format_bytes_per_pixel (data_format); diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c index 2a4cfa1e92..8b2ba6ae6d 100644 --- a/gdk/gdkmemoryformat.c +++ b/gdk/gdkmemoryformat.c @@ -23,6 +23,8 @@ #include "gsk/ngl/fp16private.h" +#include + typedef struct _GdkMemoryFormatDescription GdkMemoryFormatDescription; typedef enum { @@ -175,17 +177,32 @@ struct _GdkMemoryFormatDescription GdkMemoryAlpha alpha; gsize bytes_per_pixel; gsize alignment; - + gboolean supports_gles; + struct { + guint internal_format; + guint format; + guint type; + } gl; /* no premultiplication going on here */ void (* to_float) (float *, const guchar*, gsize); void (* from_float) (guchar *, const float *, gsize); }; +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define GDK_GL_UNSIGNED_BYTE_FLIPPED GL_UNSIGNED_INT_8_8_8_8 +#elif G_BYTE_ORDER == G_BIG_ENDIAN +# define GDK_GL_UNSIGNED_BYTE_FLIPPED GL_UNSIGNED_INT_8_8_8_8_REV +#else +# error "Define the right GL flags here" +#endif + static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { [GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 4, G_ALIGNOF (guchar), + FALSE, + { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE }, b8g8r8a8_premultiplied_to_float, b8g8r8a8_premultiplied_from_float, }, @@ -193,6 +210,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 4, G_ALIGNOF (guchar), + FALSE, + { GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED }, a8r8g8b8_premultiplied_to_float, a8r8g8b8_premultiplied_from_float, }, @@ -200,6 +219,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 4, G_ALIGNOF (guchar), + TRUE, + { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }, r8g8b8a8_premultiplied_to_float, r8g8b8a8_premultiplied_from_float, }, @@ -207,6 +228,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_STRAIGHT, 4, G_ALIGNOF (guchar), + FALSE, + { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE }, b8g8r8a8_to_float, b8g8r8a8_from_float, }, @@ -214,6 +237,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_STRAIGHT, 4, G_ALIGNOF (guchar), + FALSE, + { GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED }, a8r8g8b8_to_float, a8r8g8b8_from_float, }, @@ -221,6 +246,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_STRAIGHT, 4, G_ALIGNOF (guchar), + TRUE, + { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }, r8g8b8a8_to_float, r8g8b8a8_from_float, }, @@ -228,6 +255,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_STRAIGHT, 4, G_ALIGNOF (guchar), + FALSE, + { GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED }, a8b8g8r8_to_float, a8b8g8r8_from_float, }, @@ -235,6 +264,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_OPAQUE, 3, G_ALIGNOF (guchar), + TRUE, + { GL_RGBA8, GL_RGB, GL_UNSIGNED_BYTE }, r8g8b8_to_float, r8g8b8_from_float, }, @@ -242,6 +273,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_OPAQUE, 3, G_ALIGNOF (guchar), + FALSE, + { GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE }, b8g8r8_to_float, b8g8r8_from_float, }, @@ -249,6 +282,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_OPAQUE, 6, G_ALIGNOF (guint16), + TRUE, + { GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT }, r16g16b16_to_float, r16g16b16_from_float, }, @@ -256,6 +291,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 8, G_ALIGNOF (guint16), + TRUE, + { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT }, r16g16b16a16_to_float, r16g16b16a16_from_float, }, @@ -263,6 +300,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_OPAQUE, 6, G_ALIGNOF (guint16), + TRUE, + { GL_RGB16F, GL_RGB, GL_HALF_FLOAT }, r16g16b16_float_to_float, r16g16b16_float_from_float, }, @@ -270,6 +309,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 8, G_ALIGNOF (guint16), + TRUE, + { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, r16g16b16a16_float_to_float, r16g16b16a16_float_from_float, }, @@ -277,6 +318,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_OPAQUE, 12, G_ALIGNOF (float), + TRUE, + { GL_RGB32F, GL_RGB, GL_FLOAT }, r32g32b32_float_to_float, r32g32b32_float_from_float, }, @@ -284,6 +327,8 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = { GDK_MEMORY_ALPHA_PREMULTIPLIED, 16, G_ALIGNOF (float), + TRUE, + { GL_RGBA32F, GL_RGBA, GL_FLOAT }, r32g32b32a32_float_to_float, r32g32b32a32_float_from_float, } @@ -301,6 +346,26 @@ gdk_memory_format_alignment (GdkMemoryFormat format) return memory_formats[format].alignment; } +gboolean +gdk_memory_format_gl_format (GdkMemoryFormat format, + gboolean gles, + guint *out_internal_format, + guint *out_format, + guint *out_type) +{ + *out_internal_format = memory_formats[format].gl.internal_format; + *out_format = memory_formats[format].gl.format; + *out_type = memory_formats[format].gl.type; + + if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT) + return FALSE; + + if (gles && !memory_formats[format].supports_gles) + return FALSE; + + return TRUE; +} + static void premultiply (float *rgba, gsize n) diff --git a/gdk/gdkmemoryformatprivate.h b/gdk/gdkmemoryformatprivate.h index 0de89f0756..8c8e024b23 100644 --- a/gdk/gdkmemoryformatprivate.h +++ b/gdk/gdkmemoryformatprivate.h @@ -26,6 +26,11 @@ G_BEGIN_DECLS gsize gdk_memory_format_alignment (GdkMemoryFormat format) G_GNUC_CONST; gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) G_GNUC_CONST; +gboolean gdk_memory_format_gl_format (GdkMemoryFormat format, + gboolean gles, + guint *out_internal_format, + guint *out_format, + guint *out_type); void gdk_memory_convert (guchar *dest_data, gsize dest_stride,