diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index e99f8dc1c2..d9cb63f1ec 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -188,6 +188,7 @@ endforeach tests = [ ['rounded-rect'], ['transform'], + ['shader'], ] test_cargs = [] diff --git a/testsuite/gsk/shader.c b/testsuite/gsk/shader.c new file mode 100644 index 0000000000..c21f43db87 --- /dev/null +++ b/testsuite/gsk/shader.c @@ -0,0 +1,170 @@ +/* + * Copyright © 2020 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: Matthias Clasen + */ + +#include + +/* shader fragment as found in nature */ +const char shader0[] = +"// author: bobylito\n" +"// license: MIT\n" +"const float SQRT_2 = 1.414213562373;" +"uniform float dots;// = 20.0;" +"uniform vec2 center; //= vec2(0, 0);" +"" +"vec4 transition(vec2 uv) {" +" bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));" +" return nextImage ? getToColor(uv) : getFromColor(uv);" +"}"; + +/* Same shader, with our preamble added, and with newlines + * to make the regex happy. Added a variety of uniforms to + * exercise the parser. + */ +const char shader1[] = +"uniform float progress;\n" +"uniform sampler2D u_texture1;\n" +"uniform sampler2D u_texture2;\n" +"" +"vec4 getFromColor (vec2 uv) {\n" +" return GskTexture(u_texture1, uv);\n" +"}\n" +"\n" +"vec4 getToColor (vec2 uv) {\n" +" return GskTexture(u_texture2, uv);\n" +"}\n" +"\n" +"// author: bobylito\n" +"// license: MIT\n" +"const float SQRT_2 = 1.414213562373;\n" +"uniform float dots;// = 20.0;\n" +"uniform vec2 center; //= vec2(0, 0);\n" +"\n" +"uniform int test1 = -2;\n" +"uniform uint test2 = 2; \n" +"uniform bool test3;\n" +"uniform vec3 test4;\n" +"uniform vec4 test5;\n" +"\n" +"vec4 transition(vec2 uv) {\n" +" bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));\n" +" return nextImage ? getToColor(uv) : getFromColor(uv);\n" +"}\n" +"\n" +"void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)\n" +"{\n" +" fragColor = transition(uv);\n" +"}\n"; + +static void +test_create_simple (void) +{ + GBytes *bytes; + GskGLShader *shader; + + bytes = g_bytes_new_static (shader1, sizeof (shader1)); + shader = gsk_gl_shader_new_from_bytes (bytes); + g_assert_nonnull (shader); + + g_assert_cmpint (gsk_gl_shader_get_n_required_textures (shader), ==, 2); + g_assert_cmpint (gsk_gl_shader_get_n_uniforms (shader), ==, 8); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 0), ==, "progress"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 0), ==, GSK_GLUNIFORM_TYPE_FLOAT); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 1), ==, "dots"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 1), ==, GSK_GLUNIFORM_TYPE_FLOAT); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 2), ==, "center"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 2), ==, GSK_GLUNIFORM_TYPE_VEC2); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 3), ==, "test1"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 3), ==, GSK_GLUNIFORM_TYPE_INT); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 4), ==, "test2"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 4), ==, GSK_GLUNIFORM_TYPE_UINT); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 5), ==, "test3"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 5), ==, GSK_GLUNIFORM_TYPE_BOOL); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 6), ==, "test4"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 6), ==, GSK_GLUNIFORM_TYPE_VEC3); + g_assert_cmpstr (gsk_gl_shader_get_uniform_name (shader, 7), ==, "test5"); + g_assert_cmpint (gsk_gl_shader_get_uniform_type (shader, 7), ==, GSK_GLUNIFORM_TYPE_VEC4); + + g_object_unref (shader); + g_bytes_unref (bytes); +} + +static void +test_create_data (void) +{ + GBytes *bytes; + GskGLShader *shader; + GskUniformDataBuilder *builder; + graphene_vec2_t v2, vv2; + graphene_vec3_t v3, vv3; + graphene_vec4_t v4, vv4; + + bytes = g_bytes_new_static (shader1, sizeof (shader1)); + shader = gsk_gl_shader_new_from_bytes (bytes); + g_assert_nonnull (shader); + g_clear_pointer (&bytes, g_bytes_unref); + + builder = gsk_gl_shader_build_uniform_data (shader); + g_assert_nonnull (builder); + + graphene_vec2_init (&v2, 20, 30); + graphene_vec3_init (&v3, -1, -2, -3); + graphene_vec4_init (&v4, 100, 0, -100, 10); + gsk_uniform_data_builder_set_float (builder, 0, 0.5); + gsk_uniform_data_builder_set_float (builder, 1, 20.0); + gsk_uniform_data_builder_set_vec2 (builder, 2, &v2); + gsk_uniform_data_builder_set_int (builder, 3, -99); + gsk_uniform_data_builder_set_uint (builder, 4, 99); + gsk_uniform_data_builder_set_bool (builder, 5, 1); + gsk_uniform_data_builder_set_vec3 (builder, 6, &v3); + gsk_uniform_data_builder_set_vec4 (builder, 7, &v4); + + bytes = gsk_uniform_data_builder_finish (builder); + + g_assert_cmpfloat (gsk_gl_shader_get_uniform_data_float (shader, bytes, 0), ==, 0.5); + g_assert_cmpfloat (gsk_gl_shader_get_uniform_data_float (shader, bytes, 1), ==, 20.0); + gsk_gl_shader_get_uniform_data_vec2 (shader, bytes, 2, &vv2); + g_assert_true (graphene_vec2_equal (&v2, &vv2)); + + g_assert_cmpint (gsk_gl_shader_get_uniform_data_int (shader, bytes, 3), ==, -99); + g_assert_cmpuint (gsk_gl_shader_get_uniform_data_uint (shader, bytes, 4), ==, 99); + g_assert_cmpint (gsk_gl_shader_get_uniform_data_bool (shader, bytes, 5), ==, 1); + + gsk_gl_shader_get_uniform_data_vec3 (shader, bytes, 6, &vv3); + g_assert_true (graphene_vec3_equal (&v3, &vv3)); + gsk_gl_shader_get_uniform_data_vec4 (shader, bytes, 7, &vv4); + g_assert_true (graphene_vec4_equal (&v4, &vv4)); + + g_bytes_unref (bytes); + + gsk_uniform_data_builder_free (builder); + + g_object_unref (shader); +} + +int +main (int argc, + char *argv[]) +{ + gtk_test_init (&argc, &argv, NULL); + + g_test_add_func ("/shader/create/simple", test_create_simple); + g_test_add_func ("/shader/create/data", test_create_data); + + return g_test_run (); +}