From: Benjamin Otte Date: Sun, 28 May 2023 22:37:37 +0000 (+0200) Subject: testsuite: Add conversion tests X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~1^2~200^2~11 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3dc3d03a082f68eaaf30b1d94370487d06820ff7;p=gtk4.git testsuite: Add conversion tests Ensure we can convert from any format to any other format. --- diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c index f970d282c1..c0b10be67a 100644 --- a/testsuite/gdk/memorytexture.c +++ b/testsuite/gdk/memorytexture.c @@ -20,6 +20,13 @@ typedef enum { N_TEXTURE_METHODS } TextureMethod; +typedef enum { + CHANNEL_UINT_8, + CHANNEL_UINT_16, + CHANNEL_FLOAT_16, + CHANNEL_FLOAT_32, +} ChannelType; + struct _TextureBuilder { GdkMemoryFormat format; @@ -105,6 +112,44 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) } } +static ChannelType +gdk_memory_format_get_channel_type (GdkMemoryFormat format) +{ + switch (format) + { + case GDK_MEMORY_R8G8B8: + case GDK_MEMORY_B8G8R8: + case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: + case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: + case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: + case GDK_MEMORY_B8G8R8A8: + case GDK_MEMORY_A8R8G8B8: + case GDK_MEMORY_R8G8B8A8: + case GDK_MEMORY_A8B8G8R8: + return CHANNEL_UINT_8; + + case GDK_MEMORY_R16G16B16: + case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: + case GDK_MEMORY_R16G16B16A16: + return CHANNEL_UINT_16; + + case GDK_MEMORY_R16G16B16_FLOAT: + case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: + case GDK_MEMORY_R16G16B16A16_FLOAT: + return CHANNEL_FLOAT_16; + + case GDK_MEMORY_R32G32B32_FLOAT: + case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED: + case GDK_MEMORY_R32G32B32A32_FLOAT: + return CHANNEL_FLOAT_32; + + case GDK_MEMORY_N_FORMATS: + default: + g_assert_not_reached (); + return CHANNEL_UINT_8; + } +} + static gboolean gdk_memory_format_has_alpha (GdkMemoryFormat format) { @@ -272,6 +317,26 @@ decode (gconstpointer data, return TRUE; } +static gpointer +encode_two_formats (GdkMemoryFormat format1, + GdkMemoryFormat format2) +{ + return GSIZE_TO_POINTER (format1 * GDK_MEMORY_N_FORMATS + format2); +} + +static void +decode_two_formats (gconstpointer data, + GdkMemoryFormat *format1, + GdkMemoryFormat *format2) +{ + gsize value = GPOINTER_TO_SIZE (data); + + *format2 = value % GDK_MEMORY_N_FORMATS; + value /= GDK_MEMORY_N_FORMATS; + + *format1 = value; +} + static void texture_builder_init (TextureBuilder *builder, GdkMemoryFormat format, @@ -719,6 +784,16 @@ ensure_texture_format (GdkTexture *texture, return result; } +static void +color_make_opaque (GdkRGBA *result, + const GdkRGBA *color) +{ + result->red *= color->alpha; + result->green *= color->alpha; + result->blue *= color->alpha; + result->alpha = 1.0f; +} + static void create_random_color (GdkRGBA *color) { @@ -830,6 +905,70 @@ test_download_192x192 (gconstpointer data) g_object_unref (test); } +static void +test_conversion (gconstpointer data, + int size) +{ + GdkMemoryFormat format1, format2; + GdkTexture *test1, *test2; + GdkRGBA color1, color2; + gboolean accurate; + gsize i; + + decode_two_formats (data, &format1, &format2); + + if (gdk_memory_format_get_channel_type (format1) == CHANNEL_FLOAT_16) + accurate = FALSE; + else + accurate = TRUE; + + for (i = 0; i < N; i++) + { + /* non-premultiplied can represet GdkRGBA (1, 1, 1, 0) + * but premultiplied cannot. + * Premultiplied will always represent this as (0, 0, 0, 0) + */ + do + { + create_random_color (&color1); + } + while (color1.alpha == 0 && + gdk_memory_format_is_premultiplied (format1) != + gdk_memory_format_is_premultiplied (format2)); + + /* If the source can't handle alpha, make sure + * the target uses with the opaque version of the color. + */ + color2 = color1; + if (!gdk_memory_format_has_alpha (format1) && + gdk_memory_format_has_alpha (format2)) + color_make_opaque (&color2, &color2); + + test1 = create_texture (format1, TEXTURE_METHOD_LOCAL, 1, 1, &color1); + test2 = create_texture (format2, TEXTURE_METHOD_LOCAL, 1, 1, &color2); + + /* Convert the first one to the format of the 2nd */ + test1 = ensure_texture_format (test1, format2); + + compare_textures (test1, test2, accurate); + + g_object_unref (test2); + g_object_unref (test1); + } +} + +static void +test_conversion_1x1 (gconstpointer data) +{ + test_conversion (data, 1); +} + +static void +test_conversion_4x4 (gconstpointer data) +{ + test_conversion (data, 4); +} + static void add_test (const char *name, GTestDataFunc func) @@ -855,6 +994,29 @@ add_test (const char *name, } } +static void +add_conversion_test (const char *name, + GTestDataFunc func) +{ + GdkMemoryFormat format1, format2; + GEnumClass *enum_class; + + enum_class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT); + + for (format1 = 0; format1 < GDK_MEMORY_N_FORMATS; format1++) + { + for (format2 = 0; format2 < GDK_MEMORY_N_FORMATS; format2++) + { + char *test_name = g_strdup_printf ("%s/%s/%s", + name, + g_enum_get_value (enum_class, format1)->value_nick, + g_enum_get_value (enum_class, format2)->value_nick); + g_test_add_data_func_full (test_name, encode_two_formats (format1, format2), func, NULL); + g_free (test_name); + } + } +} + int main (int argc, char *argv[]) { @@ -865,6 +1027,8 @@ main (int argc, char *argv[]) add_test ("/memorytexture/download_1x1", test_download_1x1); add_test ("/memorytexture/download_4x4", test_download_4x4); add_test ("/memorytexture/download_192x192", test_download_192x192); + add_conversion_test ("/memorytexture/conversion_1x1", test_conversion_1x1); + add_conversion_test ("/memorytexture/conversion_4x4", test_conversion_4x4); gl_renderer = gsk_gl_renderer_new (); if (!gsk_renderer_realize (gl_renderer, NULL, NULL))